高效地计算斐波那契数列

69

我正在解决一个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需要很长时间。有没有办法使这个过程更快?或者这样做也可以吗...

(问题:通过考虑斐波那契数列中不超过四百万的值,找出偶数值项的总和。)


P.S. 我是通过尝试找到不超过400万的值的。 - user65165
提示:尝试阅读维基页面... - Mitch Wheat
不,Fibonacci数列的维基页面... - Mitch Wheat
1
简单递归仅以 O(phi^n) 运行。 - recursion.ninja
你可以在 O(log n) 的时间复杂度内计算它。请参阅子线性时间内的第n个斐波那契数 - jfs
1
Project Euler的Even Fibonacci numbers问题是关于“偶数值项”,而不是“具有偶数序号/对于偶数参数/在偶数索引处的值”。如果您可以找到小于边界(“Problem 2”中的“四百万”)的最大项的序号,您可以在一次斐波那契函数的计算中找到该总和。 - greybeard
34个回答

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))

这个程序如何“找到不超过四百万的偶数斐波那契数之和”? - greybeard

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)

你定义了一个函数,但最好使用while循环。这并不排除另一种方法。 - greybeard
就计算一个斐波那契数而言,我发现kqr在第三种方法中的观点(2015)(由dan-klasson在2018年重复)更好,但可悲的是未记录在案 - greybeard
@greybeard,我的意思是问题中定义的函数不太理想,最好使用while循环,因为问题中使用了递归。(而且递归与循环的选择取决于语言) 此外,问题还需要列出斐波那契数列中偶数值的列表并将其相加,我认为(dan-klasson在2018年重复的)答案并不适合这种情况。 我仍在努力撰写答案,感谢您对此的诚实意见。 - ranjith chilupuri

0

这比上面所有的都要快得多

from sympy import fibonacci
%timeit fibonacci(10000)

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

这个程序如何“找到不超过四百万的偶数斐波那契数之和”? - greybeard

-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;

}

1
你能否写一个简短的说明,解释一下你的代码在做什么? - Bonifacio2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接