Как решить эту ошибку памяти - python

1

У меня есть следующий код

    def gen_primes():

        D = {}  

        q = 2  

        while True:
            if q not in D:         
                yield q        
                D[q * q] = [q]
            else:           
                for p in D[q]:
                    D.setdefault(p + q, []).append(p)
                del D[q]

            q += 1


    f = open("primes1.txt","w")

    filen = 1
    ran1 = 1
    ran2 = 10000000

    k = 1
    for i in gen_primes():

        if (k >= ran1) and (k <= ran2):

            f.write(str(i) + "\n")
            if k%1000000 == 0:
                print k
            k = k + 1
        else:
            ran1 = ran2 + 1
            ran2 = ran2 + 10000000
            f.close()
            filen = filen + 1;
            f = open("primes" + str(filen) + ".txt","w")

        if k > 100000000:           
            break
    f.close()

Алгоритм первичной генерации взят из Simple Prime Generator в Python

Эта программа дает ошибку памяти

Traceback (most recent call last):
  File "C:\Python25\Projects\test.py", line 43, in <module>
    for i in gen_primes():
  File "C:\Python25\Projects\test.py", line 30, in gen_primes
    D.setdefault(p + q, []).append(p)
MemoryError

Я пытаюсь сохранить последовательные 10 000 000 простых чисел в одном файле.

Теги:
memory
primes

4 ответа

1
Лучший ответ

Этот первичный генератор не использует очень много памяти. Это также не очень быстро.

def gcd(a, b):
    rem = a % b
    while rem != 0:
        a = b
        b = rem
        rem = a % b
    return b

def primegen():
    yield 2
    yield 3
    yield 5
    yield 7
    yield 11
    accum = 2*3*5*7
    out = file('tmp_primes.txt', 'w')
    inp = file('tmp_primes.txt', 'r+')
    out.write('0x2\n0x3\n0x5\n0x7\n0xb\n')
    inp.read(20)
    inpos = inp.tell()
    next_accum = 11
    next_square = 121
    testprime = 13
    while True:
        if gcd(accum, testprime) == 1:
            accum *= testprime # It actually prime!
            out.writelines((hex(testprime), '\n'))
            yield testprime
        testprime += 2
        if testprime >= next_square:
            accum *= next_accum
            nextline = inp.readline()
            if (len(nextline) < 1) or (nextline[-1] != '\n'):
                out.flush()
                inp.seek(inpos)
                nextline = inp.readline()
            inpos = inp.tell()
            next_accum = int(nextline, 16)
            next_square = next_accum * next_accum

def next_n(iterator, n):
    """Returns the next n elements from an iterator.

    >>> list(next_n(iter([1,2,3,4,5,6]), 3))
    [1, 2, 3]
    >>> list(next_n(primegen(), 10))
    [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
    """
    while n > 0:
        yield iterator.next()
        n -= 1
  • 0
    Это может быть значительно улучшено, если кто-то хочет быть немного умным в том, чтобы не умножать простое число в накопителе до тех пор, пока оно не станет абсолютно необходимым, и использовать временный файл, содержащий список простых чисел, обнаруженных до сих пор, чтобы умножить простое число в накопитель Следующий может быть легко прочитан без сохранения их всех в памяти.
  • 0
    Вы используете евклидов алгоритм для gcd. Можете ли вы сказать мне, как я могу использовать этот код для генерации простых чисел. Я не мог понять работу next_n.
Показать ещё 3 комментария
0

Установите пакет gmpy, и вы можете записать файл, не требуя большого объема памяти

import gmpy
p=2
with open("primes.txt","w") as f:
    for n in xrange(100000000):
        print >> f, p
        p = gmpy.next_prime(p)
  • 0
    У меня проблемы с установкой gmpy в Windows. Я также установил gmp.
0

Я запустил слегка модифицированный код на моей машине 10 ^ 6 простых чисел за ~ 30 секунд (я запускаю Python 3.2)

Вот код:

def gen_primes():  
    D = {}  
    # The running integer that checked for primeness
    q = 2  

    while True:
        if q not in D:
            yield q        
            D[q * q] = [q]
        else:
            for p in D[q]:
                D.setdefault(p + q, []).append(p)
            del D[q]

        q += 1


def main():
    j = 0
    f = open("primes1.txt","w")
    for i in gen_primes():
        j += 1
        #print(j, i)
        f.write(str(i) + "\n")
        if (j > 10000000): break
    f.close()

if __name__ == "__main__":
    main()
  • 0
    Я не могу сгенерировать 100 миллионов простых чисел с этим. Проблема с памятью сохраняется.
0

Попробуйте использовать этот генератор: http://code.activestate.com/recipes/366178-a-fast-prime-number-list-generator/

Невероятно быстро (10000000 простых чисел за пару секунд), а не потребляемая память

для сохранения в файле, возможно, проще просто сделать что-то вроде:

interval_start = 100
interval_length = 10000000
f = open("primes1.txt","w")

for prime in primes(interval_start + interval_length)[interval_start::]:
   f.write(str(prime) + "\n")

f.close()
  • 0
    Мне нужно сначала 100 миллионов простых чисел. Это вызывает проблемы с памятью.
  • 0
    просто добавьте дополнительный ноль в interval_lenght, я просто проверил его, и он создал хороший файл 48,7Mb с 0,1e ^ 9 строк ...
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню