Recursion 递归优化?

Recursion 递归优化?,recursion,functional-programming,wolfram-mathematica,ocaml,compiler-optimization,Recursion,Functional Programming,Wolfram Mathematica,Ocaml,Compiler Optimization,为什么斐波那契递归过程工作这么长时间 这是在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

为什么斐波那契递归过程工作这么长时间

这是在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中没有实现,所以它可能不存在。关于这个问题的研究怎么样?

这是一个经典的例子,用来说明研究的价值。所以,这是一种让它运行得更快的方法


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

对于递归fibonacci序列,即使n=100,也不应花费太多时间进行运算。无论它是递归的还是迭代的,它都应该按时执行,因为它所做的只是将之前在固定时间内完成的数字相加。计算大约需要多长时间

我认为应该像@JeffreyScofield的回答那样进行记忆化。 定义:


试试看!这将花费很长时间,因为它会重复计算所有中间值。一种方法是看到在没有递归调用的情况下添加的唯一数字是1。但fib呈指数增长。所以加上这些1需要指数时间。我还没等完呢。至少几十分钟。不是100次计算。在我的笔记本电脑上,64位本机代码,2.6 GHz,OCaml函数计算FIB50需要70秒。每增加一个新的数字,它的phi应该会增加1.6左右,事实上FIB51需要114秒。对不起,我想不出一个主意吗?为什么这个工作更快?我是否可以将每个递归函数定义为F[n_]:=F[n]=body并从记忆中获得?记忆的思想是不重新计算旧值,因为它们存储在内存中,这是通过Fib2[n_]:=Fib2[n]位完成的,就像变量一样。使用记忆并不总是合适的,因为它使用更多的内存,如果计算速度快,可能不值得。这是打开记忆的一个技巧,或者这是标准Mathematica评估过程中可以解释的行为?@SuzanCioc这是标准Mathematica评估。它可以用于记忆,但也可以用于其他事情。详情如下:
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} *)