是否有任何确定性方法来检查数字是否为素数?

时间:2015-10-23 09:33:38

标签: primes discrete-mathematics number-theory

此方法也是一种确定性方法,如下所示:

bool isPrime(int a){
    if( a <= 0) return false;
    if( a == 1) return false;
    if( a == 2) return true;
    if( a == 3) return true;
    int sqr = sqrt(a)+1;
    if( a%2 == 0) return false;
    for(int i=3;i<=sqr;i+=2){
        if( a%i == 0 )
           return false;
    }
    return true;
}

2 个答案:

答案 0 :(得分:3)

如果您的输入小于2 ^ 64(对于使用int的示例来说已经足够了),有一些好的方法:

1)BPSW。快速,确定,正确的所有64位输入,没有已知的反例(尽管我们认为它们存在)

2)Deterministic Miller-Rabin。维基百科页面提供了一些正确但效率低下的基本集 - Best Known SPRP Bases处的基本集最为人所知的是64位输入。任何64位输入最多7次测试。 New (Sep 2015) results通过13次测试给出了81位输入的确定性结果。

3)散列确定性M-R。这只是#2的优化。 32位输入只需要一次M-R测试,64位输入只需要2次或3次测试。请参阅Forisek and Jancina 2015 papermy different hashed implementation

你所展示的方法

Trial division非常适合微小输入,比如不到一百万左右。在过去的一段时间内它仍然是计算上的好,但它是输入的位长度的指数时间。它速度非常快,并且实际上不能使用超过26个左右的数字(仅仅是因为时间的巨大增长)。在我的测试中,25位数字比BPSW慢400M(这个尺寸的PRP测试),比ECPP慢13M,比APR-CL慢3M倍。

Graph of run times for primality tests on large inputs

如果您的输入大于64位,则某些选项包括:

  • BLS75方法(来自the seminal 1975 paper),包括N-1,N + 1,以及基于部分因子分解的混合方法。这些仍然使用,并且对于高达~40位的数字而言惊人地快。 Generalized Pocklington是其中一个定理的特例。由于这依赖于n-1和/或n + 1的部分分解,因此它在一般情况下不能很好地扩展,并且在实际使用中会消失大约80-100个数字。

  • APR-CL。相当快(例如,对于200位数字,半秒)。 Pari/GPmpz_aprcl中的开源。

  • ECPP。最快的大输入方法,不是特殊形式。 Primo(免费使用和黄金标准),ecpp-dj(开源)。这使用随机化,因此它在某种意义上不具有确定性,但它是100%正确的,这是许多人在这种情况下的意思。它还可以提供快速第三方验证的证书,使其特别具有吸引力。

  • AKS可怕慢。理论上的突破和令人着迷的简单数学,但实际上没用。它比20位左右的试验分区更快,最终将通过BLS75方法,但它与我们通常使用的方法无关:APR-CL或ECPP。存在各种实现,最快的我知道在ecpp-djPerl/ntheory [警告:我是作者]。多项式时间,但指数高于APR-CL,输入数量在千万亿左右(大小可笑)。

答案 1 :(得分:0)

是的,我认为是...... Deterministic Algorithm。 另一个更有效的确定性素数测试算法是AKS Primality Testing。 此外,如果您想使用一些概率(非确定性)素性测试,可以参考Miller-Rabin Test

希望这有帮助!