Facing MemoryError in Python

Jeg skrev et program for å finne hovedfaktorer for et tall. Når jeg gir et stort tall (600851475143) som input, dukker MemoryError opp. Nedenfor er koden:

def fact(a): factors = [] for i in range(1,a+1): if a%i == 0: factors.append(i) return factors num = raw_input(">> ") #600851475143 a = b = [] a = fact(long(num)) for i in range(0,len(a)): b = fact(a[i]) if len(b) <= 2: print a[i] 

Fra surfing ble jeg kjent med at Python bruker dataminne – RAM. Jeg bruker Python i Unbuntu uten å endre konfigurasjonen. Skal jeg endre noe til å jobbe på 64-bits maskin. Eller bør jeg bruke noen ekstra funksjoner for å omgå denne feilen

Kommentarer

  • Det grunnleggende problemet er at algoritmen din sannsynligvis bruker for mye hukommelse. Hvis du bruker python 2, prøver range(1, a+1) å lage en liste med 600851475143 elementer. Dette er sannsynligvis ikke det du vil ha, da hvert element vil være et helt tall, og hvert heltall tar 4 byte. (Dette spørsmålet er ikke ' t passende for programmerere, da du virkelig trenger en kodegjennomgang og for å forstå spesielt hvordan python fungerer.)
  • (Du vil sannsynligvis ha xrange, som er en generator som returnerer elementer til for sløyfen etter behov. Det er kanskje ikke det eneste problemet du har, skjønt .)
  • Listen din er 2,2 TB stor. Å bytte til en 64-bits maskin hjelper ikke. Du må installere mer enn 2 TB RAM (for å være rettferdig vil det kreve et 64-biters operativsystem å bruke). Eller tenk på algoritmen din på nytt.
  • I tillegg til minneproblemer (bare fordi ingen andre har påpekt så langt), er det noen mer effektive algoritmer for å beregne listen over faktorer for et tall, eller å bestemme om et tall er primtall, eller for å generere en liste med primtall. Mens de fleste snakker om tidskompleksitet , er det også det relaterte begrepet romkompleksitet .

Svar

Det er forskjellige måter å måle minnet som brukes av programmet ditt, og du kan kanskje øke per brukergrenser eller noe.

Du trenger imidlertid ikke å tildele det minnet i utgangspunktet, siden du bare kan generere sekvensen uten å lagre det hele:

def fact(a): "just return a generator for the sequence you want" return (i for i in xrange(1,a+1) if a % i == 0) 

Merk at du også kan gjenta direkte over sekvenser uten å måtte indeksere dem gjentatte ganger:

for b in fact(long(num)): print b 

Kommentarer

  • Listen i spørsmålet er 2,2 TB stor, jeg tviler på at det å øke ressursgrensene vil hjelpe 😀
  • Vel, kanskje OP kan vente til 2035, når 8 TB SIMMS er tilgjengelig.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *