【问题标题】:How can sieve of Eratosthenes be implemented in O(n) time complexity?如何以 O(n) 时间复杂度实现 Eratosthenes 筛?
【发布时间】:2020-04-12 08:09:12
【问题描述】:

在O(n*log(log(n)) 的时间复杂度中,这个算法可以找到直到n 的素数。我们如何在O(n) 时间复杂度下实现它?

【问题讨论】:

  • 你为什么要标记 C++ 和 Java,好像在说“只要给我任何语言的代码”?如果您询问算法,请不要标记任何语言。如果您询问具体的实现,请向我们展示您到目前为止所做的工作并仅标记适当的语言。

标签: algorithm time-complexity primes sieve-of-eratosthenes


【解决方案1】:

您可以执行埃拉托色尼筛法来确定在O(n) 时间范围内[2, n] 中哪些数是素数,如下所示:

  • 对于区间[2, n] 中的每个数字x,我们计算x 的最小素因子。出于实现目的,这可以通过保留一个数组来轻松完成——比如MPF[]——其中MPF[x]代表x的最小素因子。最初,您应该将每个整数x 的MPF[x] 设置为零。随着算法的进行,这个表格将被填满。

  • 现在我们使用 for 循环并从 i = 2 迭代到 i = n(含)。如果我们遇到MPF[i] 等于0 的数字,那么我们立即得出结论i 是素数,因为它没有最小素因数。此时,我们通过将i 插入到列表中将其标记为素数,并将MPF[i] 设置为等于i。相反,如果MPF[i]不等于0,那么我们知道i是最小素因数等于MPF[i]的复合。

  • 在每次迭代期间,在检查完 MPF[i] 之后,我们执行以下操作:计算每个质数 p_j 小于或等于 MPF[i] 的数 y_j = i * p_j,并设置 @987654350 @ 等于 p_j。

这似乎违反直觉 --- 如果我们有两个嵌套循环,为什么运行时 O(n)?关键思想是每个值都设置为一个,因此运行时为O(n)。这个website 给出了一个 C++ 实现,我在下面提供了它:

const int N = 10000000;
int lp[N+1];
vector<int> pr;

for (int i=2; i<=N; ++i) {
    if (lp[i] == 0) {
        lp[i] = i;
        pr.push_back (i);
    }
    for (int j=0; j<(int)pr.size() && pr[j]<=lp[i] && i*pr[j]<=N; ++j)
        lp[i * pr[j]] = pr[j];
}

上述实现中的数组lp[] 与我在解释中描述的MPF[] 相同。此外,pr 存储质数列表。

【讨论】:

  • 我明白了。谢谢:)
  • 当然它不会扩展。如果您认为这不正确,请提供实际运行时间,例如n1 = 1B 和 n2 = 1.5B 所以我们可以将 Empirical orders of growth 计算为 log(t2/t1) / log(1.5)。为了比较,Eratosthenes 的简单位压缩非分段(连续)筛子在该范围内表现出 ~n^1.06 的行为on ideone(这是旧时间,当前的 ideone 肯定会更快,但增长的顺序可以'变化不大)。
【解决方案2】:

好吧,如果算法是 O(n*log(n)),那么如果不更改算法,您通常无法做得更好。

复杂度为 O(n*log(n))。但是您可以在时间和资源之间进行交易:通过确保您有 O(log(n)) 计算节点并行运行,可以在 O(n) 中完成。

希望我没有做你的功课......

【讨论】:

  • 除了log日志,能否详细说明一下?
  • 并非所有内容都是可并行的。并非每个并行化都会提高复杂性。可用 CPU 的数量通常是有限且固定的。如果有这样的需要,线程之间的通信是有成本的。等等等等等等所有这些都必须针对给定的算法专门解决。否则就是空谈。
  • 是的,但是筛子很容易并行化。由于没有给出代码,这看起来更像是计算机科学讲座中的理论问题。当我学习时,我们可以假设一台足够大的机器。在实践中,即使对于较大的 n 值,O(n^2) 也可以比 O(n) 快得多,所以给出的结果是 - 这是对理论问题的理论答案。
  • 没有固定数量的资源(如可用内核)将永远改变复杂性。
  • 啊,你太踏实了…… ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
  • 2013-10-20
  • 2019-12-09
相关资源
最近更新 更多