主元素问题
设T[1:n]是一个含有n个元素的数组。当|{i|T[i]=x}|>n/2时,称元素x是数组T的主元素。
public static boolean majority(int[]t, int n)
{// 判定主元素的蒙特卡罗算法
rnd = new Random();
int i=rnd.random(n)+1;
int x=t[i]; // 随机选择数组元素
int k=0;
for (int j=1;j<=n;j++)
if (t[j]==x) k++;
return (k>n/2); // k>n/2 时t含有主元素
}
public static boolean majorityMC(int[]t, int n, double e)
{// 重复é ù次调用算法majority
int k= (int) Math.ceil(Math.log(1/e)/Math.log(2));
for (int i=1;i<=k;i++)
if (majority(t,n)) return true;
return false;
}
对于任何给定的a>0,算法majorityMC重复调用?log(1/a)? 次算法majority。它是一个偏真蒙特卡罗算法,且其错误概率小于?。算法majorityMC所需的计算时间显然是O(nlog(1/a))。
------------------------------------------------------------
素数测试
Wilson定理:对于给定的正整数n,判定n是一个素数的充要条件是(n-1)!? -1(mod n)。
费尔马小定理:如果p是一个素数,且0<a<p,则ap-1(mod p)。
二次探测定理:如果p是一个素数,且0<x<p,则方程x2?1(mod p)的解为x=1,p-1。
private static int power(int a, int p, int n)
{// 计算 ap mod n,并实施对n的二次探测
int x, result;
if (p==0) result=1;
else {
x=power(a,p/2,n); // 递归计算
result=(x*x)%n; // 二次探测
if ((result==1)&&(x!=1)&&(x!=n-1))
composite=true;
if ((p%2)==1) // p是奇数
result=(result*a)%n;
}
return result;}
public static boolean prime(int n)
{// 素数测试的蒙特卡罗算法
rnd = new Random();
int a, result;
composite=false;
a=rnd.random(n-3)+2;
result=power(a,n-1,n);
if (composite||(result!=1)) return false;
else return true;
}
算法prime是一个偏假3/4正确的蒙特卡罗算法。通过多次重复调用错误概率不超过(1/4)4。这是一个很保守的估计,实际使用的效果要好得多。
主元素问题和素数测试
最新推荐文章于 2024-10-21 23:28:19 发布