让我阻止你,我已经知道你可以调整最大允许深度。
但我认为这个用于计算第n个斐波纳契数的函数,由于试图进行记忆而不会超过它。
我在这里缺少什么?
def fib(x, cache={1:0,2:1}):
if x is not 1 and x is not 2 and x not in cache: cache[x] = fib(x-1) + fib(x-2)
return cache[x]
答案 0 :(得分:2)
这里的问题是tdelaney在评论中指出的问题。
您正在向后填充缓存,从x
向下填充到2
。
这足以确保您只执行线性数量的递归调用。第一次调用fib(4000)
只能进行3998次递归调用。
但是3998 > sys.getcursionlimit()
,所以这没有帮助。
答案 1 :(得分:2)
您的代码有效,只需设置递归限制(默认值为1000):
>>> def fib(x, cache={1:0,2:1}):
... if x is not 1 and x is not 2 and x not in cache: cache[x] = fib(x-1) + f
ib(x-2)
... return cache[x]
...
>>> from sys import setrecursionlimit
>>> setrecursionlimit(4001)
>>> fib(4000)
24665411055943750739295700920408683043621329657331084855778701271654158540392715
48090034103786310930146677221724629877922534738171673991711165681180811514457211
13771400656054018493704811431159158792987298892998378107544456316501964164304630
21568595514449785504918067352892206292173283858530346012173429628868997174476215
95754737778371797011268738657294932351901755682732067943003555687894170965511472
22394287423465133129791428666544293424932758353804445807459873383767095726534051
03186366562265469193320676382408395686924657068094675464095820220760924728356005
27753139995364477320639625889904027436038223654786222515006804845418392308019640
53848249082837958012652040193422565794818023898141209364892225521425081077545093
40549694342959926058170589410813569880167004050051440392247460055993434072332526
101572422443738016276258104875526626L
>>>
原因是,如果你想象一棵大树,你的根节点是4000,它连接到3999和3998.你一直沿着树的一个分支向下,直到你遇到一个基本案例。然后你回来从底部构建缓存。所以这棵树超过1000深,这就是你达到极限的原因。
答案 2 :(得分:1)
要添加讨论问题评论,想总结一下:
答案 3 :(得分:0)
也许这有助于形象化,出现了什么问题:
def fib(x, cache={0:..., 1:0, 2:1}):
if x not in cache: cache[x] = fib(x-1) + fib(x-2)
return cache[x]
for n in range(4000): fib(n)
print(fib(4000))
在您明确地自下而上构建缓存时,效果非常好。 (在运行时不评估默认参数是一件好事。)
顺便说一下:你的初始词典错了。 fib(1)是1而不是0.我在我的方法中保留了这个编号偏移量。
答案 4 :(得分:0)
让memoization很好地处理这样的问题的诀窍是从你还不知道的第一个值开始,并努力实现你需要返回的值。这意味着避免自上而下的递归。迭代计算Fibonacci值很容易。这是一个非常紧凑的版本,带有备忘录列表:
def fib(n, memo=[0,1]):
while len(memo) < n+1:
memo.append(memo[-2]+memo[-1])
return memo[n]
这是一个快速演示(非常快):
>>> for i in range(90, 101):
print(fib(i))
2880067194370816120
4660046610375530309
7540113804746346429
12200160415121876738
19740274219868223167
31940434634990099905
51680708854858323072
83621143489848422977
135301852344706746049
218922995834555169026
354224848179261915075
>>> fib(4000)
39909473435004422792081248094960912600792570982820257852628876326523051818641373433549136769424132442293969306537520118273879628025443235370362250955435654171592897966790864814458223141914272590897468472180370639695334449662650312874735560926298246249404168309064214351044459077749425236777660809226095151852052781352975449482565838369809183771787439660825140502824343131911711296392457138867486593923544177893735428602238212249156564631452507658603400012003685322984838488962351492632577755354452904049241294565662519417235020049873873878602731379207893212335423484873469083054556329894167262818692599815209582517277965059068235543139459375028276851221435815957374273143824422909416395375178739268544368126894240979135322176080374780998010657710775625856041594078495411724236560242597759185543824798332467919613598667003025993715274875