Miller_Rabin質數測試
阿新 • • 發佈:2020-06-30
數論 Miller_Rabin質數測試
作用
當需要判斷一個數字是否是質數時,又發現數字過大,\(0(\sqrt n)\)難以承受的時候,就可以使用Miller_Rabin質數測試
基本定理
定理一,費馬小定理:
\[(p是質數)\Rightarrow a^{p-1}\equiv 1 \]
定理二,二次探測:
\[(p是質數)且(x^2\equiv1,當1<x<p) \Rightarrow x=1 或x=p-1 \]
基本定理的證明
直接引用一下別人部落格上的證明,感覺證明得清晰明瞭,個人複述一下反而顯得累贅
至此,是Miller_Rabin所需要的所有理論知識
演算法流程
設要測試的數字為x
- 若x是偶數,0,1,2,可以直接判斷
- 找出如下形式的s,t,使之滿足\(2^s\times t\equiv1 (mod\ x)\),要求t是個奇數
- 隨機質數a(滿足a小於x)
- 對於\(a^t\)迴圈進行:平方、二次探測..(共計迴圈s次)。倘若任意一次不滿足條件,則x為合數
- 對於\((2^{t})^{2\times s}\)驗證費馬小定理,倘若不滿足,則x為合數
- 迴圈隨機若干個質數a,繼續測試
- 上述操作之後仍未篩掉x,則x大概率是質數
Tips
[1] Miller_Rabin質數測試可以極大概率地判斷出質數,但存在會有合數誤判為質數的情況。這類強偽質數,稱之為卡米歇爾強偽素數。
[2] 雖然是大概率
[3] Miller_Rabin可以承受高達long long的資料範圍,實際上限未知
[4] 記得快速乘優化
code:
bool millar_rabin(ll x){ if(x==2) return true; if(!(x&1)||x==0||x==1) return false; ll s=0,t=x-1; while(!(t&1)) s++,t>>=1; //尋找合適的s和t for(int p=1;p<=30&&prime[p]<x;++p){ ll b=qsm((ll)prime[p],t,x),k; for(ll i=1;i<=s;++i){ k=qsc(b,b,x); //將b平方 if(k==1&&b!=1&&b!=x-1) return false; b=k; } if(b!=1) return false; } return true; }
參考資料:Miller-Rabin素數測試演算法