3

こんにちは、このコード内にエラトステネスのふるいを実装して高速化する方法を誰か教えてもらえますか? ふるいにかけて完成させていただけると助かります。この特定のコードでこれを行うのに本当に問題があります。

#!/usr/bin/env python
import sys

T=10 #no of test cases
t=open(sys.argv[1],'r').readlines()

import math
def is_prime(n):
    if n == 2:
        return True
    if n%2 == 0 or n <= 1:
        return False
    sqr = int(math.sqrt(n)) + 1
    for divisor in range(3, sqr, 2):
        if n%divisor == 0:
            return False
    return True

#first line of each test case
a=[1,4,7,10,13,16,19,22,25,28]
count=0
for i in a:

    b=t[i].split(" ")
    c=b[1].split("\n")[0]
    b=b[0]

    for k in xrange(int(b)):
        d=t[i+1].split(" ")

        e=t[i+2].split(" ")
        for g in d:
            for j in e:
                try:
                    sum=int(g)+int(j)
                    p=is_prime(sum)         
                    if p==True:
                        count+=1
                        print count
                    else:
                        pass
                except:
                    try:
                        g=g.strip("\n")
                        sum=int(g)+int(j)
                        p=is_prime(sum)
                        if p==True:
                            count+=1
                            print count
                        else:
                            pass
                    except:
                        j=j.strip("\n")
                        sum=int(g)+int(j)
                        p=is_prime(sum)
                        if p==True:
                            count+=1
                            print count
                        else:
                            pass

print "Final count"+count
4

6 に答える 6

10

ここに投稿された元のポスターと他のソリューションの両方が同じ間違いを犯しています。モジュロ演算子、または任意の形式の除算を使用する場合、アルゴリズムはエラトステネスの篩ではなく試行除算であり、O(n log log n) ではなく O(n^2) とはるかに遅くなります。これは、Python での単純なエラトステネスのふるいです。

def primes(n): # sieve of eratosthenes
    ps, sieve = [], [True] * (n + 1)
    for p in range(2, n + 1):
        if sieve[p]:
           ps.append(p)
           for i in range(p * p, n + 1, p):
               sieve[i] = False
    return ps

これにより、1 秒以内に 100 万未満のすべての素数が検出されるはずです。素数を使ったプログラミングに興味がある場合は、私のブログでこのエッセイをお勧めします。

于 2013-10-13T14:28:13.323 に答える
1

私が考えることができる最速の実装

def sieve(maxNum):
    yield 2
    D, q = {}, 3
    while q <= maxNum:
        p = D.pop(q, 0)
        if p:
            x = q + p
            while x in D: x += p
            D[x] = p
        else:
            yield q
            D[q*q] = 2*q
        q += 2
    raise StopIteration

ソース: http://code.activestate.com/recipes/117119-sieve-of-eratosthenes/#c4

この部分を交換

import math
def is_prime(n):
    if n == 2:
        return True
    if n%2 == 0 or n <= 1:
        return False
    sqr = int(math.sqrt(n)) + 1
    for divisor in range(3, sqr, 2):
        if n%divisor == 0:
            return False
    return True

primes = [prime for prime in sieve(10000000)]
def is_prime(n):
    return n in primes

代わりに、10000000素数が必要になるまでの最大数を入れることができます。

于 2013-10-13T13:10:58.177 に答える
0

これは、セットを使用した単純なソリューションです。これは、多くのリスト アルゴリズムと比較して非常に高速です。セットを使用した計算は、ハッシュ テーブルのおかげではるかに高速です。( Python でリストよりもセットの方が速い理由は何ですか? )

ご挨拶

----------------------------------
from math import *

def sievePrimes(n):

    numbers = set()
    numbers2 = set()
    bound = round(sqrt(n))

    for a in range(2, n+1):
        numbers.add(a)

    for i in range(2, n):
        for b in range(1, bound):
            if (i*(b+1)) in numbers2:
                continue
            numbers2.add(i*(b+1))
    numbers = numbers - numbers2

    print(sorted(numbers))

シンプルなソリューション

于 2016-01-20T20:47:05.517 に答える
0

これは、メモリを事前に割り当てない加算のみを使用する単純なジェネレータです。ふるいは素数の辞書と同じ大きさであり、メモリ使用量は必要な分だけ増加します。

def pgen(maxnum): # Sieve of Eratosthenes generator
    pnext, ps = 2, {}
    while pnext <= maxnum:
        for p in ps:
            while ps[p] < pnext:
                ps[p] += p
            if ps[p] == pnext:
                break
        else:
            ps[pnext] = pnext
            yield pnext
        pnext += 1

def is_prime(n):
    return n in pgen(n)

>>> is_prime(117)
>>> is_prime(117)
False
>>> 83 in pgen(83)
True
>>> list(pgen(100)) # List prime numbers less than or equal to 100
[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]
于 2013-10-16T21:22:48.573 に答える