做不是迭代通過一組數字測試每個素數。這將是不可能的緩慢。您正在尋找的算法被稱爲Eratosthenes的分割篩。
雖然Eratosthenes的篩網速度非常快,但它需要O(n)空間。對於篩選素數,可以通過在連續的片段中執行篩分將其減少到O(sqrt(n))加上O(1)的比特數。在第一個分段中,計算分段內每個篩分質數的最小倍數,然後以正常方式標記複合質量的多個篩分質數;當使用所有篩分質數時,該分段中剩餘的未標記數字是質數。然後,對於下一個分段,每個篩分質數的最小倍數是在前一個分段中結束篩分的倍數,因此篩分繼續直到完成。
考慮從20到200的分段篩選100到200的例子; 5個篩選素數是3,5,7,11和13.在100到120的第一段中,比特數有10個時隙,其中時隙0對應於101,時隙k對應於100 + 2k-1,時隙9對應於119.分段中的3的最小倍數是105,對應於時隙2;時隙2 + 3 = 5和5 + 3 = 8也是3的倍數。時隙2處的5的最小倍數是105,時隙2 + 5 = 7也是5的倍數.7的最小倍數是105在時隙2處,時隙2 + 7 = 9也是7的倍數。依此類推。
函數素數需要參數lo,hi和delta; lo和hi必須是偶數,並且lo必須大於天花板(sqrt(hi))。段的大小是兩倍三角洲。長度爲m的數組ps包含小於sqrt(hi)的篩選素數,刪除2,因爲偶數會被忽略,並且數組qs包含到相應篩選素數當前片段中最小倍數的篩子位陣列的偏移量。每個段之後,LO通過兩次增量前進,所以對應於篩bitarray的索引j的數目爲LO + 2J + 1
function primes(lo, hi, delta)
sieve := makeArray(0..delta-1) # bitarray
# calculate m and ps as described in text
qs := makeArray(0..m-1) # least multiples
for i from 0 to m-1
qs[i] := (-1/2 * (lo + ps[i] + 1)) % ps[i]
while lo < hi
for i from 0 to delta-1
sieve[i] := True
for i from 0 to m-1
for j from qs[i] to delta step ps[i]
sieve[j] := False
qs[i] := (qs[i] - delta) % ps[i]
for i from 0 to delta-1
t := lo + 2*j + 1
if sieve[i] and t < hi
output t
lo := lo + 2*delta
對於上面給出的樣品,這被稱爲質數(100, 200,10)。在上面給出的例子中,qs最初是[2,2,2,10,8],對應於最小倍數105,105,105,121和117,並且針對第二段重置爲[1,2,6, 0,11],對應於最小倍數123,125,133,121和143。該算法非常快;你應該能夠在不到一秒的時間內生成幾百萬個素數。
如果您想了解更多關於使用素數編程的信息,我會在我的博客上謙虛地推薦this essay。
這是寫什麼語言? – Jon
它有多準確?你能接受卡邁克爾號碼嗎?以及'isprime'如何實現? – tjameson
我正在使用matlab 2012,準確性很重要,但不是這裏最重要的。你的意思是卡邁克爾的數字。 isprime檢查每個值,看它是否實際上是素數。 – user1825494