package csm.work;
public class Question_10 {
/*
* 题目: 使用Miller-Rabin算法与确定性算法相比较,并给出100~10000以内错误的比例。
*
* 思路:Miller-Rabin算法简介:
* n为素数,则有n-1 = (2^k)*q , 则以下条件之一必成立。
* (1) a^q mod n =1
* (2) a^q,a^(2q),a^(4q).....a^(2^(k-1)*q) mod n = -1
*
* 相反,满足条件则不一定是素数,但很有很大几率,可以用多个a测试提高概率
* 不满足则一定不是素数
*
*
* 实验结果可以看出错误的比例很小,如果用多个a测试的话,比例则会更小
* 这里a取2 , 错误比例约为5.0E-4
*/
//Miller-Rabin算法
public static boolean testByMR(int n,int a)
{
int q=n-1,k=0;
while(q%2==0)
{
q/=2;
k++;
}
int t = 1;
for(int i=0;i<q;i++)
{
t*=a;
t%=n;
}
if(t==1)
return true;
for(int i=0;i<k;i++)
{
if(t == n-1)
return true;
t = t*t;//如果规模较大的话,这个点可能会溢出
t%=n;
}
return false;
}
// 确定算法
public static int primer[] = new int[10000];
public static int num = 1;
public static boolean isPrimeNumber(int n)
{
for(int i=0;i<num;i++)
{
if(n%primer[i]==0)
return false;
}
primer[num++] = n;
return true;
}
public static void main(String[] args) {
Question_10.primer[0] = 2;
int size = 10000;
int wrong = 0;
for(int i=3;i<size;i+=2)
{
//System.out.println("当前是"+i);
boolean r1 = Question_10.isPrimeNumber(i);
//System.out.println("使用确定性算法结果:" +r1);
boolean r2 = Question_10.testByMR(i, 2);
//System.out.println("使用MR蒙特卡罗概率算法结果 "+r2);
if(r1 != r2)
{
wrong++;
if(r2)
System.out.println("有待研究啊" +i);
}
}
System.out.println("错误比例约为" +(wrong/(size*1.0)));
//Question_10.testByMR(47741, 2);
}
}
public class Question_10 {
/*
* 题目: 使用Miller-Rabin算法与确定性算法相比较,并给出100~10000以内错误的比例。
*
* 思路:Miller-Rabin算法简介:
* n为素数,则有n-1 = (2^k)*q , 则以下条件之一必成立。
* (1) a^q mod n =1
* (2) a^q,a^(2q),a^(4q).....a^(2^(k-1)*q) mod n = -1
*
* 相反,满足条件则不一定是素数,但很有很大几率,可以用多个a测试提高概率
* 不满足则一定不是素数
*
*
* 实验结果可以看出错误的比例很小,如果用多个a测试的话,比例则会更小
* 这里a取2 , 错误比例约为5.0E-4
*/
//Miller-Rabin算法
public static boolean testByMR(int n,int a)
{
int q=n-1,k=0;
while(q%2==0)
{
q/=2;
k++;
}
int t = 1;
for(int i=0;i<q;i++)
{
t*=a;
t%=n;
}
if(t==1)
return true;
for(int i=0;i<k;i++)
{
if(t == n-1)
return true;
t = t*t;//如果规模较大的话,这个点可能会溢出
t%=n;
}
return false;
}
// 确定算法
public static int primer[] = new int[10000];
public static int num = 1;
public static boolean isPrimeNumber(int n)
{
for(int i=0;i<num;i++)
{
if(n%primer[i]==0)
return false;
}
primer[num++] = n;
return true;
}
public static void main(String[] args) {
Question_10.primer[0] = 2;
int size = 10000;
int wrong = 0;
for(int i=3;i<size;i+=2)
{
//System.out.println("当前是"+i);
boolean r1 = Question_10.isPrimeNumber(i);
//System.out.println("使用确定性算法结果:" +r1);
boolean r2 = Question_10.testByMR(i, 2);
//System.out.println("使用MR蒙特卡罗概率算法结果 "+r2);
if(r1 != r2)
{
wrong++;
if(r2)
System.out.println("有待研究啊" +i);
}
}
System.out.println("错误比例约为" +(wrong/(size*1.0)));
//Question_10.testByMR(47741, 2);
}
}