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