Самый быстрый способ генерации простых чисел - это сито. Здесь мы используем сегментированное сито Эратосфена для генерации простых чисел, по одному без максимума, по порядку; ps
- список просеивающих пропусков меньше текущего максимума, а qs
- это смещение наименьшего кратного соответствующего ps
в текущем сегменте.
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
Простой isPrime
с помощью пробного деления достаточно, так как он будет ограничен корень четвертой степени из п. Размер сегмента 2 * delta
произвольно установлен в 100000. Для этого метода требуется O (sqrt n) пространство для просеивающих простых чисел плюс постоянное пространство для сита.
Это медленнее, но экономит место для создания кандидатов простых чисел с колесом и проверяет кандидатов на первичность с помощью isPrime
, основанных на сильных тестах псевдопроизведения на основаниях 2, 7 и 61; это справедливо для 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
Если вы заинтересованы в программировании с простыми числами, я скромно рекомендую this essay в моем блоге.
Что именно вы пытаетесь использовать здесь рекурсию? – NPE
http://stackoverflow.com/questions/1628949/to-find-first-n-prime-numbers-in-python –
См. [Самый быстрый способ перечисления всех простых чисел ниже N в python] (http://stackoverflow.com/q/2068372) –