【发布时间】:2020-06-28 18:25:17
【问题描述】:
我在项目 euler 上尝试了一个问题,我需要找到 400 万以下的所有斐波那契项的总和。我花了很长时间,但后来我发现我可以使用 memoization 来做到这一点,但似乎还需要很长时间。经过大量研究,我发现我可以使用一个名为 lru_cache 的内置模块。我的问题是:为什么它不像记忆一样快?
这是我的代码:
from functools import lru_cache
@lru_cache(maxsize=1000000)
def fibonacci_memo(input_value):
global value
fibonacci_cache = {}
if input_value in fibonacci_cache:
return fibonacci_cache[input_value]
if input_value == 0:
value = 1
elif input_value == 1:
value = 1
elif input_value > 1:
value = fibonacci_memo(input_value - 1) + fibonacci_memo(input_value - 2)
fibonacci_cache[input_value] = value
return value
def sumOfFib():
SUM = 0
for n in range(500):
if fibonacci_memo(n) < 4000000:
if fibonacci_memo(n) % 2 == 0:
SUM += fibonacci_memo(n)
return SUM
print(sumOfFib())
顺便说一句,代码可以工作。当我使用 lru_cache 模块时,运行它只需不到一秒钟。
【问题讨论】:
-
总和满足常阶线性递推关系。找到它并直接计算总和。
-
这个问题可以在 O(n) 内有效地解决,方法是将当前总和和内存中的最后 2 个斐波那契值保持在一个循环中,直到达到高于 40 亿的数字。
-
更进一步,如果将递归表示为矩阵乘法,则可以在 O(ln(n)) 中求解。
-
我花了很长时间,但后来我发现我可以使用 memoization 来做到这一点,但似乎还需要很长时间。经过大量研究,我发现我可以使用一个名为 lru_cache 的内置模块。我的问题是:为什么它不如 memoization 快? 不使用
lru_cachememoization 吗?我不确定我是否了解您共享的代码中两者之间的关系。