Wagner-Fischer算法

时间:2015-06-11 22:21:02

标签: string algorithm matrix dynamic-programming edit-distance

我正在尝试理解用于找到字符串之间距离的Wagner-Fischer算法。我正在通过以下链接查看它的伪代码:http://en.wikipedia.org/wiki/Wagner%E2%80%93Fischer_algorithm

long = [1,2,3,4,5]  
short = [1,3,5]  
# same_sequence(long, short) = True  
short = [1,4,3]  
# same_sequence(long, short) = False

实际上我得到算法的观点并直观地理解它,对我来说并不明显为什么 d [i-1,j] + 1,d [i,j-1] + 1和d [i -1,j-1] + 1 被视为删除,插入和替换。如果有人以更详细的方式解释实施细微差别,那就太好了。

2 个答案:

答案 0 :(得分:7)

我创建了一个gist,它打印出操作序列以及每个步骤试图解决的目标,这应该补充我对Fischer-Wagner算法的解释。

为了能够理解Fischer-Wagner算法,您必须记住它属于dynamic programming算法族。这意味着它将计算更大问题的部分解决方案,存储部分解决方案并使用部分计算的结果进行下一次计算。

那么这对Fisher-Wagner算法意味着什么呢?在这种情况下,这意味着距离矩阵d的每个元素都包含最佳的操作跟踪,以使您从当前字符串A到另一个字符串B.这个解释仍然有点抽象,所以让我解释一下我的意思通过一个例子来引导你。

让我们假设您想要计算两个字符串的Levensthein距离" ABV "和" FV "使用Fischer-Wagner算法。然后您的距离矩阵将如下所示:

+-----+---+---+---+---+
|     |j->| 0 | 1 | 2 |
+-----+---+---+---+---+
|   i |   | # | F | V |
+-----+---+---+---+---+
|   0 | # |   |   |   |
|   1 | A |   |   |   |
|   2 | B |   |   |   |
|   3 | C |   |   |   |
+-----+---+---+---+---+

此表的第一行/列命名距离矩阵的索引,第二个名称为字符串的字符。 '#'是空字符串(即长度为零的字符串)。

此距离矩阵的每个元素都标记了您要解决的子问题。例如,条目[i = 0,j = 2]包含从空字符串到达​​的最短距离""到" FV "条目[i = 2,j = 1]包含问题的最短距离" AB " => " ˚F&#34 ;.

让我们将算法快速转发到子问题[i = 2,j = 2],即如何从" AB "到" FV "。在这种情况下,距离矩阵看起来像这样。

+-----+---+---+---+---+
|     |j->| 0 | 1 | 2 |
+-----+---+---+---+---+
|   i |   | # | F | V |
+-----+---+---+---+---+
|   0 | # | 0 | 1 | 2 |
|   1 | A | 1 | 1 | 2 |
|   2 | B | 2 | 2 |   |
|   3 | C | 3 | 3 |   |
+-----+---+---+---+---+ 

" "和" V "不相等,这意味着我们需要执行以下三个操作之一来使它们相等:

  1. 删除" B "。我们将单元格的成本高于d [i = 1,j = 2],因为我们知道这个单元格是从" A &#34获得的最便宜的操作序列; => " FV &#34 ;.但是,我们的问题来自" AB " => " FV ",而不是来自" A " => " FV 。我们知道我们可以替换" A "通过" FV "通过应用单元格d [i = 1,j = 2]的操作(我们之前解决了这个子问题),这给我们留下了一个字符串" FVB "成本为2.然后我们删除了" B " (" FVB " =>" FV ")我们完成了。此操作的成本为2 + 1。
  2. 插入" V "。类似于删除" B ",只有我们将值带到左边d [i = 2,j = 1],因为我们知道它是最便宜的操作序列来自" AB " =>" F "。由于我们的问题是来自" AB " =>" FV ",我们只需要添加费用插入" V "我们完成了。
  3. 替代" B "用" V "。与之前的案例类似。我们知道d [i = 1,j = 1]包含要更改的最便宜的操作序列" A " =>" F &#34 ;.应用此操作会将我们的问题更改更改为" FB " =>" FV ",可以通过替换来解决" "与" F "。
  4. 在考虑了这三个选项后,我们选择最便宜的一个,即取代" B " by" F " (1 + 1)。

    以这种方式解决所有子问题之后,输出将产生最终结果,这是" ABC 的最小编辑距离  => " FV &#34 ;.

答案 1 :(得分:2)

请注意,想象保留在列中的字符串是常量,我们需要找到保留在行中的字符串的编辑距离。例如,见这个 enter image description here

这里我们正在尝试计算AVERY的编辑距离! 所以现在,子结构 DP [i] [j] = DP [i-1] [j-1](如果G [j] == A [i])

注意:G代表GARVEY,A代表AVERY

因为如果我们可以在k个操作中解决G [j-1]和A [i-1]的编辑距离,我们可以解决G [j]和A [i]操作(最后一个字符不需要操作)

其他明智的

DP [i] [j] =以下

的最小值

DP [i-1] [j] +1(参见我们只能从行字符串中删除(其EDIT距离将被计算!)DP [i-1] [j]表示字符串G [1。 ..j]和A [1 ... i-1]!见字符A [i]删除??)

DP [i] [j-1] +1(看到这不是删除!!我们做的是在第i + 1位添加一个角色!因此它等于G [j](我们可以添加任何字符))

DP [i-1] [j-1] +1(我想现在这很简单,第i和第j个字符不一样,所以我们所做的就是把A [i]字符变成G [ j]个)

随意问疑惑:)