How to implement an efficient infinite generator of prime numbers in Python?

后端 未结 13 2232
醉酒成梦
醉酒成梦 2020-11-22 01:50

This is not a homework, I am just curious.

INFINITE is the key word here.

I wish to use it as for p in primes(). I believe that this is a built-

13条回答
  •  隐瞒了意图╮
    2020-11-22 02:22

    Here is a complicated heap-based implementation, which is not much faster than other heap-based implementations (see the speed comparison in another answer of mine), but it uses much less memory.

    This implementation uses two heaps (tu and wv), which contain the same number elements. Each element is an int pair. In order to find all primes up to q**2 (where q is a prime), each heap will contain at most 2*pi(q-1) elements, where pi(x) is the number of positive primes not larger than x. So the total number of integers is at most 4*pi(floor(sqrt(n))). (We could gain a factor on 2 on memory by pushing half as much stuff to the heap, but that would make the algorithm slower.)

    Other dict and heap-based approaches (e.g. erat2b, and heap_prime_gen_squares and heapprimegen) above store about `2*pi(n)' integers, because they extend their heap or dict every time they find a prime. As a comparison: to find the 1_000_000 primes, this implementation stores less than 4141 integers, other implementations store more than 1_000_000 integers.

    import heapq
    
    def heap_prime_gen_smallmem():
        yield 2
        yield 3
        f = 5
        fmar3 = 2
        q = 7
        q6 = 7 * 6
        qmar3 = 4
        tu = [(25, 30), (35, 30)]
        vw = [(25, 30), (35, 30)]
        while True:
            qmar3 += 2   
            if qmar3 == 6:  
                qb = q + 4
                q6b = q6 + 24
                qmar3 = 2
            else:
                qb = q + 2
                q6b = q6 + 12
            if q < tu[0][0]:
                d = q * q
                while f < d:
                    a, b = vw[0]
                    if f < a: 
                        yield f   
                    else:
                        a, b = vw[0]
                        heapq.heapreplace(vw, (a + b, b))
                        a, b = vw[0]
                        while f >= a:
                            heapq.heapreplace(vw, (a + b, b))
                            a, b = vw[0]   
                    fmar3 += 2
                    if fmar3 == 6:
                        f += 4
                        fmar3 = 2
                    else:
                        f += 2
                c = q * qb   
                heapq.heappush(tu, (d, q6))
                heapq.heappush(tu, (c, q6))
                heapq.heappush(vw, (d, q6))
                heapq.heappush(vw, (c, q6))
            else:
                a, b = tu[0]
                heapq.heapreplace(tu, (a + b, b))
                a, b = tu[0]  
                while q >= a:
                    heapq.heapreplace(tu, (a + b, b))
                    a, b = tu[0]
            q = qb
            q6 = q6b
    

提交回复
热议问题