Euler项目#2适用于大范围

时间:2012-12-17 22:58:38

标签: haskell

我有一个针对Project Euler Problem 2的Haskell解决方案,它适用于四百万限制,以及最多10 ^ 100000的限制,在我的机器上只需几秒钟。

但对于任何更大的东西,例如10 ^ 1000000,计算不及时返回,如果有的话(已尝试离开它几分钟)。这里的限制因素是什么?

evenFibonacciSum :: Integer -> Integer
evenFibonacciSum limit = 
  foldl' (\t (_,b) -> t + b) 0 . takeWhile ((<=limit) . snd) . iterate doIteration $ (1,2) where
    doIteration (a, b) = (twoAB - a, twoAB + b) where
      twoAB = 2*(a + b)

2 个答案:

答案 0 :(得分:5)

问题是你正在总结(偶数)斐波纳契数。这意味着你必须全部计算它们。但

F(n) ≈ φ^n / √5, with  φ = (1 + √5)/2

因此,您为Θ(n)添加了大量大小F(n)位。对于10^1000000的限制,您需要大约800000×2个大于10^500000的数字。通常,您需要添加Θ(n)位的Θ(n)个数字。

添加d位数[在任何基数]是O(d)操作。所以你的算法在指数中是二次的。

为了避免这种情况,找到第一个S(k)偶数Fibonacci数的总和k的封闭公式(提示:这是一个相对简单的公式,涉及一个 Fibonacci数) ,找到最大的k以便F(3*k) <= limit,并使用公式和算法计算总和,以F(n)步骤计算O(log n),例如here

答案 1 :(得分:0)

这里的问题似乎是你正在使用偶数斐波纳契数的公式,需要计算线性时间。如果你加倍限制,你的计算时间也会增加一倍。应该有一个只采用对数时间的算法(如果你加倍限制,时间会改变一个常数值),但你的工作就是找出来。我不是在这里破坏欧拉的答案。