レーベンシュタイン距離(編集距離)の通常の動的計画法のアルゴリズムを実装したいとしましょう。再帰を考え出すのはとても簡単です:
editDistance [] ys = length ys
editDistance xs [] = length xs
editDistance (x:xs) (y:ys)
| x == y = editDistance xs ys
| otherwise = minimum [
1 + editDistance xs (y:ys),
1 + editDistance (x:xs) ys,
1 + editDistance xs ys]
これは指数関数的な実行時間の影響を受けるため、関数をメモする必要があります。私は Data.Memocombinators を使用してこれを行いたいと考えており、いくつかの方法を試しました。これが私の現在の試みです:
import qualified Data.MemoCombinators as M
memLength str =
M.wrap
(\i -> drop i str)
(\xs -> length str - length xs)
(M.arrayRange (0,length str))
elm xs ys = (M.memo2 memListx memListy editDistance) xs ys
where
memListx = memLength xs
memListy = memLength ys
ただし、少なくとも多項式であるため、メモ化によって実行時間が大幅に改善されると予想されますが、メモ化には何の効果もないようです。実装の何が問題になっていますか? 編集距離の高レベルの定義を可能な限り維持しながら、適切な実行時間を取得するにはどうすればよいですか?