【数学】关于素数的检验
来源:互联网 发布:店淘软件 编辑:程序博客网 时间:2024/05/16 14:01
最近看了一些关于素数的检验问题(伯努利试验),简单写一写,和大家分享一下。
定义:
一个大于1的自然数,除了1和它本身外,不能被其他自然数整除,即因数中只含有1和它本身,则称其为素数,又叫质数,其他的数称为合数。
素数的分布:
定义π(n)为小于等于n的素数个数,有定理如下(素数定理):
则我们可以近似认为在前n个正整数中素数的个数大约是
暴力的检验方法:
如果我们想知道一个数n是否为素数,那么根据定义,显然我们可以从2到n-1枚举一遍,看是否是n的因数,如果有是的,则是合数,否则是素数。时间复杂度O(n)。
略微改进的暴力检验方法:
显然上一种方法实在是过于暴力,我们多做了不少无用功。其实只需要从2到
证明:
对于一个数n,如果存在一个大于(等于)
这样我们的时间复杂度降到了O(
费马检验:
以上两种方法虽然可以保证检验的正确性,但效率低下,并不适用于大素数的检验,于是便有了费马检测。
费马检测的理论基础是由“史上最杰出的业余数学家”费马提出的费马小定理:
这说明对于一个素数p,任意a∈{1,2,3…p-1},以上等式恒成立。而令人惊奇的是其逆定理也 几乎 成立,即对于一个数n,如果任意a∈{1,2,3,…n-1},都使得以上等式成立,那么这个数n 几乎 就是一个素数。
于是我们就可以根据此结论来得出一种对于大素数的检验方法:
选择一个底数a(a∈{1,2,3…n-1}),计算
bool judge(int a,int b){ int s=1,p=b+1; while (b>0){ if (b&1) s=(s*a)%p; b>>=1; a=(a*a)%p; } if (s==1) return true; else return false;}void Fermat(int n){ if (judge(2,n-1)) printf("May be a prime\n");//可能是素数 else printf("Must be a composite\n");//一定是合数}
费马检测的时间复杂度是O(logn)的,但因为是“几乎成立”,所以有一些合数会被误判为素数,这些数x满足任意a∈{1,2,3…x-1}等式均成立,它们被称为Carmichael数,不过Carmichael数并不多,分布十分稀疏,有研究证明,在以2为底的情况下,512位整数中碰到这种数的概率是
Miller-Rabin检验:
因为存在Carmichael数,所以单一的费马检验并不能完全满足人们的需求,于是便诞生了Miller-Rabin检验。
Miller-Rabin检验的理论基础:
如果n是素数,x为小于n的正整数,且
证明:
因为
这就说明,对于一个数n,如果存在小于n的正整数x使得等式有非平凡平方根(1和n-1之外的数),则n一定是一个合数。
于是我们就有了具体的操作思路:
执行T轮,以增加其可靠度。
首先把n-1分解成
int Pow(int a,int b,int p){ int s=1; while (b>0){ if (b&1) s=(s*a)%p; b>>=1; a=(a*a)%p; } return s;}bool judge(int n,int k,int t){ int a=rand()%(n-2)+2; int y=Pow(a,k,n); if (y!=1 && y!=n-1) for (int j=1; j<=t-1 && y!=n-1; j++){ y=(y*y)%n; if (y==1) return false; } if (y!=n-1) return false; return true;}bool witness(int n,int T){ if (n<2 || n&1==0) return false; if (n==2) return true; int k=n-1,t=0; bool f; for (; k%2==0; k>>=1,t++); for (int i=1; i<=T; i++){ f=true; if (!judge(n,k,t)){ f=false; break; } } return f;}void Miller_Rabin(int n){ int T=rand()%41+10; if (witness(n,T)) printf("May be a prime\n");//可能是素数 else printf("Must be a composite\n");//一定是合数 }
显然Miller-Rabin的时间复杂度是O(Tlogn),判断比较可靠。
- 【数学】关于素数的检验
- 大素数的检验
- 大素数的检验
- 几种检验素数的方法
- 几种检验素数的方法
- 关于webwork框架的检验
- 素数检验法
- 素数检验算法
- Solovay-Strassen素数检验
- Miller_rabin素数检验[HDU5391]
- 关于数学上特殊数(如质数、素数)的笔试题
- 卢卡斯莱默检验法检验梅森素数
- 关于素数的判断
- 关于素数的算法
- 关于素数的研究
- 关于素数的问题
- 关于素数的题型
- 关于素数的问题
- mybatis入门基础(八)-----查询缓存
- git tag 相关操作
- 简单使用输入/输出流
- FORM开发小问题
- 测试大数据(快速排序)100万条数据
- 【数学】关于素数的检验
- SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
- ABBYY FineReader 12激活过程详解
- 虚函数问题
- 一个Oracle存储过程
- nyoj-2 括号配对【栈】
- Android Adapter接口
- Java main方法
- ThinkPHP项目iis部署一些问题