计算Levenshtein距离的最有效方法

eff*_*iss 23 algorithm optimization levenshtein-distance

我刚刚实现了一个最佳匹配文件搜索算法,以找到与字典中字符串最接近的匹配.在分析我的代码之后,我发现绝大部分时间花在计算查询和可能结果之间的距离上.我目前正在使用2-D数组实现算法来计算Levenshtein距离,这使得实现成为O(n ^ 2)运算.我希望有人可以建议更快的方式做同样的事情.

这是我的实现:

public int calculate(String root, String query)
{
  int arr[][] = new int[root.length() + 2][query.length() + 2];

  for (int i = 2; i < root.length() + 2; i++)
  {
    arr[i][0] = (int) root.charAt(i - 2);
    arr[i][1] = (i - 1);
  }

  for (int i = 2; i < query.length() + 2; i++)
  {
    arr[0][i] = (int) query.charAt(i - 2);
    arr[1][i] = (i - 1);
  }

  for (int i = 2; i < root.length() + 2; i++)
  {
    for (int j = 2; j < query.length() + 2; j++)
    {
      int diff = 0;
      if (arr[0][j] != arr[i][0])
      {
        diff = 1;
      }
      arr[i][j] = min((arr[i - 1][j] + 1), (arr[i][j - 1] + 1), (arr[i - 1][j - 1] + diff));
    }
  }
  return arr[root.length() + 1][query.length() + 1];
}

public int min(int n1, int n2, int n3)
{
  return (int) Math.min(n1, Math.min(n2, n3));
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*lli 23

关于Levenshtein距离的维基百科条目提供了有用的优化计算建议 - 在您的情况下最适用的是如果您可以设置k最大感兴趣距离(超出可能无限远的任何东西!),您可以减少计算O(n times k)而不是O(n squared)(基本上只要最小可能的距离变为放弃> k).

由于您正在寻找最接近的匹配,您可以逐渐减少k到目前为止找到的最佳匹配距离 - 这不会影响最坏情况的行为(因为匹配可能是距离的递减顺序,这意味着你'永远不会纾困,但平均情况应该有所改善.

我认为,如果你需要得到显着更好的性能,你可能不得不接受一个计算更接近的距离(因此得到"一个相当不错的比赛",而不是一定是最优的)一些有实力的妥协.


And*_* B. 7

根据本博客的评论,Speeding Up Levenshtein,您可以使用VP-Trees并实现O(nlogn).同一博客上的另一条评论指出了VP-Trees和Levenshteinpython实现.如果有效,请告诉我们.

  • 我意识到这是一个老线程,但你让我困惑了一分钟.你不是在说同一个`n`!在OP`n`中是单词长度,我们对计算2个单词之间距离的时间感兴趣.虽然你是`n`是字典中的单词数,而'n log n`是你调用距离函数的次数.如果你将'W k D log D`与`D`字典大小,`W`字大小,`k`距离阈值结合起来. (4认同)