在大型阵列上查找编辑距离的更有效方法

时间:2016-07-03 11:09:09

标签: c++ algorithm

我有大量的单词(300k字),我想找到每个单词之间的编辑距离,所以我只是迭代它并运行这个版本的levenstein算法:

unsigned int edit_distance(const std::string& s1, const std::string& s2)
{
    const std::size_t len1 = s1.size(), len2 = s2.size();
    std::vector<std::vector<unsigned int>> d(len1 + 1, std::vector<unsigned int>(len2 + 1));
d[0][0] = 0;
for (unsigned int i = 1; i <= len1; ++i) d[i][0] = i;
for (unsigned int i = 1; i <= len2; ++i) d[0][i] = i;

for (unsigned int i = 1; i <= len1; ++i)
    for (unsigned int j = 1; j <= len2; ++j)
        // note that std::min({arg1, arg2, arg3}) works only in C++11,
        // for C++98 use std::min(std::min(arg1, arg2), arg3)
        d[i][j] = std::min({ d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1) });
return d[len1][len2];
}

所以我想知道的是,如果有更有效的方法,我听说Levenshtein Autonoma,但我不确定这是否会更有效率。

我想你可以避免通过预处理来反复处理相同的事情,但我不知道如何实际实现它(一些近似的计算将是预处理一切将是大约10 ^ 28次操作,以便不会有任何进步)

2 个答案:

答案 0 :(得分:1)

如他的评论中所述,OP实际上是在寻找编辑距离小于2的所有对。

给定n个单词的输入,一个简单的方法是进行n(n-1)/ 2个比较,但是当编辑距离中的L为metric space for strings时,可能需要较少的比较。

Levenshtein距离是一个度量空间,满足4个必需的度量公理 - 包括三角不等式。

修改

鉴于此,我们可以使用谢尔盖·布林(谷歌的联合创始人)在1995年的论文Near Neighbor Search in Large Metric Spaces中提出的方法来解决我们的问题。

引自论文:给定度量空间(X,d),数据集Y⊆X,查询点x∈X和范围r∈R,x的近邻是y的集合∈Y,使得d(x,y)≤r。

在本文中,Brin介绍了GNAT(几何近邻访问树) - 一种解决这一问题的数据结构。布林实际上使用Levenshtein距离(他称之为#34;编辑距离&#34;)对两个文本语料库测试他的算法的性能。

多年来,GNAT变得众所周知并广泛使用。 Geometric Near-neighbor Access Tree (GNAT) revisited中建议对GNAT进行一些改进 - Fredriksson 2016。

答案 1 :(得分:1)

如果在评论中指出你真正想要的是找到编辑距离最多为2的对,你可以从每个单词生成所有删除最多两个字符(最多应该是500个左右)的可能性,并存储这些在哈希表中。然后,您只需要检查哈希桶中的每对单词,通过查看删除是否重合可能不难做到。