【问题标题】:Find a largest prime number less than n [closed]找到小于 n 的最大素数 [关闭]
【发布时间】:2013-05-04 15:03:43
【问题描述】:

如何找到小于 n 的最大素数,其中 n ≤ 10¹⁸ ? 请帮我找到一个有效的算法。

for(j=n;j>=2;j--) {
  if(j%2 == 1) {
    double m = double(j);
    double a = (m-1)/6.0;
    double b = (m-5)/6.0;
    if( a-(int)a == 0 || b-(int)b == 0 ) {
      printf("%llu\n",j);
      break;
    }
  }
}

我使用了这种方法,但是对于 n>10^10 的求解效率不高;

如何优化这个..

编辑: 解决方案:对每个 j 使用素性检验。

Miller RabinFermat's Test

【问题讨论】:

  • 我们坚持人们在这里提出编程问题。做一些研究,想出一个算法,然后如果你在某些方面遇到困难,请回到这里。
  • 我对此做了很多研究......使用了复杂度为 O(nlog(n)) 的算法,但现在想要更高效..
  • 您可能已经找到了这个,但它仍然提供了一些参考:stackoverflow.com/questions/6741947/…
  • en.wikipedia.org/wiki/Primality_test 。从 n 开始连续使用该页面中的一些测试,直到第一次成功。向下舍入为奇数,并逐步为 (-2)。
  • 使用浮点是一个很好的指标,表明您在这里有错误的想法。使用uint64_t(或等效项)。

标签: algorithm primes


【解决方案1】:

我认为这个问题不应该这么快就被驳回,因为效率对于这个范围内的数字来说并不那么容易确定。首先,鉴于平均素数差距为ln(p),从给定的(n)向下工作是有意义的。即ln(10^18) ~ 41.44),因此您预计41 的迭代次数平均低于(n)。例如,测试:(n), (n - 2), (n - 4), ...

鉴于这个 平均 差距,下一步是决定您是否希望使用朴素测试 - 检查素数 <= floor(sqrt(n)) 的可分性。使用n <= (10^18),您需要针对素数<= (10^9) 进行测试。在这个范围内有~ 50 million 素数。如果您愿意预先计算并将这些值制成表格(所有这些值都适合 32 位),那么您可以对 64 位值进行合理的测试n <= 10^18。在这种情况下,一个 200MB 的素数表是可接受的方法吗? 20年前,可能还不是。今天,这不是问题。

将素数表与筛分和/或Pocklington's test 结合使用可能会提高效率。或者,如果内存受到更多限制,可以使用Miller-Rabin test 的确定性变体,其基数为:2, 325, 9375, 28178, 450775, 9780504, 1795265022(SPRP set)。大多数复合材料通过 SPRP-2 测试立即失败。

关键是 - 您需要在算法复杂度(理论上和实现难度方面)与空间/时间权衡之间做出决定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-06
    • 2022-11-17
    • 2020-05-29
    • 1970-01-01
    • 2021-12-25
    • 2013-11-21
    • 2021-06-09
    • 2011-10-08
    相关资源
    最近更新 更多