3

文字列間の距離を見つけるための Wagner-Fischer アルゴリズムを理解しようとしています。次のリンクで疑似コードを調べています: http://en.wikipedia.org/wiki/Wagner%E2%80%93Fischer_algorithm

int EditDistance(char s[1..m], char t[1..n])
   // For all i and j, d[i,j] will hold the Levenshtein distance between
   // the first i characters of s and the first j characters of t.
   // Note that d has (m+1)  x(n+1) values.
   let d be a 2-d array of int with dimensions [0..m, 0..n]

   for i in [0..m]
     d[i, 0] ← i // the distance of any first string to an empty second string
   for j in [0..n]
     d[0, j] ← j // the distance of any second string to an empty first string

   for j in [1..n]
     for i in [1..m]
       if s[i] = t[j] then  
         d[i, j] ← d[i-1, j-1]       // no operation required
       else
         d[i, j] ← minimum of
                    (
                      d[i-1, j] + 1,  // a deletion
                      d[i, j-1] + 1,  // an insertion
                      d[i-1, j-1] + 1 // a substitution
                    )

   return d[m,n]

実際、私はアルゴリズムの要点を理解し、直感的に理解しています。なぜなら、d[i-1, j] + 1, d[i, j-1] + 1 と d[i-1, j-1 ] + 1は、削除、挿入、置換と見なされます。誰かが実装のニュアンスをより詳細に説明してくれれば幸いです。

4

2 に答える 2

9

一連の操作と、各ステップが解決しようとしている目標を出力する要点を作成しました。これは、Fischer-Wagner アルゴリズムの説明を補足するものです。

Fischer-Wagner アルゴリズムを理解するには、それが動的計画 法アルゴリズムのファミリーに属していることを覚えておく必要があります。これは、より大きな問題の部分的な解決策を計算し、部分的な解決策を保存し、部分的な計算の結果を次の計算に使用することを意味します。

それでは、これはフィッシャー・ワグナーのアルゴリズムにとって何を意味するのでしょうか? このコンテキストでは、これは、距離行列 d の各要素に、現在の文字列 A から別の文字列 B に移動するための可能な限り最良の操作のトレースが含まれていることを意味します。この説明はまだ少し抽象的です。例を紹介します。

Fischer-Wagner アルゴリズムを使用して、2 つの文字列 " ABV " と " FV "のレーベンシュタイン距離を計算するとします。次に、距離行列は次のようになります。

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

このテーブルの最初の行/列は距離行列のインデックスを示し、2 番目の名前は文字列の文字を示します。'#' は空の文字列 (つまり、長さがゼロの文字列) です。

この距離行列の各要素は、解決するサブ問題をマークします。たとえば、エントリ [i=0, j=2] には、空の文字列 "" から " FV " に到達するまでの最短距離が含まれます。エントリ [i=2, j=1] には、問題 " ABの最短距離が含まれます。 " => " F ".

アルゴリズムをサブ問題 [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 |   |
+-----+---+---+---+---+ 

" B " と " V " は等しくありません。つまり、それらを等しくするには、次の 3 つの操作のいずれかを実行する必要があります。

  1. 「 B 」を削除します。d[i=1, j=2] より上のセルのコストを計算します。これは、このセルが " A " => " FV "から得られる演算の最も安価なシーケンスであることがわかっているためです。しかし、私たちの問題は、" A " => " FV からではなく、" AB " = > " FV "から取得することです.セル d[i= 1, j=2] (この部分問題は前に解決した)、コスト 2 の文字列 " FVB " が残る。その後、" 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 "を変更する最も安価な操作シーケンスが含まれていることがわかっています。この操作を適用すると、問題は「 FB」=>「FV 」に変わります。これは、「 B」を「F 」に置き換えることで解決できます。

これら 3 つのオプションを検討した後、" B " を " F " (1+1)に置き換えた最も安価なオプションを選択します。

その方法ですべての下位問題を解決した後、出力は最終結果を生成します。これは、" ABC => " FV "からの最小編集距離です。

于 2016-11-23T13:58:22.370 に答える