如何在Java中实现AKS测试来确定一个数字是否为素数?
我首先编写了一些伪代码。我在编写expand多项式()方法时遇到问题。另外,我不知道如何在isPrime()中表示任意的int x。 以下是解释AKS的链接:如何在Java中实现AKS测试来确定一个数字是否为素数?,java,algorithm,optimization,Java,Algorithm,Optimization,我首先编写了一些伪代码。我在编写expand多项式()方法时遇到问题。另外,我不知道如何在isPrime()中表示任意的int x。 以下是解释AKS的链接: 公共类解决方案{ 公共静态void main(字符串[]args) { 扫描仪扫描=新扫描仪(System.in); int n=scan.nextInt(); System.out.println(isPrime(n)); } 私有静态布尔iPrime(int p) { /* AKS素性测试表明如果 ((x-1)^p-(x^p-1))模
公共类解决方案{
公共静态void main(字符串[]args)
{
扫描仪扫描=新扫描仪(System.in);
int n=scan.nextInt();
System.out.println(isPrime(n));
}
私有静态布尔iPrime(int p)
{
/*
AKS素性测试表明如果
((x-1)^p-(x^p-1))模p==0,
那么p是素数
*/
int x;
布尔素数=真;
int[]arr=可展开多项式(x-1,p);
例如(int i=1;ix
不是一个具有实际值的Java变量。它是多项式中的一个符号。在这里,您希望用Java表示一个实际多项式,而不是一个单独的值;因此,例如,对于x2+3 x+5,您可能希望将其表示为多项式系数的数组[1,3,5](虽然用相反的方法可能更好,[5,3,1],首先是系数x0——我认为这会使算法更平滑)。所以要表示x-1,需要一个int[]
的值为[1,-1]或[-1,1]。您可以编写一个乘法方法,将两个多项式相乘;将a0+a1 x1+a2 x2…乘以b0+b1 x1+b2 x2,结果中x0的系数为a0 b0;x1的系数为a0 b1+a1 b0,x2的系数为a0 b2+a1 b1+a2 b0,依此类推。使用此方法,您可以将x-1表示为多项式,然后再进行多重运算将其自身叠加p次(使用多项式乘法方法)以得到多项式(x-1)p;然后减去xp和x0系数(以实现-(x^p-1)
部分),并查看是否所有结果系数都可以被p
整除
或者,不用做所有的多项式数学,你可以用(x-1)p的系数是二项式系数这一事实(也可以在Pascal三角形中找到),每切换一个符号。但无论如何,在测试p的可除性时,符号并不重要。因此,您可以通过计算所有二项式系数并查看它们是否可被p整除来执行测试。看哪一个表示相同的事情。要获得所有二项式系数,请从1开始,然后乘以p
和di除以1,然后乘以p-1
再除以2,然后乘以p-2
再除以3,以此类推
当然,这样做实际上比仅仅通过奇数并查看p
是否可以被其中任何一个整除要慢——这是检查素数的老方法。维基百科关于AKS测试的文章给出了一种算法,它实际上看起来要快一些,但它涉及到乘法阶和欧拉托蒂安(Euler's totien)等问题t函数,所以它太复杂了,无法在这里解释。x
不是一个具有实际值的Java变量。它是多项式中的一个符号。在这里,您希望用Java表示一个实际多项式,而不是单个值;因此,例如,对于x2+3 x+5,您可能希望将其表示为一个数组[1,3,5],多项式的系数(虽然可能最好用相反的方式[5,3,1],首先是系数x0——我认为这会使算法更平滑)。因此,要表示x-1,需要一个int[]
的值为[1,-1]或[-1,1]。您可以编写一个乘法方法,将两个多项式相乘;将a0+a1 x1+a2 x2…乘以b0+b1 x1+b2 x2,结果中x0的系数为a0 b0;x1的系数为a0 b1+a1 b0,x2的系数为a0 b2+a1 b1+a2 b0,依此类推。使用此方法,您可以将x-1表示为多项式,然后再进行多重运算将其自身叠加p次(使用多项式乘法方法)以得到多项式(x-1)p;然后减去xp和x0系数(以实现-(x^p-1)
部分),并查看是否所有结果系数都可以被p
整除
或者,不用做所有的多项式数学,你可以用(x-1)p的系数是二项式系数这一事实(也可以在Pascal三角形中找到),每切换一个符号。但无论如何,在测试p的可除性时,符号并不重要。因此,您可以通过计算所有二项式系数并查看它们是否可被p整除来执行测试。看哪一个表示相同的事情。要获得所有二项式系数,请从1开始,然后乘以p
和di除以1,然后乘以p-1
再除以2,然后乘以p-2
再除以3,以此类推
当然,这样做实际上比仅仅通过奇数并查看p
是否可以被其中任何一个整除要慢——这是检查素数的老方法。维基百科关于AKS测试的文章给出了一种算法,它实际上看起来要快一些,但它涉及到乘法阶和欧拉托蒂安(Euler's totien)等问题t函数,所以这里解释起来太复杂了。不幸的是,视频在很多方面都很容易误导人
Grime博士在视频中花了大部分时间描述的是方程(1)。它是引理2.1,也是中的方程(1)。它是在16世纪被知道的,是指数时间。事实上,它比简单的试验划分慢。除了纯粹的乐趣,实现它真的没有什么意义
格里姆博士知道这不是真正的AKS,并在结尾提到了“其他一些微妙的部分”,这实际上是AKS的全部观点。数百年来,成千上万的人都在研究这个方程,可能用不同的方法来证明它,可能把它与帕斯卡三角形之类的东西联系起来(如果你愿意的话,也可以是塔塔利亚三角、杨辉三角、卡亚姆三角、平加拉三角等等)。关于
public class Solution {
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.println(isPrime(n));
}
private static boolean isPrime(int p)
{
/*
AKS primality test says that if
((x-1)^p - (x^p-1)) mod p == 0,
then p is a prime
*/
int x;
boolean prime=true;
int[] arr = expandPolynomial(x-1, p);
for (int i=1;i<arr.length-1; i++)
{
// arr[0] and arr[arr.length-1] omitted
// due to the subtraction in the test
if (arr[i] % p != 0)
{
prime = false;
}
}
return prime;
}
private static int[] expandPolynomial()
{
/*
return the coefficient of each term
from the leading term to x^1;
*/
}
}