我想计算递归定义的函数值r(i,j)
,它们由
r i j | i<0 || j<0 = 0
| i==0 && j==0 = 1
| otherwise = (i-1) * r (i-2) j + r (i-1) (j-1)
显然,这些系数的NxN
表可以在O(N^2)
中计算。
不幸的是,直截了当的评估,如
[[r i j | j <-[0..50]]| i <- [0..50]]
以惊人的无效方式(指数复杂性)执行。显然,Haskell为每个r i j
构建整个递归树,并忽略先前计算的r (i-1) (j-1)
等的值。
计算这样一张桌子的优雅有效方法是什么?
答案 0 :(得分:3)
正如FUZxxl所说,这是一个回忆问题。
r i j | i < 0 || j < 0 = 0
| otherwise = rss !! i !! j
rss = [[r' i j | j <- [0..]] | i <- [0..]]
where r' 0 0 = 1
r' i j = (i-1) * r (i-2) j + r (i-1) (j-1)
如果您需要一个精确显示最多50个值的显式表格,您可以使用take 51 (map (take 51) rss)
或[[r i j | j <-[0..50]]| i <- [0..50]]
。否则,您可以直接致电r
或引用rss
。