[英]Is there a way to avoid this memory error?
我目前正在研究Euler項目上的問題,到目前為止,我已經提出了解決此問題的代碼。
from itertools import combinations
import time
def findanums(n):
l = []
for i in range(1, n + 1):
s = []
for j in range(1, i):
if i % j == 0:
s.append(j)
if sum(s) > i:
l.append(i)
return l
start = time.time() #start time
limit = 28123
anums = findanums(limit + 1) #abundant numbers (1..limit)
print "done finding abundants", time.time() - start
pairs = combinations(anums, 2)
print "done finding combinations", time.time() - start
sums = map(lambda x: x[0]+x[1], pairs)
print "done finding all possible sums", time.time() - start
print "start main loop"
answer = 0
for i in range(1,limit+1):
if i not in sums:
answer += i
print "ANSWER:",answer
當我運行它時,我遇到了MemoryError
。
追溯:
File "test.py", line 20, in <module>
sums = map(lambda x: x[0]+x[1], pairs)
我試圖通過禁用我無法從Google獲得的垃圾收集來阻止垃圾收集,但無濟於事。 我是否以錯誤的方式處理此問題? 在我的腦海中,這感覺是最自然的方式,而我對此感到茫然。
旁注:我使用的是PyPy 2.0 Beta2(Python 2.7.4),因為它比我使用的任何其他python實現都要快得多,而Scipy / Numpy卻讓我望而卻步,因為我仍然才剛剛開始編程並我沒有工程學或扎實的數學背景。
正如Kevin在評論中提到的那樣,您的算法可能是錯誤的,但是無論如何您的代碼都沒有得到優化。
當使用非常大的列表時,通常使用generators
,有一個著名的,很棒的Stackoverflow答案解釋了yield
和generator
的概念-Python 中的“ yield”關鍵字是做什么的?
問題是您的pairs = combinations(anums, 2)
不會生成生成generator
,而是生成大對象,這會消耗更多的內存。
我將您的代碼更改為具有此功能,因為您僅對集合進行了一次迭代,所以您可以延遲計算值:
def generator_sol(anums1, s):
for comb in itertools.combinations(anums1, s):
yield comb
現在,不是pairs = combinations(anums, 2)
,而是生成一個大對象。 使用:
pairs = generator_sol(anums, 2)
然后,代替使用lambda
我將使用另一個generator
:
sums_sol = (x[0]+x[1] for x in pairs)
另一個技巧是,您最好看一下更合適的xrange ,它不會生成列表,而是會生成在許多情況下(例如此處)更有效的xrange object
。
讓我建議您使用生成器 。 嘗試更改此:
sums = map(lambda x: x[0]+x[1], pairs)
至
sums = (a+b for (a,b) in pairs)
Ofiris解決方案也可以,但是暗示itertools.combinations
在錯誤時會返回一個列表。 如果您要繼續解決項目歐拉問題,請查看itertools文檔 。
問題是原子量很大-大約28000個元素長。 因此,對必須為28000 * 28000 * 8字節= 6GB。 如果使用numpy,則可以將anums轉換為numpy.int16數組,在這種情況下,結果對將為1.5GB-更易於管理:
import numpy as np
#cast
anums = np.array([anums],dtype=np.int16)
#compute the sum of all the pairs via outer product
pairs = (anums + anums.T).ravel()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.