def factors(n):
t = []
for i in xrange(1, n+1):
if n % i == 0:
t.append(i)
return len(t)
def trignum(x):
return sum(i for i in xrange(1+x))
for j in xrange(1,13000):
if trignum(j) and factors(trignum(j))>=300:
print factors(trignum(j))
print trignum(j)
上面是我对项目问题12的Python尝试,运行需要很长时间,我该如何改进呢?
答案 0 :(得分:1)
你浪费了大量的时间来重新计算触发器及其因素:
如果 trignum(j)和因素( trignum(j))> = 300:
.... print 因素( trignum(j))
.... print trignum(j)
计算一次并为其分配变量,然后使用变量:
for j in xrange(1,13000):
N = trignum(j)
F = factors(N)
if F>=300:
print F
print N
除此之外,您不必计算每j
总和所有数字的触发,N(j+1)
可以根据N(j)
计算:N(j+1) = N(j)+j
。< / p>
N = 0
for j in xrange(1,13000):
N += j
F = factors(N)
if F>=300:
print F
print N
在factors(n)
中,您应该在不创建整个列表的情况下计算因子的数量。此外,你可以停止分数的一半:
def factors(n):
nb = 2
for i in xrange(2, n/2+1):
if n % i == 0:
n+=1
return n
答案 1 :(得分:1)
你应该估计你的算法的整体复杂性,如果你觉得它太重,找到一个更好的。如果您来这里寻求更好的算法,请编辑您的问题。我只会在问题要求时“优化和改进你的代码”。除了bigOTHER的回答之外,我建议重写你的factors
函数(再一次,我没有改变任何算法,只是优化你的代码,虽然bigOTHER建议一个有价值的算法优化,即基本的动态编程)
def new_factors(n):
return len([i for i in xrange(1, n+1) if not n%i])
如果n
很大,你可以懒得保存内存。但这会慢一些。
def lazy_new_factors(n):
return sum(not n%i for i in xrange(1, n+1))
或者你可以去numpy
- 开心。 更新改进了基于NumPy的功能
import numpy as np
def numpy_factors(n):
return n - np.count_nonzero(np.arange(1, n+1) % 2)
这是基准时间:
In [37]: %timeit factors(10000)
1000 loops, best of 3: 706 µs per loop
In [38]: %timeit new_factors(10000)
The slowest run took 4.02 times longer than the fastest. This could mean that an intermediate result is being cached
1000 loops, best of 3: 668 µs per loop
In [39]: %timeit lazy_new_factors(10000)
1000 loops, best of 3: 1.23 ms per loop
In [40]: %timeit numpy_factors(10000)
1000 loops, best of 3: 258 µs per loop
所以,如你所见,numpy_factors
获胜约3倍。由于该函数具有O(n)复杂度,因此该性能增益相对于输入大小是稳定的。纯Python new_factors
也快一点。
然后我们可以用NumPy重写trignum
。顺便说一下,your sum(i for i in xrange(1+x))
是写sum(xrange(1+x))
的过度方法。
def mod_trignum(x):
return sum(xrange(1+x))
def numpy_trignum(x):
return np.sum(np.arange(x+1))
基准:
In [45]: %timeit trignum(1000)
10000 loops, best of 3: 53.1 µs per loop
In [46]: %timeit mod_trignum(1000)
100000 loops, best of 3: 12.4 µs per loop
In [47]: %timeit numpy_trignum(1000)
The slowest run took 130.23 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 4.88 µs per loop
因此,我们在NumPy中获得了10倍的性能提升,在纯Python中获得了大约4倍的增益。
答案 2 :(得分:0)
一个显而易见的问题:最多N的总和可以写成O(1),作为N的单个表达式。我不会破坏你的追捕,但是一个提示:比较表面trignum
的三角形:
1 x . . .
2 x x . .
3 x x x .
4 x x x x