MR素性檢測算法


  轉載地址: http://m.blog.csdn.net/blog/spirtsong/38273187

 

  素數是除了自身和1以外,沒有其它素數因子的自然數。自從歐幾里得證明了有無窮個素數以后,人們就企圖尋找一個可以構造所有素數的公式,尋找判定一個自然數是不是素數的方法。因為素數的地位非常重要。

  鑒別一個自然數是素數還是合數,這個問題在中世紀就引起人們注意,當時人們試圖尋找質數公式,到了高斯時代,基本上確認了簡單的質數公式是不存在的,因此,高斯認為對素性判定是一個相當困難的問題。從此以后,這個問題吸引了大批數學家。 素性判斷算法可分為兩大類,確定性算法及隨機算法。前者可給出確定的結果但通常較慢,后者則反之。

  這里主要講米勒拉賓算法,最后提供c++實現代碼。

  要測試 N 是否為素數,首先將 N-1 分解為 2^s d。在每次測試開始時,先隨機選一個 介於 [1, N-1]的整數 a,之后如果對所有的 r \in [0, s-1],若a^d \mod N \neq 1a^{2^{r}d} \mod N \neq -1,則 N 是合數。否則,N3/4 的概率為素數。

  Miller- Rabin算法隨機生成底數a,進行多次調用函數進行測試,Miller-Rabin檢測也存在偽素數的問題,但是與費馬檢測不同,MR檢測的正確概率不 依賴被檢測數p,而僅依賴於檢測次數。已經證明,如果一個數p為合數,那么Miller-Rabin檢測的證據數量不少於比其小的正整數的3/4,換言 之,k次檢測后得到錯誤結果的概率為(1/4)^k。我們在實際應用中一般可以測試15~20次。

 

 1 #include <iostream>
 2 #include <cmath>
 3 using namespace std;
 4 
 5 long long qpow(int a,int b,int r)//快速冪
 6 {
 7     long long ans=1,buff=a;
 8     while(b)
 9     {
10         if(b&1)ans=(ans*buff)%r;
11         buff=(buff*buff)%r;
12         b>>=1;
13     }
14     return ans;
15 }
16 bool Miller_Rabbin(int n,int a)//米勒拉賓素數測試
17 {
18     int r=0,s=n-1,j;
19     if(!(n%a))
20         return false;
21     while(!(s&1)){
22         s>>=1;
23         r++;
24     }
25     long long k=qpow(a,s,n);
26     if(k==1)
27         return true;
28     for(j=0;j<r;j++,k=k*k%n)
29         if(k==n-1)
30             return true;
31     return false;
32 }
33 bool IsPrime(int n)//判斷是否是素數
34 {
35     int tab[]={2,3,5,7};
36     for(int i=0;i<4;i++)
37     {
38         if(n==tab[i])
39             return true;
40         if(!Miller_Rabbin(n,tab[i]))
41             return false;
42     }
43     return true;
44 }
45 int main()
46 {
47     long long n;
48     while(1)
49     {
50        cin >> n;
51     cout << IsPrime(n)<< endl;
52     }
53 
54     return 0;
55 }

      在一次檢驗中,該算法出錯的可能頂多是四分之一。如果我們獨立地和隨機地選擇 a 進行重復檢驗,一旦此算法報告 n 是合數,我們就可以確信 n 肯定不是素數。但如果此算法重復檢驗 25 次報告都報告說 n 可能是素數,則我們可以說 n “幾乎肯定是素數”。因為這樣一個 25 次的檢驗過程給出關於它的輸入的錯誤信息的概率小於 (1/4)25。這種機會小於 1015 分之一。即使我們以這樣一個過程驗證了十億個不同的素數,預料出錯的概率仍將小於百萬分之一。因此如果真出了錯,與其說此算法重復地猜測錯,倒不如說由於 硬件的失靈或宇宙射線的原因,我們的計算機在它的計算中丟了一位。這樣的概率性算法使我們對傳統的可靠性標准提出一個問號:我們是否真正需要有素性的嚴格 證明。(以上文字引用自 Donald E.Knuth 所著的《計算機程序設計藝術 第2卷 半數值算法(第3版)》第 359 頁“4.5.4 分解素因子”中的“算法P(概率素性檢驗)”后面的說明)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM