这是我在评论中链接的范围筛选程序的修改版本。它使用prime number theorem得到hi附近素数密度的近似值,并使用该密度估计lo,使得range(lo, hi)>;=num中的素数。有关更多信息,请参阅Mathworld关于Prime Counting Function的文章。在
一般来说,没有简单的方法来精确估计给定范围内的素数。FWIW,在特殊情况下,很容易证明给定范围内没有素数,例如range(n! + 2, n! + n + 1)中的每个数都可以被range(2, n + 1)中的一个数整除。在
下面的代码(希望是:)高估了所需的范围。但我们不想让它浪费时间,因为它使用了一个值lo太低了。在某些情况下,lo将不够小,特别是当{}非常小时,但是如果对num使用合理的值,则应该可以。在#! /usr/bin/env python
''' Prime range sieve.
Written by PM 2Ring 2014.10.15
2015.05.24 Modified to find the `num` highest primes < `hi`
'''
import sys
from math import log
def potential_primes():
''' Make a generator for 2, 3, 5, & thence all numbers coprime to 30 '''
s = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29)
for i in s:
yield i
s = (1,) + s[3:]
j = 30
while True:
for i in s:
yield j + i
j += 30
def range_sieve(lo, hi):
''' Create a list of all primes in the range(lo, hi) '''
#Mark all numbers as prime
primes = [True] * (hi - lo)
#Eliminate 0 and 1, if necessary
for i in range(lo, min(2, hi)):
primes[i - lo] = False
ihi = int(hi ** 0.5)
for i in potential_primes():
if i > ihi:
break
#Find first multiple of i: i >= i*i and i >= lo
ilo = max(i, 1 + (lo - 1) // i ) * i
#Determine how many multiples of i >= ilo are in range
n = 1 + (hi - ilo - 1) // i
#Mark them as composite
primes[ilo - lo : : i] = n * [False]
return [i for i,v in enumerate(primes, lo) if v]
def main():
hi = int(sys.argv[1]) if len(sys.argv) > 1 else 1000000
num = int(sys.argv[2]) if len(sys.argv) > 2 else 1000
#Estimate required range using the prime number theorem
#The constant 1.25506 is from the MathWorld article on
#the Prime Counting Function
d = num * log(hi) * 1.25506
#An alternate estimator. Sometimes estimates a little too low.
#d = num * (log(hi) + log(log(hi)))
lo = max(2, hi - int(d))
print 'lo =', lo
primes = range_sieve(lo, hi)
print len(primes), 'primes found'
for i, p in enumerate(reversed(primes[-num:]), 1): print '%2d: %d' % (i, p)
if __name__ == '__main__':
main()
使用^{调用时输出
^{pr2}$