1. 程式人生 > 實用技巧 >Miller_Rabin質數測試

Miller_Rabin質數測試

數論 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

  1. 若x是偶數,0,1,2,可以直接判斷
  2. 找出如下形式的s,t,使之滿足\(2^s\times t\equiv1 (mod\ x)\),要求t是個奇數
  3. 隨機質數a(滿足a小於x)
  4. 對於\(a^t\)迴圈進行:平方、二次探測..(共計迴圈s次)。倘若任意一次不滿足條件,則x為合數
  5. 對於\((2^{t})^{2\times s}\)驗證費馬小定理,倘若不滿足,則x為合數
  6. 迴圈隨機若干個質數a,繼續測試
  7. 上述操作之後仍未篩掉x,則x大概率是質數

Tips

[1] Miller_Rabin質數測試可以極大概率地判斷出質數,但存在會有合數誤判為質數的情況。這類強偽質數,稱之為卡米歇爾強偽素數。

[2] 雖然是大概率

,但概率之大足以放心使用。據考證:在int範圍內,取遍30以內的所有質數後,保證該演算法的正確性

[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素數測試演算法