নীচের সমস্ত প্রাইম তালিকাভুক্ত করার দ্রুততম উপায়


357

এটি আমি আসতে পারে সেরা অ্যালগরিদম।

def get_primes(n):
    numbers = set(range(n, 1, -1))
    primes = []
    while numbers:
        p = numbers.pop()
        primes.append(p)
        numbers.difference_update(set(range(p*2, n+1, p)))
    return primes

>>> timeit.Timer(stmt='get_primes.get_primes(1000000)', setup='import   get_primes').timeit(1)
1.1499958793645562

এটি আরও দ্রুত তৈরি করা যেতে পারে?

এই কোডটিতে একটি ত্রুটি রয়েছে: যেহেতু numbersএকটি আনর্ডারড সেট নয় তাই কোনও গ্যারান্টি নেই যা numbers.pop()সেট থেকে সর্বনিম্ন সংখ্যাটি সরিয়ে দেবে। তবুও এটি কিছু ইনপুট সংখ্যার জন্য (কমপক্ষে আমার জন্য) কাজ করে:

>>> sum(get_primes(2000000))
142913828922L
#That's the correct sum of all numbers below 2 million
>>> 529 in get_primes(1000)
False
>>> 529 in get_primes(530)
True

সংখ্যাগুলিতে সংখ্যা = সেট (পরিসীমা (এন, 2, -2)) হিসাবে ঘোষিত যদি প্রশ্নে কোড স্নিপলেট আরও দ্রুত হয়। তবে সান্দরম 3 কে পরাতে পারবেন না। প্রশ্নের জন্য ধন্যবাদ।
শেখর

3
উত্তরের মধ্যে পাইথন 3 ফাংশনের সংস্করণ থাকতে পারে তবে তা ভালো লাগবে।
মাইকেল ফৌকারকিস

নিশ্চয় এতে তাই আমরা পাকানো আমাদের নিজস্ব> প্রতিশ্রুত xkcd পাইথন হিসাবে সহজ হিসাবে হবে না এই কাজ করতে একটি লাইব্রেরি import antigravityrequire 'prime'; Prime.take(10)(রুবি) এর মতো কিছু নেই ?
কর্নেল আতঙ্ক

2
@ কলোনেলপ্যানিক এটি হ'ল আমি পাই 3 এর জন্য github.com/jaredks/pyprimesieve আপডেট করেছি এবং পাইপিতে যুক্ত করেছি। এটি অবশ্যই এর চেয়ে দ্রুত তবে মাত্রার অর্ডার নয় - সেরা আকাঙ্ক্ষিত সংস্করণগুলির চেয়ে 5x ডলার দ্রুত।
জ্যারেড

3
@ কলোনেলপ্যানিক: আমি মনে করি যে পুরানো উত্তরগুলি সম্পাদনা করা উচিত যে তারা পুরনো হয়েছে তা লক্ষ করার জন্য এটি উপযুক্ত, কারণ এটি এটিকে আরও কার্যকর সংস্থান হিসাবে পরিণত করে। যদি "গৃহীত" উত্তরটি আর সেরা না হয়, তবে বর্তমানের সেরা পদ্ধতিতে লোককে নির্দেশ করতে 2015 এর আপডেট দিয়ে প্রশ্নের মধ্যে একটি নোট সম্পাদনা করুন।
পিটার কর্ডেস

উত্তর:


365

সতর্কতা: timeit পাইথনের হার্ডওয়্যার বা সংস্করণে পার্থক্যের কারণে ফলাফলগুলি পৃথক হতে পারে।

নীচে একটি স্ক্রিপ্ট যা বেশ কয়েকটি বাস্তবায়নের তুলনা করে:

অনেক ধন্যবাদ স্টিফেন আমার মনোযোগ sieve_wheel_30 আনার জন্য। ক্রেডিট রবার্ট উইলিয়াম হ্যাঙ্কসকে প্রাইমসফ্রম 2 টু, প্রাইমসফ্রম 3 টু, আরডাব্লু_প্রাইমস, আরডাব্লু_প্রাইমস 1 এবং আরডাব্লু_প্রাইমস 2 এর জন্য।

সাইকো দিয়ে সাইথ পাইথন পদ্ধতি পরীক্ষা করা হয়েছে, এন = 1000000 এর জন্য, rW_primes1 সবচেয়ে দ্রুত পরীক্ষা করা হয়েছিল।

+---------------------+-------+
| Method              | ms    |
+---------------------+-------+
| rwh_primes1         | 43.0  |
| sieveOfAtkin        | 46.4  |
| rwh_primes          | 57.4  |
| sieve_wheel_30      | 63.0  |
| rwh_primes2         | 67.8  |    
| sieveOfEratosthenes | 147.0 |
| ambi_sieve_plain    | 152.0 |
| sundaram3           | 194.0 |
+---------------------+-------+

সাইকো ছাড়াই সাইথ পাইথন পদ্ধতি পরীক্ষা করা হয়েছে, এন = 1000000 এর জন্য, rW_primes2 সবচেয়ে দ্রুত ছিল।

+---------------------+-------+
| Method              | ms    |
+---------------------+-------+
| rwh_primes2         | 68.1  |
| rwh_primes1         | 93.7  |
| rwh_primes          | 94.6  |
| sieve_wheel_30      | 97.4  |
| sieveOfEratosthenes | 178.0 |
| ambi_sieve_plain    | 286.0 |
| sieveOfAtkin        | 314.0 |
| sundaram3           | 416.0 |
+---------------------+-------+

N = 1000000 এর জন্য নম্পিকে অনুমতি দেওয়া , পরীক্ষিত সমস্ত পদ্ধতিগুলির মধ্যে প্রাইমসফ্রুম 2 সবচেয়ে দ্রুত পরীক্ষা করা হয়েছিল।

+---------------------+-------+
| Method              | ms    |
+---------------------+-------+
| primesfrom2to       | 15.9  |
| primesfrom3to       | 18.4  |
| ambi_sieve          | 29.3  |
+---------------------+-------+

কমান্ডটি ব্যবহার করে সময়গুলি পরিমাপ করা হয়েছিল:

python -mtimeit -s"import primes" "primes.{method}(1000000)"

সঙ্গে {method}পদ্ধতি নামের প্রতিটি দ্বারা প্রতিস্থাপিত।

primes.py:

#!/usr/bin/env python
import psyco; psyco.full()
from math import sqrt, ceil
import numpy as np

def rwh_primes(n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Returns  a list of primes < n """
    sieve = [True] * n
    for i in xrange(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i)+1)
    return [2] + [i for i in xrange(3,n,2) if sieve[i]]

def rwh_primes1(n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Returns  a list of primes < n """
    sieve = [True] * (n/2)
    for i in xrange(3,int(n**0.5)+1,2):
        if sieve[i/2]:
            sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1)
    return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]]

def rwh_primes2(n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Input n>=6, Returns a list of primes, 2 <= p < n """
    correction = (n%6>1)
    n = {0:n,1:n-1,2:n+4,3:n+3,4:n+2,5:n+1}[n%6]
    sieve = [True] * (n/3)
    sieve[0] = False
    for i in xrange(int(n**0.5)/3+1):
      if sieve[i]:
        k=3*i+1|1
        sieve[      ((k*k)/3)      ::2*k]=[False]*((n/6-(k*k)/6-1)/k+1)
        sieve[(k*k+4*k-2*k*(i&1))/3::2*k]=[False]*((n/6-(k*k+4*k-2*k*(i&1))/6-1)/k+1)
    return [2,3] + [3*i+1|1 for i in xrange(1,n/3-correction) if sieve[i]]

def sieve_wheel_30(N):
    # http://zerovolt.com/?p=88
    ''' Returns a list of primes <= N using wheel criterion 2*3*5 = 30

Copyright 2009 by zerovolt.com
This code is free for non-commercial purposes, in which case you can just leave this comment as a credit for my work.
If you need this code for commercial purposes, please contact me by sending an email to: info [at] zerovolt [dot] com.'''
    __smallp = ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
    61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139,
    149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
    229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311,
    313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401,
    409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491,
    499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599,
    601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683,
    691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,
    809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887,
    907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997)

    wheel = (2, 3, 5)
    const = 30
    if N < 2:
        return []
    if N <= const:
        pos = 0
        while __smallp[pos] <= N:
            pos += 1
        return list(__smallp[:pos])
    # make the offsets list
    offsets = (7, 11, 13, 17, 19, 23, 29, 1)
    # prepare the list
    p = [2, 3, 5]
    dim = 2 + N // const
    tk1  = [True] * dim
    tk7  = [True] * dim
    tk11 = [True] * dim
    tk13 = [True] * dim
    tk17 = [True] * dim
    tk19 = [True] * dim
    tk23 = [True] * dim
    tk29 = [True] * dim
    tk1[0] = False
    # help dictionary d
    # d[a , b] = c  ==> if I want to find the smallest useful multiple of (30*pos)+a
    # on tkc, then I need the index given by the product of [(30*pos)+a][(30*pos)+b]
    # in general. If b < a, I need [(30*pos)+a][(30*(pos+1))+b]
    d = {}
    for x in offsets:
        for y in offsets:
            res = (x*y) % const
            if res in offsets:
                d[(x, res)] = y
    # another help dictionary: gives tkx calling tmptk[x]
    tmptk = {1:tk1, 7:tk7, 11:tk11, 13:tk13, 17:tk17, 19:tk19, 23:tk23, 29:tk29}
    pos, prime, lastadded, stop = 0, 0, 0, int(ceil(sqrt(N)))
    # inner functions definition
    def del_mult(tk, start, step):
        for k in xrange(start, len(tk), step):
            tk[k] = False
    # end of inner functions definition
    cpos = const * pos
    while prime < stop:
        # 30k + 7
        if tk7[pos]:
            prime = cpos + 7
            p.append(prime)
            lastadded = 7
            for off in offsets:
                tmp = d[(7, off)]
                start = (pos + prime) if off == 7 else (prime * (const * (pos + 1 if tmp < 7 else 0) + tmp) )//const
                del_mult(tmptk[off], start, prime)
        # 30k + 11
        if tk11[pos]:
            prime = cpos + 11
            p.append(prime)
            lastadded = 11
            for off in offsets:
                tmp = d[(11, off)]
                start = (pos + prime) if off == 11 else (prime * (const * (pos + 1 if tmp < 11 else 0) + tmp) )//const
                del_mult(tmptk[off], start, prime)
        # 30k + 13
        if tk13[pos]:
            prime = cpos + 13
            p.append(prime)
            lastadded = 13
            for off in offsets:
                tmp = d[(13, off)]
                start = (pos + prime) if off == 13 else (prime * (const * (pos + 1 if tmp < 13 else 0) + tmp) )//const
                del_mult(tmptk[off], start, prime)
        # 30k + 17
        if tk17[pos]:
            prime = cpos + 17
            p.append(prime)
            lastadded = 17
            for off in offsets:
                tmp = d[(17, off)]
                start = (pos + prime) if off == 17 else (prime * (const * (pos + 1 if tmp < 17 else 0) + tmp) )//const
                del_mult(tmptk[off], start, prime)
        # 30k + 19
        if tk19[pos]:
            prime = cpos + 19
            p.append(prime)
            lastadded = 19
            for off in offsets:
                tmp = d[(19, off)]
                start = (pos + prime) if off == 19 else (prime * (const * (pos + 1 if tmp < 19 else 0) + tmp) )//const
                del_mult(tmptk[off], start, prime)
        # 30k + 23
        if tk23[pos]:
            prime = cpos + 23
            p.append(prime)
            lastadded = 23
            for off in offsets:
                tmp = d[(23, off)]
                start = (pos + prime) if off == 23 else (prime * (const * (pos + 1 if tmp < 23 else 0) + tmp) )//const
                del_mult(tmptk[off], start, prime)
        # 30k + 29
        if tk29[pos]:
            prime = cpos + 29
            p.append(prime)
            lastadded = 29
            for off in offsets:
                tmp = d[(29, off)]
                start = (pos + prime) if off == 29 else (prime * (const * (pos + 1 if tmp < 29 else 0) + tmp) )//const
                del_mult(tmptk[off], start, prime)
        # now we go back to top tk1, so we need to increase pos by 1
        pos += 1
        cpos = const * pos
        # 30k + 1
        if tk1[pos]:
            prime = cpos + 1
            p.append(prime)
            lastadded = 1
            for off in offsets:
                tmp = d[(1, off)]
                start = (pos + prime) if off == 1 else (prime * (const * pos + tmp) )//const
                del_mult(tmptk[off], start, prime)
    # time to add remaining primes
    # if lastadded == 1, remove last element and start adding them from tk1
    # this way we don't need an "if" within the last while
    if lastadded == 1:
        p.pop()
    # now complete for every other possible prime
    while pos < len(tk1):
        cpos = const * pos
        if tk1[pos]: p.append(cpos + 1)
        if tk7[pos]: p.append(cpos + 7)
        if tk11[pos]: p.append(cpos + 11)
        if tk13[pos]: p.append(cpos + 13)
        if tk17[pos]: p.append(cpos + 17)
        if tk19[pos]: p.append(cpos + 19)
        if tk23[pos]: p.append(cpos + 23)
        if tk29[pos]: p.append(cpos + 29)
        pos += 1
    # remove exceeding if present
    pos = len(p) - 1
    while p[pos] > N:
        pos -= 1
    if pos < len(p) - 1:
        del p[pos+1:]
    # return p list
    return p

def sieveOfEratosthenes(n):
    """sieveOfEratosthenes(n): return the list of the primes < n."""
    # Code from: <dickinsm@gmail.com>, Nov 30 2006
    # http://groups.google.com/group/comp.lang.python/msg/f1f10ced88c68c2d
    if n <= 2:
        return []
    sieve = range(3, n, 2)
    top = len(sieve)
    for si in sieve:
        if si:
            bottom = (si*si - 3) // 2
            if bottom >= top:
                break
            sieve[bottom::si] = [0] * -((bottom - top) // si)
    return [2] + [el for el in sieve if el]

def sieveOfAtkin(end):
    """sieveOfAtkin(end): return a list of all the prime numbers <end
    using the Sieve of Atkin."""
    # Code by Steve Krenzel, <Sgk284@gmail.com>, improved
    # Code: https://web.archive.org/web/20080324064651/http://krenzel.info/?p=83
    # Info: http://en.wikipedia.org/wiki/Sieve_of_Atkin
    assert end > 0
    lng = ((end-1) // 2)
    sieve = [False] * (lng + 1)

    x_max, x2, xd = int(sqrt((end-1)/4.0)), 0, 4
    for xd in xrange(4, 8*x_max + 2, 8):
        x2 += xd
        y_max = int(sqrt(end-x2))
        n, n_diff = x2 + y_max*y_max, (y_max << 1) - 1
        if not (n & 1):
            n -= n_diff
            n_diff -= 2
        for d in xrange((n_diff - 1) << 1, -1, -8):
            m = n % 12
            if m == 1 or m == 5:
                m = n >> 1
                sieve[m] = not sieve[m]
            n -= d

    x_max, x2, xd = int(sqrt((end-1) / 3.0)), 0, 3
    for xd in xrange(3, 6 * x_max + 2, 6):
        x2 += xd
        y_max = int(sqrt(end-x2))
        n, n_diff = x2 + y_max*y_max, (y_max << 1) - 1
        if not(n & 1):
            n -= n_diff
            n_diff -= 2
        for d in xrange((n_diff - 1) << 1, -1, -8):
            if n % 12 == 7:
                m = n >> 1
                sieve[m] = not sieve[m]
            n -= d

    x_max, y_min, x2, xd = int((2 + sqrt(4-8*(1-end)))/4), -1, 0, 3
    for x in xrange(1, x_max + 1):
        x2 += xd
        xd += 6
        if x2 >= end: y_min = (((int(ceil(sqrt(x2 - end))) - 1) << 1) - 2) << 1
        n, n_diff = ((x*x + x) << 1) - 1, (((x-1) << 1) - 2) << 1
        for d in xrange(n_diff, y_min, -8):
            if n % 12 == 11:
                m = n >> 1
                sieve[m] = not sieve[m]
            n += d

    primes = [2, 3]
    if end <= 3:
        return primes[:max(0,end-2)]

    for n in xrange(5 >> 1, (int(sqrt(end))+1) >> 1):
        if sieve[n]:
            primes.append((n << 1) + 1)
            aux = (n << 1) + 1
            aux *= aux
            for k in xrange(aux, end, 2 * aux):
                sieve[k >> 1] = False

    s  = int(sqrt(end)) + 1
    if s  % 2 == 0:
        s += 1
    primes.extend([i for i in xrange(s, end, 2) if sieve[i >> 1]])

    return primes

def ambi_sieve_plain(n):
    s = range(3, n, 2)
    for m in xrange(3, int(n**0.5)+1, 2): 
        if s[(m-3)/2]: 
            for t in xrange((m*m-3)/2,(n>>1)-1,m):
                s[t]=0
    return [2]+[t for t in s if t>0]

def sundaram3(max_n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/2073279#2073279
    numbers = range(3, max_n+1, 2)
    half = (max_n)//2
    initial = 4

    for step in xrange(3, max_n+1, 2):
        for i in xrange(initial, half, step):
            numbers[i-1] = 0
        initial += 2*(step+1)

        if initial > half:
            return [2] + filter(None, numbers)

################################################################################
# Using Numpy:
def ambi_sieve(n):
    # http://tommih.blogspot.com/2009/04/fast-prime-number-generator.html
    s = np.arange(3, n, 2)
    for m in xrange(3, int(n ** 0.5)+1, 2): 
        if s[(m-3)/2]: 
            s[(m*m-3)/2::m]=0
    return np.r_[2, s[s>0]]

def primesfrom3to(n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Returns a array of primes, p < n """
    assert n>=2
    sieve = np.ones(n/2, dtype=np.bool)
    for i in xrange(3,int(n**0.5)+1,2):
        if sieve[i/2]:
            sieve[i*i/2::i] = False
    return np.r_[2, 2*np.nonzero(sieve)[0][1::]+1]    

def primesfrom2to(n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Input n>=6, Returns a array of primes, 2 <= p < n """
    sieve = np.ones(n/3 + (n%6==2), dtype=np.bool)
    sieve[0] = False
    for i in xrange(int(n**0.5)/3+1):
        if sieve[i]:
            k=3*i+1|1
            sieve[      ((k*k)/3)      ::2*k] = False
            sieve[(k*k+4*k-2*k*(i&1))/3::2*k] = False
    return np.r_[2,3,((3*np.nonzero(sieve)[0]+1)|1)]

if __name__=='__main__':
    import itertools
    import sys

    def test(f1,f2,num):
        print('Testing {f1} and {f2} return same results'.format(
            f1=f1.func_name,
            f2=f2.func_name))
        if not all([a==b for a,b in itertools.izip_longest(f1(num),f2(num))]):
            sys.exit("Error: %s(%s) != %s(%s)"%(f1.func_name,num,f2.func_name,num))

    n=1000000
    test(sieveOfAtkin,sieveOfEratosthenes,n)
    test(sieveOfAtkin,ambi_sieve,n)
    test(sieveOfAtkin,ambi_sieve_plain,n) 
    test(sieveOfAtkin,sundaram3,n)
    test(sieveOfAtkin,sieve_wheel_30,n)
    test(sieveOfAtkin,primesfrom3to,n)
    test(sieveOfAtkin,primesfrom2to,n)
    test(sieveOfAtkin,rwh_primes,n)
    test(sieveOfAtkin,rwh_primes1,n)         
    test(sieveOfAtkin,rwh_primes2,n)

স্ক্রিপ্ট পরীক্ষা চালানো যা সমস্ত বাস্তবায়ন একই ফলাফল দেয়।


4
আপনি যদি খাঁটি-পাইথন কোডটিতে আগ্রহী হন, তবে আপনার পরীক্ষা করা উচিত gmpy- এর প্রাইমগুলির next_primeপদ্ধতিতে এটি প্রাইমগুলির পক্ষে বেশ ভাল সমর্থন করে mpz
অ্যালেক্স মার্তেলি

1
আপনি যদি পাইপি ব্যবহার করেন তবে এই মানদণ্ডগুলি (সাইকোগুলি) মোটামুটি বন্ধ বলে মনে হচ্ছে। আশ্চর্যজনকভাবে যথেষ্ট, আমি পাইপির সাথে দ্রুততম হিসাবে সিভিওফেরাতোস্টিনিস এবং অ্যাম্বি_সিয়েভ_প্লেইনকে পেয়েছি। এটি আমি নন-অলসদের জন্য খুঁজে পেয়েছি gist.github.com/5bf466bb1ee9e5726a52
এহসান কিয়া

1
যদি কেউ আশ্চর্য হয়ে যায় যে কীভাবে এখানে ফাংশনগুলি সাইকো বা পাইপ ছাড়াই খাঁটি পাইথনটির জন্য উইকিউবুকগুলির PG7.8 এর বিরুদ্ধে ভাড়া দেয়: এন = 1000000: পিজি 7.8: 4.93 এর জন্য লুপ প্রতি; rW_primes1: লুপ প্রতি 69 এমএস; rW_primes2: প্রতি লুপে 57.1 এমএস
গৌরবময়

8
আপনি কি পাইপাই দিয়ে এটি আপডেট করতে পারবেন, এখন যে সাইকো মারা গেছে এবং পাইপি এটি ছাড়িয়ে গেছে?
noɥʇʎԀʎzɐɹƆ

2
অজগর 3 এর জন্য এই ফাংশন এবং সময়গুলি আপডেট করা যেতে পারে তবে দুর্দান্ত হবে।
cs95

134

আরও দ্রুত এবং আরও মেমরি-ভিত্তিক খাঁটি পাইথন কোড:

def primes(n):
    """ Returns  a list of primes < n """
    sieve = [True] * n
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
    return [2] + [i for i in range(3,n,2) if sieve[i]]

বা অর্ধ চালনি দিয়ে শুরু

def primes1(n):
    """ Returns  a list of primes < n """
    sieve = [True] * (n//2)
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i//2]:
            sieve[i*i//2::i] = [False] * ((n-i*i-1)//(2*i)+1)
    return [2] + [2*i+1 for i in range(1,n//2) if sieve[i]]

আরও দ্রুত এবং আরও মেমরি-ভিত্তিক নমপি কোড:

import numpy
def primesfrom3to(n):
    """ Returns a array of primes, 3 <= p < n """
    sieve = numpy.ones(n//2, dtype=numpy.bool)
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i//2]:
            sieve[i*i//2::i] = False
    return 2*numpy.nonzero(sieve)[0][1::]+1

একটি চালনের তৃতীয়াংশ দিয়ে শুরু হওয়া দ্রুত পরিবর্তন:

import numpy
def primesfrom2to(n):
    """ Input n>=6, Returns a array of primes, 2 <= p < n """
    sieve = numpy.ones(n//3 + (n%6==2), dtype=numpy.bool)
    for i in range(1,int(n**0.5)//3+1):
        if sieve[i]:
            k=3*i+1|1
            sieve[       k*k//3     ::2*k] = False
            sieve[k*(k-2*(i&1)+4)//3::2*k] = False
    return numpy.r_[2,3,((3*numpy.nonzero(sieve)[0][1:]+1)|1)]

একটি (হার্ড-টু-কোড) উপরের কোডটির বিশুদ্ধ পাইথন সংস্করণটি হবে:

def primes2(n):
    """ Input n>=6, Returns a list of primes, 2 <= p < n """
    n, correction = n-n%6+6, 2-(n%6>1)
    sieve = [True] * (n//3)
    for i in range(1,int(n**0.5)//3+1):
      if sieve[i]:
        k=3*i+1|1
        sieve[      k*k//3      ::2*k] = [False] * ((n//6-k*k//6-1)//k+1)
        sieve[k*(k-2*(i&1)+4)//3::2*k] = [False] * ((n//6-k*(k-2*(i&1)+4)//6-1)//k+1)
    return [2,3] + [3*i+1|1 for i in range(1,n//3-correction) if sieve[i]]

দুর্ভাগ্যক্রমে খাঁটি-পাইথন অ্যাসাইনমেন্ট করার সহজ এবং দ্রুত অদ্ভুত উপায় অবলম্বন করেন না এবং len()লুপের ভিতরে কল [False]*len(sieve[((k*k)//3)::2*k])করা খুব ধীর। সুতরাং আমাকে ইনপুট সংশোধন করতে (এবং আরও গণিত এড়ানোর জন্য) উন্নতি করতে হয়েছিল এবং কিছু চরম ((বেদনাদায়ক) গণিত-যাদু করতে হয়েছিল।

ব্যক্তিগতভাবে আমি মনে করি এটি লজ্জাজনক যে নিম্পি (যা এত বেশি ব্যবহৃত হয়) পাইথন স্ট্যান্ডার্ড লাইব্রেরির অংশ নয় এবং সিনট্যাক্স এবং গতির উন্নতি পাইথন বিকাশকারীদের দ্বারা সম্পূর্ণ উপেক্ষা করা বলে মনে হয়।


2
নম্পি এখন পাইথন 3 এর সাথে সামঞ্জস্যপূর্ণ যে এটি স্ট্যান্ডার্ড লাইব্রেরিতে নেই তা ভাল, সেভাবে তাদের নিজস্ব প্রকাশের চক্র থাকতে পারে।
অ্যাডাম

কেবলমাত্র আমি প্রস্তাবিত একটি অ্যারেতে বাইনারি মানগুলি সঞ্চয় করতে bitarray- যেমনটি এখানে ব্যবহৃত হয়েছে (এখানে সর্বাধিক প্রধান চালনী হিসাবে; এখানে দৌড়ের প্রতিযোগী নয়!) stackoverflow.com/questions/31120986/…
হিরো নায়ক

ইন ভোটদান primesfrom2to()পদ্ধতি, বিভাজন বন্ধনী ভেতরে কী হওয়া উচিত?
355durch113

3
পাইথন 3 এর সাথে সামঞ্জস্যপূর্ণ খাঁটি অজগর সংস্করণের জন্য, এই লিঙ্কটি অনুসরণ করুন: stackoverflow.com/a/33356284/2482582
মোবিয়াস

FWIW, আপনার 1 ম কোড ব্লকের সংস্করণটি এই প্রশ্নের বিষয় । আমার আরও উল্লেখ করা উচিত যে আমি এখানে আপনার কোডের একটি পাইথন 3 সংস্করণ ব্যবহার করেছি ।
প্রধানমন্ত্রী 2 রিং

42

পাইথন কুকবুক থেকে একটি সুন্দর ঝরঝরে নমুনা রয়েছে এখানে - সেই ইউআরএলটিতে প্রস্তাবিত দ্রুততম সংস্করণটি হ'ল:

import itertools
def erat2( ):
    D = {  }
    yield 2
    for q in itertools.islice(itertools.count(3), 0, None, 2):
        p = D.pop(q, None)
        if p is None:
            D[q*q] = q
            yield q
        else:
            x = p + q
            while x in D or not (x&1):
                x += p
            D[x] = p

যাতে যে দিতে হবে

def get_primes_erat(n):
  return list(itertools.takewhile(lambda p: p<n, erat2()))

শেল প্রম্পটে পরিমাপ করা (যেমনটি আমি পছন্দ করি) pri.py এ এই কোডটি সহ, আমি পর্যবেক্ষণ করি:

$ python2.5 -mtimeit -s'import pri' 'pri.get_primes(1000000)'
10 loops, best of 3: 1.69 sec per loop
$ python2.5 -mtimeit -s'import pri' 'pri.get_primes_erat(1000000)'
10 loops, best of 3: 673 msec per loop

সুতরাং দেখে মনে হচ্ছে কুকবুক সমাধানটি দ্বিগুণ দ্রুত শেষ হয়েছে।


1
@ জবোচি, আপনি স্বাগত - তবে ক্রেডিট সহ সেই ইউআরএলটি দেখুন: টিম পিটারস এবং রেমন্ড হেইটিঞ্জারের মতো পাইথন-পারফরম্যান্সের আলোকসজ্জা সহ আমি এই দশকে সম্মিলিতভাবে কোডটি পরিমার্জন করতে গিয়েছিলাম (আমি লিখেছিলাম) আমি মুদ্রিত কুকবুকটি সম্পাদনা করার পরে রেসিপিটির চূড়ান্ত পাঠ্যটি ছিল, তবে কোডিংয়ের ক্ষেত্রে আমার অবদান অন্যদের সাথে সমান ছিল)) - শেষ পর্যন্ত, এটি সত্যিই সূক্ষ্ম এবং সূক্ষ্ম সুরযুক্ত কোড এবং এটি আশ্চর্যজনক নয়! -)
অ্যালেক্স মার্টেলি

@ অ্যালেক্স: আপনার কোডটি আমার চেয়ে দ্বিগুণ দ্রুত "কোড" হয়েছে তা জেনেও আমাকে তখন গর্বিত করে। :) ইউআরএল পড়তে খুব আকর্ষণীয় ছিল। আবার ধন্যবাদ.
jbochi

এবং এটা আরও দ্রুত একটি ছোটখাট পরিবর্তন দিয়ে তৈরি করা যেতে পারে: দেখুন stackoverflow.com/questions/2211990/...
tzot

1
... এবং এটা এখনো দ্রুত তৈরি করা যেতে পারে গবেষণামূলক সময় জটিলতা মধ্যে O (বর্গমূল (ঢ)) এবং উন্নতি করার জন্য অতিরিক্ত ~ 1.2x-1.3x speedup হে (ঢ) থেকে মেমরি পদাঙ্ক মধ্যে প্রচণ্ড হ্রাস সঙ্গে, যোগে পিছিয়ে দেয়ার মাধ্যমে তাদের স্কোয়ারটি ইনপুটটিতে না দেখা পর্যন্ত ডিকের প্রাইমগুলি । এটি এখানে পরীক্ষা করুন
নেস

28

সুন্দরমের চালনী ব্যবহার করে , আমি মনে করি আমি খাঁটি-পাইথনের রেকর্ডটি ভেঙেছি:

def sundaram3(max_n):
    numbers = range(3, max_n+1, 2)
    half = (max_n)//2
    initial = 4

    for step in xrange(3, max_n+1, 2):
        for i in xrange(initial, half, step):
            numbers[i-1] = 0
        initial += 2*(step+1)

        if initial > half:
            return [2] + filter(None, numbers)

Comparasion:

C:\USERS>python -m timeit -n10 -s "import get_primes" "get_primes.get_primes_erat(1000000)"
10 loops, best of 3: 710 msec per loop

C:\USERS>python -m timeit -n10 -s "import get_primes" "get_primes.daniel_sieve_2(1000000)"
10 loops, best of 3: 435 msec per loop

C:\USERS>python -m timeit -n10 -s "import get_primes" "get_primes.sundaram3(1000000)"
10 loops, best of 3: 327 msec per loop

1
আমি ফাংশনটির শীর্ষে "শূন্য = 0" যোগ করে এবং তারপরে আপনার ফিল্টারগুলিতে ল্যাম্বডাকে "শূন্য .__ সাব__" দিয়ে প্রতিস্থাপন করে আপনার ফাংশনটি প্রায় 20% গতিতে সক্ষম হয়েছি। বিশ্বের সবচেয়ে সুন্দর কোড নয়, তবে খানিকটা দ্রুত :)
truppo

1
@ ট্রুপ্পো: আপনার মন্তব্যের জন্য ধন্যবাদ! আমি কেবল বুঝতে পেরেছি যে Noneমূল ফাংশনের পরিবর্তে পাস করা কাজ করে এবং এটি এর চেয়েও দ্রুতzero.__sub__
jbochi

7
আপনি কি জানেন যে পাস sundaram3(9)করলে তা ফিরে আসবে [2, 3, 5, 7, 9]? দেখে মনে হচ্ছে এটি অসংখ্য - সম্ভবত সমস্ত - বিজোড় সংখ্যার (এমনকি যখন তারা প্রধান নাও হয়) দিয়ে এটি করে
wrhall

1
এটির একটি সমস্যা রয়েছে: সূন্দরাম 3 (7071) এর মধ্যে 7071 রয়েছে যখন এটি প্রাইম নয়
বিগঅথার

18

অ্যালগরিদম দ্রুত, তবে এটির মারাত্মক ত্রুটি রয়েছে:

>>> sorted(get_primes(530))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73,
79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251,
257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 527, 529]
>>> 17*31
527
>>> 23*23
529

আপনি ধরে নিচ্ছেন যে numbers.pop()সেটে সবচেয়ে ছোট সংখ্যাটি ফিরে আসবে, তবে এটি মোটেই নিশ্চিত নয়। সেটগুলি আনর্ডার্ড করা হয় এবং pop()মুছে ফেলা হয় এবং একটি প্রদান করে স্বেচ্ছাসেবক উপাদানটি, তাই এটি অবশিষ্ট সংখ্যা থেকে পরবর্তী প্রধান নির্বাচন করতে ব্যবহার করা যায় না।


17

জন্য সত্যিই যথেষ্ট বৃহৎ এন সঙ্গে দ্রুততম সমাধান ডাউনলোড করতে হবে মৌলিক সংখ্যার প্রাক নির্ণিত তালিকা , একটি tuple যেমন সংরক্ষণ এবং ভালো কিছু করতে:

for pos,i in enumerate(primes):
    if i > N:
        print primes[:pos]

যদি N > primes[-1] শুধুমাত্র তারপর আরো মৌলিক গণনা এবং আপনার কোডে তাই পরের বার নতুন তালিকা সংরক্ষণ করুন, এটা সমানভাবে হিসাবে দ্রুত।

সর্বদা বাক্সের বাইরে ভাবুন।


9
ন্যায্য হওয়ার জন্য, আপনাকে প্রাইমগুলি ডাউনলোড, আনজিপ এবং ফর্ম্যাট করার সময় গণনা করতে হবে এবং একটি অ্যালগরিদম ব্যবহার করে প্রাইম জেনার সময়টির সাথে তুলনা করতে হবে - এই অ্যালগরিদমগুলির মধ্যে যে কোনও একটি পরের জন্য খুব সহজেই ফলাফলগুলিতে লিখতে পারে ব্যবহার করুন। আমি মনে করি সেক্ষেত্রে 982,451,653 এর চেয়ে কম সমস্ত প্রাইম গণনা করার জন্য পর্যাপ্ত মেমরি দেওয়া হলেও ন্যালি সমাধানটি আরও দ্রুত হবে।
ড্যানিয়েল জি

3
@ ড্যানিয়েল সঠিক তবে আপনার কাছে যা স্টোর রয়েছে এবং যখনই প্রয়োজন হবে তখনও চালিয়ে যান ...
কিমভাইস

@ ড্যানিয়েল জিআই মনে করেন ডাউনলোডের সময়টি অপ্রাসঙ্গিক। এটি কী সংখ্যাটি উত্পন্ন করার বিষয়ে নয়, তাই আপনি যে তালিকাটি ডাউনলোড করছেন তা তৈরি করতে আপনি যে অ্যালগরিদমটি ব্যবহার করেছিলেন তা বিবেচনায় রাখতে চান। এবং যে কোনও সময় জটিলতা এটিকে ও (এন) প্রদত্ত একবার ফাইল স্থানান্তরের বিষয়টি উপেক্ষা করবে।
রস

প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী UTM প্রধানমন্ত্রী পৃষ্ঠার জন্য প্রস্তাব দেওয়া ছোট মৌলিক গণক দ্রুত তাদের একটি ডিস্ক বন্ধ পড়া চেয়ে (প্রশ্ন কি ছোট উপায়ে) হয়।
ব্যাটম্যান

12

আপনি যদি চাকাটি পুনরায় উদ্ভাবন করতে না চান, আপনি প্রতীকী গণিতের গ্রন্থাগার সিম্পি ইনস্টল করতে পারেন (হ্যাঁ এটি পাইথন 3 সামঞ্জস্যপূর্ণ)

pip install sympy

এবং প্রাইমারেজ ফাংশনটি ব্যবহার করুন

from sympy import sieve
primes = list(sieve.primerange(1, 10**6))

8

আপনি যদি ইটারটুলগুলি স্বীকার করেন তবে নকল নয়, পাইথন 3 এর জন্য rW_primes2 এর একটি অভিযোজন যা আমার মেশিনে প্রায় দ্বিগুণ দ্রুত চলে। চূড়ান্ত তালিকাটি তৈরির জন্য বুলিয়ানগুলির জন্য তালিকার পরিবর্তে একটি বাইটারি ব্যবহার করা এবং চূড়ান্ত তালিকা তৈরির জন্য তালিকার বোঝার পরিবর্তে সংক্ষেপ ব্যবহার করা হচ্ছে কেবলমাত্র উল্লেখযোগ্য পরিবর্তন। (আমি সক্ষম হলে আমি এটি মরনিংসনের মত একটি মন্তব্য হিসাবে যুক্ত করব))

import itertools
izip = itertools.zip_longest
chain = itertools.chain.from_iterable
compress = itertools.compress
def rwh_primes2_python3(n):
    """ Input n>=6, Returns a list of primes, 2 <= p < n """
    zero = bytearray([False])
    size = n//3 + (n % 6 == 2)
    sieve = bytearray([True]) * size
    sieve[0] = False
    for i in range(int(n**0.5)//3+1):
      if sieve[i]:
        k=3*i+1|1
        start = (k*k+4*k-2*k*(i&1))//3
        sieve[(k*k)//3::2*k]=zero*((size - (k*k)//3 - 1) // (2 * k) + 1)
        sieve[  start ::2*k]=zero*((size -   start  - 1) // (2 * k) + 1)
    ans = [2,3]
    poss = chain(izip(*[range(i, n, 6) for i in (1,5)]))
    ans.extend(compress(poss, sieve))
    return ans

তুলনা:

>>> timeit.timeit('primes.rwh_primes2(10**6)', setup='import primes', number=1)
0.0652179726976101
>>> timeit.timeit('primes.rwh_primes2_python3(10**6)', setup='import primes', number=1)
0.03267321276325674

এবং

>>> timeit.timeit('primes.rwh_primes2(10**8)', setup='import primes', number=1)
6.394284538007014
>>> timeit.timeit('primes.rwh_primes2_python3(10**8)', setup='import primes', number=1)
3.833829450302801

খুব শীতল বাস্তবায়ন। :)
ক্রিশ

7

এটি আপনার নিজস্ব প্রাইম ফাইন্ডিং কোডটি লেখার জন্য শিক্ষণীয়, তবে একটি দ্রুত নির্ভরযোগ্য গ্রন্থাগার হাতে রাখাও এটি কার্যকর। আমি সি ++ গ্রন্থাগার প্রাইমসিভের চারপাশে একটি মোড়ক লিখেছিলাম , এটির নাম রেখেছি প্রাইমসিভ-পাইথন

চেষ্টা করে দেখুন pip install primesieve

import primesieve
primes = primesieve.generate_primes(10**8)

আমি গতি তুলনা করতে আগ্রহী হতে হবে।


এটি ঠিক ওপি যা আদেশ করেছিল তা নয় তবে ডাউনটা কেন কেন তা আমি ব্যর্থ হয়েছি। এটি অন্যান্য কয়েকটি বাইরের মডিউলগুলির বিপরীতে একটি 2.8 সেকস সমাধান। আমি উত্সে লক্ষ্য করেছি যে এটি থ্রেডেড হয়েছে, এটি কতটা ভালভাবে আঁকে তার কোনও পরীক্ষা পেয়েছি?
ljetibo

@ লেজেটিবো চিয়ার্স বাধাটি পাইথনের তালিকায় সি ++ ভেক্টর অনুলিপি করে মনে হচ্ছে, সুতরাং count_primesফাংশনটি এর চেয়ে অনেক দ্রুতgenerate_primes
কর্নেল প্যানিক

আমার কম্পিউটারে এটি আরামে 1e8 অবধি প্রাইম তৈরি করতে পারে (এটি 1e9 এর জন্য মেমোরিএরার দেয়) এবং 1e10 পর্যন্ত প্রাইমগুলি গণনা করতে পারে। @ হ্যাপিলিপসেকেন্ড উপরে 1e6 এর জন্য অ্যালগরিদমের তুলনা করেছে
কর্নেল প্যানিক

7

এখানে দ্রুততম ফাংশনগুলির একটির দুটি আপডেট (খাঁটি পাইথন 3.6) সংস্করণ রয়েছে,

from itertools import compress

def rwh_primes1v1(n):
    """ Returns  a list of primes < n for n > 2 """
    sieve = bytearray([True]) * (n//2)
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i//2]:
            sieve[i*i//2::i] = bytearray((n-i*i-1)//(2*i)+1)
    return [2,*compress(range(3,n,2), sieve[1:])]

def rwh_primes1v2(n):
    """ Returns a list of primes < n for n > 2 """
    sieve = bytearray([True]) * (n//2+1)
    for i in range(1,int(n**0.5)//2+1):
        if sieve[i]:
            sieve[2*i*(i+1)::2*i+1] = bytearray((n//2-2*i*(i+1))//(2*i+1)+1)
    return [2,*compress(range(3,n,2), sieve[1:])]

1
পাইথন 3-তে আমি এই ফাংশনটি স্ট্যাকওভারফ্লো.com/a/3035188/7799269 ব্যবহার করেছি তবে / দিয়ে // এবং xेंज রেঞ্জের সাথে প্রতিস্থাপন করেছি এবং এগুলি তার চেয়ে অনেক দ্রুত বলে মনে হয়েছিল।
samerivertwice

4

মিলার-রবিনের আদিমত্ব পরীক্ষার একটি নির্ধারিত বাস্তবায়ন এই অনুমানের উপর যে এন <9,080,191

import sys
import random

def miller_rabin_pass(a, n):
    d = n - 1
    s = 0
    while d % 2 == 0:
        d >>= 1
        s += 1

    a_to_power = pow(a, d, n)
    if a_to_power == 1:
        return True
    for i in xrange(s-1):
        if a_to_power == n - 1:
            return True
        a_to_power = (a_to_power * a_to_power) % n
    return a_to_power == n - 1


def miller_rabin(n):
    for a in [2, 3, 37, 73]:
      if not miller_rabin_pass(a, n):
        return False
    return True


n = int(sys.argv[1])
primes = [2]
for p in range(3,n,2):
  if miller_rabin(p):
    primes.append(p)
print len(primes)

উইকিপিডিয়ায় নিবন্ধ অনুসারে ( http://en.wikedia.org/wiki/Miller–Rabin_primality_test ) N = 9,080,191 কে a = ২,৩, ,৩ এর জন্য পরীক্ষা করা, এবং N৩ সিদ্ধান্ত নিতে যথেষ্ট হবে যে N যৌগিক কিনা।

এবং আমি এখানে পাওয়া মিলার-রবিনের পরীক্ষার সম্ভাব্য বাস্তবায়ন থেকে উত্স কোডটি গ্রহণ করেছি: http://en.literateprograms.org/ মিলার- রবিন_প্রিয়ালিটি_টেষ্ট_( পাইথন)


1
মিলার-রবিন আদিমতার পরীক্ষার জন্য ধন্যবাদ, তবে এই কোডটি আসলে ধীর এবং সঠিক ফলাফল সরবরাহ করছে না। 37 প্রধান এবং পরীক্ষায় পাস করে না।
jbochi

আমি অনুমান করি যে 37 টি বিশেষ ক্ষেত্রেগুলির মধ্যে একটি, আমার খারাপ। যদিও আমি
নির্দলীয়

রাবিন মিলার জন্য বিশেষ কোনও মামলা নেই।
বিভ্রান্ত

2
আপনি নিবন্ধটি ভুল লিখেছেন। এটি ৩১, নয় ৩ 37 This এই কারণেই আপনার প্রয়োগ ব্যর্থ হয়।
লোগান

4

যদি আপনার এন এর নিয়ন্ত্রণ থাকে তবে সমস্ত প্রাইম তালিকা করার খুব দ্রুততম উপায় হ'ল সেগুলি প্রতিরোধ করা। সিরিয়াসলি। প্রিকম্পুটিং একটি উপায়ে অপ্টিমাইজেশন।


3
বা এগুলি এখান থেকে ডাউনলোড করুন primes.utm.edu/lists/small/millions , তবে ধারণাটি হল পাইথনের সীমা পরীক্ষা করা এবং দেখতে অপ্টিমাইজেশান থেকে সুন্দর কোড উত্থাপিত হয়েছে কিনা।
jbochi

4

পাইথনের প্রাইমগুলি উত্পন্ন করতে আমি সাধারণত কোডটি ব্যবহার করি:

$ python -mtimeit -s'import sieve' 'sieve.sieve(1000000)' 
10 loops, best of 3: 445 msec per loop
$ cat sieve.py
from math import sqrt

def sieve(size):
 prime=[True]*size
 rng=xrange
 limit=int(sqrt(size))

 for i in rng(3,limit+1,+2):
  if prime[i]:
   prime[i*i::+i]=[False]*len(prime[i*i::+i])

 return [2]+[i for i in rng(3,size,+2) if prime[i]]

if __name__=='__main__':
 print sieve(100)

এটি এখানে পোস্ট করা দ্রুত সমাধানগুলির সাথে প্রতিযোগিতা করতে পারে না, তবে কমপক্ষে এটি খাঁটি অজগর।

এই প্রশ্ন পোস্ট করার জন্য ধন্যবাদ। আমি আজ সত্যিই অনেক কিছু শিখেছি।


3

দ্রুততম কোডের জন্য, নমপি সমাধানটি সেরা। নিখুঁত একাডেমিক কারণে, যদিও আমি আমার খাঁটি পাইথন সংস্করণ পোস্ট করছি, যা উপরে পোস্ট করা কুকবুক সংস্করণের চেয়ে 50% এর চেয়ে কম দ্রুত faster যেহেতু আমি পুরো তালিকাটি মেমোরিতে তৈরি করেছি, তাই আপনাকে সমস্ত কিছু ধরে রাখার জন্য পর্যাপ্ত জায়গা দরকার তবে এটি মোটামুটি ভাল স্কেল বলে মনে হচ্ছে।

def daniel_sieve_2(maxNumber):
    """
    Given a number, returns all numbers less than or equal to
    that number which are prime.
    """
    allNumbers = range(3, maxNumber+1, 2)
    for mIndex, number in enumerate(xrange(3, maxNumber+1, 2)):
        if allNumbers[mIndex] == 0:
            continue
        # now set all multiples to 0
        for index in xrange(mIndex+number, (maxNumber-3)/2+1, number):
            allNumbers[index] = 0
    return [2] + filter(lambda n: n!=0, allNumbers)

এবং ফলাফল:

>>>mine = timeit.Timer("daniel_sieve_2(1000000)",
...                    "from sieves import daniel_sieve_2")
>>>prev = timeit.Timer("get_primes_erat(1000000)",
...                    "from sieves import get_primes_erat")
>>>print "Mine: {0:0.4f} ms".format(min(mine.repeat(3, 1))*1000)
Mine: 428.9446 ms
>>>print "Previous Best {0:0.4f} ms".format(min(prev.repeat(3, 1))*1000)
Previous Best 621.3581 ms

3

নিম্পি ব্যবহার করে একটি অর্ধ চালনি কিছুটা আলাদা বাস্তবায়ন:

http://rebrained.com/?p=458

গণিত আমদানি করুন
ইম্পোর্ট ন্যালি
Def prime6 (অবধি):
    মৌলিক = numpy.arange (3, পর্যন্ত + + 1,2)
    isprime = numpy.ones ((অবধি -1) / 2 dtype = bool,)
    প্রাইমগুলিতে ফ্যাক্টরের জন্য [: int (math.sqrt (upto))]:
        যদি ইসপ্রাইম [(ফ্যাক্টর -২) / ২]: ইসপ্রাইম [(ফ্যাক্টর * 3-2) / 2: (আপ -1) / 2: ফ্যাক্টর] = 0
    রিটার্ন numpy.insert (প্রাইমস [isprime], 0,2)

কেউ কি অন্য সময়ের সাথে এটি তুলনা করতে পারে? আমার মেশিনে এটি অন্যান্য নম্পি অর্ধ-চালনিগুলির সাথে তুলনাযোগ্য মনে হয়।


upto=10**6: primesfrom2to()- 7 এমএস; prime6()- 12 এমএস আদর্শ
ওডিজি

3

এটি সবই লিখিত এবং পরীক্ষিত। সুতরাং চাকা পুনরায় উদ্ভাবনের প্রয়োজন নেই।

python -m timeit -r10 -s"from sympy import sieve" "primes = list(sieve.primerange(1, 10**6))"

আমাদের একটি রেকর্ড ব্রেকিং 12.2 এমসেক দেয় !

10 loops, best of 10: 12.2 msec per loop

যদি এটি পর্যাপ্ত দ্রুত না হয় তবে আপনি পাইপাই চেষ্টা করতে পারেন:

pypy -m timeit -r10 -s"from sympy import sieve" "primes = list(sieve.primerange(1, 10**6))"

যার ফলাফল:

10 loops, best of 10: 2.03 msec per loop

247 আপ-ভোট সহ উত্তরটি সেরা সমাধানের জন্য 15.9 এমএস তালিকাভুক্ত করে। এই তুলনা !!!


3

আমি কিছু আনটবু'র ফাংশন পরীক্ষা করেছি , আমি এটির সংখ্যা কয়েক মিলিয়ন সংখ্যার সাথে গণনা করেছি

বিজয়ীরা হ'ল ফাংশন যা অদ্ভুত গ্রন্থাগার ব্যবহার করে,

দ্রষ্টব্য : এটি মেমরির ব্যবহারের পরীক্ষাও আকর্ষণীয় করে তোলে :)

গণনার সময় ফলাফল

কোডের উদাহরণ

আমার গিথুব সংগ্রহস্থলের সম্পূর্ণ কোড

#!/usr/bin/env python

import lib
import timeit
import sys
import math
import datetime

import prettyplotlib as ppl
import numpy as np

import matplotlib.pyplot as plt
from prettyplotlib import brewer2mpl

primenumbers_gen = [
    'sieveOfEratosthenes',
    'ambi_sieve',
    'ambi_sieve_plain',
    'sundaram3',
    'sieve_wheel_30',
    'primesfrom3to',
    'primesfrom2to',
    'rwh_primes',
    'rwh_primes1',
    'rwh_primes2',
]

def human_format(num):
    # /programming/579310/formatting-long-numbers-as-strings-in-python?answertab=active#tab-top
    magnitude = 0
    while abs(num) >= 1000:
        magnitude += 1
        num /= 1000.0
    # add more suffixes if you need them
    return '%.2f%s' % (num, ['', 'K', 'M', 'G', 'T', 'P'][magnitude])


if __name__=='__main__':

    # Vars
    n = 10000000 # number itereration generator
    nbcol = 5 # For decompose prime number generator
    nb_benchloop = 3 # Eliminate false positive value during the test (bench average time)
    datetimeformat = '%Y-%m-%d %H:%M:%S.%f'
    config = 'from __main__ import n; import lib'
    primenumbers_gen = {
        'sieveOfEratosthenes': {'color': 'b'},
        'ambi_sieve': {'color': 'b'},
        'ambi_sieve_plain': {'color': 'b'},
         'sundaram3': {'color': 'b'},
        'sieve_wheel_30': {'color': 'b'},
# # #        'primesfrom2to': {'color': 'b'},
        'primesfrom3to': {'color': 'b'},
        # 'rwh_primes': {'color': 'b'},
        # 'rwh_primes1': {'color': 'b'},
        'rwh_primes2': {'color': 'b'},
    }


    # Get n in command line
    if len(sys.argv)>1:
        n = int(sys.argv[1])

    step = int(math.ceil(n / float(nbcol)))
    nbs = np.array([i * step for i in range(1, int(nbcol) + 1)])
    set2 = brewer2mpl.get_map('Paired', 'qualitative', 12).mpl_colors

    print datetime.datetime.now().strftime(datetimeformat)
    print("Compute prime number to %(n)s" % locals())
    print("")

    results = dict()
    for pgen in primenumbers_gen:
        results[pgen] = dict()
        benchtimes = list()
        for n in nbs:
            t = timeit.Timer("lib.%(pgen)s(n)" % locals(), setup=config)
            execute_times = t.repeat(repeat=nb_benchloop,number=1)
            benchtime = np.mean(execute_times)
            benchtimes.append(benchtime)
        results[pgen] = {'benchtimes':np.array(benchtimes)}

fig, ax = plt.subplots(1)
plt.ylabel('Computation time (in second)')
plt.xlabel('Numbers computed')
i = 0
for pgen in primenumbers_gen:

    bench = results[pgen]['benchtimes']
    avgs = np.divide(bench,nbs)
    avg = np.average(bench, weights=nbs)

    # Compute linear regression
    A = np.vstack([nbs, np.ones(len(nbs))]).T
    a, b = np.linalg.lstsq(A, nbs*avgs)[0]

    # Plot
    i += 1
    #label="%(pgen)s" % locals()
    #ppl.plot(nbs, nbs*avgs, label=label, lw=1, linestyle='--', color=set2[i % 12])
    label="%(pgen)s avg" % locals()
    ppl.plot(nbs, a * nbs + b, label=label, lw=2, color=set2[i % 12])
print datetime.datetime.now().strftime(datetimeformat)

ppl.legend(ax, loc='upper left', ncol=4)

# Change x axis label
ax.get_xaxis().get_major_formatter().set_scientific(False)
fig.canvas.draw()
labels = [human_format(int(item.get_text())) for item in ax.get_xticklabels()]

ax.set_xticklabels(labels)
ax = plt.gca()

plt.show()


3

পাইথন 3 এর জন্য

def rwh_primes2(n):
    correction = (n%6>1)
    n = {0:n,1:n-1,2:n+4,3:n+3,4:n+2,5:n+1}[n%6]
    sieve = [True] * (n//3)
    sieve[0] = False
    for i in range(int(n**0.5)//3+1):
      if sieve[i]:
        k=3*i+1|1
        sieve[      ((k*k)//3)      ::2*k]=[False]*((n//6-(k*k)//6-1)//k+1)
        sieve[(k*k+4*k-2*k*(i&1))//3::2*k]=[False]*((n//6-(k*k+4*k-2*k*(i&1))//6-1)//k+1)
    return [2,3] + [3*i+1|1 for i in range(1,n//3-correction) if sieve[i]]

3

খাঁটি পাইথনের দ্রুততম চালনী :

from itertools import compress

def half_sieve(n):
    """
    Returns a list of prime numbers less than `n`.
    """
    if n <= 2:
        return []
    sieve = bytearray([True]) * (n // 2)
    for i in range(3, int(n ** 0.5) + 1, 2):
        if sieve[i // 2]:
            sieve[i * i // 2::i] = bytearray((n - i * i - 1) // (2 * i) + 1)
    primes = list(compress(range(1, n, 2), sieve))
    primes[0] = 2
    return primes

গতি এবং স্মৃতির জন্য আমি সিরিভ অফ ইরোটোথিনিসকে অনুকূলিত করেছি ।

মাপকাঠি

from time import clock
import platform

def benchmark(iterations, limit):
    start = clock()
    for x in range(iterations):
        half_sieve(limit)
    end = clock() - start
    print(f'{end/iterations:.4f} seconds for primes < {limit}')

if __name__ == '__main__':
    print(platform.python_version())
    print(platform.platform())
    print(platform.processor())
    it = 10
    for pw in range(4, 9):
        benchmark(it, 10**pw)

আউটপুট

>>> 3.6.7
>>> Windows-10-10.0.17763-SP0
>>> Intel64 Family 6 Model 78 Stepping 3, GenuineIntel
>>> 0.0003 seconds for primes < 10000
>>> 0.0021 seconds for primes < 100000
>>> 0.0204 seconds for primes < 1000000
>>> 0.2389 seconds for primes < 10000000
>>> 2.6702 seconds for primes < 100000000

2

পাইথনটি প্রথমবার ব্যবহার করে, তাই এর মধ্যে আমি যে কয়েকটি পদ্ধতি ব্যবহার করি তা কিছুটা জটিল মনে হতে পারে। আমি কেবল আমার সি ++ কোডটি অজগরে রূপান্তরিত করেছি এবং এটি আমার কাছে রয়েছে (পাইথনে কিছুটা ধীরে ধীরে হলেও)

#!/usr/bin/env python
import time

def GetPrimes(n):

    Sieve = [1 for x in xrange(n)]

    Done = False
    w = 3

    while not Done:

        for q in xrange (3, n, 2):
            Prod = w*q
            if Prod < n:
                Sieve[Prod] = 0
            else:
                break

        if w > (n/2):
            Done = True
        w += 2

    return Sieve



start = time.clock()

d = 10000000
Primes = GetPrimes(d)

count = 1 #This is for 2

for x in xrange (3, d, 2):
    if Primes[x]:
        count+=1

elapsed = (time.clock() - start)
print "\nFound", count, "primes in", elapsed, "seconds!\n"

পাইথনউ প্রাইমস.পি

12.799119 সেকেন্ডে 664579 প্রাইম পাওয়া গেছে!

#!/usr/bin/env python
import time

def GetPrimes2(n):

    Sieve = [1 for x in xrange(n)]

    for q in xrange (3, n, 2):
        k = q
        for y in xrange(k*3, n, k*2):
            Sieve[y] = 0

    return Sieve



start = time.clock()

d = 10000000
Primes = GetPrimes2(d)

count = 1 #This is for 2

for x in xrange (3, d, 2):
    if Primes[x]:
        count+=1

elapsed = (time.clock() - start)
print "\nFound", count, "primes in", elapsed, "seconds!\n"

পাইথনউ Primes2.py

10.230172 সেকেন্ডে 664579 প্রাইম পাওয়া গেছে!

#!/usr/bin/env python
import time

def GetPrimes3(n):

    Sieve = [1 for x in xrange(n)]

    for q in xrange (3, n, 2):
        k = q
        for y in xrange(k*k, n, k << 1):
            Sieve[y] = 0

    return Sieve



start = time.clock()

d = 10000000
Primes = GetPrimes3(d)

count = 1 #This is for 2

for x in xrange (3, d, 2):
    if Primes[x]:
        count+=1

elapsed = (time.clock() - start)
print "\nFound", count, "primes in", elapsed, "seconds!\n"

পাইথন প্রাইমস 2.py

7.113776 সেকেন্ডে 664579 প্রাইম পাওয়া গেছে!


2

আমি জানি প্রতিযোগিতাটি কয়েক বছর ধরে বন্ধ রয়েছে। ...

তবে খাঁটি পাইথন প্রাইম চালুনির জন্য আমার পরামর্শ, চালুনি এগিয়ে নিয়ে যাওয়ার সময় যথাযথ পদক্ষেপগুলি ব্যবহার করে 2, 3 এবং 5 এর গুণকগুলি বাদ দেওয়ার উপর ভিত্তি করে pure তবে এটি @ রবার্ট উইলিয়াম হ্যাঙ্কস এর চেয়ে ভাল সমাধান rW_primes2 এবং rW_primes1 এর চেয়ে এন <10 ^ 9 এর চেয়ে ধীর slow 1.5 * 10 ^ 8 এর উপরে সিটিপিস.সি.সোর্ট চালনা অ্যারে ব্যবহার করে এটি কোনওভাবে মেমরির সীমাতে অভিযোজিত।

10 ^ 6

y পাইথন-মিমিটিট-এস "আমদানি প্রাইমসিভস্পিডকম্প" "প্রাইমসিভসস্পিডকম্প.প্রাইমসিয়েভসেক্স (1000000)" 10 লুপ, প্রতি লুপে 3: 46.7 মেসি সর্বোত্তম

তুলনা করতে: $ পাইথন -মাইমাইটিট-এস "আমদানি প্রাইমসিভস্পিডকম্প" "প্রাইমসিভস্পিডকম্প.আরএইচ_প্রাইমস 1 (1000000)" 10 লুপ, তুলনা করতে প্রতি লুপটিতে 3: 43.2 ম্যাসিস্টের সেরা: $ পাইথন-এম টাইমিট -স "ইম্পোর্ট প্রাইমসিভসপিডকম্প" "প্রাইমসিরিপসম্প 2 (1000000) "10 টি লুপ, প্রতি লুপটিতে 3: 34.5 ম্যাসিচুরতম

10 ^ 7

y পাইথন -মিমিটিট-এস "আমদানি প্রাইমসিভস্পিডকম্প" "প্রাইমসিভসস্পিডকম্প.প্রাইমসিয়েভসেক্স (10000000)" 10 লুপ, প্রতি লুপে 3: 530 ম্যাসিলে সেরা

তুলনা করতে: $ পাইথন -মিমিটিট-এস "আমদানি প্রাইমসিভসস্পিডকম্প" "প্রাইমসিভস্পিডকম্প.আরএইচ_প্রাইমস 1 (10000000)" 10 লুপ, তুলনা করতে প্রতি লুপে 3: 494 এমসির সেরা: $ পাইথন-এম টাইমিট -স "আমদানি প্রাইমসিভসম্পিডকম্প" "প্রাইমসিরিপসম্প 2 (10000000) "10 টি লুপ, প্রতি লুপটিতে 3: 375 এমসিতে সেরা

10 ^ 8

$ পাইথন -মিমিটিট-এস "আমদানি প্রাইমসিভস্পিডকম্প" "প্রাইমসিভসস্পিডকম্প.প্রাইমসিয়েভসেক্স (100000000)" 10 লুপ, প্রতি লুপে 3: 5.55 সেকেন্ডের সেরা

তুলনা করতে: $ পাইথন -মাইমাইটিট-এস "আমদানি প্রাইমসিভস্পিডকম্প" "প্রাইমসিভস্পিডকম্প.আরএইচ_প্রাইমস 1 (100000000)" 10 লুপ, তুলনা করতে প্রতি লুপে 3: 5.33 সেকেন্ডের সেরা: $ পাইথন-এম টাইমিট -স "ইম্পোর্ট প্রাইমসিভস্পিডকম্প" "প্রাইমসরিপসম্পিপি 2" (100000000) "10 লুপ, প্রতি লুপে 3: 3.95 সেকেন্ডের সেরা

10 ^ 9

y পাইথন-মিমিটিট-এস "আমদানি প্রাইমসিভস্পিডকম্প" "প্রাইমসিভসস্পিডকম্প.প্রাইমসিয়েভসেক্স (1000000000)" 10 লুপ, প্রতি লুপে 3: 61.2 সেকেন্ডের মধ্যে সেরা

তুলনা করতে: y পাইথন -মিমিটিট-এন 3-এস "আমদানি প্রাইমসিভস্পিডকম্প" "প্রাইমসিভসস্পিডকম্প.আরএইচ_প্রাইম 1 (1000000000)" 3 লুপ, 3 লুপ প্রতি 3: 97.8 সেকেন্ডের সেরা

তুলনা করতে: y পাইথন-মি টাইমিট-এস "আমদানি প্রাইমসিভস্পিডকম্প" "প্রাইমসিভস্পিডকম্প.আর.ভি.প্রাইমস 2 (1000000000)" 10 লুপ, প্রতি লুপে 3: 41.9 সেকেন্ডের সেরা

এই পরীক্ষাগুলি পর্যালোচনা করতে আপনি নীচের কোডটি উবুন্টাস প্রাইমসিভস্পিডকম্পে অনুলিপি করতে পারেন।

def primeSieveSeq(MAX_Int):
    if MAX_Int > 5*10**8:
        import ctypes
        int16Array = ctypes.c_ushort * (MAX_Int >> 1)
        sieve = int16Array()
        #print 'uses ctypes "unsigned short int Array"'
    else:
        sieve = (MAX_Int >> 1) * [False]
        #print 'uses python list() of long long int'
    if MAX_Int < 10**8:
        sieve[4::3] = [True]*((MAX_Int - 8)/6+1)
        sieve[12::5] = [True]*((MAX_Int - 24)/10+1)
    r = [2, 3, 5]
    n = 0
    for i in xrange(int(MAX_Int**0.5)/30+1):
        n += 3
        if not sieve[n]:
            n2 = (n << 1) + 1
            r.append(n2)
            n2q = (n2**2) >> 1
            sieve[n2q::n2] = [True]*(((MAX_Int >> 1) - n2q - 1) / n2 + 1)
        n += 2
        if not sieve[n]:
            n2 = (n << 1) + 1
            r.append(n2)
            n2q = (n2**2) >> 1
            sieve[n2q::n2] = [True]*(((MAX_Int >> 1) - n2q - 1) / n2 + 1)
        n += 1
        if not sieve[n]:
            n2 = (n << 1) + 1
            r.append(n2)
            n2q = (n2**2) >> 1
            sieve[n2q::n2] = [True]*(((MAX_Int >> 1) - n2q - 1) / n2 + 1)
        n += 2
        if not sieve[n]:
            n2 = (n << 1) + 1
            r.append(n2)
            n2q = (n2**2) >> 1
            sieve[n2q::n2] = [True]*(((MAX_Int >> 1) - n2q - 1) / n2 + 1)
        n += 1
        if not sieve[n]:
            n2 = (n << 1) + 1
            r.append(n2)
            n2q = (n2**2) >> 1
            sieve[n2q::n2] = [True]*(((MAX_Int >> 1) - n2q - 1) / n2 + 1)
        n += 2
        if not sieve[n]:
            n2 = (n << 1) + 1
            r.append(n2)
            n2q = (n2**2) >> 1
            sieve[n2q::n2] = [True]*(((MAX_Int >> 1) - n2q - 1) / n2 + 1)
        n += 3
        if not sieve[n]:
            n2 = (n << 1) + 1
            r.append(n2)
            n2q = (n2**2) >> 1
            sieve[n2q::n2] = [True]*(((MAX_Int >> 1) - n2q - 1) / n2 + 1)
        n += 1
        if not sieve[n]:
            n2 = (n << 1) + 1
            r.append(n2)
            n2q = (n2**2) >> 1
            sieve[n2q::n2] = [True]*(((MAX_Int >> 1) - n2q - 1) / n2 + 1)
    if MAX_Int < 10**8:
        return [2, 3, 5]+[(p << 1) + 1 for p in [n for n in xrange(3, MAX_Int >> 1) if not sieve[n]]]
    n = n >> 1
    try:
        for i in xrange((MAX_Int-2*n)/30 + 1):
            n += 3
            if not sieve[n]:
                r.append((n << 1) + 1)
            n += 2
            if not sieve[n]:
                r.append((n << 1) + 1)
            n += 1
            if not sieve[n]:
                r.append((n << 1) + 1)
            n += 2
            if not sieve[n]:
                r.append((n << 1) + 1)
            n += 1
            if not sieve[n]:
                r.append((n << 1) + 1)
            n += 2
            if not sieve[n]:
                r.append((n << 1) + 1)
            n += 3
            if not sieve[n]:
                r.append((n << 1) + 1)
            n += 1
            if not sieve[n]:
                r.append((n << 1) + 1)
    except:
        pass
    return r

আপনার পরীক্ষার ফলাফলগুলি ভিজ্যুয়ালাইজ করতে, লগ-লগ স্কেলে এগুলি প্লট করুন , বৃদ্ধির অভিজ্ঞতাগত আদেশগুলি দেখতে এবং তুলনা করতে ।
নেস


1

এখানে সিভী অফ ইরোটোস্টিনিসের একটি অদ্ভুত সংস্করণ রয়েছে যা উভয় ভাল জটিলতা রয়েছে (দৈর্ঘ্যের এন অ্যারে বাছাই করার চেয়ে কম) এবং ভেক্টরাইজেশন। এক মিলিয়নের নীচে সমস্ত প্রাইম খুঁজে পেতে 46 মাইক্রোস্যাকসন সহ প্যাকেজগুলি যত দ্রুত তাড়াতাড়ি @ ইউন্টবু তুলনায় এটি তুলনা করুন।

import numpy as np 
def generate_primes(n):
    is_prime = np.ones(n+1,dtype=bool)
    is_prime[0:2] = False
    for i in range(int(n**0.5)+1):
        if is_prime[i]:
            is_prime[i**2::i]=False
    return np.where(is_prime)[0]

সময়:

import time    
for i in range(2,10):
    timer =time.time()
    generate_primes(10**i)
    print('n = 10^',i,' time =', round(time.time()-timer,6))

>> n = 10^ 2  time = 5.6e-05
>> n = 10^ 3  time = 6.4e-05
>> n = 10^ 4  time = 0.000114
>> n = 10^ 5  time = 0.000593
>> n = 10^ 6  time = 0.00467
>> n = 10^ 7  time = 0.177758
>> n = 10^ 8  time = 1.701312
>> n = 10^ 9  time = 19.322478

1

পাইথন 3 এর কোডের বেশিরভাগ অংশ আমি আপডেট করেছি এবং এটি আসলে সবচেয়ে দ্রুত যা তা দেখার জন্য এটি পেরফ্লট (আমার একটি প্রকল্প) এ ছুড়ে ফেলেছি । বড় আকারের জন্য n, primesfrom{2,3}toকেক নিন:

এখানে চিত্র বর্ণনা লিখুন


প্লটটি পুনরুত্পাদন করার কোড:

import perfplot
from math import sqrt, ceil
import numpy as np
import sympy


def rwh_primes(n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Returns  a list of primes < n """
    sieve = [True] * n
    for i in range(3, int(n ** 0.5) + 1, 2):
        if sieve[i]:
            sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
    return [2] + [i for i in range(3, n, 2) if sieve[i]]


def rwh_primes1(n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Returns  a list of primes < n """
    sieve = [True] * (n // 2)
    for i in range(3, int(n ** 0.5) + 1, 2):
        if sieve[i // 2]:
            sieve[i * i // 2::i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
    return [2] + [2 * i + 1 for i in range(1, n // 2) if sieve[i]]


def rwh_primes2(n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """Input n>=6, Returns a list of primes, 2 <= p < n"""
    assert n >= 6
    correction = n % 6 > 1
    n = {0: n, 1: n - 1, 2: n + 4, 3: n + 3, 4: n + 2, 5: n + 1}[n % 6]
    sieve = [True] * (n // 3)
    sieve[0] = False
    for i in range(int(n ** 0.5) // 3 + 1):
        if sieve[i]:
            k = 3 * i + 1 | 1
            sieve[((k * k) // 3)::2 * k] = [False] * (
                (n // 6 - (k * k) // 6 - 1) // k + 1
            )
            sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = [False] * (
                (n // 6 - (k * k + 4 * k - 2 * k * (i & 1)) // 6 - 1) // k + 1
            )
    return [2, 3] + [3 * i + 1 | 1 for i in range(1, n // 3 - correction) if sieve[i]]


def sieve_wheel_30(N):
    # http://zerovolt.com/?p=88
    """ Returns a list of primes <= N using wheel criterion 2*3*5 = 30

Copyright 2009 by zerovolt.com
This code is free for non-commercial purposes, in which case you can just leave this comment as a credit for my work.
If you need this code for commercial purposes, please contact me by sending an email to: info [at] zerovolt [dot] com."""
    __smallp = (
        2,
        3,
        5,
        7,
        11,
        13,
        17,
        19,
        23,
        29,
        31,
        37,
        41,
        43,
        47,
        53,
        59,
        61,
        67,
        71,
        73,
        79,
        83,
        89,
        97,
        101,
        103,
        107,
        109,
        113,
        127,
        131,
        137,
        139,
        149,
        151,
        157,
        163,
        167,
        173,
        179,
        181,
        191,
        193,
        197,
        199,
        211,
        223,
        227,
        229,
        233,
        239,
        241,
        251,
        257,
        263,
        269,
        271,
        277,
        281,
        283,
        293,
        307,
        311,
        313,
        317,
        331,
        337,
        347,
        349,
        353,
        359,
        367,
        373,
        379,
        383,
        389,
        397,
        401,
        409,
        419,
        421,
        431,
        433,
        439,
        443,
        449,
        457,
        461,
        463,
        467,
        479,
        487,
        491,
        499,
        503,
        509,
        521,
        523,
        541,
        547,
        557,
        563,
        569,
        571,
        577,
        587,
        593,
        599,
        601,
        607,
        613,
        617,
        619,
        631,
        641,
        643,
        647,
        653,
        659,
        661,
        673,
        677,
        683,
        691,
        701,
        709,
        719,
        727,
        733,
        739,
        743,
        751,
        757,
        761,
        769,
        773,
        787,
        797,
        809,
        811,
        821,
        823,
        827,
        829,
        839,
        853,
        857,
        859,
        863,
        877,
        881,
        883,
        887,
        907,
        911,
        919,
        929,
        937,
        941,
        947,
        953,
        967,
        971,
        977,
        983,
        991,
        997,
    )
    # wheel = (2, 3, 5)
    const = 30
    if N < 2:
        return []
    if N <= const:
        pos = 0
        while __smallp[pos] <= N:
            pos += 1
        return list(__smallp[:pos])
    # make the offsets list
    offsets = (7, 11, 13, 17, 19, 23, 29, 1)
    # prepare the list
    p = [2, 3, 5]
    dim = 2 + N // const
    tk1 = [True] * dim
    tk7 = [True] * dim
    tk11 = [True] * dim
    tk13 = [True] * dim
    tk17 = [True] * dim
    tk19 = [True] * dim
    tk23 = [True] * dim
    tk29 = [True] * dim
    tk1[0] = False
    # help dictionary d
    # d[a , b] = c  ==> if I want to find the smallest useful multiple of (30*pos)+a
    # on tkc, then I need the index given by the product of [(30*pos)+a][(30*pos)+b]
    # in general. If b < a, I need [(30*pos)+a][(30*(pos+1))+b]
    d = {}
    for x in offsets:
        for y in offsets:
            res = (x * y) % const
            if res in offsets:
                d[(x, res)] = y
    # another help dictionary: gives tkx calling tmptk[x]
    tmptk = {1: tk1, 7: tk7, 11: tk11, 13: tk13, 17: tk17, 19: tk19, 23: tk23, 29: tk29}
    pos, prime, lastadded, stop = 0, 0, 0, int(ceil(sqrt(N)))

    # inner functions definition
    def del_mult(tk, start, step):
        for k in range(start, len(tk), step):
            tk[k] = False

    # end of inner functions definition
    cpos = const * pos
    while prime < stop:
        # 30k + 7
        if tk7[pos]:
            prime = cpos + 7
            p.append(prime)
            lastadded = 7
            for off in offsets:
                tmp = d[(7, off)]
                start = (
                    (pos + prime)
                    if off == 7
                    else (prime * (const * (pos + 1 if tmp < 7 else 0) + tmp)) // const
                )
                del_mult(tmptk[off], start, prime)
        # 30k + 11
        if tk11[pos]:
            prime = cpos + 11
            p.append(prime)
            lastadded = 11
            for off in offsets:
                tmp = d[(11, off)]
                start = (
                    (pos + prime)
                    if off == 11
                    else (prime * (const * (pos + 1 if tmp < 11 else 0) + tmp)) // const
                )
                del_mult(tmptk[off], start, prime)
        # 30k + 13
        if tk13[pos]:
            prime = cpos + 13
            p.append(prime)
            lastadded = 13
            for off in offsets:
                tmp = d[(13, off)]
                start = (
                    (pos + prime)
                    if off == 13
                    else (prime * (const * (pos + 1 if tmp < 13 else 0) + tmp)) // const
                )
                del_mult(tmptk[off], start, prime)
        # 30k + 17
        if tk17[pos]:
            prime = cpos + 17
            p.append(prime)
            lastadded = 17
            for off in offsets:
                tmp = d[(17, off)]
                start = (
                    (pos + prime)
                    if off == 17
                    else (prime * (const * (pos + 1 if tmp < 17 else 0) + tmp)) // const
                )
                del_mult(tmptk[off], start, prime)
        # 30k + 19
        if tk19[pos]:
            prime = cpos + 19
            p.append(prime)
            lastadded = 19
            for off in offsets:
                tmp = d[(19, off)]
                start = (
                    (pos + prime)
                    if off == 19
                    else (prime * (const * (pos + 1 if tmp < 19 else 0) + tmp)) // const
                )
                del_mult(tmptk[off], start, prime)
        # 30k + 23
        if tk23[pos]:
            prime = cpos + 23
            p.append(prime)
            lastadded = 23
            for off in offsets:
                tmp = d[(23, off)]
                start = (
                    (pos + prime)
                    if off == 23
                    else (prime * (const * (pos + 1 if tmp < 23 else 0) + tmp)) // const
                )
                del_mult(tmptk[off], start, prime)
        # 30k + 29
        if tk29[pos]:
            prime = cpos + 29
            p.append(prime)
            lastadded = 29
            for off in offsets:
                tmp = d[(29, off)]
                start = (
                    (pos + prime)
                    if off == 29
                    else (prime * (const * (pos + 1 if tmp < 29 else 0) + tmp)) // const
                )
                del_mult(tmptk[off], start, prime)
        # now we go back to top tk1, so we need to increase pos by 1
        pos += 1
        cpos = const * pos
        # 30k + 1
        if tk1[pos]:
            prime = cpos + 1
            p.append(prime)
            lastadded = 1
            for off in offsets:
                tmp = d[(1, off)]
                start = (
                    (pos + prime)
                    if off == 1
                    else (prime * (const * pos + tmp)) // const
                )
                del_mult(tmptk[off], start, prime)
    # time to add remaining primes
    # if lastadded == 1, remove last element and start adding them from tk1
    # this way we don't need an "if" within the last while
    if lastadded == 1:
        p.pop()
    # now complete for every other possible prime
    while pos < len(tk1):
        cpos = const * pos
        if tk1[pos]:
            p.append(cpos + 1)
        if tk7[pos]:
            p.append(cpos + 7)
        if tk11[pos]:
            p.append(cpos + 11)
        if tk13[pos]:
            p.append(cpos + 13)
        if tk17[pos]:
            p.append(cpos + 17)
        if tk19[pos]:
            p.append(cpos + 19)
        if tk23[pos]:
            p.append(cpos + 23)
        if tk29[pos]:
            p.append(cpos + 29)
        pos += 1
    # remove exceeding if present
    pos = len(p) - 1
    while p[pos] > N:
        pos -= 1
    if pos < len(p) - 1:
        del p[pos + 1 :]
    # return p list
    return p


def sieve_of_eratosthenes(n):
    """sieveOfEratosthenes(n): return the list of the primes < n."""
    # Code from: <dickinsm@gmail.com>, Nov 30 2006
    # http://groups.google.com/group/comp.lang.python/msg/f1f10ced88c68c2d
    if n <= 2:
        return []
    sieve = list(range(3, n, 2))
    top = len(sieve)
    for si in sieve:
        if si:
            bottom = (si * si - 3) // 2
            if bottom >= top:
                break
            sieve[bottom::si] = [0] * -((bottom - top) // si)
    return [2] + [el for el in sieve if el]


def sieve_of_atkin(end):
    """return a list of all the prime numbers <end using the Sieve of Atkin."""
    # Code by Steve Krenzel, <Sgk284@gmail.com>, improved
    # Code: https://web.archive.org/web/20080324064651/http://krenzel.info/?p=83
    # Info: http://en.wikipedia.org/wiki/Sieve_of_Atkin
    assert end > 0
    lng = (end - 1) // 2
    sieve = [False] * (lng + 1)

    x_max, x2, xd = int(sqrt((end - 1) / 4.0)), 0, 4
    for xd in range(4, 8 * x_max + 2, 8):
        x2 += xd
        y_max = int(sqrt(end - x2))
        n, n_diff = x2 + y_max * y_max, (y_max << 1) - 1
        if not (n & 1):
            n -= n_diff
            n_diff -= 2
        for d in range((n_diff - 1) << 1, -1, -8):
            m = n % 12
            if m == 1 or m == 5:
                m = n >> 1
                sieve[m] = not sieve[m]
            n -= d

    x_max, x2, xd = int(sqrt((end - 1) / 3.0)), 0, 3
    for xd in range(3, 6 * x_max + 2, 6):
        x2 += xd
        y_max = int(sqrt(end - x2))
        n, n_diff = x2 + y_max * y_max, (y_max << 1) - 1
        if not (n & 1):
            n -= n_diff
            n_diff -= 2
        for d in range((n_diff - 1) << 1, -1, -8):
            if n % 12 == 7:
                m = n >> 1
                sieve[m] = not sieve[m]
            n -= d

    x_max, y_min, x2, xd = int((2 + sqrt(4 - 8 * (1 - end))) / 4), -1, 0, 3
    for x in range(1, x_max + 1):
        x2 += xd
        xd += 6
        if x2 >= end:
            y_min = (((int(ceil(sqrt(x2 - end))) - 1) << 1) - 2) << 1
        n, n_diff = ((x * x + x) << 1) - 1, (((x - 1) << 1) - 2) << 1
        for d in range(n_diff, y_min, -8):
            if n % 12 == 11:
                m = n >> 1
                sieve[m] = not sieve[m]
            n += d

    primes = [2, 3]
    if end <= 3:
        return primes[: max(0, end - 2)]

    for n in range(5 >> 1, (int(sqrt(end)) + 1) >> 1):
        if sieve[n]:
            primes.append((n << 1) + 1)
            aux = (n << 1) + 1
            aux *= aux
            for k in range(aux, end, 2 * aux):
                sieve[k >> 1] = False

    s = int(sqrt(end)) + 1
    if s % 2 == 0:
        s += 1
    primes.extend([i for i in range(s, end, 2) if sieve[i >> 1]])

    return primes


def ambi_sieve_plain(n):
    s = list(range(3, n, 2))
    for m in range(3, int(n ** 0.5) + 1, 2):
        if s[(m - 3) // 2]:
            for t in range((m * m - 3) // 2, (n >> 1) - 1, m):
                s[t] = 0
    return [2] + [t for t in s if t > 0]


def sundaram3(max_n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/2073279#2073279
    numbers = range(3, max_n + 1, 2)
    half = (max_n) // 2
    initial = 4

    for step in range(3, max_n + 1, 2):
        for i in range(initial, half, step):
            numbers[i - 1] = 0
        initial += 2 * (step + 1)

        if initial > half:
            return [2] + filter(None, numbers)


# Using Numpy:
def ambi_sieve(n):
    # http://tommih.blogspot.com/2009/04/fast-prime-number-generator.html
    s = np.arange(3, n, 2)
    for m in range(3, int(n ** 0.5) + 1, 2):
        if s[(m - 3) // 2]:
            s[(m * m - 3) // 2::m] = 0
    return np.r_[2, s[s > 0]]


def primesfrom3to(n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Returns an array of primes, p < n """
    assert n >= 2
    sieve = np.ones(n // 2, dtype=np.bool)
    for i in range(3, int(n ** 0.5) + 1, 2):
        if sieve[i // 2]:
            sieve[i * i // 2::i] = False
    return np.r_[2, 2 * np.nonzero(sieve)[0][1::] + 1]


def primesfrom2to(n):
    # /programming/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Input n>=6, Returns an array of primes, 2 <= p < n """
    assert n >= 6
    sieve = np.ones(n // 3 + (n % 6 == 2), dtype=np.bool)
    sieve[0] = False
    for i in range(int(n ** 0.5) // 3 + 1):
        if sieve[i]:
            k = 3 * i + 1 | 1
            sieve[((k * k) // 3)::2 * k] = False
            sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = False
    return np.r_[2, 3, ((3 * np.nonzero(sieve)[0] + 1) | 1)]


def sympy_sieve(n):
    return list(sympy.sieve.primerange(1, n))


perfplot.save(
    "prime.png",
    setup=lambda n: n,
    kernels=[
        rwh_primes,
        rwh_primes1,
        rwh_primes2,
        sieve_wheel_30,
        sieve_of_eratosthenes,
        sieve_of_atkin,
        # ambi_sieve_plain,
        # sundaram3,
        ambi_sieve,
        primesfrom3to,
        primesfrom2to,
        sympy_sieve,
    ],
    n_range=[2 ** k for k in range(3, 25)],
    logx=True,
    logy=True,
    xlabel="n",
)

0

আমার অনুমান যে আপনার কোডের প্রাইমগুলিকে হার্ড কোড করা সব দিক থেকে দ্রুততম

সুতরাং কেন কেবল একটি ধীর স্ক্রিপ্ট লিখবেন না যা অন্য উত্স ফাইল তৈরি করে যা এতে সমস্ত সংখ্যার হার্ডওয়ার্ড রয়েছে এবং তারপরে আপনি যখন আসল প্রোগ্রামটি চালাবেন তখন সেই উত্স ফাইলটি আমদানি করুন।

অবশ্যই, এটি কেবল তখনই কাজ করে যদি আপনি কমপাইল সময়ে এন এর উপরের সীমানাটি জানেন তবে এইভাবে (প্রায়) সমস্ত প্রকল্পের ইউলারের সমস্যার ক্ষেত্রে এটি ঘটে।

 

PS: আমি ভুল হতে পারি যদিও iff হার্ড-ওয়্যার্ড প্রাইমগুলির সাথে উত্সটি পার্সিং করা প্রথম স্থানে তুলনা করার চেয়ে ধীর, তবে আমি জানি যতদূর পাইথন সংকলিত .pycফাইলগুলি থেকে রান করে তাই এন পর্যন্ত সমস্ত প্রাইম সহ বাইনারি অ্যারে পড়া রক্তাক্ত হওয়া উচিত ক্ষেত্রে দ্রুত।


0

বিরক্ত করার জন্য দুঃখিত তবে erat2 () এর অ্যালগরিদমে গুরুতর ত্রুটি রয়েছে।

পরবর্তী যৌগিক অনুসন্ধান করার সময়, আমাদের কেবল বিজোড় সংখ্যাগুলি পরীক্ষা করতে হবে test q, p উভয়ই অদ্ভুত; তাহলে q + p সমান এবং এটির পরীক্ষা করার দরকার নেই, তবে q + 2 * p সর্বদা বিজোড়। এটি যখন লুপ অবস্থায় "যদি এমনকি" পরীক্ষাটি সরিয়ে দেয় এবং রানটাইমের প্রায় 30% সংরক্ষণ করে।

যখন আমরা এটিতে এসেছি: মার্জিত 'ডিপপ (কিউ, কিছুই নয়) এর পরিবর্তে' ডি পদ্ধতিতে ব্যবহার করুন এবং মুছুন 'যদি ডি: পি = ডি [কিউ], ডেল ডি [q]' এর দ্বিগুণ দ্রুত হয় ! কমপক্ষে আমার মেশিনে (P3-1Ghz)। সুতরাং আমি এই চতুর অ্যালগরিদমের এই প্রয়োগের পরামর্শ দিচ্ছি:

def erat3( ):
    from itertools import islice, count

    # q is the running integer that's checked for primeness.
    # yield 2 and no other even number thereafter
    yield 2
    D = {}
    # no need to mark D[4] as we will test odd numbers only
    for q in islice(count(3),0,None,2):
        if q in D:                  #  is composite
            p = D[q]
            del D[q]
            # q is composite. p=D[q] is the first prime that
            # divides it. Since we've reached q, we no longer
            # need it in the map, but we'll mark the next
            # multiple of its witnesses to prepare for larger
            # numbers.
            x = q + p+p        # next odd(!) multiple
            while x in D:      # skip composites
                x += p+p
            D[x] = p
        else:                  # is prime
            # q is a new prime.
            # Yield it and mark its first multiple that isn't
            # already marked in previous iterations.
            D[q*q] = q
            yield q

ডিকটিতে প্রাইমগুলি স্থগিত করার জন্য (ইনপুটটিতে কোনও প্রাইমের বর্গক্ষেত্র দেখা না যাওয়া পর্যন্ত) দেখুন স্ট্যাকওভারফ্লো . com /a/ 10733621/849891
নেস

0

আমি এখন পর্যন্ত দ্রুততম পদ্ধতিটি পাইথন কুকবুকerat2 ফাংশনের উপর ভিত্তি করে তৈরি করেছি :

import itertools as it
def erat2a( ):
    D = {  }
    yield 2
    for q in it.islice(it.count(3), 0, None, 2):
        p = D.pop(q, None)
        if p is None:
            D[q*q] = q
            yield q
        else:
            x = q + 2*p
            while x in D:
                x += 2*p
            D[x] = p

গতি বাড়ানোর ব্যাখ্যার জন্য এই উত্তরটি দেখুন ।


0

আমি পার্টিতে দেরিতে হতে পারি তবে এর জন্য আমার নিজের কোড যুক্ত করতে হবে। এটি স্পেসে আনুমানিক এন / ২ ব্যবহার করে কারণ আমাদের এমনকি সংখ্যার সঞ্চয় করার দরকার নেই এবং আমি বিটারে পাইথন মডিউলটিও ব্যবহার করি, আরও মজাদারভাবে মেমোরি খরচ কমানো এবং সমস্ত প্রাইমকে ১,০০,০০,০০০ পর্যন্ত কম্পিউটিং সক্ষম করে

from bitarray import bitarray
def primes_to(n):
    size = n//2
    sieve = bitarray(size)
    sieve.setall(1)
    limit = int(n**0.5)
    for i in range(1,limit):
        if sieve[i]:
            val = 2*i+1
            sieve[(i+i*val)::val] = 0
    return [2] + [2*i+1 for i, v in enumerate(sieve) if v and i > 0]

python -m timeit -n10 -s "import euler" "euler.primes_to(1000000000)"
10 loops, best of 3: 46.5 sec per loop

এটি 64 বিট 2.4GHZ ম্যাক ওএসএক্স 10.8.3 এ চালানো হয়েছিল


1
অজানা মেশিনের জন্য একটি সময় পোস্ট করা কিছুই বলে না। এখানে গৃহীত উত্তরটি বলেছে "সাইকো ছাড়াই, এন = 1000000 এর জন্য, rW_primes2 সবচেয়ে দ্রুত"। সুতরাং আপনি যদি সেই কোডটির জন্য একই সময় আপনার নিজের জন্য একই মেশিনে এবং 2, 4, 10 মিলিয়ন এও সরবরাহ করেন তবে এটি আরও তথ্যপূর্ণ হয়ে উঠবে।
নেস

-১, এই কোডটি সিটিতে প্রয়োগ করা বিটারয়ের বিশেষ বৈশিষ্ট্যগুলির উপর নির্ভর করে, তাই কোডটি দ্রুত কারণ স্লাইস অ্যাসাইনমেন্টে বেশিরভাগ কাজ দেশীয় কোডে করা হচ্ছে। বিটারে প্যাকেজ BREAKS পরিবর্তনীয় ক্রমগুলির জন্য যথাযথ টুকরোগুলির (একটি পরিসরের উপরে সূচিযুক্ত ) স্ট্যান্ডার্ড সংজ্ঞা যা স্লাইসের সমস্ত উপাদানকে একক বুলিয়ান 0/1 বা সত্য / মিথ্যা নির্ধারণ করতে দেয়, যেখানে খাঁটি পাইথনের মানক আচরণ মনে হয় এটির অনুমতি না দেওয়া এবং কেবল 0 এর অ্যাসাইনমেন্ট মানটিকে অনুমতি দিন যা ক্ষেত্রে এটি সিকোয়েন্স / অ্যারে থেকে সমস্ত স্লাইস উপাদানগুলির একটি ডেল হিসাবে বিবেচনা করা হয়।
গর্ডনবিগুড

সংক্ষেপ: যদি অ-মানক দেশীয় কোডের সাথে কল করার তুলনা করা হয়, আমরা পাশাপাশি সি কোডের ভিত্তিতে একটি "ফাস্টপ্রিমস" সিকোয়েন্স জেনারেটর প্যাকেজ লিখতে পারি যেমন কিম ওয়ালিশের প্রাইমসিভের মতো এবং চারটি বিলিয়ন প্লাস 32 এ সমস্ত প্রাইম জেনারেট করে সিকোয়েন্স জেনারেটরে একক কল সহ-কয়েক সেকেন্ডের মধ্যে -বিট নম্বর পরিসর। এটি প্রায় কোনও স্মৃতিও ব্যবহার করবে না কারণ লিঙ্কযুক্ত কোডটি ইরোটোস্টিনিস বিভাগের সিগমেন্টেড সিভির উপর ভিত্তি করে তৈরি করা হয়েছে এবং এইভাবে কেবলমাত্র র‌্যামের কয়েক কিলোবাইট ব্যবহার করে, এবং যদি সিক্যুয়েন্স তৈরি করা হয় তবে কোনও তালিকা সংগ্রহের প্রয়োজন হবে না।
গর্ডনবিবুড

0

আমি সময়ের সাথে সাথে বেশ কয়েকটি প্রাইম নাম্বার সেভি সংগ্রহ করেছি। আমার কম্পিউটারে দ্রুততম এটি:

from time import time
# 175 ms for all the primes up to the value 10**6
def primes_sieve(limit):
    a = [True] * limit
    a[0] = a[1] = False
    #a[2] = True
    for n in xrange(4, limit, 2):
        a[n] = False
    root_limit = int(limit**.5)+1
    for i in xrange(3,root_limit):
        if a[i]:
            for n in xrange(i*i, limit, 2*i):
                a[n] = False
    return a

LIMIT = 10**6
s=time()
primes = primes_sieve(LIMIT)
print time()-s

0

আমি এই প্রশ্নের ধীরে ধীরে সাড়া দিচ্ছি তবে মনে হচ্ছে এটি একটি মজাদার অনুশীলনের মতো। আমি ন্যাপি ব্যবহার করছি যা প্রতারিত হতে পারে এবং আমি সন্দেহ করি যে এই পদ্ধতিটি সবচেয়ে দ্রুত তবে এটি পরিষ্কার হওয়া উচিত। এটি বুলিয়ান অ্যারে কেবলমাত্র তার সূচকগুলি উল্লেখ করে এবং এটি সমস্ত সত্য মানগুলির সূচকগুলি থেকে প্রাথমিক সংখ্যা বের করে দেয়। কোনও মডুলোর দরকার নেই।

import numpy as np
def ajs_primes3a(upto):
    mat = np.ones((upto), dtype=bool)
    mat[0] = False
    mat[1] = False
    mat[4::2] = False
    for idx in range(3, int(upto ** 0.5)+1, 2):
        mat[idx*2::idx] = False
    return np.where(mat == True)[0]

এটি ভুল, যেমন ajs_primes3a(10)- -> array([2, 3, 5, 7, 9])9প্রধান নয়
jfs

আপনি একটি প্রান্তের মামলাটি করেছেন যা আমি করিনি - ভাল হয়েছে! সমস্যাটি ছিল 'আইডিএক্স ইন রেঞ্জ (3, ইনট (** 0.5) পর্যন্ত):' যা 'আইডিএক্স রেঞ্জের (3, ইনট (** 0.5) পর্যন্ত + 1, 2):' হওয়া উচিত: '। ধন্যবাদ তবে এটি এখন কাজ করে।
অ্যালান জেমস সালমনি

কারণটি ছিল যে আইডিএক্স লুপটি'* ** 05 'পর্যন্ত চলে গেছে যা 15 পর্যন্ত কেস এবং এর জন্য রয়েছে 16 16 থেকে এটি ঠিকঠাক কাজ করে। এটি আমার পক্ষে পরীক্ষিত ছিল না এমন এক প্রান্তের কেসগুলির সেট। 1 যোগ করার অর্থ এটি সমস্ত সংখ্যার জন্য কাজ করা উচিত।
অ্যালান জেমস সালমনি

এটা এখন কাজ মনে হচ্ছে। এটি numpyভিত্তিযুক্ত সমাধানগুলির মধ্যে ধীরতম্য যা একটি অ্যারে ফেরত দেয়। দ্রষ্টব্য: ইরোটোথিনিস বাস্তবায়নের সত্যিকারের চালনী মডুলো ব্যবহার করে না - এটি উল্লেখ করার দরকার নেই। আপনি mat[idx*idx::idx]পরিবর্তে ব্যবহার করতে পারে mat[idx*2::idx]। এবং np.nonzero(mat)[0]পরিবর্তে np.where(mat == True)[0]
jfs

ধন্যবাদ জেএফ। আমি প্রাইম 6 () এর বিপরীতে পরীক্ষা করেছিলাম এবং প্রাইম 6 () দায়িত্ব নেওয়ার সময় প্রায় 250 কে-র দিকে দ্রুত (আইআইআরসি) দ্রুত ফলাফল পেয়েছি। primesfrom2to () দ্রুত ছিল। 20 মিটার অবধি, @s_primes3a () 0.034744977951ms, prime6 () 0.0222899913788ms এবং primesfrom2to () নিয়েছে 0.0104751586914ms (একই মেশিন, একই বোঝা, 10 সময় সেরা)। এটা সত্যিই আমি এটি ভেবেছিলাম চেয়ে ভাল!
অ্যালান জেমস সালমনি

0

পাইথনের তালিকার উপলব্ধিগুলি ব্যবহার করে প্রাথমিক সংখ্যা (এখনও সর্বাধিক দক্ষ নয়) তৈরি করার একটি আকর্ষণীয় কৌশল এখানে রয়েছে:

noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
primes = [x for x in range(2, 50) if x not in noprimes]

আপনি উদাহরণ এবং কিছু ব্যাখ্যা এখানে পেতে পারেন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.