Levenshtein距离算法实现中的填充动作矩阵

时间:2012-03-01 16:32:52

标签: javascript algorithm levenshtein-distance

我正在尝试改进现有的javascript levenstein距离计算源代码,以生成不仅包含当前setps值的martix,还包括所采取的操作(插入,替换,删除或匹配)

我在“动作”矩阵中得到了错误的结果:

levenstein actions

在我们看到的算法中(不是来自维基百科的js):

 d[i, j] := minimum
                    (
                      d[i-1, j] + 1,  // a deletion
                      d[i, j-1] + 1,  // an insertion
                      d[i-1, j-1] + 1 // a substitution
                    )

因此,在我的JS代码中,我执行以下操作:

// Step 6
d[i][j] = Minimum(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);

// a deletion
if(d[i][j] == d[i - 1][j] + 1) {
    actions[i][j] = 'D';
}

// a insertion
if(d[i][j] == d[i][j - 1] + 1) {
    actions[i][j] = 'I';
}

// a substitution
if(d[i][j] == d[i - 1][j - 1] + cost) {
    actions[i][j] = 'R';
}

d矩阵(二维数组)用于值,并且使用正确的值填充。 但为什么相应的actions矩阵不显示逻辑算法会做什么?

在分配'我','R','D'方面我做错了什么?或者它是正确的,对我来说似乎不合逻辑,因为我认为在上述场景中,插入将在第二步中发生。

BTW,在Levenstein算法的情况下生成这样的“动作”矩阵实际上是否明智?

1 个答案:

答案 0 :(得分:1)

通常有很多方法可以为任何给定的Levensthein矩阵生成一组“动作”。在您的示例中,您可以将结果成本矩阵追溯到最小值,您将找到相当多的路径。

以下是一些例子:

(0,0)(0,1)(1,2)(1,3)(2,4)(3,5)

(0,0)(1,1)(1,2)(1,3)(2,4)(3,5)

(0,0)(0,1)(0,2)(1,3)(2,4)(3,5)

所以我可以找到相同距离矩阵的至少三种不同的解释。这意味着,除非您有某种方式来偏向方向(例如,优先选择替换而不是插入的删除),否则您的矩阵将非常模糊。

现在你建议用于填充动作矩阵的算法:在你的情况下,你隐含地喜欢替换(因为它们被最后检查并将覆盖先前的选择)而不是删除的插入和插入。这就是矩阵中所有R的来源。让我们看看这里发生了什么:

当我们更喜欢替换时,建议的解决方案是在其他任何内容之前插入AN,然后将M替换为N,将A替换为{{1} {}}和A X。如果你检查你可以看到这将花费四(两次插入和两次“实际”替换),这正是矩阵确定的(这是我追踪的路径中的最后一条路径)。

现在再次检查您的操作矩阵,我们发现,如果我们从最后一个角落追溯:SRR位于R,{ {1}}和(3,5)。这相当于(2,4)(1,3)的最终替换。然而,这里缺少的是插入我在上面描述的前导MAX。查看矩阵,可以看到第一行和列中有数字,而不是动作。然而,这些应该分别是删除和替换,在这种情况下,您可以生成最终序列NAS,其成本为4,将AN转换为SSRRR

但是你应该知道,没有必要像你一样计算矩阵中的动作,因为所有信息都可以在最终的成本矩阵中获得。您始终可以追溯从最后一个角落到第一个角落的最终成本矩阵,您将能够重建所有可以将一个单词转换为另一个单词的路径。但是,一旦你在动作矩阵中修复了动作,所有可能性中只剩下一条路径。

这必须做很多事情,成本很好且唯一地定义,而路径可能非常模糊。

修改

以下是路径的完整动作矩阵,其中包含歧义:

MAX