每次我试着运行这个程序都要花几分钟时间。cycle_length
是指Collatz循环长度(Collatz conjecture声称,无论你从哪个数字开始,如果你进行给定的计算,你最终总会达到1
)。max_length
计算i
和{
def cycle_length(n):
if n == 1:
return n
elif n % 2 == 0:
return cycle_length(n//2) + 1
else:
return cycle_length(3*n + 1) + 1
def max_length(i,j):
mxl = cycle_length(i)
mxn = i
while i <= j:
start = time.time()
y = cycle_length(i)
if y > mxl:
mxl = y
mxn = i
i += 1
return (mxn,mxl)
print(max_length(1, 10**6))
我想将程序从1
迭代到10**6
。有没有什么有效的方法可以让程序更快(10秒以下)?在
Collatz序列是使用"dynamic programming" techniques的好机会。来自给定数字
n
的序列的长度将始终相同,因此您可以存储该结果,并在将来的某个序列中再次到达n
时使用它。例如,使用修饰符来"memoize"结果:现在,如果我们运行程序的初始值为
^{pr2}$n
,您可以看到cache
被预先计算的结果填充,从而加快了将来的调用(以牺牲存储空间为代价—这是一种典型的编程权衡):这可以在大约1.5s内得出结果:
你做了很多相同的计算。为了避免这种情况,我们可以存储以下值:
在我的机器上,你的代码运行了29.9秒。我的代码给出了相同的结果,并在1.8秒内运行。在
编辑:我写了一个脚本来比较3个答案的效率。在
^{pr2}$结果:
我认为这是一个比较简单的答案(我认为这是一个比较简单的答案)。在
最简单的方法是记住
cycle_length
的值。如果您确实在使用Python3(3.3+),您可以用lru_cache(maxsize=None)
来装饰函数cycle_length
;这个程序在我的笔记本电脑上运行时间为5秒:相关问题 更多 >
编程相关推荐