Gibt es eine Möglichkeit, diesen Speicherfehler zu vermeiden?

8

Ich arbeite gerade an den Problemen von Project Euler und bis jetzt habe ich diesen Code für ein Problem entwickelt.

%Vor%

Wenn ich das ausführe, laufe ich auf MemoryError .

Die Rückverfolgung:

%Vor%

Ich habe versucht, dies zu verhindern, indem ich die Garbage-Collection von dem, was ich von Google bekommen habe, deaktiviert habe, aber ohne Erfolg. Komme ich dem in die falsche Richtung? In meinem Kopf fühlt sich das wie die natürlichste Art an, es zu tun und ich bin an diesem Punkt ratlos.

SEITENHINWEIS: Ich benutze PyPy 2.0 Beta2 (Python 2.7.4), weil es so viel schneller ist als jede andere Python-Implementierung, die ich benutzt habe, und Scipy / Numpy sind über meinem Kopf, da ich gerade erst anfange zu programmieren und ich habe keinen technischen oder starken mathematischen Hintergrund.

    
Jesse Neff 18.04.2013, 19:46
quelle

3 Antworten

4

Wie Kevin in den Kommentaren erwähnt, könnte Ihr Algorithmus falsch sein, aber Ihr Code ist sowieso nicht optimiert.

Wenn Sie sehr große Listen verwenden, ist es üblich, generators zu verwenden. Es gibt eine berühmte, große Stackoverflow-Antwort, die die Konzepte von yield und generator - Was bewirkt das Keyword" yield "in Python?

Das Problem ist, dass Ihr pairs = combinations(anums, 2) kein generator erzeugt, sondern ein großes Objekt erzeugt, das viel mehr Speicher verbraucht.

Ich habe Ihren Code geändert, um diese Funktion zu haben. Da Sie die Sammlung nur einmal durchlaufen, können Sie die Werte faul auswerten:

%Vor%

Jetzt anstelle von pairs = combinations(anums, 2) , was ein großes Objekt erzeugt. Verwenden Sie:

%Vor%

Dann würde ich anstelle von lambda ein anderes generator verwenden:

%Vor%

Noch ein Tipp, schauen Sie sich xrange genauer an, was besser passt erzeuge eine Liste, aber eine xrange object , die in vielen Fällen (wie hier) effizienter ist.

    
Ofiris 18.04.2013, 20:30
quelle
2

Lassen Sie mich vorschlagen, dass Sie Generatoren verwenden. Versuchen Sie, dies zu ändern:

%Vor%

bis

%Vor%

Ofiris Lösung ist auch in Ordnung, aber impliziert, dass itertools.combinations eine Liste zurückgibt, wenn sie falsch ist. Wenn Sie weiterhin Probleme mit dem Projekt euler lösen möchten, sehen Sie sich die Dokumentation zu itertools an.

    
Alex 18.04.2013 20:40
quelle
1

Das Problem ist, dass Anums groß ist - etwa 28000 Elemente lang. Paare müssen also 28000 * 28000 * 8 Bytes = 6 GB sein. Wenn Sie numpy verwenden, können Sie Anums als numpy.int16-Array darstellen. In diesem Fall wären die Ergebnispaare 1,5 GB - besser zu handhaben:

%Vor%     
Patrick Mineault 18.04.2013 20:37
quelle

Tags und Links