Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 使用Data.Memo组合器实现编辑距离算法_Haskell_Memoization_Levenshtein Distance - Fatal编程技术网

Haskell 使用Data.Memo组合器实现编辑距离算法

Haskell 使用Data.Memo组合器实现编辑距离算法,haskell,memoization,levenshtein-distance,Haskell,Memoization,Levenshtein Distance,假设我想实现(编辑距离)的常用动态规划算法。很容易得出递归: 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,

假设我想实现(编辑距离)的常用动态规划算法。很容易得出递归:

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.Memo组合器来实现这一点,我已经尝试了几种方法。以下是我目前的尝试:

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

然而,回忆录似乎没有任何效果,尽管我希望任何回忆录都能显著提高运行时间,因为它至少是多项式的。我的实现有什么问题?如何在尽可能保留编辑距离的高级别定义的同时获得正常运行时间

如果您发布的代码实际上是您正在做的,那么您是做错了!:-)。如果要记忆递归函数,则需要将对递归版本的调用回调到记忆版本中。例如:

editDistance (x:xs) (y:ys)
  | x == y = elm xs ys
  | ...
否则,您将执行完整的递归计算并仅存储最终结果。您需要存储中间结果

这里还有一个问题。elm的memo表不应该依赖于它的参数(理想情况下,您甚至不应该提及参数,因此您不应该依赖于编译器是否足够聪明来找出依赖项)。如果memo表依赖于参数,那么您必须为每个不同的参数构建一个新表,并且我们需要为所有参数共享一个表。你可以尝试一些愚蠢的事情,比如对论点的整个结构进行记忆:

elm = M.memo2 (M.list M.char) (M.list M.char)
看看这是否加快了速度(结合前一个技巧)。然后,您可以继续尝试使用长度而不是整个列表结构来获得额外的提升


希望有帮助。

你难道不知道吗,这实际上就是问题所在,现在看来很明显=D。