[英]Python recursive fibonacci function doesn't process large values
我编写了一个简单的递归斐波那契函数:
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)
并尝试在其中发挥较大的价值:
print(recursive_fibonacci(100))
控制台什么都没掉,我的Mac上的风扇开始剧烈旋转
有人可以解释发生了什么。 堆栈框架内部发生了什么?
用参数N
调用例程的总次数为phi^N
次。 对于N = 100,这大约是10 ^ 20次调用。 不要等待N = 100的输出; 你不会活那么久。
但是,您可以记住该功能。 查找术语; 还有一个Python软件包可以自动为您完成此操作。 这个想法是存储每个值调用的结果。 对于任何N
,您只计算一次f(N)
; 之后,您只需在表中查找值。
在Prune的一个很好的答案的基础上,您可以轻松地记住函数调用,从而通过在函数定义中传递一个可变参数(一个dict)并将已计算的值存储在dict中,每个n
值仅被计算一次:
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
已经计算出的值已经在字典中查询了,不需要进一步的递归调用。
基本的递归解决方案需要很多时间。 这样做的原因是,对于每个计算出的数字,它需要多次计算所有先前的数字。 看下面的图片。
代表斐波那契计算的树
它代表使用您的函数计算Fibonacci(5)。 如您所见,它计算Fibonacci(2)的值是3倍,而Fibonacci(1)的值是5倍。 您要计算的数字越高,情况就越糟。
更糟糕的是,对于列表中计算出的每个斐波那契数,您不会使用以前知道的数字来加快计算速度,而是“从头开始”计算每个数。 最简单的方法是只创建一个斐波纳契数字列表,直到您想要的数字为止。 如果这样做,您可以说是“从下而上”构建的,可以重复使用前一个数字来创建下一个。 如果您有斐波那契数字[0,1,1,2,2,3]的列表,则可以使用该列表中的最后两个数字来创建下一个数字,并返回列表的最后一个数字,这是您的最终答案。
def fib_to(n):
fibs = [0, 1]
for i in range(2, n+1):
fibs.append(fibs[-1] + fibs[-2])
return fibs[-1]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.