今天看了一下miller-rabin素數檢測的演算法,總結了一下,希望這篇部落格對你們有幫助。
先說幾個理論基礎:
1. 費馬小定理:假如p是質數,a是整數,且a、p互質,那麼a的(p-1)次方除以p的餘數恆等於1,即:a^(p-1)≡1(mod p).
但是反過來卻不一定成立,就是說,如果a、p互質,且a^(p-1)≡1(mod p),不能推出p是質數,比如carmichael數。
2. 二次探測定理:如果p是乙個素數,0
3. 模運算的規則:(a*b)%n=(a%n * b%n)%n
4. 快速積取模、快速冪取模:可以看看我之前寫的一篇部落格簡單快速的演算法
然後是演算法的過程:
對於要判斷的數n
1.先判斷是不是2,是的話就返回true。
2.判斷是不是小於2的,或合數,是的話就返回false。
3.令n-1=u*2^t,求出u,t,其中u是奇數。
4.隨機取乙個a,且1
/*根據費馬小定理,如果a^(n-1)≡1(mod p)那麼n就極有可能是素數,如果等式不成立,那肯定不是素數了
因為n-1=u*2^t,所以a^(n-1)=a^(u*2^t)=(a^u)^(2^t)。*/
5.所以我們令x=(a^u)%n
6.然後是t次迴圈,每次迴圈都讓y=(x*x)%n,x=y,這樣t次迴圈之後x=a^(u*2^t)=a^(n-1)了
7.因為迴圈的時候y=(x*x)%n,且x肯定是小於n的,正好可以用二次探測定理,
如果(x^2)%n==1,也就是y等於1的時候,假如n是素數,那麼x==1||x==n-1,如果x!=1&&x!=n-1,那麼n肯定不是素數了,返回false。
8.執行到這裡的時候x=a^(n-1),根據費馬小定理,x!=1的話,肯定不是素數了,返回false
9.因為miller-rabin得到的結果的正確率為 75%,所以要多次迴圈步驟4~8來提高正確率
10.迴圈多次之後還沒返回,那麼n肯定是素數了,返回true
下面是模板:
# include # include typedef long long ll;
ll modmul(ll a,ll b,ll n)//快速積取模 a*b%n
return ans;
} ll modexp(ll a,ll b,ll n)//快速冪取模 a^b%n
return ans;
} bool miller_rabin(ll n)//miller-rabin素數檢測演算法
{ ll i,j,a,x,y,t,u,s=10;
if(n==2)
return true;
if(n<2||!(n&1))
return false;
for(t=0,u=n-1;!(u&1);t++,u>>=1);//n-1=u*2^t
for(i=0;ihdu 2138 是一道模板題,你們可以練習一下
Miller Rabin素數快速檢測
update 2017 03 26 滿足費馬小定理 a n 1 1 mod n 偽素數 對於所有a belong zn 總存在滿足的合數n,稱為carmichael數 miller rabin 1.隨機找多個s個a 2.二次探測定理 如果p是奇素數,則 x2 1 mod p 的解為 x 1 x p ...
Miller Rabin素數檢測演算法
對於給定的不小於3的奇數n,驗證次數t,miller rabin演算法如下 millerabin n,t 1.計算r,s,使滿足n 1 2的s次方 r 其中r是奇數 2.迴圈t次 1 隨機選取整數a,2 a n 2 2 計算y a的r次方 mod n 3 if y 1 y n 1 then j 1 ...
Miller Rabin素數檢測演算法 acm模板
其基於以下兩個定理。fermat小定理 若n是素數,則 a a 0 mod n forall a a not equiv 0 pmod a a 0 m odn 有an 1 1 modn a equiv 1 pmod an 1 1 mod n 二次探測定理 若n是素數,則x2 1 mo dn x 2 ...