我想解决的问题是problem 87。这个问题需要你找到低于50000000的主要三元组。到目前为止,代码已经运行了超过10分钟,有足够的时间来写这个。
28 = 2 ^ 2 + 2 ^ 3 + 2 ^ 4
33 = 3 ^ 2 + 2 ^ 3 + 2 ^ 4
49 = 5 ^ 2 + 2 ^ 3 + 2 ^ 4
47 = 2 ^ 2 + 3 ^ 3 + 2 ^ 4
在我的蛮力方法中,我已将其优化为仅检查小于50000000的方形,立方体和夸脱值。我使用筛子生成高达7071的数字,这不需要很长时间。
def algo(primes_matrix):
suma = []
counter2 = 0;
limit = 50000000
# square max, primes_matrix[907][1] = 7041
# cube max, primes_matrix[72][2] = 368
# quart max, primes_matrix[22][3] = 84
for n2 in range(0, len(primes_matrix)-1): # loop power 2
for n3 in range(0, 72): # loop power 3
for n4 in range(0, 22): # loop power 4
add = primes_matrix[n2][1] + primes_matrix[n3][2]
if(add<limit):
add+=primes_matrix[n4][3]
if(add<limit):
if add not in suma:
suma.append(add)
counter2+=1
print "counter =",counter2
我只是开始学习Python,因此我宁愿通常使用C / C ++来解决这类问题,因为我相信它会表现得更快。是这样的吗?或者更确切地说,我滥用Python的某些功能使其运行速度比它应该慢得多,或者以某种方式搞乱了我的算法。无论我是否会尝试在C中重新实现它以查看差异。谢谢你的帮助!
答案 0 :(得分:6)
没有足够的声誉来评论,但使用一组“in”是一个散列函数,其平均查找接近于O(1),而列表“in”需要O(n)。针对此问题的Python解决方案可以在一秒钟内轻松运行。我将列出其他几个要考虑的优化:
答案 1 :(得分:3)
我不知道这是否有用,因为我无法对我即将说的任何内容进行测试,但是......
看起来你应该放置
add = primes_matrix[n2][1] + primes_matrix[n3][2]
在n4
循环之外,因为它独立于它。无需重新计算22次。
看起来好像add
可以用你迭代的列表来表示,这意味着你可以通过使用列表解析而不是嵌套的for循环来节省时间 - 即代替:
for n2 in range(0, len(primes_matrix)-1): # loop power 2
for n3 in range(0, 72):
...
add = primes_matrix[n2][1] + primes_matrix[n3][2]
尝试:
add_list = [primes_matrix[n2][1] + primes_matrix[n3][2] for n2 in range(0, len(primes_matrix)-1) for n3 in range(0, 72)]
for add in add_list:
for n4 in range(22):
...
也许您想要用一个集替换suma
,而不是使用列表。我认为将元素添加到集合中应该更快,尽管我没有时间计算这样的事情。
为什么不在add > limit
- 即
for n4 in range(0, 22):
...
if (add >= limit):
break
我认为您只需要在if (add < limit)
循环
n4
次检查
for n4 in range(22):
add+=primes_matrix[n4][3]
if (add <= limit):
if add not in suma:
suma.append(add) # Or suma.add(add) if suma is a set - perhaps a variable name other than add would be good
counter2+=1
else:
break #add > limit, so no need to keep looping through n4
好的 - 这几乎是我所有的。我可以看到其中一些在其他答案中被回应(先于),但HTH