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

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) означает квадратный корень. Ницца.
Р. Мартиньо Фернандес
13
Каким образом наличие loglog (n) означает, что где-то есть sqrt (n)? (@Martinho: Почему вы говорите, что «только что научились этому»?) Фактический анализ не включает никаких квадратных корней!
ShreevatsaR

Ответы:

118
  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) битовых операций.

ShreevatsaR
источник
Для одной части проблемы вы учитываете асимптотическую сложность. С другой стороны, вы рассматриваете амортизированную сложность. Я запутался.
crisron
2
@crisron В чем проблема? Дело не в том, что «асимптотическая сложность» и «амортизированная сложность» - это два разных вида одного и того же. Амортизация - это просто метод более тщательного подсчета чего-либо, что может оказаться асимптотической сложностью.
ShreevatsaR
Все это время я думал о них как о разных. Спасибо за разъяснение.
crisron
1
@ShreevatsaR Почему мы вычисляем сумму гармонических рядов с точностью до n членов. Разве мы не должны рассчитывать только до sqrt (n) терминов? Давать ответ как тета из n (loglogsqrt (n)) арифметических операций? Кроме того, в Википедии говорится, что сложность пространства равна O (n). Разве это не тета из n, потому что в любом случае нам нужен массив из n элементов?
a_123
@ s_123 Да, вы можете вычислить до √n членов, но это не имеет значения для асимптотического анализа (или даже существенной практической разницы во времени выполнения), потому что log (√x) = (1/2) log x для любого x. Итак, Θ (n log log √n) = Θ (n log log n). На ваш другой вопрос, да, сложность пространства равна Θ (n), что также является O (n): обычно используется O (), чтобы указать, что вы указываете верхнюю границу, вместо того, чтобы говорить Θ (), чтобы указать что это тоже нижняя граница (особенно когда нижняя граница очевидна, как здесь).
ShreevatsaR
7

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

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

джемфинч
источник
10
это утверждение истинно само по себе, но не имеет отношения к процитированному утверждению, которое само по себе не имеет значения. Начнем ли мы с pили p^2, сложность одинакова (с массивами прямого доступа). SUM (1/p) {p<N} ~ log (log N)это причина.
Will Ness
6
  1. Внутренний цикл выполняет n/iшаги, где iпростое число => вся сложность sum(n/i) = n * sum(1/i). Согласно ряду простых гармоник, 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;
            }
        }    
    }
    
Ананд Трипати
источник
2
нет, замена n на sqrt (n) делает ~ n log log (sqrt n), который по-прежнему остается ~ n log log n. и isprimeэто абсолютно неправильное имя для использования там.
Will Ness
-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 log log (sqrt N) ~ N log log N.
Will Ness