【问题标题】:Find the minimum hamming distance between a string and a long vector of strings (fast)找到一个字符串和一个长字符串向量之间的最小汉明距离(快速)
【发布时间】:2018-08-19 13:36:44
【问题描述】:

我需要计算输入字符串和大字符串数据集之间的汉明距离。 (数据集中所有字符串的长度与输入字符串的长度相同。

例如,如果

input <- "YNYYEY"
dataset <- c("YNYYEE", "YNYYYY", "YNENEN", "YNYYEY")

inputdataset 中的每个字符串之间的汉明距离是 1、1、3、0,所以最小值是 0。我写了一个函数来计算两个字符串之间的汉明距离:

HD <- function(str1, str2){

   str1 <- as.character(str1)
   str2 <- as.character(str2)

   length.str1 <- nchar(str1)
   length.str2 <- nchar(str2)

   string.temp1 <- c()
   for (i in 1:length.str1){
     string.temp1[i] = substr(str1, start=i, stop=i)
   }
   string.temp2 <- c()
   for (i in 1:length.str2){
     string.temp2[i] = substr(str2, start=i, stop=i)
   }
   return(sum(string.temp1 != string.temp2))
   }

但是数据集太大了,所以我需要加快速度,您知道我可以快速完成吗?感谢您的帮助。

【问题讨论】:

    标签: r string performance vectorization hamming-distance


    【解决方案1】:

    在 R 级别,您可以使用 strsplitcbind!=colSumsmin。它们都是“矢量化的”。

    a <- "YNYYEY"
    b <- c("YNYYEE", "YNYYYY", "YNENEN", "YNYYEY")
    A <- strsplit(a, split = "")[[1]]
    #[1] "Y" "N" "Y" "Y" "E" "Y"
    B <- do.call("cbind", strsplit(b, split = ""))
    #     [,1] [,2] [,3] [,4]
    #[1,] "Y"  "Y"  "Y"  "Y" 
    #[2,] "N"  "N"  "N"  "N" 
    #[3,] "Y"  "Y"  "E"  "Y" 
    #[4,] "Y"  "Y"  "N"  "Y" 
    #[5,] "E"  "Y"  "E"  "E" 
    #[6,] "E"  "Y"  "N"  "Y" 
    D <- colSums(A != B)
    #[1] 1 1 3 0
    min(D)
    #[1] 0
    

    This kind of "vectorization" creates many temporary matrices / vectors and uses plenty of RAM。但希望这是值得的。

    在 C/C++ 级别上,您可以做得更好(参见 here 的案例研究),但我今天并不热衷于编写 C/C++ 代码。


    我遇到了stringdist 包(甚至还有一个 标签)。函数stringdist 依赖于一个主力例程stringdist:::do_dist,它是用C 编写的。它省了我的努力。

    library(stringdist)
    d <- stringdist(a, b, method = "hamming")
    #[1] 1 1 3 0
    min(d)
    #[1] 0
    

    stringdist() 的运行速度几乎比 colSum() 慢十倍。

    这真的很有趣。可能它的 C 代码或 R 代码正在做其他复杂的事情。

    【讨论】:

      【解决方案2】:

      您无法比O(n) 更好地改进它,这意味着您必须查看所有数据集,并计算每次观察的距离。

      如果您 sort 基于给定点的所有观察结果,唯一的改进可能会发生在您的数据集上。在这种情况下,您可能更容易在数据集中找到一个字符串(0 距离结果)。这是您唯一可以做的改进。

      【讨论】:

      • 感谢您的回答。我在 R 中的实现怎么样?有没有可能使代码运行得更快?或者是否有任何算法可以通过将字母转换为二进制字符串来加快速度?
      • @Codezy 代码本身没有问题。主要耗时的活动是在所有数据集上运行它。所以,这里的距离评估没什么大不了的。
      • 我同意,如果数据集很大,则无法根据strings 对观察结果进行排序。但是,如果它是这样设计的,那么从一开始就是可行的。
      猜你喜欢
      • 2017-05-18
      • 1970-01-01
      • 2014-08-28
      • 2014-01-28
      • 2019-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-10
      相关资源
      最近更新 更多