【问题标题】:Fastest algorithm for primality test [closed]素数测试的最快算法[关闭]
【发布时间】:2011-02-04 21:47:27
【问题描述】:

我需要在非常大的数字之间的间隔上测试素数(在 long long 的范围内),所以我需要一些快速算法来检查一个数字是否为素数。请提出您的想法。

【问题讨论】:

  • 你只需要检查它是否是质数,还是需要找到它的质因数?
  • 质数分解很困难。这就是 RSA 加密的基础。虽然你没有回答斯蒂芬的问题,所以我假设你只是想测试一个数字的素性。
  • 您是否需要确定它是否是质数,或者您是否会对正确答案的概率非常高感到满意?
  • 这个问题似乎是题外话,因为它是关于数论的。试试 math.stackexchange.com。

标签: c++ algorithm math primes


【解决方案1】:

Jim Sinclair 证明了对七个碱基 2、325、9375、28178、450775、9780504、1795265022 的 Miller-Rabin 测试可以确定性地测试小于 2^64 的数是否为素数。见http://miller-rabin.appspot.com/

【讨论】:

    【解决方案2】:

    我认为最好的算法是“ALI primality test”。

    【讨论】:

      【解决方案3】:

      如果你想测试一个 long long 的素数,那么Baillie PSW primality test 是一个不错的选择。该测试进行了一次强伪素测试和一次卢卡斯测试,因此速度非常快。预计会有一些复合材料通过了这个测试,但到目前为止还没有一个已知的,1015以下当然也不例外。该测试的一个变体例如在 Mathematica 中使用。

      【讨论】:

        【解决方案4】:

        我相信渐近最快的当前(非概率)素性测试是“Lenstra/Pomerance 改进的 AKS”,其复杂性基本上为 O(n^6)。

        但是,long long 的范围(假设这是一个 64 位整数的典型系统)并没有那么大。特别是,只有大约 2 亿个小于 2^32 的素数,因此使用快速概率测试,然后使用预先计算的素数列表进行试除(或者只是在素数列表中查找数字,如果你有一个) 在该范围内会非常快,并且可能是正确的方法。

        【讨论】:

        • 概率测试后不需要再做试除法。如果您运行概率测试 n 次迭代,则错误答案的概率为 1/2^n,因此如果 n = 100,算法将在 10^30 次中不正确 1。只运行概率测试的迭代次数比进行试验除法要好。
        • 特别是,在真实硬件上,由于寄存器值被异常高能的宇宙射线(或其他零星的硬件故障)。
        【解决方案5】:

        我建议使用Miller-Rabin 算法的GNU MP library。我用了几个月,速度很快。

        具体来说,函数 mpz_probab_prime_p 就是这样做的,你也可以使用另一个函数 mpz_nextprime 来查找下一个大于某个数的素数。如果您愿意,我可以发布代码示例。

        【讨论】:

          【解决方案6】:

          在这里看看我的回答:

          how to test a prime number 1000 digits long?

          测试非常快。如果您在 64 位或更小的范围内工作,您可以放入一个 30030 的 GCD,以便为大多数数字节省一点时间。

          【讨论】:

            【解决方案7】:

            Cobbal 和 Grokus 是对的。 Miller-Rabin 检验是可用算法中最有用的。是的,它是概率性的,但真的不应该吓跑你。该测试是最广泛用于实际目的的测试。

            请注意,通过重复测试,可以任意减小误报(没有误报)的概率。

            【讨论】:

              【解决方案8】:

              最快的可能是在预先计算的素数列表中查找它。请参阅here for example,它们最多有 2^43112609-1(已知的最大素数)。

              【讨论】:

              • 这行不通。从来没有计算机有足够的存储空间来保存这么长的列表。根据对pi(2^64) 的粗略估计,该列表将需要超过 10 亿 GB 的无压缩存储空间。
              • @Dietrich:但是 OP 不需要那么多。
              【解决方案9】:

              一个好方法是Miller-Rabin 测试。不过需要注意的是,这只是一个概率测试。

              【讨论】:

              • Miller-Rabin 在广义黎曼假设的假设下可以适应确定性。由于 GRH 被广泛认为是正确的,我可以设想一个场景,您使用这个测试就好像它被证明是确定性的,因为它是迄今为止最快的。
              • @Mark:对于指定的输入范围,我们不需要假设 GRH 为真,我们只需要一个较弱的假设,即 M-R 的确定性版本没有低于 LONGLONG_MAX 的误报。这可能更容易证明,尽管我仍然不喜欢通过详尽的测试来证明。
              【解决方案10】:

              我想出了一个非常好的算法,它比检查所有除数要快得多——当然这也让我可以破解公钥加密。

              等等——我只需要关上窗户,头顶上全是黑色的直升机......

              (或者看How can I test for primality?

              【讨论】:

              • 因式分解复合数(破解 RSA 需要)与仅测试一个数是否为素数(不一定需要找到任何特定因数)不同。事实上,实现 RSA 需要找到具有数百位数字的素数,这对于简单的“检查所有潜在除数”算法是不可行的。
              • 是的,但是如果有更快的测试素数的方法,你就不会在这里告诉任何人了 ;-) 这个问题无论如何都会被当作骗子来解决的。
              猜你喜欢
              • 2011-05-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-07
              • 2011-05-31
              • 2011-01-24
              相关资源
              最近更新 更多