Eratosthenes算法的筛选时间复杂度


95

维基百科:

该算法的复杂性是 O(n(logn)(loglogn))位运算。

你怎么到达的?

包含loglogn术语的复杂性告诉我在sqrt(n)某处。


假设我在前100个数字(n = 100)上运行筛子,假设将数字标记为复合数字需要固定的时间(数组实现),那么我们使用的次数mark_composite()将类似于

n/2 + n/3 + n/5 + n/7 + ... + n/97        =      O(n^2)                         

并且要查找下一个质数(例如,7在除掉所有倍数为的数字后跳至5),操作数将为O(n)

因此,复杂度为O(n^3)你同意吗?


5
我不知道其余的(现在我的大脑太困了,太数学了),但是平方根源自这样一个事实,即如果一个数的除数小于其平方根,则它是质数。另外,我刚刚了解到loglog(n)表示存在平方根。真好
R. Martinho Fernandes

13
那里的loglog(n)如何表示某个地方有sqrt(n)?(@Martinho:您为什么说您“刚刚学到了这个”?)实际分析不包含任何平方根!
ShreevatsaR

Answers:


117
  1. 您的n / 2 + n / 3 + n / 5 +…n / 97不是O(n),因为项数不是常数。[编辑后编辑:O(n 2)的上限太宽松。]宽松的上限是n(1 + 1/2 + 1/3 + 1/4 + 1/5 + 1/6 +… 1 / n)(不超过n 的所有数字的倒数之和),即O(n log n):请参见谐波数。一个更合适的上限是n(1/2 + 1/3 + 1/5 + 1/7 +…),即最高达n的质数的倒数之和,即O(n log log n)。(请参阅此处此处。)

  2. 总的来说,“查找下一个质数”位仅为O(n),摊销后 –您将总共只查找n次下一个数,而不是逐步查找。因此,算法的整个部分仅需O(n)。

因此,使用这两个,可以得到O(n log log n)+ O(n)= O(n log log n)算术运算的上限。如果您对位运算进行计数,则由于您要处理的数字最多为n,因此它们大约有log n位,这就是log n的因数,从而给出O(n log n log log n)位运算。


对于问题的一部分,您正在考虑渐近复杂性。对于另一部分,您正在考虑摊销费用。我很困惑。
crisron

2
@crisron有什么问题?并非“渐进复杂度”和“摊余复杂度”是两种不同的同一事物。摊销只是一种用于更仔细地计算事物的技术,这可能恰好是渐进复杂性。
ShreevatsaR

所有这些,我以前都认为它们是不同的。感谢您的澄清。
crisron

1
@ShreevatsaR为什么我们要计算最多n个项的谐波序列之和。我们不应该仅计算sqrt(n)项吗?给出答案为n(loglogsqrt(n))个算术运算的theta吗?同样,维基百科说空间复杂度为O(n)。那不应该是n的θ,因为无论如何我们都需要一个n个元素的数组?
a_123

@ s_123是的,您最多可以计算√n个项,但是因为log(√x)=(1/2),所以它在渐近分析中没有任何区别(甚至在运行时间上没有显着的实际差异)。将x记录为x。因此Θ(n log log√n)=Θ(n log log n)。对于另一个问题,是的,空间复杂度为Θ(n),也为O(n):通常使用O()来表示您正在指定上限,而不是说Θ()来表示它也是下限(特别是当下限很明显时,如此处所示)。
ShreevatsaR

7

复杂度包括loglogn项,这告诉我某处有一个sqrt(n)。

请记住,在P筛分时发现质数时,您不会在当前位置+上开始相除P;您实际上开始在处舍弃数字P^2P小于的所有倍数P^2将被以前的质数相除。


10
该语句本身是正确的,但与引用的语句无关,后者本身没有任何优点。无论我们是从p还是从头开始p^2,复杂度都是相同的(使用直接访问数组)。SUM (1/p) {p<N} ~ log (log N)是原因。
内斯

6
  1. 内部循环执行n/i步骤,其中i素数=>整个复杂度为sum(n/i) = n * sum(1/i)。根据素数谐波序列,素数在sum (1/i)哪里。总计。ilog (log n)O(n*log(log n))
  2. 我认为可以通过替换来优化上层循环nsqrt(n)因此总体时间复杂度将为O(sqrt(n)loglog(n))

    void isprime(int n)
    {
        int prime[n],i,j,count1=0;
        for(i=0;i<n;i++)
        {
           prime[i]=1;
        }
        prime[0]=prime[1]=0;
        for(i=2;i<=n;i++)
        {
            if(prime[i]==1)
            {
                printf("%d ",i);
                for(j=2;(i*j)<=n;j++)
                    prime[i*j]=0;
            }
        }    
    }
    

2
不,用sqrt(n)替换n使其〜n log log(sqrt n)仍然是〜n log log n。并且 isprime绝对是使用有错误的名称。
威尔·内斯

-1

参见上面的解释,内循环是所有素数的平方和,直到sqrt(n)。因此,的实际复杂度为O(sqrt(n)* log(log(sqrt(n))))


2
错误。我们一直标记到N:N / 2 + N / 3 + N / 5 + N / 7 + N / 11 + ... = N(1/2 + 1/3 + 1/5 + 1/7 + 1/11 + ...)〜N日志日志(开方N)〜N日志日志N.
威尔尼斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.