我想解决的问题是问题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中重新实现它,看看有什么不同。谢谢你的帮助!
没有足够的信誉来评论,但使用集合"in"是一个平均查找接近O(1)的哈希函数,而列表"in"需要O(n)。这个问题的Python解决方案可以很容易地运行不到一秒钟。我将列出其他几个需要考虑的优化:
- add=素数矩阵[n2][1]+素数矩阵[n3][2]应该在for n4…循环之外,因为它的值不会更改,并且您正在重新计算它
- 只要add已经大于限制,就中断循环,而不是继续迭代
我不知道这是否有帮助,因为我无法真正测试我要说的任何内容,但是。。。。
看起来你应该放置
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
,而不是使用列表。我认为在一个集合中添加元素应该更快,尽管我从来没有这样的计时。
为什么不突破n4循环一次add > limit
-即
for n4 in range(0, 22):
...
if (add >= limit):
break
我认为你只需要在n4
循环中进行1次if (add < limit)
检查
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