RubyでDPマッチング
端っこから端っこまでのシンプルなDPマッチング.
べたーっとやっているので簡単なはず.聞いた話では探索をきちんとすれば余分な領域確保とか要らないらしいです.僕は頭が爆発しそうなので諦めました.
別のファイルから音素間のユークリッド距離を引っ張ってきてコストに使ってます.
#!/usr/bin/ruby require 'DP' onoA = "hogehoge" onoB = "fugafuga" aryA = onoA.split(//) aryB = onoB.split(//) LenA = aryA.length LenB = aryB.length dptable = Array.new(LenA){Array.new(LenB)} #スコアテーブル euc = EUC_TABLE.new #ユークリッド距離テーブル distance = 0 #マッチング結果 #初期値の角 dptable[0][0] = euc.get(aryA[0], aryB[0]) #端を埋める 1.upto(LenA-1) do |i| dptable[i][0] = euc.get(aryA[i], aryB[0]) + dptable[i-1][0] end 1.upto(LenB-1) do |i| dptable[0][i] = euc.get(aryA[0], aryB[i]) + dptable[0][i-1] end #スコア表を作成 1.upto(LenA-1) do |i| 1.upto(LenB-1) do |j| #現在の位置の距離 dist = euc.get(aryA[i], aryB[j]) #現在の位置へとかかるコストをハッシュ costs = { "yoko"=>dptable[i-1][j]+dist, "tate"=>dptable[i][j-1]+dist, "naname"=>dptable[i-1][j-1]+2*dist } #文字が同じ場合は斜め移動を選択,それ以外は最小値を選択 if aryA[i] == aryB[j] dptable[i][j] = costs["naname"] elsif dptable[i][j] = costs.values.min end end end p distance = dptable[LenA-1][LenB-1]
参考にしたサイトは以下の通り.
Dynamic Programming による類似文字列マッチの実装例
DPマッチングのプログラム、ソースコード
DPマッチング
配列の初期化で詰まった
mapee.jp
↑を見て解決.
ary = Array.new(LenA, Array.new(LenB, nil))
みたいな感じで最初初期化してて,値の代入が上手くいかなかった.
ブロックを渡して初期化.