Da Wikipedia:
A complexidade do algoritmo é a
O(n(logn)(loglogn))
operação de bits.
Como você chegou a isso?
O fato de a complexidade incluir o loglogn
termo me diz que existe um sqrt(n)
lugar.
Suponha que eu esteja executando a peneira nos primeiros 100 números ( n = 100
), supondo que marcar os números como compostos leva um tempo constante (implementação de matriz), o número de vezes que usamos mark_composite()
seria algo como
n/2 + n/3 + n/5 + n/7 + ... + n/97 = O(n^2)
E para encontrar o próximo número primo (por exemplo, para saltar 7
depois de riscar todos os números que são múltiplos de 5
), o número de operações seria O(n)
.
Então, a complexidade seria O(n^3)
. Você concorda?
Respostas:
Seu n / 2 + n / 3 + n / 5 +… n / 97 não é O (n), porque o número de termos não é constante. [Edite após sua edição: O (n 2 ) é um limite superior muito vago.] Um limite superior solto é n (1 + 1/2 + 1/3 + 1/4 + 1/5 + 1/6 +… 1 / n) (soma dos recíprocos de todos os números até n), que é O (n log n): consulte o número do Harmônico . Um limite superior mais adequado é n (1/2 + 1/3 + 1/5 + 1/7 + ...), que é a soma dos recíprocos dos primos até n, que é O (n log log n). (Vejo aqui ou aqui .)
O bit "encontre o próximo número primo" é apenas O (n) no geral, amortizado - você avançará para encontrar o próximo número apenas n vezes no total , não por etapa. Portanto, toda essa parte do algoritmo leva apenas O (n).
Então, usando esses dois, você obtém um limite superior de O (n log log n) + O (n) = O (n log log n) operações aritméticas. Se você contar as operações de bits, já que está lidando com números até n, elas têm cerca de log n bits, que é onde o fator de log n entra, dando O (n log n log log n) operações de bits.
fonte
Lembre-se de que, ao encontrar um número primo
P
durante a peneiração, você não começa a riscar os números na posição atual +P
; você começa a riscar os números emP^2
. Todos os múltiplos deP
menos do queP^2
serão riscados pelos números primos anteriores.fonte
p
oup^2
, a complexidade é a mesma (com matrizes de acesso direto).SUM (1/p) {p<N} ~ log (log N)
É a razão.n/i
etapas, ondei
é primo => toda a complexidade ésum(n/i) = n * sum(1/i)
. De acordo com as séries harmônicas primos,sum (1/i)
ondei
é primo élog (log n)
. No total,O(n*log(log n))
,.Eu acho que o loop superior pode ser otimizado substituindo
n
-osqrt(n)
por complexidade de tempo geralO(sqrt(n)loglog(n))
:fonte
isprime
é absolutamente o nome errado para usar lá.veja a explicação acima, o loop interno é a soma harmônica de todos os números primos até sqrt (n). Portanto, a complexidade real de é O (sqrt (n) * log (log (sqrt (n))))
fonte