Haskell:递归定义的函数值的有效计算

时间:2012-05-17 09:04:11

标签: algorithm haskell functional-programming complexity-theory recurrence

我想计算递归定义的函数值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)等的值。

计算这样一张桌子的优雅有效方法是什么?

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