Fibonacci系列的有效计算

时间:2013-08-11 13:11:22

标签: python performance algorithm fibonacci

我正在研究一个Project Euler问题:关于偶数斐波纳契数的总和问题。

我的代码:

def Fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return Fibonacci(n-1) + Fibonacci(n-2)

list1 = [x for x in range(39)]
list2 = [i for i in list1 if Fibonacci(i) % 2 == 0]

通过打印sum(list2)可以很容易地找到问题的解决方案。但是,我猜测它需要花费大量时间来提出list2。有没有办法让这更快?或者这样就可以了......

(问题:通过考虑Fibonacci序列中的值不超过四百万的项,找到偶数项的总和。)

29 个答案:

答案 0 :(得分:80)

是。原始递归解决方案需要很多时间。这样做的原因是,对于计算的每个数字,它需要多次计算所有先前的数字。请看下面的图片。

Tree representing fibonacci calculation

它表示使用您的函数计算Fibonacci(5)。如您所见,它计算Fibonacci(2)三次的值,以及Fibonacci(1)五次的值。只是越来越差,你想要计算的数字越高。

使甚至更糟糕的是,您在列表中计算的每个斐波那契数字都不会使用您之前知道的数字来加速计算 - 您计算每个数字“从零开始。“

有一些方法可以加快速度:


1。从“自下而上”

创建一个列表

最简单的方法是创建一个斐波纳契数列表,最多可达到您想要的数字。如果你这样做,你可以“自下而上”构建或者说,你可以重复使用以前的数字来创建下一个数字。如果您有斐波纳契数字[0, 1, 1, 2, 3]的列表,则可以使用该列表中的最后两个数字来创建下一个数字。

这种方法看起来像这样:

>>> def fib_to(n):
...     fibs = [0, 1]
...     for i in range(2, n+1):
...         fibs.append(fibs[-1] + fibs[-2])
...     return fibs
...

然后你可以通过

获得前20个斐波那契数字
>>> fib_to(20)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]

或者你可以通过

从前40个列表中获得第17个斐波那契数字
>>> fib_to(40)[17]
1597

2。记忆(相对先进的技术)

另一种使其更快的替代方案存在,但它也有点复杂。由于您的问题是您重新计算已经计算的值,因此您可以选择将已经计算的值保存在dict中,并在重新计算之前尝试从中获取它们。这称为 memoization 。它可能看起来像这样:

>>> def fib(n, computed = {0: 0, 1: 1}):
...     if n not in computed:
...         computed[n] = fib(n-1, computed) + fib(n-2, computed)
...     return computed[n]

这使您可以轻松计算大的斐波那契数字:

>>> fib(400)
176023680645013966468226945392411250770384383304492191886725992896575345044216019675

这实际上是一种常见的技术,Python 3包含一个装饰器来为您完成此操作。我告诉你,自动记忆!

import functools

@functools.lru_cache(None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

这与上一个函数几乎完全相同,但computed装饰器处理了所有lru_cache内容。


3。算起来(一个天真的迭代解决方案)

Mitch建议的第三种方法是在不保存列表中的中间值的情况下进行计数。你可以想象做

>>> def fib(n):
...     a, b = 0, 1
...     for _ in range(n):
...         a, b = b, a+b
...     return a

如果您的目标是创建斐波纳契数字的列表,我不推荐这两种方法。 fib_to(100)将比[fib(n) for n in range(101)]更快 ,因为对于后者,您仍然会遇到从头开始计算列表中每个数字的问题。

答案 1 :(得分:45)

这是一个非常快速的算法,它可以比其他答案中提到的简单迭代方法更快地找到第n个斐波纳契数,但是它非常先进:

def fib(n):
    v1, v2, v3 = 1, 1, 0    # initialise a matrix [[1,1],[1,0]]
    for rec in bin(n)[3:]:  # perform fast exponentiation of the matrix (quickly raise it to the nth power)
        calc = v2*v2
        v1, v2, v3 = v1*v1+calc, (v1+v3)*v2, calc+v3*v3
        if rec=='1':    v1, v2, v3 = v1+v2, v1, v2
    return v2

您可以阅读更多有关数学here的内容。


答案 2 :(得分:8)

Python没有优化尾递归,因此如果Error: maximum recursion depth exceeded in comparison太大(而且大,我的意思是1000),那么此处介绍的大多数解决方案将失败n

可以增加递归限制,但它会使Python在操作系统中的堆栈溢出时崩溃。

请注意fib_memo / fib_localfib_lru / fib_local_exc之间的性能差异:LRU缓存速度慢得多,甚至没有完成,因为它产生了n = ~500的运行时错误:

import functools
from time import clock
#import sys
#sys.setrecursionlimit()

@functools.lru_cache(None)
def fib_lru(n):
    if n < 2:
        return n
    return fib_lru(n-1) + fib_lru(n-2)

def fib_memo(n, computed = {0: 0, 1: 1}):
    if n not in computed:
        computed[n] = fib_memo(n-1, computed) + fib_memo(n-2, computed)
    return computed[n]

def fib_local(n):
    computed = {0: 0, 1: 1}
    def fib_inner(n):
        if n not in computed:
            computed[n] = fib_inner(n-1) + fib_inner(n-2)
        return computed[n]
    return fib_inner(n)

def fib_local_exc(n):
    computed = {0: 0, 1: 1}
    def fib_inner_x(n):
        try:
            computed[n]
        except KeyError:
            computed[n] = fib_inner_x(n-1) + fib_inner_x(n-2)
        return computed[n]

    return fib_inner_x(n)

def fib_iter(n):
    a, b = 0, 1
    for i in range(n):
        a, b = b, a + b
    return a

def benchmark(n, *args):
    print("-" * 80)
    for func in args:
        print(func.__name__)
        start = clock()
        try:
            ret = func(n)
            #print("Result:", ret)
        except RuntimeError as e:
            print("Error:", e)
        print("Time:", "{:.8f}".format(clock() - start))
        print()

benchmark(500, fib_iter, fib_memo, fib_local, fib_local_exc, fib_lru)

结果:

fib_iter
Time: 0.00008168

fib_memo
Time: 0.00048622

fib_local
Time: 0.00044645

fib_local_exc
Time: 0.00146036

fib_lru
Error: maximum recursion depth exceeded in comparison
Time: 0.00112552

迭代解决方案是迄今为止最快的,即使n=100k(0.162秒)也不会破坏堆栈。它确实没有返回中间的斐波那契数字。

如果你想计算n偶数Fibonacci数,你可以调整这样的迭代方法:

def fib_even_iter(n):
    a, b = 0, 1
    c = 1
    while c < n:
        a, b = b, a + b
        if a % 2 == 0:
            c += 1
    return a

或者,如果您对途中的每个偶数感兴趣,请使用生成器

def fib_even_gen(n):
    a, b = 0, 1
    c = 1
    yield a
    while c < n:
        a, b = b, a + b
        if a % 2 == 0:
            yield a
            c += 1
    return a

for i, f in enumerate(fib_even_gen(100), 1):
    print("{:3d}.  {:d}".format(i, f))

结果:

  1.  0
  2.  2
  3.  8
  4.  34
  5.  144
  6.  610
  7.  2584
  8.  10946
  9.  46368
 10.  196418
 11.  832040
 12.  3524578
 13.  14930352
 14.  63245986
 15.  267914296
 16.  1134903170
 17.  4807526976
 18.  20365011074
 19.  86267571272
 20.  365435296162
 21.  1548008755920
 22.  6557470319842
 23.  27777890035288
 24.  117669030460994
 25.  498454011879264
 26.  2111485077978050
 27.  8944394323791464
 28.  37889062373143906
 29.  160500643816367088
 30.  679891637638612258
 31.  2880067194370816120
 32.  12200160415121876738
 33.  51680708854858323072
 34.  218922995834555169026
 35.  927372692193078999176
 36.  3928413764606871165730
 37.  16641027750620563662096
 38.  70492524767089125814114
 39.  298611126818977066918552
 40.  1264937032042997393488322
 41.  5358359254990966640871840
 42.  22698374052006863956975682
 43.  96151855463018422468774568
 44.  407305795904080553832073954
 45.  1725375039079340637797070384
 46.  7308805952221443105020355490
 47.  30960598847965113057878492344
 48.  131151201344081895336534324866
 49.  555565404224292694404015791808
 50.  2353412818241252672952597492098
 51.  9969216677189303386214405760200
 52.  42230279526998466217810220532898
 53.  178890334785183168257455287891792
 54.  757791618667731139247631372100066
 55.  3210056809456107725247980776292056
 56.  13598018856492162040239554477268290
 57.  57602132235424755886206198685365216
 58.  244006547798191185585064349218729154
 59.  1033628323428189498226463595560281832
 60.  4378519841510949178490918731459856482
 61.  18547707689471986212190138521399707760
 62.  78569350599398894027251472817058687522
 63.  332825110087067562321196029789634457848
 64.  1409869790947669143312035591975596518914
 65.  5972304273877744135569338397692020533504
 66.  25299086886458645685589389182743678652930
 67.  107168651819712326877926895128666735145224
 68.  453973694165307953197296969697410619233826
 69.  1923063428480944139667114773918309212080528
 70.  8146227408089084511865756065370647467555938
 71.  34507973060837282187130139035400899082304280
 72.  146178119651438213260386312206974243796773058
 73.  619220451666590135228675387863297874269396512
 74.  2623059926317798754175087863660165740874359106
 75.  11111460156937785151929026842503960837766832936
 76.  47068900554068939361891195233676009091941690850
 77.  199387062373213542599493807777207997205533596336
 78.  844617150046923109759866426342507997914076076194
 79.  3577855662560905981638959513147239988861837901112
 80.  15156039800290547036315704478931467953361427680642
 81.  64202014863723094126901777428873111802307548623680
 82.  271964099255182923543922814194423915162591622175362
 83.  1152058411884454788302593034206568772452674037325128
 84.  4880197746793002076754294951020699004973287771475874
 85.  20672849399056463095319772838289364792345825123228624
 86.  87571595343018854458033386304178158174356588264390370
 87.  370959230771131880927453318055001997489772178180790104
 88.  1571408518427546378167846658524186148133445300987550786
 89.  6656593304481317393598839952151746590023553382130993248
 90.  28197781736352815952563206467131172508227658829511523778
 91.  119447720249892581203851665820676436622934188700177088360
 92.  505988662735923140767969869749836918999964413630219877218
 93.  2143402371193585144275731144820024112622791843221056597232
 94.  9079598147510263717870894449029933369491131786514446266146
 95.  38461794961234640015759308940939757590587318989278841661816
 96.  162926777992448823780908130212788963731840407743629812913410
 97.  690168906931029935139391829792095612517948949963798093315456
 98.  2923602405716568564338475449381171413803636207598822186175234
 99.  12384578529797304192493293627316781267732493780359086838016392
100.  52461916524905785334311649958648296484733611329035169538240802

Time: 0.00698620

这是大约7毫秒内的前100个甚至斐波那契数字,包括打印到终端的开销(在Windows上容易低估)。

答案 3 :(得分:5)

基于fib(n) = fib(n-1)+fib(n-2)的事实,直截了当的解决方案是

def fib(n):
    if (n <=1):
        return(1)
    else:
        return(fib(n-1)+fib(n-2))

然而,这里的问题是一些值被多次计算,因此效率非常低。原因可以在这个草图中看到:

Fibonacci

基本上,对fib函数的每次递归调用都必须计算所有以前的斐波纳契数以供自己使用。因此,计算得最多的值将是fib(1),因为它必须出现在@kqr的答案所示的树的所有叶节点中。该算法的复杂性是树的节点数,即$ O(2 ^ n)$。

现在更好的方法是跟踪两个数字,即当前值和前一个值,因此每次调用都不必计算所有先前的值。这是草图中的第二个算法,可以按如下方式实现

def fib(n):
   if (n==0):
       return(0,1)
   elif (n==1):
       return(1,1)
   else:
       a,b = fib(n-1)
       return(b,a+b)

这种算法的复杂性是线性$ O(n)$,一些例子是

>>> fib(1)
(1, 1)
>>> fib(2)
(1, 2)
>>> fib(4)
(3, 5)
>>> fib(6)
(8, 13)

答案 4 :(得分:3)

R中的解决方案,基准测试在1.9秒内计算1到1000个斐波纳契数列。事实上,在写C ++或Fortran之后会更快,因为我在C ++中编写了一个等效的函数,它在令人印象深刻的0.0033秒内完成,甚至python在0.3秒内完成。

#Calculate Fibonnaci Sequence
fib <- function(n){
  if(n <= 2)
    return(as.integer(as.logical(n)))
  k = as.integer(n/2)
  a = fib(k + 1)
  b = fib(k)
  if(n %% 2 == 1)
    return(a*a + b*b)
  return(b*(2*a - b))
}

#Function to do every fibonacci number up to nmax
doFib <- function(nmax = 25,doPrint=FALSE){
    res = sapply(0:abs(nmax),fib)
    if(doPrint)
        print(paste(res,collapse=","))
    return(res)
}

#Benchmark
system.time(doFib(1000))

#user  system elapsed 
#  1.874   0.007   1.892 

答案 5 :(得分:3)

我的基础是关于维基百科上斐波那契数字的文章。这个想法是避免循环和递归,并根据需要简单地计算值。

不是数学专家,选择其中一个公式并将其渲染为代码并进行调整,直到值出现正确。

import cmath

def getFib(n):
    #Given which fibonacci number we want, calculate its value
    lsa = (1 / cmath.sqrt(5)) * pow(((1 + cmath.sqrt(5)) / 2), n)
    rsa = (1 / cmath.sqrt(5)) * pow(((1 - cmath.sqrt(5)) / 2), n)
    fib = lsa-rsa
    #coerce to real so we can round the complex result
    fn = round(fib.real) 
    return fn 

#Demo using the function
s = ''
for m in range(0,30):
    s = s + '(' + str(m) + ')' + str(getFib(m)) + ' '

print(s)

答案 6 :(得分:2)

kqr的解决方案nr 2是我最喜欢的。
但是在这种特殊情况下,我们在列表理解中的后续调用之间失去了所有计算:

list2 = [i for i in list1 if fib(i) % 2 == 0]

,所以我决定更进一步,在循环步骤之间记忆如下:

def cache_fib(ff):
    comp = {0: 0, 1: 1}

    def fib_cached(n, computed=comp):
        return ff(n, computed)
    return fib_cached


@cache_fib
def fib(n, computed={0: 0, 1: 1}):
    if n not in computed:
        computed[n] = fib(n - 1, computed) + fib(n - 2, computed)
    return computed[n]

答案 7 :(得分:1)

递归计算Fibonacci比迭代计算效率最低。我的建议是:

花点时间创建一个Fibonacci类作为迭代器,并为索引中的每个元素独立进行计算,也许用一些@memoize decorator(以及here)来缓存以前的所有计算。

希望这有帮助!

答案 8 :(得分:1)

O(1)解决方案

该公式也称为 Binet公式read more

基本上,我们可以像这样在python中写它:

def fib(n):
    a = ((1 + (5 ** 0.5)) / 2)**int(n)
    b = ((1 - (5 ** 0.5)) / 2)**int(n)
    return round((a - b) / (5 ** 0.5))

但是,由于b的值相对较低,我们可以忽略它,并且函数可以简单到

def fib(n):
    return round((((1+(5**0.5))/2)**int(n))/(5**0.5))

答案 9 :(得分:1)

有一个O(1)解决方案:https://en.wikipedia.org/wiki/Fibonacci_number#Computation_by_rounding

import math

PHI = (1 + math.sqrt(5)) / 2
SQRT5 = math.sqrt(5)


def fast_fib(n):
    if n < 0:
        raise ValueError('Fibs for negative values are not defined.')
    return round(math.pow(PHI, n) / SQRT5)

答案 10 :(得分:1)

O(1)解决方案

事实证明,即使斐波那契数的总和也有一个很好的递归公式。甚至Fibonacci数的和的序列中的第n项是S_{n} = 4*S_{n-1} + S_{n-2} + 2证明留给读者,但涉及证明1)甚至Fibo数是第三个,2)使用定义的归纳证明上面的公式Fibo号码使用here中的逻辑,我们可以通过一点努力得到一个封闭形式的公式:

S_{n} = -1/2 + (1/4 + 3*sqrt(5)/20)*(2+sqrt(5))**n + (1/4 - 3*sqrt(5)/20)*(2-sqrt(5))**n

尽管有sqrt,但这对于整数n是不可或缺的,所以这可以使用我之前的答案中的方便函数或使用sympy之类的包来方便地计算准确的根源。

import sympy as sp
one = sp.sympify(1) #to force casting to sympy types
k1 = -one/2
k2 = one/4 + 3*sp.sqrt(5)/20
k3 = one/4 - 3*sp.sqrt(5)/20
r1 = one
r2 = 2 + sp.sqrt(5)
r3 = 2 - sp.sqrt(5)
def even_sum_fibo(n):
  #get the nth number in the sequence of even sums of Fibonacci numbers.  If you want the sum of Fibos up to some number m, use n = m/3 (integer division)
  return sp.simplify(k1*r1**n + k2*r2**n + k3*r3**n)

答案 11 :(得分:1)

这是Fibonacci的一些改进版本,我们只计算一次数字的Fibonacci:

dicFib = { 0:0 ,1 :1 }
iterations = 0
def fibonacci(a):
    if  (a in dicFib):      
        return dicFib[a]    
    else :
        global iterations               
        fib = fibonacci(a-2)+fibonacci(a-1)
        dicFib[a] = fib
        iterations += 1
        return fib

print ("Fibonacci of 10 is:" , fibonacci(10))
print ("Fibonacci of all numbers:" ,dicFib)
print ("iterations:" ,iterations)

# ('Fibonacci of 10 is:', 55)
# ('Fibonacci of all numbers:', {0: 0, 1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8, 7: 13, 8: 21, 9: 34, 10: 55})
# ('iterations:', 9)

这里我们将每个数字的Fibonacci存储在字典中。所以你可以看到它只为每次迭代计算一次,对于Fibonacci(10)它只计算9次。

答案 12 :(得分:1)

如果不使用浮点运算,可以使用带有平方根的公式来计算此值,但是当你去的时候,可以用其他方式跟踪系数。这为Fibonacci数提供了一个基本恒定的时间精确算法:

def rootiply(a1,b1,a2,b2,c):
    ''' multipy a1+b1*sqrt(c) and a2+b2*sqrt(c)... return a,b'''
    return a1*a2 + b1*b2*c, a1*b2 + a2*b1

def rootipower(a,b,c,n):
    ''' raise a + b * sqrt(c) to the nth power... returns the new a,b and c of the result in the same format'''
    ar,br = 1,0
    while n != 0:
        if n%2:
            ar,br = rootiply(ar,br,a,b,c)
        a,b = rootiply(a,b,a,b,c)
        n /= 2
    return ar,br

def fib(k):
    ''' the kth fibonacci number'''
    a1,b1 = rootipower(1,1,5,k)
    a2,b2 = rootipower(1,-1,5,k)
    a = a1-a2
    b = b1-b2
    a,b = rootiply(0,1,a,b,5)
    # b should be 0!
    assert b == 0
    return a/2**k/5

if __name__ == "__main__":
    assert rootipower(1,2,3,3) == (37,30) # 1+2sqrt(3) **3 => 13 + 4sqrt(3) => 39 + 30sqrt(3)
    assert fib(10)==55

答案 13 :(得分:1)

要直接找到第一个n偶数值斐波纳契数的总和,将3n + 2放在您最喜欢的方法中,以有效地计算单个斐波纳契数,减1并除以2({{ 1}})。数学假人是如何在OEIS之前生存的?

答案 14 :(得分:1)

Haskell 1班轮: -

fibs = 0 : (f 1 1) where f a b = a : f b (a+b)

此代码效率极高,可在不到一秒的时间内计算最多(10^1000)的斐波纳契数! 此代码对Project Euler中的this problem也很有用。

答案 15 :(得分:1)

一种快速方法是递归计算fib(n / 2)数:

fibs = {0: 0, 1: 1}
def fib(n):
    if n in fibs: return fibs[n]
    if n % 2 == 0:
        fibs[n] = ((2 * fib((n / 2) - 1)) + fib(n / 2)) * fib(n / 2)
        return fibs[n]
    else:
        fibs[n] = (fib((n - 1) / 2) ** 2) + (fib((n+1) / 2) ** 2)
        return fibs[n]

from time import time
s=time()
print fib(1000000)
print time()-s

答案 16 :(得分:1)

如果有很多级别的递归,这样的任何问题都需要很长时间才能运行。递归定义适用于以易于理解的方式对问题进行编码,但如果您需要它以更快的速度运行,则this thread中的答案等迭代解决方案会更快。

答案 17 :(得分:0)

虽然答案很晚但可能会有所帮助

fib_dict = {}

def fib(n): 
    try:
        return fib_dict[n]
    except:
        if n<=1:
            fib_dict[n] = n
            return n
        else:
            fib_dict[n] = fib(n-1) + fib (n-2)
            return fib(n-1) + fib (n-2)

print fib(100)

这比传统方式快得多

答案 18 :(得分:0)

给出起始编号和最大编号;我认为以下针对斐波那契的解决方案将很有趣。好处是它不包含递归-从而减少了内存负担。

# starting number is a
# largest number in the fibonacci sequence is b

def fibonacci(a,b):
    fib_series = [a, a]

    while sum(fib_series[-2:]) <=b:
        next_fib = sum(fib_series[-2:])
        fib_series.append(next_fib)

    return fib_series

print('the fibonacci series for the range %s is %s'
      %([3, 27], fibonacci(3, 27)))

the fibonacci series for the range [1, 12] is [3, 3, 6, 9, 15, 24]

答案 19 :(得分:0)

这是一个没有递归和O(n)的简单

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

答案 20 :(得分:0)

剧透警报:如果您正在做欧拉计画的问题2,请先阅读本内容。

除了基于闭式序列求和的方法外,这似乎比我所见过的大多数/所有方法都更有效,因为每个偶数斐波那契数仅需要一个相当便宜的循环迭代,因此只有12次迭代才能达到4,000,000。

def sumOfEvenFibonacciNumbersUpTo(inclusiveLimit):
    even = 0
    next = 1
    sum  = 0
    while even<=inclusiveLimit:
        sum  += even
        even += next<<1
        next  = (even<<1)-next
    return sum

答案 21 :(得分:0)

这是带有字典的优化解决方案

def Fibonacci(n):
    if n<2 : return n
    elif not n in fib_dict :
            fib_dict[n]= Fibonacci(n-1) + Fibonacci(n-2)
    return fib_dict[n]

#dictionary which store Fibonacci values with the Key
fib_dict = {}
print(Fibonacci(440))

答案 22 :(得分:0)

import time


def calculate_fibonacci_1(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    return calculate_fibonacci_1(n - 1) + calculate_fibonacci_1(n - 2)


def calculate_fibonacci_2(n):
    fib = [0] * n
    fib[0] = 1
    fib[1] = 1
    for i in range(2, n):
        fib[i] = fib[i - 1] + fib[i - 2]
    return fib[n-1]


def calculate_fibonacci_3(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a


def calculate_fibonacci_4(n):
    v1, v2, v3 = 1, 1, 0
    for rec in bin(n)[3:]:
        calc = v2*v2
        v1, v2, v3 = v1*v1+calc, (v1+v3)*v2, calc+v3*v3
        if rec == '1':
            v1, v2, v3 = v1+v2, v1, v2
    return v2


def calculate_fibonacci_5(n):
    if n == 0:
        return (0, 1)
    else:
        a, b = calculate_fibonacci_5(n // 2)
        c = a * (b * 2 - a)
        d = a * a + b * b
        if n % 2 == 0:
            return (c, d)
        else:
            return (d, c + d)

    n = 30

    start = time.time()
    calculate_fibonacci_1(n)
    end = time.time()
    print(end - start)

    start = time.time()
    calculate_fibonacci_2(n)
    end = time.time()
    print(end - start)

    start = time.time()
    calculate_fibonacci_3(n)
    end = time.time()
    print(end - start)

    start = time.time()
    calculate_fibonacci_4(n)
    end = time.time()
    print(end - start)

    start = time.time()
    calculate_fibonacci_5(n)
    end = time.time()
    print(end - start)

for n=30:

0.264876127243
6.19888305664e-06
8.10623168945e-06
7.15255737305e-06
4.05311584473e-06

for n=300:

>10s
3.19480895996e-05
1.78813934326e-05
7.15255737305e-06
6.19888305664e-06

for n=3000:

>10s
0.000766038894653
0.000277996063232
1.78813934326e-05
1.28746032715e-05

for n=30000:

>10s
0.0550990104675
0.0153529644012
0.000290870666504
0.000216007232666

for n=300000:

>10s
3.35211610794
0.979753017426
0.012097120285
0.00845909118652

for n=3000000:

>10s
>10s
>10s
0.466345071793
0.355515003204

for n=30000000:

>100s
>100s
>100s
16.4943139553
12.6505448818

disclaimer: codes of functions no. 4 and 5 were not written by me

答案 23 :(得分:0)

这比上面的一切都要快

from sympy import fibonacci
%timeit fibonacci(10000)

262 ns ± 10.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

答案 24 :(得分:0)

还有更多公式,来自OEIS

  • F(n)=((1 + sqrt(5))^ n-(1-sqrt(5))^ n)/(2 ^ n * sqrt(5))
  • 或者,F(n)=((1/2 + sqrt(5)/ 2)^ n-(1 / 2-sqrt(5)/ 2)^ n)/ sqrt(5)
  • F(n)= round(phi ^ n / sqrt(5)); phi是(1 + sqrt(5))/ 2
  • F(n + 1)= Sum_ {j = 0..floor(n / 2)}二项式(n-j,j)

其中一些公式在上面的其他注释中具有实现。

答案 25 :(得分:0)

又一个快速解决方案:

def fibonnaci(n):
    a = []  
    while n != 1: 
        a.append(n&1)
        n >>= 1
    f1 = 1
    f2 = 1
    while a:
        t = f1 * (f2 * 2 - f1)
        f2 = f2 * f2 + f1 * f1
        if a.pop() is 1:
            f1 = f2
            f2 += t
        else:
            f1 = t
    return f1

答案 26 :(得分:0)

Project Euler 是练习编码的好地方。

来回答你的问题...

斐波那契数列;将最后一个数字之前的数字与最后一个数字相加,所得的和就是该系列中的新数字。

您定义了一个函数,但最好使用 while 循环。

i = 0
x = [0,1,2]
y =[]
n = int(input('upper limit of fibonacci number is '))
while i< n:
    z= x[-1]+x[-2]
    x.append(z)
    if z%2 == 0:
        y.append(z)
    i = x[-1]
    print(i)
print('The sum of even fibbunacci num in given fibonacci number is ',sum(y)+2)

答案 27 :(得分:0)

我做了一些研究,发现了一个叫做比奈公式的公式。 这个公式可以在 O(1) 时间内轻松计算出第 n 个斐波那契数列。

这是我翻译成 Python 的 Java 代码:

def fibonacci(n):
    five_sqrt = 5 ** 0.5

    return int(round((((1 + five_sqrt)/2) ** n)/five_sqrt))

for i in range(1, 21):
    print(fibonacci(i))

输出:

1, 1、 2、 3、 5、 8、 13、 21, 34、 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765

答案 28 :(得分:-4)

int count=0;
void fibbo(int,int);

void main()

{

fibbo(0,1);

    getch();
}

void fibbo(int a,int b)

{

 count++;

 printf(" %d ",a);

if(count<=10)

     fibbo(b,a+b);

else

      return;

}