Временная сложность алгоритма решета Эратосфена

С Википедия:

сложность алгоритма 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). вы согласны?

4 ответов


  1. ваш n/2 + n/3 + n/5 + ... n / 97 не является O(n), потому что число членов не является постоянным. [Редактировать после редактирования: O (n2) слишком свободная верхняя граница.] Свободный верхний-предел Н(1+1/2+1/3+1/4+1/5+1/6+...1/н) (сумма обратных величин все числа до 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 N) битные операции.


то, что сложность включает термин loglogn, говорит мне, что где-то есть sqrt(n).

имейте в виду, что, когда вы найти простое число P во время просеивания вы не начинаете вычеркивать числа в своей текущей позиции + P; вы действительно начинаете вычеркивать числа в P^2. Все кратные P меньше P^2 будут зачеркнуты предыдущими простыми числами.


  1. внутренний цикл делает n/i действия, где i is prime = > целое сложность есть sum(n/i) = n * sum(1/i). По данным prime harmonic серии sum (1/i) здесь i премьер-это log (log n). В итого, O(n*log(log n)).
  2. Я думаю, что верхний цикл можно оптимизировать, заменив n С sqrt(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;
            }
        }    
    }
    

см. приведенное выше объяснение внутренний цикл является гармонической суммой всех простых чисел до sqrt (n). Итак, фактическая сложность - O (sqrt(n) * log(log(sqrt(n))))