递归优化?

时间:2013-01-22 07:19:55

标签: recursion functional-programming wolfram-mathematica ocaml compiler-optimization

为什么Fibonacci递归程序工作这么久?

这是在OCaml:

let rec fib n = if n<2 then n else fib (n-1) + fib (n-2);;

这是在Mathematica:

Fib[n_] := If[n < 2, n, Fib[n - 1] + Fib[n - 2]]

这是Java:

public static BigInteger fib(long n) {
    if( n < 2 ) {
        return BigInteger.valueOf(n);
    }
    else {
        return fib(n-1).add(fib(n-2));
    }
}

对于n=100,它可以工作很长时间,因为我猜它会及时追踪2^100个节点的树。

虽然只生成100个数字,但它只能消耗100个内存寄存器和100个计算间谍。

因此,可以优化执行。

这项任务是什么以及如何解决?由于Mathematica中没有实现解决方案,因此可能不存在。关于此事的研究呢?

3 个答案:

答案 0 :(得分:7)

这是用于显示memoization值的经典示例。所以,这是让它变得更快的一种方法。

(如果你只是想快速计算斐波纳契,当然重写函数非常容易,以便快速得到答案。从0开始,一直工作到n,每次传递前2个斐波纳契数。)

答案 1 :(得分:1)

我认为要走的路是memoization,就像@JeffreyScofield的回答一样。 定义:

Fib2[n_] := Fib2[n] = If[n < 2, n, Fib2[n - 1] + Fib2[n - 2]]

检查:

Fib[30] // AbsoluteTiming
(* {9.202920, 832040} *)

Fib2[30] // AbsoluteTiming
(* {0., 832040} *)

Fib2[100] // AbsoluteTiming
(* {0.001000, 354224848179261915075} *)

答案 2 :(得分:-2)

对于递归的Fibonacci序列,即使n = 100,也不应该花费那么多时间来操作。无论是递归的还是迭代的,它仍然应该在O(N)时间内执行,因为它所做的只是总结先前在恒定时间内完成的数字。计算需要多长时间?

相关问题