假设我想为Levensthein 距离(编辑距离)实现通常的动态规划算法。很容易想出递归:
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
然而,记忆化似乎没有任何效果,尽管我希望任何记忆化都能显着改善运行时间,因为它至少是多项式的。我的实施有什么问题?如何在尽可能多地保留编辑距离的高级定义的同时获得良好的运行时间?