关于性能:Eratosthenes算法筛选的时间复杂度

Time complexity of Sieve of Eratosthenes algorithm

维基百科:

The complexity of the algorithm is
O(n(logn)(loglogn)) bit operations.

你是怎么到那里的?

复杂性包括loglogn这个术语,这告诉我在某个地方有一个sqrt(n)

假设我在前100个数字上运行筛子(EDOCX1,2),假设将数字标记为复合时间(数组实现),我们使用EDCOX1×3的次数将是类似的。

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

为了找到下一个质数(例如,去掉所有5的倍数后跳到7),操作的次数将是O(n)

因此,复杂性将是O(n^3)。你同意吗?


  • 你的N/2+N/3+N/5+…N/97不是O(N),因为项的数目不是常数。[编辑后编辑:o(n2)上界太宽松]宽松上界为n(1+1/2+1/3+1/4+1/5+1/6+…1/n)(所有数字的倒数之和,最大为n),即o(n logn):见谐波数。一个更合适的上界是n(1/2+1/3+1/5+1/7+……),它是素数倒数之和,最大为n,即o(n对数n)。(请参见此处或此处。)

  • "查找下一个质数"位总体上仅为O(N),摊销-您将继续查找下一个数字,总共仅为N次,而不是每个步骤。所以整个算法只需要O(n)。

  • 因此,使用这两个函数,可以得到O(n log log n)+O(n)=O(n log log n)算术运算的上界。如果您计算位操作,因为您处理的是最多n个数字,那么它们有大约logn位,这就是logn的因子出现的地方,给出o(n logn logn)位操作。


    That the complexity includes the loglogn term tells me that there is a sqrt(n) somewhere.

    请记住,当你在筛选时发现一个质数P,你不会在你当前位置+P开始划掉数字;你实际上会在P^2开始划掉数字。P小于P^2的所有倍数将被以前的质数所抵消。


  • 内环执行n/i步,其中i是prime=>整个复杂性是sum(n/i) = n * sum(1/i)。根据主谐波系列,其中i是prime的sum (1/i)log (log n)。在合计,O(n*log(log n))
  • 我认为可以通过用sqrt(n)替换n来优化上环,因此O(sqrt(n)loglog(n))的总体时间复杂度如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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;
            }
        }    
    }

  • 请看上面的解释,内环是所有素数的调和和,直到qRT(n)。因此,O(Sqt(n)*log(log(qRT(n)))的实际复杂性