Cod*_*ice 0 haskell dynamic-programming
Haskell是否提供动态编程的任何工具?在过程语言中,我将使用数组来存储基于递归关系的计算.我如何在Haskell中做类似的事情?
根据情况有很多不同的方式.也就是说,Haskell中的简单动态编程算法通常比其他语言简单得多,因为Haskelll很懒惰
考虑Fibonacci函数(函数式编程的"Hello World")
fib n | n < 2 = 1
fib n | otherwise = fib (n-1) + fib (n-2)
Run Code Online (Sandbox Code Playgroud)
这是以指数时间(grr)运行的.我们可以在一个懒惰的无限长列表中平凡地存储fib的所有值
fibs = map fib [0..]
Run Code Online (Sandbox Code Playgroud)
现在我们可以观察到
fibs !! n
= (map fib [0..]) !! n =
= fib ([0..] !! n)
= fib n
Run Code Online (Sandbox Code Playgroud)
到目前为止,这对我们没有帮助,但我们可以利用这种等同性来发挥我们的优势
fib n | n < 2 = 1
fib n | otherwise = (fibs !! (n-1)) + (fibs !! (n-2)) where
fibs = map fib [0..]
Run Code Online (Sandbox Code Playgroud)
这为Fibonacci函数提供了一个线性时间解决方案(虽然它泄漏了空间......实际上并没有这样做),并且只有在Haskell是懒惰的情况下才有效.我们根据自身的递归关系定义了无限的数据结构.奇迹是它在有限的时间内运行(非严格),它在线性时间内运行是需要调用的时间最优性(Haskell的成本模型)的乘积.这种线性时间性能的原因是每个条目fibs最多计算一次(或可能永远不会).