在Python中计算Fibonacci数

时间:2016-08-05 04:58:52

标签: python python-2.7 fibonacci series memoization

在做Project Euler Problem 25时,我遇到了各种计算第n个Fibonacci数的技术。记忆似乎是其中最快的,直观地说,我期望记忆化比从下至上创建列表更快。

这两个函数的代码是:

def fib3(n): #FASTEST YET
    fibs= [0,1] #list from bottom up
    for i in range(2, n+1):
        fibs.append(fibs[-1]+fibs[-2])
    return fibs[n]

def fib4(n, computed= {0:0, 1:1}): #memoization
    if n not in computed:
        computed[n]= fib4(n-1, computed)+ fib4(n-2, computed)
    return computed[n]
print fib3(1000)
print fib4(1000)

fib3比fib4快约8倍。我无法弄清楚这背后的原因。基本上两者都是在计算时存储值,一个在列表中,另一个在字典中,以便他们可以访问它们作为"缓存"后来。为什么会有巨大的差异?

3 个答案:

答案 0 :(得分:0)

在thesonyman101上进行开发:my_list[i]使您能够立即访问该元素,而my_dict[key]需要计算哈希函数并在查看存储桶中的内容之前检查冲突。此外,您的memoization设置了一些潜在的深度递归堆栈,这也有一些成本。

更快(如果你不需要重新计算几个值,我知道Euler问题不是这样的话:)只是跟踪最后两个术语。所以你不会浪费任何列表管理费用。

答案 1 :(得分:-1)

您正在使用fib4函数中的递归。这在时间复杂度方面是指数

编辑后,有人说记忆使fib4线性化: 除了它没有。

记忆的东西只能减少重复呼叫的计算时间。数字n的斐波纳契值首次仅通过递归计算。

自己尝试一下

0.00010111480978441638
0.00039419570581368307
[Finished in 0.1s]

这将显示fib4需要更长时间。

print (min(timeit.Timer('fib3(600)', setup=setup).repeat(3, 100)))

print (min(timeit.Timer('fib4(600)', setup=setup).repeat(3, 100)))

如果更改最后两行,即每次重复100次,结果会发生变化现在,fib4变得更快,好像不仅没有递归,几乎没有额外的时间来计算

0.00501430622506104
0.00045805769094068097
[Finished in 0.1s]

50次重复的结果

0.01583016969421893
0.0006815746388851851
[Finished in 0.2s]

100次重复的结果

pair_count = df.mapPartitions(lambda iterable: pair_func_cnt(iterable))
pair_count.collection()

答案 2 :(得分:-2)

看看这个stackoverflow question

正如您所看到的,斐波那契算法(带递归)的复杂性约为O(2 ^ n)。

而对于fib3,它将是O(n)。

现在您可以计算,如果您的输入大小为3,fib3将具有O(3)的复杂度,但fib4将具有O(8)。

你可以看到,为什么它会变慢。

相关问题