📜  AKS原始性测试

📅  最后修改于: 2021-04-26 07:11:24             🧑  作者: Mango

有几种素数检验可用来检查数字是否为素数,例如费马定理Miller-Rabin素数检验等等。但是所有这些问题都在于它们本质上都是概率性的。因此,这里出现了另一种方法,即AKS素数检验(Agrawal–Kayal–Saxena素数检验) ,对于任何通用数,它在确定性上都是正确的。
AKS素数测试的功能:
1. AKS算法可用于验证给定任何通用数的素数。
2.算法的最大运行时间可以表示为目标数中位数的多项式。
3.保证算法能够确定性地区分目标数是素数还是复合数。
4. AKS的正确性不以任何未经证实的辅助假设为条件。
AKS素数检验基于以下定理:且仅当多项式同余关系时,大于2的整数n为质数。
{\displaystyle (x+a)^{n}\equiv (x^{n}+a){\pmod {n}}}
持有n的一个互质数。这里x只是一个正式的符号。
AKS测试通过使复杂度取决于r的大小来评估相等性。表示为
{\displaystyle (x+a)^{n}\equiv (x^{n}+a){\pmod {x^{r}-1, n}}}
可以用更简单的术语表示为
{\displaystyle (x+a)^{n}-(x^{n}+a)=(x^{r}-1)g+nf}
对于某些多项式f和g。
当r是n的多项式时,可以在多项式时间内检查该一致性。 AKS算法针对一大组值(其大小与n的位数成多项式)评估该一致性。 AKS算法的有效性证明表明,可以找到具有上述属性的r和一组值,使得如果等价成立,则n是质数的幂。蛮力方法将要求(x – a)^ n多项式的展开,以及所得n + 1系数的减小(mod n)。
作为a应该与n互质。因此,要实现此算法,我们可以采用a = 1进行检查,但是对于较大的n值,我们应该采用较大的a值。
该算法基于以下条件:如果n是任意数字,则在以下情况下为质数:
(x – 1)^ n –(x ^ n – 1)可被n整除。
检查n = 3:
(x-1)^ 3 –(x ^ 3 – 1)
=(x ^ 3 – 3x ^ 2 + 3x – 1)–(x ^ 3 – 1)
= -3x ^ 2 + 3x
由于所有系数都可以被n整除,即3,所以3(n)是素数。随着数量的增加,大小也会增加。
此处的代码基于此条件,并且可以检查素数直到64。
下面是上述方法的实现:

C++
// C++ code to check if number is prime. This
// program demonstrates concept behind AKS
// algorithm and doesn't implement the actual
// algorithm (This works only till n = 64)
#include 
using namespace std;
 
// array used to store coefficients .
long long c[100];
 
// function to calculate the coefficients
// of (x - 1)^n - (x^n - 1) with the help
// of Pascal's triangle .
void coef(int n)
{
    c[0] = 1;
    for (int i = 0; i < n; c[0] = -c[0], i++) {
        c[1 + i] = 1;
 
        for (int j = i; j > 0; j--)
            c[j] = c[j - 1] - c[j];
    }
}
 
// function to check whether
// the number is prime or not
bool isPrime(int n)
{
    // Calculating all the coefficients by
    // the function coef and storing all
    // the coefficients in c array .
    coef(n);
 
    // subtracting c[n] and adding c[0] by 1
    // as ( x - 1 )^n - ( x^n - 1), here we
    // are subtracting c[n] by 1 and adding
    // 1 in expression.
    c[0]++, c[n]--;
 
    // checking all the coefficients whether
    // they are divisible by n or not.
    // if n is not prime, then loop breaks
    // and (i > 0).
    int i = n;
    while (i-- && c[i] % n == 0)
        ;
 
    // Return true if all coefficients are
    // divisible by n.
    return i < 0;
}
 
// driver program
int main()
{
    int n = 37;
    if (isPrime(n))
        cout << "Prime" << endl;
    else
        cout << "Not Prime" << endl;
    return 0;
}


Java
// Java code to check if number is prime. This
// program demonstrates concept behind AKS
// algorithm and doesn't implement the actual
// algorithm (This works only till n = 64)
 
class GFG {
    // array used to store coefficients .
    static long c[] = new long[100];
 
    // function to calculate the coefficients
    // of (x - 1)^n - (x^n - 1) with the help
    // of Pascal's triangle .
    static void coef(int n)
    {
        c[0] = 1;
        for (int i = 0; i < n; c[0] = -c[0], i++) {
            c[1 + i] = 1;
 
            for (int j = i; j > 0; j--)
                c[j] = c[j - 1] - c[j];
        }
    }
 
    // function to check whether
    // the number is prime or not
    static boolean isPrime(int n)
    {
        // Calculating all the coefficients by
        // the function coef and storing all
        // the coefficients in c array .
        coef(n);
 
        // subtracting c[n] and adding c[0] by 1
        // as ( x - 1 )^n - ( x^n - 1), here we
        // are subtracting c[n] by 1 and adding
        // 1 in expression.
        c[0]++;
        c[n]--;
 
        // checking all the coefficients whether
        // they are divisible by n or not.
        // if n is not prime, then loop breaks
        // and (i > 0).
        int i = n;
        while ((i--) > 0 && c[i] % n == 0)
            ;
 
        // Return true if all coefficients are
        // divisible by n.
        return i < 0;
    }
    // Driver code
    public static void main(String[] args)
    {
        int n = 37;
        if (isPrime(n))
            System.out.println("Prime");
        else
            System.out.println("Not Prime");
    }
}
 
// This code is contributed by Anant Agarwal.


Python3
# Python3 code to check if
# number is prime. This
# program demonstrates concept
# behind AKS algorithm and
# doesn't implement the actual
# algorithm (This works only
# till n = 64)
 
# array used to
# store coefficients .
c = [0] * 100;
 
# function to calculate the
# coefficients of (x - 1)^n -
# (x^n - 1) with the help
# of Pascal's triangle .
def coef(n):
    c[0] = 1;
    for i in range(n):
        c[1 + i] = 1;
        for j in range(i, 0, -1):
            c[j] = c[j - 1] - c[j];
        c[0] = -c[0];
         
# function to check whether
# the number is prime or not
def isPrime(n):
     
    # Calculating all the coefficients
    # by the function coef and storing
    # all the coefficients in c array .
    coef(n);
     
    # subtracting c[n] and adding
    # c[0] by 1 as ( x - 1 )^n -
    # ( x^n - 1), here we are
    # subtracting c[n] by 1 and
    # adding 1 in expression.
    c[0] = c[0] + 1;
    c[n] = c[n] - 1;
     
    # checking all the coefficients
    # whether they are divisible by
    # n or not. if n is not prime,
    # then loop breaks and (i > 0).
    i = n;
    while (i > -1 and c[i] % n == 0):
        i = i - 1;
     
    # Return true if all coefficients
    # are divisible by n.
    return True if i < 0 else False;
 
# Driver Code
n = 37;
if (isPrime(n)):
    print("Prime");
else:
    print("Not Prime");
     
# This code is contributed by mits


C#
// C# code to check if number is prime. This
// program demonstrates concept behind AKS
// algorithm and doesn't implement the actual
// algorithm (This works only till n = 64)
using System;
 
class GFG {
     
    // array used to store coefficients .
    static long []c = new long[100];
 
    // function to calculate the coefficients
    // of (x - 1)^n - (x^n - 1) with the help
    // of Pascal's triangle .
    static void coef(int n)
    {
        c[0] = 1;
         
        for (int i = 0; i < n; c[0] = -c[0], i++)
        {
            c[1 + i] = 1;
 
            for (int j = i; j > 0; j--)
                c[j] = c[j - 1] - c[j];
        }
    }
 
    // function to check whether
    // the number is prime or not
    static bool isPrime(int n)
    {
         
        // Calculating all the coefficients by
        // the function coef and storing all
        // the coefficients in c array .
        coef(n);
 
        // subtracting c[n] and adding c[0] by 1
        // as ( x - 1 )^n - ( x^n - 1), here we
        // are subtracting c[n] by 1 and adding
        // 1 in expression.
        c[0]++;
        c[n]--;
 
        // checking all the coefficients whether
        // they are divisible by n or not.
        // if n is not prime, then loop breaks
        // and (i > 0).
        int i = n;
        while ((i--) > 0 && c[i] % n == 0)
            ;
 
        // Return true if all coefficients are
        // divisible by n.
        return i < 0;
    }
     
    // Driver code
    public static void Main()
    {
        int n = 37;
        if (isPrime(n))
            Console.WriteLine("Prime");
        else
            Console.WriteLine("Not Prime");
    }
}
 
// This code is contributed by anuj_67.


PHP
 0; $j--)
            $c[$j] = $c[$j - 1] - $c[$j];
    }
}
 
// function to check whether
// the number is prime or not
function isPrime($n)
{
    global $c;
     
    // Calculating all the
    // coefficients by the
    // function coef and
    // storing all the
    // coefficients in c array .
    coef($n);
 
    // subtracting c[n] and
    // adding c[0] by 1 as
    // ( x - 1 )^n - ( x^n - 1),
    // here we are subtracting c[n]
    // by 1 and adding 1 in expression.
    // $c[0]++; $c[$n]--;
     
    // checking all the coefficients whether
    // they are divisible by n or not.
    // if n is not prime, then loop breaks
    // and (i > 0).
    $i = $n;
    while ($i-- && $c[$i] % $n == 0)
 
    // Return true if all
    // coefficients are
    // divisible by n.
    return $i < 0;
}
 
    // Driver Code
    $n = 37;
    if (isPrime($n))
        echo "Not Prime", "\n";
    else
        echo "Prime", "\n";
 
// This code is contributed by aj_36
?>


Javascript


输出:

Prime

参考:
https://zh.wikipedia.org/wiki/AKS_primality_test
https://rosettacode.org/wiki/AKS_test_for_primes#C
https://www.youtube.com/watch?v=HvMSRWTE2mI