Vous êtes sur la page 1sur 5

Université Badji Mokhtar , Annaba, Département d’Informatique, L2, ALGO-STD-2, sabri.ghazi@univ-annaba.

dz

Chapitre 1 : La Complexité Algorithmique


Comment peut-on comparer les algorithmes ?
Imaginez qu’on a deux algorithmes A1 et A2, les deux peuvent résoudre le même problème P. Les
deux nous donnent des résultats corrects. La question qui vient en tête, lequel d’entre eux nous
allons exploiter ? Le meilleur ? Comment peut-on mesurer l’efficacité d’un algorithme ?
On sait comparer les voitures, par exemple si on a deux voitures V1 et V2 on peut les comparer en
se basant sur leurs caractéristiques, par exemple selon la puissance du moteur, le poids, le carburant
utilisé etc. En Algorithmique, on peut comparer les algorithmes selon deux paramètres : le premier
c’est l’espace mémoire, ceci veut dire, combien d’espace mémoire va être utilisé par l’algorithme
pour résoudre le problème. Le deuxième paramètre est le temps d’exécution. En fait, un algorithme
peut donner le résultat avant l’autre, lorsqu’on les exécute sur la même machine. Il n’est pas
possible de comparer des algorithmes lorsqu’on a pas la même combinaison matérielles (processeur,
bus de la carte mère, vitesse et capacité de la RAM), car cette dernière influence sur le temps
d’exécution.
Il est important de ne pas confondre performances et complexité. Lorsqu’on mesure les
performances d’un algorithme on cherche qu’elle est l’implémentation la plus efficace, car par
exemple, une implémentation en java sera moins rapide qu’une implémentation en langage natif tel
que le C.
De ce fait en algorithmique au lieu de calculer le temps d’exécution, on se base sur le calcul du
nombre d’instructions qu’exécute l’algorithme pour arriver au résultat.

Complexité en temps
Soit l’algorithme suivant qui permet de chercher l’existence d’un élément x dans un tableau tab

Figure 1, algorithme permet de trouver un élément dans un tableau.


Si on analyse ensemble cet algorithme, on peut compter les instructions de base, il est à noter que
ces instructions seront après traduites par le compilateur en instructions assembleur, bien sûr selon
le jeux d’instruction du processeur (exemple MOV, ADD, SUB, etc.). Car notre algorithme une fois
programmé, il peut être exécuté sur plusieurs type de processeur : Intel, AMD ou même sur un
processeur d’un téléphone Android ou iPhone.
Au début de la fonction on a deux affectations b=0 et i=0 (ligne 2 et 3), donc on a déjà 2
14

instructions, après on a deux comparaisons i<10 et b==0 plus une opération logique le « et »
Page

logique représenté par l’opérateur &&, donc on a 3 instructions. Dans le corps de la boucle on a
Université Badji Mokhtar , Annaba, Département d’Informatique, L2, ALGO-STD-2, sabri.ghazi@univ-annaba.dz

l’accès à un élément dans le tableau, une comparaison et une affectation plus l’incrémentation du i
et son affectation, ceci fait 5 instructions, à la fin nous avons le retour qui peut être vu comme étant
une opération d’affectation, donc on a une dernière instruction. Si on suppose que notre algorithme
reçoit un tableau de n cellules donc la boucle sera exécutée au maximum n fois. De ce fait, on peut
résumer le nombre d’instruction qu’exécute notre algorithme par une fonction mathématique qui
dépende de n la taille du tableau, et on aura f(n) = 2+ 8 n +1 = 8 n+ 3.
D’après notre analyse on a pu approximativement compter le nombre d’instruction que fait notre
algorithme, cette approximation reste encore dépendante du contenu de tableau T, en fait, la façon
avec laquelle ce dernier est remplis peut affecter le nombre d’instructions exécutées par notre
algorithme. Imaginez les cas suivants :
L’élément X qu’on cherche figure dans la première cellule du tableau Tab,
L’élément X se trouve au milieu du tableau.
L’élément X figure dans la dernière cellule ou bien n’existe pas dans le tableau.
En analysant ensemble ces trois cas, le cas A signifié que notre algorithme exécutera le corps de la
boucle uniquement une fois seulement, est ceci quel que soit la taille du table n. Quand on calcule la
complexité en temps, ce cas est appelé le meilleur cas (the best case, en anglais). Le deuxième cas
B est nommé le cas moyen, le dernier cas C est appelé le pire des cas (worst case en Anglais).
Il est important de garder en tête que la complexité en temps d’un algorithme dépend de la taille et
la distribution des données reçus en entrée.

La notation asymptotique
Lorsqu’on calcule la complexité d’un algorithme, le plus intéressant pour nous c’est le pire des cas,
c’est à dire le scénario durant lequel notre algorithme recevra les données qui montreront ses pires
performances. On compare après les algorithmes selon ce cas.
Une fois qu’on a la fonction qui permet d’approximer le nombre d’instruction (le comportement) de
notre algorithme, le but est de voir l’évolution de ce nombre lorsqu’on tend n vers l’infinie,
mathématiquement parlant, on cherche a trouvé la limite de la fonction lorsque n tend vers l’infinie.
Dans notre exemple f(n) = 8 n+3, imaginez que n = 1000, f(n) = 8* 1000 +3=8003, ici on peut
ignorer la constante 3, de même on peut aussi ignorer les facteurs on dit que le comportement
asymptotique de F(n)= 8 n +3 et f(n)= n, car lorsque n tend ver l’infinie, F(n) tend aussi vers
l’infinie donc on écrit f(n)=n, c’est ce terme qui « domine » la fonction.
De la même façon on peut examiner les fonctions suivantes :
f(n)= 5 n + 12 donnera f(n)= n
f(n) = 200 donnera f(n) =1 , ici on remplace 200 par 1 pour dire que la fonction n’est pas nulle mais
elle est constante.
f(n) = n2+3 n + 100 , ce qui donnera f(n) = n2, ici n2 croit plus vite que 3 n , donc on ignore 3 n et
aussi la constante 100.

f(n) = n + √𝑛, ici f(n) = n, vu que elle croît plus vite que la racine carrée de n, donc c’est ce terme
15

qui domine.
Page
Université Badji Mokhtar , Annaba, Département d’Informatique, L2, ALGO-STD-2, sabri.ghazi@univ-annaba.dz

L’algorithme décrit dans la figure 1, suit une stratégie nommée recherche linéaire (linear search en
Anglais). Comme on peut remarquer sa fonction qui approxime son nombre d’instructions est aussi
une fonction linéaire.

La notation thêta Θ
Une fois qu’on a pu avoir la fonction qui calcule le nombre d’instruction on peut après suivre la
notation est dire que notre algorithme est Θ(f(n)). Dans notre cas , l’algorithme décrit dans la figure
1 on dit qu’il est Θ(n), d’autres exemples :

n2 + 3n ∈ Θ( n2 ) , on dit que n puissance 6 est thêta (n puissance 6).

5n + 12 ∈ Θ( 5n )

6n + 10n ∈ Θ( 10n )

Complexité :
Une fois qu’on a pu déduire la fonction asymptomatique la fonction qui approxime le nombre
d’instructions que fait un algorithme. On peut dorénavant déduire sa complexité. Simplement, un
programme qui ne possède aucune boucle aura la fonction f(n)=1, un programme avec une boucle
aura f(n)=n, un programme avec deux boucles imbriquées, aura f(n)=n2, de même trois boucles
imbriquées est à f(n)=n3.
Questions : Que pensez-vous d’un algorithme qui possède
Deux boucles qui ne sont pas imbriquées,
Ou bien un autre avec 3 boucles, deux imbriquées et l’autre indépendante ?
De même si on a un algorithme avec trois boucles consécutives, laquelle sera elle considérée pour
estimer son comportement asymptotique ?
Le cas d’un algorithme qui dans une boucle appel une fonction et cette dernière est implémentée à
l’aide d’une boucle, que faire dans ce cas ?
Réponses : En cours

La notation Big O (appelée aussi la notation de Landau) :


La notation theta permet d’exprimer la complexité actuelle d’un algorithme, il existe une autre
notation qui permet de décrire la limite maximale de la complexité d’un algorithme, ceci veut dire
qu’en modifiant l’algorithme pour le rendre plus pire on ne peut obtenir au maximum O. exemple
l’algorithme de la figure 1 est Θ(n) et aussi O(n).
Exemple de complexités couramment trouvées, dans la figure 3 on peut voir comment ces
complexités évoluent :
16
Page
Université Badji Mokhtar , Annaba, Département d’Informatique, L2, ALGO-STD-2, sabri.ghazi@univ-annaba.dz

Figure 3, l’évolution des fonctions selon la taille d’entrée n

La complexité constante O(1) :


Un algorithme est dit a complexité constante, lorsque sa complexité ne dépend pas du paramètre n.
ceci veut dire qu’en modifiant la valeur de n le nombre d’instructions de l’algorithme restera le
même. f(n+1)=f(n)=1 (une constante) . Exemple : l’algorithme qui permet de permuter les valeurs
de deux cases d’un tableau, quel que soit la taille du tableau seules trois instructions seront exécuté.
Voir le listing dans la figure 2.

Figure 2, algorithme de permutation entre les case i et j du tableau A.

Complexité linéaire O(n) :


Le nombre d’instructions f(n+1)=f(n)+1, ceci signifie une complexité linéaire, en incrémentant n le
nombre d’instruction s’incrémente linéairement. L’algorithme de la figure 1 a une complexité
linéaire O(n). En augmentant la taille du tableau, le nombre d’itérations augmente aussi.

Complexité logarithmique O(log n)


Une autre sous-catégorie de ce niveau de complexité est la complexité logarithmique. Par exemple
la recherche dans un tableau trié, il suffit de pouvoir comparer l’élément cherché avec l’élément de
la position n/2 (le milieu du tableau), ce qui permet d’ignorer la partie qui soit supérieure à X, et
diviser à chaque fois la taille du tableau en deux. Cette recherche est nommée recherche
dichotomique.
17

La complexité dans ce cas est inférieur a une fonction linéaire. f(n+1)=f(n)+£. Cette fonction est
Page

moins rapide qu’une fonction linéaire. On note la complexité logarithmique par O(log (n)).
Université Badji Mokhtar , Annaba, Département d’Informatique, L2, ALGO-STD-2, sabri.ghazi@univ-annaba.dz

Complexité linéaire logarithmique O( n log(n))


Lorsqu’on a une fonction évolue selon n * log(n), l’algorithme est dit a complexité linéaire
logarithmique.

Complexité polynomiale O(nc) ,


Si le nombre d’instructions évolue selon une fonction polynomiale on dit que l’algorithme est de
complexité polynomiale. Un exemple est un algorithme avec deux boucles imbriquées dans ce cas
c=2, on parle d’une complexité quadratique O(n2).

Complexité exponentielle O(cn),


Lorsque la fonction de nombre d’instructions d’un algorithme évolue selon une loi exponentielle, on
parle d’une complexité O(cn). Exemple d’un algorithme de parcours d’un arbre binaire, dans ce cas,
chaque nœud de l’arbre donnera au maximum un accès à deux autres nœuds, dans ce cas c=2, est la
complexité est d’ordre O(2n)

Complexité factorielle O (n!)


Mathématiquement parlant la fonction qui permet de calculer n ! est une fonction qui croit très
rapidement.
Série de TD de premier chapitre : la complexité algorithmique
Exercice 1
Examiner le comportement asymptotique des fonctions suivantes :
f( n ) = n6 + 3n | 2. f( n ) = 2n + 12

f( n ) = 3n + 2n | 3. f( n ) = nn + n | 4. f ( n) = n+ √𝑛
Exercice 2
Soit deux tableaux T1 et T2 , de différentes tailles, contenants des entiers:
 Ecrire un algorithme qui calcule la somme des éléments d’un tableau. Compter son nombre
d’instructions et déterminer sa complexité.
 Ecrire un algorithme qui mit dans un troisième tableau T3 les éléments pairs de T1 et T2.
Déterminer le nombre d’instructions et sa complexité.
 Ecrire un algorithme qui calcule l’intersection entre T1 et T2, compter le nombre
d’instructions et déterminer la complexité.
Exercice 3
Soit l’algorithme suivant
18
Page

Vous aimerez peut-être aussi