Le moyen le plus rapide de générer des nombres premiers est un tamis. Ici, nous utilisons un tamis segmenté d'Ératosthènes pour générer les nombres premiers, un par un sans maximum, dans l'ordre; ps
est la liste des nombres premiers de tamisage inférieure au maximum actuel et qs
est le décalage du plus petit multiple du ps
correspondant dans le segment en cours.
def genPrimes():
def isPrime(n):
if n % 2 == 0: return n == 2
d = 3
while d * d <= n:
if n % d == 0: return False
d += 2
return True
def init(): # change to Sieve of Eratosthenes
ps, qs, sieve = [], [], [True] * 50000
p, m = 3, 0
while p * p <= 100000:
if isPrime(p):
ps.insert(0, p)
qs.insert(0, p + (p-1)/2)
m += 1
p += 2
for i in xrange(m):
for j in xrange(qs[i], 50000, ps[i]):
sieve[j] = False
return m, ps, qs, sieve
def advance(m, ps, qs, sieve, bottom):
for i in xrange(50000): sieve[i] = True
for i in xrange(m):
qs[i] = (qs[i] - 50000) % ps[i]
p = ps[0] + 2
while p * p <= bottom + 100000:
if isPrime(p):
ps.insert(0, p)
qs.insert(0, (p*p - bottom - 1)/2)
m += 1
p += 2
for i in xrange(m):
for j in xrange(qs[i], 50000, ps[i]):
sieve[j] = False
return m, ps, qs, sieve
m, ps, qs, sieve = init()
bottom, i = 0, 1
yield 2
while True:
if i == 50000:
bottom = bottom + 100000
m, ps, qs, sieve = advance(m, ps, qs, sieve, bottom)
i = 0
elif sieve[i]:
yield bottom + i + i + 1
i += 1
else: i += 1
Un isPrime
simple à l'aide Section de première instance est suffisante, car elle sera limitée à la racine quatrième de n. La taille de segment 2 * delta
est arbitrairement fixée à 100000. Cette méthode nécessite l'espace O (sqrt n) pour les nombres premiers de tamisage plus l'espace constant pour le tamis.
Il est plus lent mais économise de l'espace pour générer des nombres premiers candidats avec une roue et tester les candidats pour la primalité avec un isPrime
basé sur des tests de pseudoprime forts aux bases 2, 7 et 61; ceci est valable pour 2^32.
def genPrimes(): # valid to 2^32
def isPrime(n):
def isSpsp(n, a):
d, s = n-1, 0
while d % 2 == 0:
d /= 2; s += 1
t = pow(a,d,n)
if t == 1: return True
while s > 0:
if t == n-1: return True
t = (t*t) % n; s -= 1
return False
for p in [2, 7, 61]:
if n % p == 0: return n == p
if not isSpsp(n, p): return False
return True
w, wheel = 0, [1,2,2,4,2,4,2,4,6,2,6,4,2,4,\
6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,6,4,6,\
2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10]
p = 2; yield p
while True:
p = p + wheel[w]
w = 4 if w == 51 else w + 1
if isPrime(p): yield p
Si vous êtes intéressé par la programmation avec des nombres premiers, je recommande modestement this essay sur mon blog.
Quelle est exactement la raison pour laquelle vous essayez d'utiliser la récursivité ici? – NPE
http://stackoverflow.com/questions/1628949/to-find-first-n-prime-numbers-in-python –
Voir [Le moyen le plus rapide de lister tous les nombres premiers sous N en python] (http://stackoverflow.com/q/2068372) –