【问题标题】:What is the time complexity for this algorithm which finds every prime number up to n该算法找到最多 n 个素数的时间复杂度是多少
【发布时间】:2012-05-03 05:38:35
【问题描述】:

这是有问题的算法,伪代码:

list.add(2)
for (i = 3 to n)
    isPrime=true
    for each (j in list)
        if ((i mod j) = 0)
            isPrime=false
            break
    if (isPrime)
        list.add(i)
return list

我的 TA 今天告诉我这个算法的复杂度为 O(n^2),但我很确定这是不正确的,特别是考虑到大约有 n/ln(n) 个素数直到任何 n,因此,如果 n 本身是素数,则内部循环在其最后一次迭代中的迭代次数不会超过 n/ln(n) 次。但是我认为它实际上低于 O(n^2/ln(n)) ,但我不确定如何确定它实际上是什么。例如,每个偶数只迭代第二个循环两次。

【问题讨论】:

  • 现在,这完全是错误的。当它发现它们是复合的时,它会将数字添加到素数列表中。当且仅当您检查当前已知的素数(直到 sqrt(n))并且它们中的 none 均分新候选时,它们才是素数。有了这个固定值,你就大致正确了——素数定理说 1/log(n) 质数小于 n,所以你将测试 ~1/log(n) 数,而不是每次迭代中的 N 个数。
  • 过去有一段时间分析 O() 变得毫无意义;你已经通过了。但是,这个算法是错误的,所以也许你的算法意思会有所不同。
  • 糟糕——这应该是 N/log(N),而不是 1/Log(N)。问题在于他几乎是对的——log(N) 增长如此缓慢,以至于它非常对整体复杂性几乎没有影响。
  • 我修正了算法。我的直觉也告诉我实际的复杂度将在 O(x * sqrt(x)) 附近
  • 您可以轻松地从循环中省略偶数,因为测试它们没有意义;它们总是复合的(因此for (i = 3 to n step 2) 节省了一些时间)。

标签: algorithm complexity-theory primes


【解决方案1】:

在您检查的n 数中是否为素数,实际上大约有n / ln(n) 素数,这要求所有i / ln(i) 已经找到的素数都被尝试作为除数。因此,您的算法的复杂度是W(n^2 / ln(n)^2)W 是大欧米茄)和O(n^2 / ln(n)n^2 / ln(n)^2 的增长速度比 n * sqrt(n) 快。

为了达到O(n * sqrt(n)) 的时间复杂度,您应该使用以下伪代码:

list.add(2)
for (i = 3 to n)
    isPrime=true
    for each (j in list)
        if j > sqrt(i)
            break
        if ((i mod j) = 0)
            isPrime=false
            break
    if (isPrime)
        list.add(i)
return list

【讨论】:

    【解决方案2】:

    复杂度是O((n/log(n))**2)

    你分析如下。您会遇到两组数字,素数和复合数。

    您有 O(n/log(n)) 质数,您必须针对所有较小的质数对每个质数进行测试,O(n/log(n)) 每个质数工作,O((n/log(n))**2) 工作总数。

    您有O(n - n/log(n)) = O(n) 复合,每个都必须在sqrt(n) 下方的某个素数子集上进行测试,以用于上面由O(sqrt(n)) 界定的工作,因此总工作在上面由O(n sqrt(n)) 界定。

    因此,O((n/log(n))**2) 术语占主导地位。

    当然,这不是你的直觉引导你找到的答案。如果您很聪明并在素数平方超过您的目标数时切断内部循环,您试图直觉会发生什么,那么需要多长时间?答案原来是O(n sqrt(n) / (log(n))**2)。原因是sqrt(n) 下方有O(sqrt(n)/log(sqrt(n)) = O(sqrt(n)/log(n)) 质数,每个质数都需要测试O(n/log(n)) 数字(请参阅http://mathworld.wolfram.com/MertensTheorem.html 了解为什么会这样)。

    然而,此时我们已经从算法世界进入了数论世界。 :D

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-18
      • 1970-01-01
      • 2021-07-23
      • 2015-08-05
      • 2015-06-12
      • 1970-01-01
      相关资源
      最近更新 更多