Vous êtes sur la page 1sur 9

Module : Algorithmique et structure de donnes - Anne universitaire : 2016-2017

Universit Stif 1 - Facult des Sciences


Dpartement dinformatique
Filire : Licence Acadmique
Module : Algorithmique et structure de donnes
Anne universitaire : 2016-2017

CHAP 5 : complexit
1- Objectifs des calculs de complexit :
-

pouvoir prvoir le temps d'excution d'un algorithme


pouvoir comparer deux algorithmes ralisant le mme traitement

Exemples :
- si on lance le calcul de la factorielle de 100, combien de temps faudra t-il attendre le rsultat?
- quel algorithme de tri vaut-il mieux utiliser pour retrier un tableau o on vient de changer un lment?
2- L'valuation de la complexit peut se faire plusieurs niveaux :

au niveau purement algorithmique, par l'analyse et le calcul


au niveau de l'excution du programme exprimentalement

2-1 Complexit exprimentale


Il est possible d'valuer de faon exprimentale le temps d'excution des programmes.

Cette valuation exprimentale dpend beaucoup des langages de programmation, ordinateurs et systmes
d'exploitation utiliss.
Pour avoir un sens, l'valuation exprimentale requiert un talonnage(Benchmarking) des ordinateurs utiliss.

2-2 Benchmarking
Un logiciel de benchmark (talonnage) donne une mesure de puissance d'un ordinateur en flops (floating point
operations per second).
Cette puissance varie en fonction des traitements effectus (calculs bruts, sur des entiers ou des rels, calculs lis
l'affichage, ...)
Puissance des ordinateurs grand public actuels : quelques Gigaflops (106 flops)
Puissance des meilleurs super-ordinateurs actuels : environ 1000 Teraflops (1015 flops)

Module : Algorithmique et structure de donnes - Anne universitaire : 2016-2017


(cf. www.top500.org)
3- Complexit temporelle vs spatiale
Exemple : change de deux valeurs entires :
// change des valeurs de deux variables entier x, y, z; ...
// initialisation de x et y
z <- x;
x <- y;
y <- z;
// change des valeurs de deux variables entier x, y; ...
// initialisation de x et y
x <- y-x;
y <- y-x;
x <- y+x;
- la premire mthode utilise une variable supplmentaire et ralise 3 affectations
- la deuxime mthode n'utilise que les deux variables dont on veut changer les valeurs, mais ralise 3 affectations
et 3 oprations
L'efficacit d'un algorithme peut tre value en temps et en espace :
- complexit en temps : valuation du temps d'excution de l'algorithme
- complexit en espace : valuation de l'espace mmoire occup par l'excution de l'algorithme
Rgle (non officielle) de l'espace-temps informatique : pour gagner du temps de calcul, on doit utiliser davantage
d'espace mmoire.
On s'intresse essentiellement la complexit en temps (ce qui n'tait pas forcment le cas quand les mmoires
coutaient cher)

4- Paramtre de complexit
Exemple 1: la calcul de la factorielle
fonction avec retour entier factorielle1(entier n)
entier i, resultat;
dbut
resultat <- 1;
pour (i allant de 2 n pas 1) faire
resultat <- resultat*i;
finpour
retourne resultat;
fin
Le paramtre de complexit est la valeur de n

Exemple 2: multiplier tous les lments d'un tableau d'entiers par un entier donn
fonction sans retour multiplie(entier[] tab, int x)
entier i;
dbut
pour (i allant de 0 tab.longueur-1 pas de 1) faire
tab[i] <- tab[i] * x;
finpour

Module : Algorithmique et structure de donnes - Anne universitaire : 2016-2017


fin ;
Le paramtre de complexit est la longueur du tableau tab.
Exemple 3: faire la somme des premiers lments de chaque ligne d'un tableau deux dimensions
fonction avec retour entier sommeTeteLigne(entier[][] tab)
entier i,s;
dbut
s <- 0;
pour (i allant de 0 tab[0].longueur-1 pas de 1) faire
s <- s + tab[0][i];
finpour
retourne s;
fin
Le seul paramtre de complexit est la longueur de tab[0].
Quand l'algorithme opre sur une structure multidimensionnelle, il faut bien prciser le paramtre de complexit.
Un algorithme oprant sur de telles structures peut avoir des complexits diffrentes selon la dimension considre.

5- Calcul de complexit
Exemple : la factorielle
fonction avec retour entier factorielle1(entier n)
entier i, resultat;
dbut
resultat <- 1;
pour (i allant de 2 n pas 1) faire
resultat <- resultat*i;
finpour
retourne resultat;
fin
On peut fixer des temps d'excution constants chaque type d'instruction :
- affectation d'entier : ae
- comparaison d'entier : ce
- opration lmentaire sur des entiers : oe
On nglige le cot des dclarations, des affectations et du retour.
L'excution de la fonction va prendre :
resultat <- 1;

ae
+

pour (i allant de 2 n pas 1) faire


resultat <- resultat*i;
(n-1) * (ae + oe)
finpour
Au total, le temps d'excution sera de la forme a*n+b
a et b dpendent du langage de programmation et de l'ordinateur utiliss.

6- Complexit au mieux et au pire


Exemple : recherche squentielle d'un lment dans un tableau de n chaines de caractres
fonction avec retour boolen rechercheElement(chaine[] tab, chaine x)

Module : Algorithmique et structure de donnes - Anne universitaire : 2016-2017


entier i;
dbut
i <- 0;
tantque (i < tab.longueur) faire
si (tab[i] = x) alors
retourne VRAI;
finsi
fintantque
retourne FAUX;
fin
Le paramtre de complexit est la taille du tableau d'entre.
Le nombre de tours de boucles varie selon que x est dans le tableau ou pas, et selon l'endroit o x est prsent.
Si x est dans la premire case du tableau : 1 tour de boucle avec la condition tab[i]=x vraie
Si x est dans la deuxime case du tableau : 1 tour de boucle avec la condition tab[i]=x fausse et 1 tour de boucle avec
la condition tab[i]=x vraie
... Si x est dans dernire case du tableau : tab.longueur-1 tours de boucle avec la condition tab[i]=x fausse et 1 tour
de boucle avec la condition tab[i]=x vraie
Si x n'est pas dans le tableau : tab.longueur tours de boucle avec la condition tab[i]=x fausse
Lorsque, pour une valeur donne du paramtre de complexit, le temps d'excution varie selon les donnes
d'entre, on peut distinguer :
- La complexit au pire : temps d'excution maximum, dans le cas le plus dfavorable.
- La complexit au mieux : temps d'excution minimum, dans le cas le plus favorable (en pratique, cette complexit
n'est pas trs utile).
- La complexit moyenne : temps d'excution dans un cas mdian, ou moyenne des temps d'excution.
Le plus souvent, on utilise la complexit au pire, car on veut borner le temps d'excution.
Pour lexemple prcdent :
n = la taille du tableau, ae = affectation d'entier, ce = comparaison d'entier, oe=opration sur les entiers.
Complexit au pire (x n'est pas dans le tableau) : ae+n*(2*ce+oe+ae)
Complexit au mieux (x est dans la premire case du tableau) : ae+2*ce
Complexit en moyenne : considrons qu'on a 50% de chance que x soit dans le tableau, et 50% qu'il n'y soit pas, et,
s'il y est sa position moyenne est au milieu. Le temps d'excution est [ (ae+n*(2*ce+oe+ae)) + (ae+
(n/2)*(2*ce+oe+ae)) ] /2, de la forme a*n+b (avec a et b constantes)

7- Complexit asymptotique
Calculer la complexit de faon exacte n'est pas raisonnable vu la quantit d'instructions de la plupart des
programmes et n'est pas utile pour pouvoir comparer deux algorithmes.
Premire approximation : on ne considre souvent que la complexit au pire
Deuxime approximation : on ne calcule que la forme gnrale de la complexit
Troisime approximation : on ne regarde que le comportement asymptotique de la complexit
f et g tant des fonctions, f = O(g) s'il existe des constantes c>0 et n0 telles que f(x) < c*g(x) pour tout x > n0

Module : Algorithmique et structure de donnes - Anne universitaire : 2016-2017

f = O(g) signifie que f est domine asymptotiquement par g.

7-1 Domination asymptotique


La notation O, dite notation de Landau, vrifie les proprits suivantes :
- si f=O(g) et g=O(h) alors f=O(h)
- si f=O(g) et k un nombre, alors k*f=O(g)
- si f1=O(g1) et f2=O(g2) alors f1+f2 = O(g2+g2)
- si f1=O(g1) et f2=O(g2) alors f1*f2 = O(g2*g2)
Exemples de domination asymptotique :
x = O(x2 ) car pour x>1, x<x2
x2 = O(x3 ) car pour x>1, x2<x3
100*x = O(x2 ) car pour x>100, x < x2
ln(x) = O(x) car pour x>0, ln(x)<x
si i>0, xi = O(ex ) car pour x tel que x/ln(x) > i, xi<ex
Notation : f = (g) s'il existe des constantes c>0 et n0 telles que f(x) c*g(x) pour tout x n0

7-2 Equivalence asymptotique


f et g tant des fonctions, f = (g) s'il existe des constantes c1 , c2 , strictement positives et n0 telles que c1*g(x) f(x)
c2*g(x) pour tout x n0

Module : Algorithmique et structure de donnes - Anne universitaire : 2016-2017


8- Classes de complexit
O(1) : complexit constante, pas d'augmentation du temps d'excution quand le paramtre croit
O(log(n)) : complexit logarithmique, augmentation trs faible du temps d'excution quand le paramtre croit.
Exemple : algorithmes qui dcomposent un problme en un ensemble de problmes plus petits (dichotomie).
O(n) : complexit linaire, augmentation linraire du temps d'excution quand le paramtre croit (si le paramtre
double, le temps double). Exemple : algorithmes qui parcourent squentiellement des structures linaires.
O(nlog(n)) : complexit quasi-linaire, augmentation un peu suprieure O(n). Exemple : algorithmes qui
dcomposent un problme en d'autres plus simples, traits indpendamment et qui combinent les solutions
partielles pour calculer la solution gnrale.
O(n2) : complexit quadratique, quand le paramtre double, le temps d'excution est multipli par 4.
Exemple : algorithmes avec deux boucles imbriques.
O(ni) : complexit polynomiale, quand le paramtre double, le temps d'excution est multipli par 2i. Exemple :
algorithme utilisant i boucles imbriques.
O(in) : complexit exponentielle, quand le paramtre double, le temps d'excution est lev la puissance 2.
O(n!) : complexit factorielle, asymptotiquement quivalente nn
Encore pire : la fonction d'Ackerman
Ack(m,n) = n+1 si m = 0
Ack(m,n) = Ack(m-1,1) si n=0 et m > 0
Ack(m,n) = Ack(m-1, Ack(m,n-1)) sinon
Ack(0,0) = 1, Ack(1,1) = 3, Ack(2,2) = 7, Ack(3,3) = 61, Ack(4,4) est suprieur 1080

Module : Algorithmique et structure de donnes - Anne universitaire : 2016-2017


Les algorithmes de complexit polynomiale ne sont utilisables que sur des donnes rduites, ou pour des
traitements ponctuels Les algorithmes exponentiels ou au del ne sont pas utilisables en pratique

Complexit et temps d'excution


Temps de calcul pour des donnes de taille 1 million

Loi de Moore (empirique) : cot constant, la rapidit des processeurs double tous les 18 mois (les capacits de
stockage suivent la mme loi).
Constat : le volume des donnes stockes dans les systmes d'informations augmente de faon exponentielle.
Conclusion : il vaut mieux optimiser ses algorithmes qu'attendre des annes qu'un processeur surpuissant soit
invent.

Applications :
1- Recherche squentielle
fonction avec retour boolen rechercheElement(chaine[] tab, chaine x)
entier i;
dbut
i <- 0;
tantque (i < tab.longueur) faire
si (tab[i] = x) alors
retourne VRAI;
finsi
i <- i + 1;
fintantque
retourne FAUX;
fin
n = la taille du tableau, ae = affectation d'entier, ce = comparaison d'entier, oe = opration sur les entiers.
Complexit au pire (x n'est pas dans le tableau) : ae+n*(2*ce+ae+oe) = O(n)
Complexit au mieux (x est dans la premire case du tableau) : ae+2*ce = O(1)
Complexit en moyenne : considrons qu'on a 50% de chance que x soit dans le tableau, et 50% qu'il n'y soit pas, et,
s'il y est sa position moyenne est au milieu. Le temps d'excution est [ (ae+n*(2*ce+oe+ae)) + (ae+
(n/2)*(2*ce+oe+ae)) ] /2, de la forme a*n+b (avec a et b constantes) = O(n)
2- Recherche dichotomique
fonction avec retour boolen rechercheDicho(chaine[] tab, chaine x)

Module : Algorithmique et structure de donnes - Anne universitaire : 2016-2017


entier i, j;
dbut i <- 0; j <- tab.longueur-1;
tantque (i <= j) faire
si (tab[(j+i)/2] = x) alors
retourne VRAI;
sinon si (tab[(j+i)/2] > x) alors
j <- (j+i)/2 - 1;
sinon i <- (j+i)/2 + 1;
finsi
finsi
fintantque
retourne FAUX;
fin
Le paramtre de complexit est la longueur du tableau, qu'on appelle n.
Cas au pire : x n'est pas dans le tableau. La longueur de la partie du tableau comprise entre i et j est d'abord n, puis
n/2, puis n/4, ...., jusqu' ce que n/2t = 1. Le nombre de tours de boucles est donc un entier t tel que n/2t = 1 soit 2t
= n soit t*log(2) = log(n) soit t = log2 (n)
3- Recherche dichotomique
fonction avec retour boolen rechercheDicho(chaine[] tab, chaine x)
entier i, j;
dbut
i <- 0;
j <- tab.longueur-1;
tantque (i <= j) faire
si (tab[(j+i)/2] = x) alors
retourne VRAI;
sinon si (tab[(j+i)/2] > x) alors
j <- (j+i)/2 - 1;
sinon i <- (j+i)/2 + 1;
finsi
finsi
fintantque
retourne FAUX;
fin
La complexit au pire de la recherche dichotomique est (ce + 2* cc + 3*oe)*log2 (n)
avec ce = comparaison d'entier, cc = comparaison de chaine, oe = opration lmentaire.
Complexit asymptotique : O(log(n))
Conclusion : pour des donnes de grande taille, si le tableau est tri, il vaut mieux utiliser la recherche dichotomique
4- Factorielle rcursive
Exemple : calcul rcursif de la factorielle
// cette fonction renvoie n! (n est suppos suprieur ou gal 1) fonction avec retour entier factorielle2(entier n)
dbut
si (n = 1) alors
retourne 1;
sinon
retourne n*factorielle2(n-1);
finsi
fin
Paramtre de complexit : la valeur de n
Il n'y a qu'un seul cas d'excution (pas de cas au pire ou au mieux)

Module : Algorithmique et structure de donnes - Anne universitaire : 2016-2017


Si n 1, le calcul de la factorielle de n cote une comparaison d'entiers, le calcul de la factorielle de n-1 et une
multiplication d'entiers
Si n = 1, le calcul de la factorielle cote une comparaison d'entiers
On pose une quation de rcurrence : appelons c(n) la complexit
c(n) = ce + c(n-1) + oe si n 1
c(1) = ce
On rsoud cette quation de rcurrence : c(n) = n*ce + (n-1)*oe = O(n)
La complexit de la factorielle rcursive est donc linaire, comme celle de la factorielle itrative.
A l'excution, la fonction rcursive est un peu moins rapide (pente de la droite plus forte) du fait des appels rcursifs.

Complexit et rcursivit
En gnral, drcursiver un algorithme ne change pas la forme de sa complexit, pas plus que passer en rcursivit
terminale!
Il existe diverses techniques pour la rsolution des quations de rcurrence (mthode des fonctions gnratrices et
dcomposition des fractions rationnelles, transforme en Z, ).
5- Complexit du tri bulle
fonction sans retour triBulle(entier[] tab)
{ entier i,j,temp;
dbut
pour (i allant de tab.longueur-2 1 pas -1) faire
pour (j allant de 0 i pas 1) faire
si (tab[j] > tab[j+1]) alors
temp <- tab[j]; tab[j] <- tab[j+1]; tab[j+1] <- temp;
finsi
finpour
finpour
fin
Paramtre de complexit : la taille du tableau
Cas au pire : les lments sont tris dans l'ordre inverse de celui voulu
Complexit au pire : remonter le premier lment ncessite (n-1) tours de la boucle imbrique, remonter le
deuxime ncessite (n-2) tours, etc. Donc le nombre de tours total est (n-1) + (n-2) + + 1 = n*(n-1)/2 soit O(n2 ).
Remarque : les tris par slection et par insertion sont aussi quadratiques. Mais il existe des algorithmes de tri quasilinaires.