簡體   English   中英

有辦法避免這種內存錯誤嗎?

[英]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答案解釋了yieldgenerator的概念-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM