浅谈Miller-Rabin素数检测算法

浅谈Miller-Rabin素数检测

对于素数判断的操作,我们通常使用的是时间复杂度为\(O(\sqrt N)\)的试除法。按理说这种复杂度已经是较优秀的了,但是假如给定的需要判断的数极其之大,并且给定的时限不够以\(O(\sqrt N)\)的试除法来判断,该怎么办?

题出错了

想得美。

于是,今天的主角出场了:Miller-Rabin素数检测

Miller-Rabin素数检测算法用于在短时间内判断出一个数是否是质数,时间复杂度比试除法优秀,应该是\(O(T\times \log N)\)级别的(T为检测轮数)。

Miller-Rabin算法的实现原理

其实,试除法是目前能实现的百分百正确率判断质数的最快方法。Miller-Rabin之所以能够比它更快,是在牺牲了正确率的基础上。(汗)但是千万不要质疑这个算法的正确性。这种有一定容错率的算法统称为概率型算法,它们的特点就是不保对,但是用起来的确非常的爽。并且,它们的容错率也非常低,可以用多次检测来弥补。

经过理论证明,Miller-Rabin的错误率是\(4^{-T}\),T是检测轮数,一般来讲,当\(T\)达到50左右时,就可以将错误率降到非常低的程度。甚至,比计算机本身出错的概率还要低。

那么,在了解了Miller-Rabin的随机性之后,我们接下来要学习它的实现原理。

Miller-Rabin的实现原理利用了费马小定理。费马小定理的内容是:

\[
a^{p-1}\equiv 1\,\,\,\,(mod\,\,p)
\]

(\(p\)为质数)

如果想详细了解费马小定理,敬请参考百度百科。

那么,这个费马小定理就可以作为素数性的一个判断依据。往简单说,就是针对一个大整数,如果\(a^{p-1}\%p=1\),那么这个数有很大可能是质数。反之,那么这个数一定不是质数。

好啦!那就拿\(a^{p-1}\%p\),快速幂取模一下看一看就得了!

这当然是错的。首先,这种方式的错误率很高,你需要反复地用不同的a检测很多次,时间复杂度噌噌上,最后还有可能依然是错误答案。所以我们应该在费吗小定理的基础上再加一个约束条件,使得算法能够稳定、有序的输出正确解。

介绍下一个理论依据:二次探测定理

二次探测定理的内容是:

如果一个数\(p\)是质数,对于一个\(x\in (0,p)\)且\(x\in Z\),方程\(x^2 \equiv 1\,\,\,\,(mod\,\,p)\)的解有且只有两个:\(x=1\)或\(x=p-1\)。

那么,在快速幂累乘的基础上,反复判断现在的\(p\)是否符合二次探测定理,就大大增加了其正确性。

具体的实现方式是:

如果一个数\(p\)是质数,那么\(p-1\)一定会是个偶数(你不要拿2来刚我),那么,对于这个指数\(p-1\),我们可以将其分解成\(m\times 2^k\)的形式,其中\(m\)为奇数。那么根据快速幂的原理,我们就会依次对以下数列进行二次探测定理的检测:

\[
m,2m,4m\cdots m\times 2^{k-1},m\times 2^k
\]

如果这些都合法,最后用费马小定理判断一下是否合法即可。

Miller-Rabin算法的模板

bool Miller_check(int a,int n)
{
    int ret=1;
    int b=n-1;
    while(b)
    {
        if(b&1)
            ret=(ret*a)%n;
        int x=a;//采用临时变量保存改变前的a
        a=(a*a)%n;
        if(a==1 && x!=1 && x!=n-1)//当a为1的时候,方程成立,开始判断解。
            return 0;//不是素数
        b>>=1;
    }
    return (ret==1)?1:0;
}
bool Miller_Rabin(int n,int t)
{
    if(n==2)
        return 1;
    if(n<2 || !(n&1))
        return 0;
    while(t--)
    {
        srand(time(NULL));
        int a=rand();//a要随机数
        if(!Miller_check(a,n))
            return 0;
    }
    return 1;
}

要注意的是,因为我们普遍用Miller-Rabin检测大数,所以在实际应用的时候往往要开long long。代码为了美观简化就删去了这个步骤,请应用的时候一定要加上。

Miller-Rabin算法大体就是这样!谢谢大家的观看!!

原文地址:https://www.cnblogs.com/fusiwei/p/12222848.html

时间: 2024-10-11 20:10:10

浅谈Miller-Rabin素数检测算法的相关文章

51nod 1106 质数检测(miller rabin 素数测试.)

1106 质数检测 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出N个正整数,检测每个数是否为质数.如果是,输出"Yes",否则输出"No". Input 第1行:一个数N,表示正整数的数量.(1 <= N <= 1000) 第2 - N + 1行:每行1个数(2 <= S[i] <= 10^9) Output 输出共N行,每行为 Yes 或 No. Input示例 5 2 3 4 5 6

Apache Spark源码走读之21 -- 浅谈mllib中线性回归的算法实现

欢迎转载,转载请注明出处,徽沪一郎. 概要 本文简要描述线性回归算法在Spark MLLib中的具体实现,涉及线性回归算法本身及线性回归并行处理的理论基础,然后对代码实现部分进行走读. 线性回归模型 机器学习算法是的主要目的是找到最能够对数据做出合理解释的模型,这个模型是假设函数,一步步的推导基本遵循这样的思路 假设函数 为了找到最好的假设函数,需要找到合理的评估标准,一般来说使用损失函数来做为评估标准 根据损失函数推出目标函数 现在问题转换成为如何找到目标函数的最优解,也就是目标函数的最优化

POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】

Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time Limit: 4000MS Description Given a big integer number, you are required to find out whether it's a prime number. Input The first line contains the num

POJ2429_GCD &amp;amp; LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】

GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 Description Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b.

HDU1164_Eddy&amp;#39;s research I【Miller Rabin素数测试】【Pollar Rho整数分解】

Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6664    Accepted Submission(s): 3997 Problem Description Eddy's interest is very extensive, recently he is interested in prime

POJ2429_GCD &amp; LCM Inverse【Miller Rabin素数测试】【Pollar Rho整数分解】

GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 Description Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b.

POJ1811_Prime Test【Miller Rabin素数測试】【Pollar Rho整数分解】

Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time Limit: 4000MS Description Given a big integer number, you are required to find out whether it's a prime number. Input The first line contains the num

HDU1164_Eddy&#39;s research I【Miller Rabin素数测试】【Pollar Rho整数分解】

Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6664    Accepted Submission(s): 3997 Problem Description Eddy's interest is very extensive, recently he is interested in prime

Miller-Rabin素数检测算法

Description: Goldbach's conjecture is one of the oldest and best-known unsolved problems in number theory and all of mathematics. It states: Every even integer greater than 2 can be expressed as the sum of two primes. The actual verification of the G