Miller-Rabin(米勒罗宾)素性测试

算法思想

对于大于2的素数n,将n-1拆分为

其中s和d是正整数且d是奇数。对所有整数a(0{2r*d}\equiv -1 \pmod{n} (for \ some \ r \ that \ 0\leq r \leq s-1))
对于待测数n,当找到的a不符合上述条件,那么称a为一个"witness for the compositeness of n",且n一定是一个合数。否则称a为一个"strong liar",且n是一个基于a的"strong probable prime"。

准确性

所有的奇合数都有很多的a满足"witness"的条件,不过目前为止还没有确定的算法能够直接根据n生成这样的数a,于是我们可以多次随机抽取1~n-1中的整数并做测试。
当我们k次随机选取a测试时,一个合数被该算法判定为素数的概率是4^(-k)。

一种实现

#include 
#include 
using namespace std;
typedef long long ll;

ll mod_pow(ll x, ll y, ll m) {
    ll base = x, res = 1;
    while (y) {
        if (y&1) (res*=base)%=m;
        (base*=base)%=m;
        y>>=1;
    }
    return res;
}

bool MillerRabin(ll n, int k) {
    if (n==2||n==3||n==5||n==7||n==11||n==13) return true;
    if (n==1||n%2==0||n%3==0||n%5==0||n%7==0||n%11==0||n%13==0) return false;
    ll d=n-1;
    int r=0;
    while (d%2==0) {
        d>>=1;
        ++r;
    }
    for (int i=0;i>n) {
        if (MillerRabin(n,5))
            cout<<"n is a prime number\n";
        else cout<<"n is not a prime number\n";
    }
    return 0;
}

其中ll mod_pow(ll x, ll y, ll m)实现的是模m意义下的快速幂运算。

扩展阅读

  • 详细的准确性、时间复杂度分析和证明请参照https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test

你可能感兴趣的:(Miller-Rabin(米勒罗宾)素性测试)