web-dev-qa-db-fra.com

Complexité temporelle de l'algorithme Sieve of Eratosthenes

De Wikipedia:

La complexité de l'algorithme est Opérations de bits O(n(logn)(loglogn))

Comment y arrivez-vous?

Le fait que la complexité inclut le terme loglogn m'indique qu'il existe une sqrt(n) quelque part.


Supposons que je lance le tamis sur les 100 premiers nombres (n = 100), en supposant que le marquage des nombres en tant que composite prend un temps constant (implémentation de tableau), le nombre de fois que nous utilisons mark_composite() serait quelque chose comme 

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

Et pour trouver le prochain nombre premier (par exemple, pour passer à 7 après avoir biffé tous les nombres qui sont des multiples de 5), le nombre d'opérations serait O(n).

La complexité serait donc O(n^3). Êtes-vous d'accord?

76
Lazer
  1. Votre n/2 + n/3 + n/5 +… n/97 n'est pas O (n), car le nombre de termes n'est pas constant. [Éditer après votre édition: O (n2) est trop lâche une borne supérieure.] Une borne supérieure lâche est n (1 + 1/2 + 1/3 + 1/4 + 1/5 + 1/6 +… 1/n) (somme des inverses de tous nombres jusqu'à n), ce qui correspond à O (n log n): voir numéro harmonique . Une borne supérieure plus appropriée est n (1/2 + 1/3 + 1/5 + 1/7 +…), c'est-à-dire la somme des inverses de nombres premiers jusqu'à n, qui est O (n log log n). (Voir ici ou ici .)

  2. Le bit "trouver le prochain nombre premier" est seulement O(n) dans son ensemble, amorti - vous allez rechercher le prochain nombre uniquement n fois dans total, et non par étape. Donc, toute cette partie de l'algorithme ne prend que O (n).

Donc, en utilisant ces deux, vous obtenez une limite supérieure de O (n log log n) + O(n) = O (n log log n) opérations arithmétiques. Si vous comptez les opérations sur les bits, puisque vous traitez avec des nombres allant jusqu'à n, ils ont environ log n bits, c'est là que le facteur de log n entre en jeu, ce qui donne O (n log n log log n) bits.

101
ShreevatsaR

Le fait que la complexité inclut le terme loglogn me dit qu’il existe un sqrt (n) quelque part.

N'oubliez pas que lorsque vous trouvez un nombre premier P lors du tamisage, vous ne commencez pas à rayer des numéros à votre position actuelle + P; vous commencez à rayer des numéros à P^2. Tous les multiples de P inférieurs à P^2 auront été rayés par des nombres premiers précédents.

8
jemfinch
  1. La boucle interne effectue n/i étapes, où i est premier => toute la complexité de Est sum(n/i) = n * sum(1/i). Selon la série prime harmonique .__, la sum (1/i)i est premier est log (log n). Autotal, O(n*log(log n)).
  2. Je pense que la boucle supérieure peut être optimisée en remplaçant n par sqrt(n) afin que la complexité globale du temps soit 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;
            }
        }    
    }
    
7
anand tripathi

voir prendre l'explication ci-dessus la boucle interne est la somme harmonique de tous les nombres premiers jusqu'à sqrt (n). Ainsi, la complexité réelle de est O (sqrt (n) * log (log (log (sqrt (n))))