Complessità temporale dell'algoritmo del setaccio di Eratostene


95

Da Wikipedia:

La complessità dell'algoritmo è costituita dalle O(n(logn)(loglogn))operazioni sui bit.

Come ci si arriva?

Il fatto che la complessità includa il loglogntermine mi dice che c'è un sqrt(n)da qualche parte.


Supponiamo che io esegua il setaccio sui primi 100 numeri ( n = 100), assumendo che contrassegnare i numeri come composti richieda tempo costante (implementazione dell'array), il numero di volte che usiamo mark_composite()sarebbe qualcosa di simile

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

E per trovare il numero primo successivo (ad esempio a cui saltare 7dopo aver barrato tutti i numeri multipli di 5), il numero di operazioni sarebbe O(n).

Quindi, la complessità sarebbe O(n^3). Sei d'accordo?


5
Non so per il resto (troppo mathy per il mio cervello troppo assonnato in questo momento), ma la radice quadrata deriva dal fatto che se un numero non ha divisori inferiori alla sua radice quadrata, è primo. Inoltre, ho appena imparato che loglog (n) significa che c'è una radice quadrata. Bello.
R. Martinho Fernandes

13
In che modo la presenza del loglog (n) significa che c'è un sqrt (n) da qualche parte? (@Martinho: Perché dici che "hai appena imparato questo"?) L'analisi effettiva non coinvolge radici quadrate!
ShreevatsaR

Risposte:


117
  1. Il tuo n / 2 + n / 3 + n / 5 +… n / 97 non è O (n), perché il numero di termini non è costante. [Modifica dopo la tua modifica: O (n 2 ) è un limite superiore troppo largo.] Un limite superiore sciolto è n (1 + 1/2 + 1/3 + 1/4 + 1/5 + 1/6 + ... 1 / n) (somma dei reciproci di tutti i numeri fino an), che è O (n log n): vedi numero armonico . Un limite superiore più appropriato è n (1/2 + 1/3 + 1/5 + 1/7 +…), cioè la somma dei reciproci dei numeri primi fino a n, che è O (n log log n). (Vedi qui o qui .)

  2. Il bit "trova il prossimo numero primo" è solo O (n) in totale, ammortizzato : andrai avanti per trovare il numero successivo solo n volte in totale , non per passo. Quindi tutta questa parte dell'algoritmo richiede solo O (n).

Quindi usando questi due si ottiene un limite superiore di O (n log log n) + O (n) = O (n log log n) operazioni aritmetiche. Se conti le operazioni di bit, poiché hai a che fare con numeri fino a n, hanno circa log n bit, che è dove entra in gioco il fattore di log n, dando O (n log n log log n) operazioni bit.


Per una parte del problema, stai considerando la complessità asintotica. Per l'altra parte, stai considerando la compexity ammortizzata. Non ho capito bene.
crisron

2
@crisron Qual è il problema? Non è il caso che "complessità asintotica" e "complessità ammortizzata" siano due tipi diversi della stessa cosa. L'ammortamento è solo una tecnica per contare più attentamente qualcosa, che può essere la complessità asintotica.
ShreevatsaR

Tutto questo mentre li consideravo diversi. Grazie per averlo chiarito.
crisron

1
@ShreevatsaR Perché calcoliamo la somma delle serie armoniche fino a n termini. Non dovremmo calcolare solo fino a termini sqrt (n)? Fornire la risposta come theta di n (loglogsqrt (n)) operazioni aritmetiche? Inoltre, wikipedia dice che la complessità dello spazio è O (n). Non dovrebbe essere theta di n perché in ogni caso abbiamo bisogno di un array di n elementi?
a_123

@ s_123 Sì, puoi calcolare fino a √n termini, ma non fa differenza nell'analisi asintotica (o anche una differenza pratica significativa nel tempo di esecuzione), perché log (√x) = (1/2) log x per qualsiasi x. Quindi Θ (n log log √n) = Θ (n log log n). Alla tua altra domanda, sì, la complessità dello spazio è Θ (n), che è anche O (n): è convenzionale usare O () per indicare che stai specificando il limite superiore, invece di dire Θ () per indicare che è anche il limite inferiore (specialmente quando il limite inferiore è ovvio, come lo è qui).
ShreevatsaR

7

Il fatto che la complessità includa il termine loglogn mi dice che c'è un sqrt (n) da qualche parte.

Tieni presente che quando trovi un numero primo Pdurante il setacciamento, non inizi a barrare i numeri nella posizione corrente + P; effettivamente inizi a barrare i numeri a P^2. Tutti i multipli Pinferiori a P^2saranno stati cancellati dai numeri primi precedenti.


10
questa affermazione è vera in sé, ma non ha alcuna relazione con l'affermazione citata che di per sé non ha alcun merito. Sia che partiamo da po p^2, la complessità è la stessa (con array ad accesso diretto). SUM (1/p) {p<N} ~ log (log N)è la ragione.
Will Ness

6
  1. Il ciclo interno esegue i n/ipassaggi, dove iè primo => l'intera complessità è sum(n/i) = n * sum(1/i). Secondo le serie armoniche prime, il sum (1/i)dove iè primo è log (log n). In totale, O(n*log(log n)).
  2. Penso che il ciclo superiore possa essere ottimizzato sostituendo n con una sqrt(n)complessità temporale così complessiva 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
no, sostituendo n con sqrt (n) diventa ~ n log log (sqrt n) che è ancora ~ n log log n. ed isprimeè assolutamente il nome sbagliato da usare lì.
Will Ness

-1

vedere prendere la spiegazione sopra, il ciclo interno è la somma armonica di tutti i numeri primi fino a sqrt (n). Quindi, la complessità effettiva di è O (sqrt (n) * log (log (sqrt (n))))


2
sbagliato. segniamo fino alla 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.