对于Python(我刚刚在两周前开始学习它),我是一个新手,但我在完成挑战时有很多乐趣。给我带来麻烦的一个挑战是使用致死兔子的斐波那契序列的变异(即Padovan序列,但具有可变的寿命)。
经过多次试验和错误,我编写了一个代码,返回的输出与我为不同的生命周期设置所做的表格相匹配。然而,算法在大约40转时变得非常慢,并且寿命超过15个月,并且挑战是定时的。我的代码是:
def fib(n):
if n == 1:
return 1
elif n == 2:
return 1
else:
return fib(n-1) + fib(n-2)
def fibd(n, m):
if n < (m+2) and m > 3:
return fib(n)
elif n < (m+1) and m == 3:
return fib(n)
elif n >= (m+1) and m==3:
return fibd(n-2, m) + fibd(n-3, m)
elif n >= (m+2) and m > 3:
return sum(map(fibd, [n-(m+x) for x in (range(-(m-2), 2))], [m]*m))
这就像我能用我的谦虚技能一样简单,但我不知所措。 n表示我们停止计数的转弯次数,m表示每只兔子在死亡前的转弯次数。基本上,第一个函数给出Fibonacci序列。这是因为在兔子实际死亡之前,Padovan泛化与Fibonacci序列相同,所以我需要回调它作为递归的一部分。然后,有一个单独的代码块,寿命为3,因为对于4或更多的寿命,在第n个转弯处获得兔子数的公式是(n-2)+(n-3).. 。(n-(m + 1)),寿命为3,公式不同(它只是(n-2)+(n-3)。下一个代码块的寿命为4或更大。< / p>
如果您没有完整的解决方案,任何输入都会受到赞赏,甚至是一些提示。我有兴趣学习如何优化,就像我有兴趣解决这个特殊问题一样,因为这不是为了工作或学校,而是为了我自己的启发。
答案 0 :(得分:0)
你的两个函数都具有指数时间复杂度,所以它们会很慢。您需要找到更好的算法。在你想的时候,你可能想用Python运行这个程序,比如fibs(50)
,看看它做了什么:
def fibs(n):
a,b = 1,1
while n > 0:
print a
a,b,n = b,a+b,n-1
答案 1 :(得分:0)
下面是一个代码的返工,它具有更好的递归Fibonacci函数(虽然没有迭代那么快)和 memoizing ,@ johnY无法在评论中找到它,来自博客{{ 3}}
单独升级的斐波那契功能可将速度提高约20倍。 memoize装饰器缓存值,因此它们不会重新计算,将速度提高40倍。 (我对fibd()
的重写在性能方面没有任何区别,叹息。)
def memoize(f):
cache = {}
return lambda *args: cache[args] if args in cache else cache.update({args: f(*args)}) or cache[args]
@memoize
def fib(n, res=0, nxt=1):
if n == 0:
return res
return fib(n - 1, nxt, res + nxt)
@memoize
def fibd(n, m):
if m > 3:
if n < (m + 2):
return fib(n)
return sum(map(fibd, (n - (m + x) for x in range(2 - m, 2)), [m] * m))
elif m == 3:
if n < (m + 1):
return fib(n)
return fibd(n - 2, m) + fibd(n - 3, m)
print(fibd(40, 15))
我的系统的总体性能从47秒变为1/20秒。但是,我只测试了fibd(40, 15)
案例,您需要对此修改后的代码进行更多测试。