【问题标题】:I wish to create a program to implement prime-counting function for n<=10^14我希望创建一个程序来实现 n<=10^14 的素数计数功能
【发布时间】:2015-02-14 16:57:08
【问题描述】:

我可以使用埃拉托色尼筛法来计算素数的数量,但它需要我创建一个太大而无法创建的数组。我只是期待找到一种方法或算法来完成这项任务。名称或参考将达到目的。我只需要一些方法来继续这项任务。有了方法,我会弄清楚编程部分。请帮忙。

【问题讨论】:

  • 为什么要保留所有素数?有 3,204,941,750,802 个质数小于 10^14 - 你很难将它们全部保存在内存中(!)
  • 我不想保留素数,我只想计算素数的个数。
  • This SO question 询问Sieve of Atkin,这是埃拉托色尼筛的优化版本。该问题尚未得到公认的答案,但可能值得您看一看。
  • @WaiHaLee,阿特金的筛子不值得得到积极关注:它需要在 10^14 的范围内进行页面分段,而且效果很差,而且性能不如根据这些范围的理论时间复杂度——即使是作者的参考“primegen”实现也不能很好地适应这个范围。将素数计数到 10^14 的更好方法是数值分析技术。
  • 这个问题中建议的 10^14 范围足够大,因此即使是最优化的页面分段 Sieve of Eratosthenes Kim Walisch's primesieve 也需要大约四个小时才能在使用多线程的现代桌面 CPU 上完成.对于素数计数,this SO algorithm 之类的方法可以在几秒钟内完成,Kim Walisch's extremely optimized version 使用改进的算法和多线程可以在几分之一秒内完成。

标签: primes


【解决方案1】:

我想不出比 Sieve of Eratosthenes 更好的方法来满足您的需求,所以这就是我要做的。

埃拉托色尼筛法只需要检查一个数的素数除数直到该数的平方根,因此您不需要为 所有 小于 10^14 的素数创建一个数组 - 只需小于 10^7 的素数。

664,579 primes 小于 10^7 - 即使在具有非常普通规格的计算机上,该大小的数组也应该没问题(将它们存储为 4 字节整数,约为 2MB)。

这是一个伪代码方法:

  • 为小于 10^7 的素数创建存储 - 我们称之为除数存储。
  • 用第一个素数 2 播种您的存储。
  • 为找到的素数创建一个计数器,将其初始化为 1(对于素数 2)。
  • 为主要候选人创建一个计数器,从 3 开始。
  • 将候选素数除以除数存储中的所有素数。如果没有余数,则它是素数,因此将其添加到除数存储中(除非它大于 10^7)并增加找到的素数计数器。
  • 将候选计数器增加 2。
  • 重复最后两步进入主要候选超过10^14。

你不需要保留除数素数 - 你可以天真地除以小于候选根的每个数字,但这会更快 log(n)。

这是一种非常粗暴的做法,但确实有效。

【讨论】:

  • 如果你使用朴素的方法,你只需要 tiny 的内存量:主要用于存储 (a) 候选者,(b) 除数,(c)余数,(d) 到目前为止找到的素数。
  • 这是一个不错的方法。 :) 但是我仍然必须以两个步骤重复 i=3 到 i=10^14 的过程。所以总而言之,我必须重复 5x10^13 次,这已经很多了。我使用 Eratosthenes 的分段筛解决了这个问题。看看discuss.codechef.com/questions/61937/…
  • 嗯,听起来很有趣 - 我会读一读。 我自学了寻找素数的程序。topic>
猜你喜欢
  • 1970-01-01
  • 2013-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多