【SinGuLaRiTy-1003】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.
背景
數論學家利用費馬小定理研究出了多種素數測試辦法,Miller-Rabbin 素數測試算法是其中較快的一種。
步驟
(1)計算奇數M,使得N=2^r * M + 1;
(2)選擇隨機數A<N;
(3)對於任意i<r,若A^(2^i*M) mod N = N - 1,則N通過隨機數A的測試;
(4)或者,若A^M mod N = 1,則N通過隨機數A的測試;
(5)讓A取不同的值對N進行行多次測試(一般要求5~10次,有較高要求的話可以進行20~30次),若全部通過則判定N為素數;
概率
若N通過一次測試,則N不是素數的概率為25%;
若N通過 t 次測試,則N不是素數的概率為1/( 4 ^ t );
事實上,當 t = 5 時,N不是素數的概率已為1/128,已經大於99.99%。
在實際運用中,可首先用300~500個小素數對N進行測試,以提高測試通過的概率與算法的速度。在隨機生成的素數中,選取的隨機數最好讓 r = 0,則可以省去步驟(3)的操作,進一步減少判定時間。
代碼
#include<cstdlib> #include<ctime> #include<cstdio> using namespace std; const int count=10; int modular_exp(int a,int m,int n) { if(m==0) return 1; if(m==1) return (a%n); long long w=modular_exp(a,m/2,n); w=w*w%n; if(m&1) w=w*a%n; return w; } bool Miller_Rabin(int n) { if(n==2) return true; for(int i=0;i<count;i++) { int a=rand()%(n-2)+2; if(modular_exp(a,n,n)!=a) return false; } return true; } int main() { srand(time(NULL)); int n; scanf("%d",&n); if(Miller_Rabin(n)) printf("Probably a prime."); else printf("A composite."); printf("\n"); return 0; }
Time:2017-02-07