Python 400万以下的斐波那契

Python 400万以下的斐波那契,python,sequence,Python,Sequence,可能重复: 嘿,我试着写一个脚本,把“斐波那契序列”中的所有偶数项加起来不超过400万 Fibonacci1 = 1 Fibonacci2 = 2 a = 2 i = 4 for i in range(1,4000000): Fibonacci1 = Fibonacci1 + Fibonacci2 if Fibonacci1 % 2 == 0: a = a + Fibonacci1 Fibonacci2 = Fibonacci1 + Fibonacci2 if Fibonacci2

可能重复:

嘿,我试着写一个脚本,把“斐波那契序列”中的所有偶数项加起来不超过400万

Fibonacci1 = 1
Fibonacci2 = 2
a = 2
i = 4
for i in range(1,4000000):
 Fibonacci1 = Fibonacci1 + Fibonacci2
 if Fibonacci1 % 2 == 0:
  a = a + Fibonacci1
 Fibonacci2 = Fibonacci1 + Fibonacci2
 if Fibonacci2 % 2 == 0:
  a = a + Fibonacci2
print a
raw_input()
这应该不到一分钟,但它花了一整晚,它没有解决


编辑:对不起,伙计们,我误解了这个问题。我想这意味着我必须把所有的偶数项加起来达到400万!但解决办法是将所有偶数项相加,直到400万

工作代码(在不到一秒钟内完成):

Fibonacci1=1
斐波那契2=2
a=2
而<4000000:
Fibonacci1=Fibonacci1+Fibonacci2
如果Fibonacci1%2==0:
a=a+Fibonacci1
Fibonacci2=Fibonacci1+Fibonacci2
如果Fibonacci2%2==0:
a=a+Fibonacci2
打印
原始输入()

您确定要小于400万是
i
吗?

循环条件错误,应该是这样的:

while True:
    Fibonacci1 = Fibonacci1 + Fibonacci2
    if Fibonacci1 % 2 == 0:
        if a + Fibonacci1 > 4000000:
            break
        a = a + Fibonacci1
    Fibonacci2 = Fibonacci1 + Fibonacci2
    if Fibonacci2 % 2 == 0:
        if a + Fibonacci2 > 4000000:
            break
        a = a + Fibonacci2

目前,将前200万个偶数斐波那契数相加


但这不是任务。你必须对所有小于400万的偶数斐波那契数求和。

我不完全理解你的算法,但斯梅里曼似乎有一点,400万斐波那契数列肯定会增长到4M以上。我想更快的方法是生成多达4M的序列,然后将偶数序列相加。

您的代码有几个问题:

  • 你将循环400万次,而不是直到条件为真
  • 循环体中有重复的代码
大多数人在开始学习Python时只学习命令式编程。这并不奇怪,因为Python是一种命令式语言。但是Python在某种程度上也支持函数式编程,在我看来,对于这种练习,函数式编程方法更具启发性

首先定义生成所有斐波那契数的生成器:

def fib():
    a = b = 1
    while True:
        yield a
        a, b = b, a + b
要使用此生成器,我们可以从itertools导入一些有用的函数。要打印前几个数字,请使用:

2. 8. 34 144 610 要从生成器获取数字,直到数字超过400万,请使用:

适用于takewhile中的x(λx:x<4000000,均匀光纤):
打印x
要解决此问题,可以使用sum:

sum(list(takewhile(lambda x: x < 4000000, evenfibs)))
sum(列表(takewhile(lambda x:x<4000000,evenfibs)))

我希望这表明函数式编程方法并不困难,是解决某些类型问题的一种更优雅的方法。

注意:为了解决实际问题,对其进行了大量修改

这里有一个替代方法(非常快,但未经测试)。 它依赖于几个属性:

  • 每个斐波那契数都可以直接计算为floor(pow(phi,n)+0.5)(参见四舍五入计算)。相反,小于i的最大斐波那契数的指数由floor(log(i*sqrt(5))/log(phi))给出
  • 前N个斐波那契数之和是N+2个斐波那契数减去1(参见同一维基百科页面上的第二个标识)
  • 偶数斐波那契数是每三个数。(看看序列mod 2,结果很简单)
  • 偶数斐波那契数的和是奇数斐波那契数到序列中同一点之和的一半。(这是从3.和性质,即F(3N)=F(3N-1)+F(3N-2)所以F(3N-2)+F(3N-1)+F(3N)=2f(N)…然后两边求和
  • 因此,转换我们的最大值4000000,计算最高斐波那契数的指数 比它小

    int n = floor(log(4000000*sqrt(5))/log(phi)) = 33. 
    
    33可以被3整除,所以它是一个偶数斐波那契数,如果不是,我们需要像这样调整n

    n = (n/3)*3
    
    到目前为止所有斐波那契数的总和,如果由

    sum = floor( pow( phi, n+2 )/sqrt(5) + 0.5 ) - 1 = 9227464
    
    所有偶数之和是这个数的一半:

    sum_even = 4613732
    

    这是一个O(1)(或O(log(N)),如果你包括pow/log算法的成本,它可以用于双倍运算。因此,我们可以计算非常大的值的和。

    来吧,计算斐波那契序列的最佳方法是使用两个技巧:

    已编辑,很抱歉先前的错误

    1:

    矩阵N*M^(N/3)具有前N个fibonacci数之和(仅过滤到偶数)为右上角元素

    2:

    可以使用,因为矩阵乘法是一个环


    因此,你可以用O(logn)来解决我们的问题。

    还有其他一些技巧比简单地计算完整的斐波那契数列表,然后对列表中的偶数求和更有效

    若我试图解决这个问题,我会列出一个偶数斐波纳契数的列表。这个列表有什么有趣的特征吗?你们能说服自己这个模式在一般情况下是正确的吗

    接下来,我可能会寻找一种方法来计算该列表的成员,并且只计算那些需要的元素。我甚至可能会寻找是否有任何公式可以产生斐波那契数序列的和


    当然,所有这些都会占用你自己更多的时间,而不仅仅是编写蛮力解决方案,但Euler项目就是要找到漂亮的解决方案,而不是蛮力解决方案。最后,如果你学会了一些数学和计算,那么你就获得了。

    你可能有兴趣了解关于

    您可以按名称或顺序搜索信息

    如果您搜索0、2、8、34或“甚至斐波那契”,您将重定向到序列

    在那里你可以找到很多信息,包括公式,
    从这一点出发,编写一个直接生成偶数斐波那契数的生成器是很容易的

    def evenfib():
        """ Generates the even fibonacci numbers """
        a, b = 2, 0
        while True:
            a, b = b, a+4*b
            yield a  
    

    @che-对我来说,这闻起来像是欧拉项目。你可能想添加一个数学和一个斐波那契标记+1非常好!通常我认为在这样的问题上发布代码对OP没有帮助,但你解释得很好!这种优化在这里没有帮助,因为你无论如何都需要计算每个斐波那契数
    sum(list(takewhile(lambda x: x < 4000000, evenfibs)))
    
    int n = floor(log(4000000*sqrt(5))/log(phi)) = 33. 
    
    n = (n/3)*3
    
    sum = floor( pow( phi, n+2 )/sqrt(5) + 0.5 ) - 1 = 9227464
    
    sum_even = 4613732
    
    N =|2 0 0|
       |1 0 0|
       |0 0 0|
    
    M =|3 2 1|
       |2 1 0|
       |0 0 1|
    
    def evenfib():
        """ Generates the even fibonacci numbers """
        a, b = 2, 0
        while True:
            a, b = b, a+4*b
            yield a  
    
    ## nice simple generator Mark Byers
    def fib():
        a = b = 1
        while True:
            yield a
            a, b = b, a + b
    
    ## does same as takewhile 5
    for fibonacci in zip(range(1,1+5),fib()):
        print "fib(%i) = %i" %  fibonacci
    
    ## we can slice to take every second
    print "even sequence upto 100th"
    total=0
    for fibonacci in zip(range(1,1+100),fib())[::2]:
        print "fib(%i) = %i" %  fibonacci
        total+=fibonacci[1] ## to double check
    print "Has sum: ", sum( b for a,b in zip(range(1,1+100),fib())[::2] ),'that is ',total
    
    print "odd sequence upto 100th"
    
    total=0
    for fibonacci in zip(range(1,1+100),fib())[1::2]:
        print "fib(%i) = %i" %  fibonacci
        total+=fibonacci[1] ## to double check
    
    print "Has sum: ", sum( b for a,b in zip(range(1,1+100),fib())[1::2] ),'that is ',total