我写了一个简单的递归fibonacci函数:
var()
并试图在其中运行一个大值:
def recursive_fibonacci(n):
if n == 0:
return 0
if n == 1:
return 1
if n > 1:
return recursive_fibonacci(n-1) + recursive_fibonacci(n-2)
没有任何东西从控制台出来,我的Mac上的风扇开始剧烈旋转
有人可以解释发生了什么。堆栈框架内部发生了什么?
答案 0 :(得分:2)
使用参数N
调用您的例行程序会使phi^N
总呼叫的顺序发生。对于N = 100,这大约是10 ^ 20个呼叫。不要等待N = 100时的输出;你不会活得那么久。
但是,你可以 memoize 这个功能。查找这个词;还有一个Python包可以自动为您完成。想法是存储每个值调用的结果;对于任何N
,您只计算一次f(N)
;之后,您只需在表格中查找该值。
答案 1 :(得分:2)
基于Prune的好答案,您可以轻松地 memoize 函数调用,以便n
的每个值仅通过在函数定义中传递可变参数(dict)来计算一次在dict中存储已计算的值:
def recursive_fibonacci(n, mem={}):
if n == 0 or n == 1:
return n
else:
if n-1 not in mem:
mem[n-1] = recursive_fibonacci(n-1)
if n-2 not in mem:
mem[n-2] = recursive_fibonacci(n-2)
return mem[n-1] + mem[n-2]
print(recursive_fibonacci(100))
# 354224848179261915075
已经计算出的值被查找到dict,并且不需要进一步的递归调用。
答案 2 :(得分:1)
原始递归解决方案需要花费大量时间。这样做的原因是,对于计算的每个数字,它需要多次计算所有先前的数字。请看下面的图片。
表示斐波纳契计算的树
它表示用你的函数计算Fibonacci(5)。如您所见,它计算Fibonacci(2)的值三次,Fibonacci(1)的值五次。只是越来越差,你想要计算的数字越高。
更糟糕的是,您在列表中计算的每个斐波那契数字都不会使用您之前知道的数字来加速计算 - 您可以“从头开始”计算每个数字。 最简单的方法是创建一个斐波纳契数列表,最多可达到您想要的数字。如果你这样做,你可以“自下而上”构建或者说,你可以重复使用以前的数字来创建下一个数字。如果您有斐波那契数字[0,1,1,2,3]的列表,您可以使用该列表中的最后两个数字来创建下一个数字,并返回列表的最后一个数字,这是您的最终答案。< / p>
def fib_to(n):
fibs = [0, 1]
for i in range(2, n+1):
fibs.append(fibs[-1] + fibs[-2])
return fibs[-1]