Chapitre 2 : Analyse des algorithmes
Download
Report
Transcript Chapitre 2 : Analyse des algorithmes
Chapitre 2
Analyse des algorithmes
Analyser un algorithme consiste `a calculer les ressources qui seront n´ecessaires
a` son ex´ecution. Mais avant de l’analyser, il faut d’abord s’assurer qu’il est
correct, c’est-`
a-dire qu’il calcule bien ce pourquoi il a ´et´e ´ecrit.
2.1
Preuves de la correction d’un algorithme
Comment s’assurer qu’un algorithme calcule bien ce qu’il est cens´e calculer ? Comment s’assurer qu’un algorithme termine quelle que soit les donn´ees
qui lui seront fournies en entr´ee ? Les algorithmes sont suffisamment formalis´es pour qu’on puisse prouver qu’ils poss`edent les propri´et´es attendues de
correction ou de terminaison. Les preuves sont facilit´ees lorsque les algorithmes sont bien ´ecrits, et en particulier s’ils sont d´ecompos´es en de nombreux sous algorithmes courts et bien sp´ecifi´es.
Ce sont bien ´evidemment les structures it´eratives et les appels r´ecursifs
qui n´ecessitent le plus de travail.
2.1.1
Preuve de la correction d’une structure it´
erative
Consid´erons le sch´ema d’algorithme suivant :
7
8
CHAPITRE 2. ANALYSE DES ALGORITHMES
Algorithme 1: Structure it´erative g´en´erique
r´
esultat : R
d´
ebut
Initialisation
# Point A
tant que Condition faire
# Point B1
Instructions
# Point B2
fintq
# Point C
fin
Un invariant de boucle est une propri´et´e ou une formule logique,
– qui est v´erifi´ee apr`es la phase d’initialisation,
– qui reste vraie apr`es l’ex´ecution d’une it´eration,
– et qui, conjointement `a la condition d’arrˆet, permet de montrer que le
r´esultat attendu est bien celui qui est calcul´e.
Exemple 1 Pour l’algorithme InsertionOrdonn´
ee du chapitre pr´ec´edent,
qui ins`ere un ´el´ement x dans un tableau tri´e T [1, n], consid´erons la propri´et´e
I suivante :
la juxtaposition des tableaux T [1, i] et T [i + 2, n + 1] 1 est ´egale
au tableau initial et x est plus petit que tous les ´el´ements du
deuxi`eme tableau 2 �.
�
1. La propri´et´e est v´erifi´ee apr`es l’initialisation (point A) puisque T [1, i]
est ´egal au tableau initial (i = n), et que le second tableau T [i+2, n+1]
est vide.
2. Si la propri´et´e I est vraie au d´ebut d’une it´eration (point B1), elle est
vraie `
a la fin de cette it´eration (point B2) puisque le dernier ´el´ement
T [i] du premier tableau passe en tˆete du second (l’ordre n’est pas
modifi´e), que l’on a x < T [i] et que l’indice est modifi´e en cons´equence.
Si la condition reste vraie, alors la propri´et´e est donc v´erifi´ee au d´ebut
de l’it´eration suivante.
3. Si la condition est fausse (point C), on peut montrer que
x est ≥ `
a tous les ´el´ements du premier tableau.
En effet,
1. si m > n, T [m, n] d´esigne un tableau vide.
2. propri´et´e vraie si le deuxi`eme tableau est vide.
2.1. PREUVES DE LA CORRECTION D’UN ALGORITHME
9
– c’est vrai si i = 0, car le premier tableau est vide,
– c’est vrai si i > 0 et x ≥ T [i], car le tableau T [1, i] est tri´e.
Comme l’invariant est vrai, x est `a la fois ≥ `a tous les ´el´ements de
T [1, i] et < `
a tous les ´el´ements de T [i + 2, n + 1]. Il suffit donc d’´ecrire
T [i + 1] = x pour obtenir le r´esultat attendu.
Remarque : Pour prouver la correction d’une boucle Pour, on peut
remarquer que
Pour i:=1 `
a n faire
Instructions
´equivaut `
a
i:=1
Tant que i<= n faire
Instructions
i:=i+1
et utiliser la technique pr´ec´edente.
Exemple 2 Pour prouver la correction de l’algorithme TriParInsertion,
on consid`ere l’invariant de boucle suivant :
�
T [1, j − 1] est tri´e �.
1. Apr`es l’initialisation, la propri´et´e est vraie puisque j = 2 et que le
tableau T [1, j − 1] ne contient qu’un seul ´el´ement.
2. Supposons que T [1, j − 1] soit tri´e au d´ebut d’une it´eration. Apr`es
appel de l’algorithme InsertionOrdonn´
ee, le tableau T [1, j] est tri´e.
Apr`es l’incr´ementation de j, le tableau T [1, j − 1] est tri´e.
3. Si la condition devient fausse, c’est que j = n + 1. Le tableau T [1, n]
est donc tri´e.
2.1.2
Preuve de correction d’un algorithme r´
ecursif
On prouve la correction d’un algorithme r´ecursif au moyen d’un raisonnement par r´ecurrence.
Exemple 3 Pour prouver la correction de l’algorithme rechercheDichotomique,
on effectue une r´ecurrence sur le nombre N = n − m + 1 d’´el´ements du tableau.
– si N = 1, alors m = n et on v´erifie que l’algorithme est correct dans
ce cas ;
10
CHAPITRE 2. ANALYSE DES ALGORITHMES
– soit N ≥ 1. Supposons que le programme soit correct pour tout tableau
de longueur ≤ N et consid´erons un tableau T [m, n] de N +1 ´el´ements :
n − m + 1 = N + 1. En particulier, m �= n puisque N ≥ 1. Soit
k = � m+n
es en
2 �. On a m ≤ k < n. Donc, les deux tableaux pass´
argument des appels r´ecursifs ont au plus N ´el´ements. En effet, le
premier a k − m + 1 ´el´ements et k − m + 1 ≤ n − m ≤ N ; le second a
n − k ´el´ements et n − k ≤ n − m ≤ N . Par hypoth`ese de r´ecurrence,
quelque soit le r´esultat du test T [k] < x, l’algorithme donnera une
r´eponse correcte.
2.1.3
Exercices
1. Recherche du plus grand ´el´ement d’un tableau (version it´erative) :
Algorithme rechercheMaxIter: Recherche it´erative du plus grand
´el´ement d’un tableau
entr´
ee : T [1, n] est un tableau d’entiers.
sortie : le plus grand ´el´ement de T [1, n].
d´
ebut
M ax := T [1]
pour i = 2 `
a n faire
si T [i] > M ax alors
M ax := T [i]
finsi
finpour
retourner M ax
fin
(a) Remplacez la structure it´erative Pour par un Tant que.
(b) Trouvez l’invariant de boucle.
(c) Prouvez la correction de l’algorithme.
2. Recherche du plus grand ´el´ement d’un tableau (version r´ecursive) :
´ DES ALGORITHMES
2.2. COMPLEXITE
11
Algorithme rechercheMaxRec: Recherche r´ecursive du plus grand
´el´ement d’un tableau
entr´
ee : T [1, n] est un tableau d’entiers.
sortie : le plus grand ´el´ement de T [1, n].
d´
ebut
si n = 1 alors
retourner T [1]
sinon
retourner M ax(T [n], M axRec(T [1, n − 1]))
finsi
fin
(a) Prouvez la correction de l’algorithme par r´ecurrence sur le nombre
d’´el´ements du tableau.
2.2
Complexit´
e des algorithmes
En plus d’ˆetre correct, c’est-`
a-dire d’effectuer le calcul attendu, on demande `
a un algorithme d’ˆetre efficace, l’efficacit´e ´etant mesur´ee par le temps
que prend l’ex´ecution de l’algorithme ou plus g´en´eralement, par les quantit´es de ressources n´ecessaires `
a son ex´ecution (temps d’ex´ecution, espace
m´emoire, bande passante, . . . ).
Le temps d’ex´ecution d’un algorithme d´epend ´evidemment de la taille
des donn´ees fournies en entr´ee, ne serait-ce que parce qu’il faut les lire avant
de les traiter. La taille d’une donn´ee est mesur´ee par le nombre de bits
n´ecessaires `
a sa repr´esentation en machine. Cette mesure ne d´epend pas du
mat´eriel sur lequel l’algorithme sera programm´e.
Mais comment mesurer le temps d’ex´ecution d’un algorithme puisque
les temps de calcul de deux impl´ementations du mˆ
eme algorithme sur deux
machines diff´erentes peuvent ˆetre tr`es diff´erents ? En fait, quelle que soit la
machine sur laquelle un algorithme est impl´ement´e, le temps de calcul du
programme correspondant est ´egal au nombre d’op´erations ´el´ementaires effectu´ees par l’algorithme, `
a un facteur multiplicatif constant pr`
es, et ce,
quelle que soit la taille des donn´ees d’entr´ee de l’algorithme. Par op´erations
´el´ementaires on entend les ´evaluations d’expressions, les affectations, et plus
g´en´eralement tous les traitements en temps constant ou ind´ependant de l’algorithme (entr´ees-sorties, . . . ). Le d´etail de l’ex´ecution de ces op´erations au
niveau du processeur par l’interm´ediaire d’instructions machine donnerait
des r´esultats identiques `
a un facteur constant pr`es.
12
CHAPITRE 2. ANALYSE DES ALGORITHMES
Autrement dit, pour toute machine M, il existe des constantes m et M
telles que pour tout algorithme A et pour toute donn´ee d fournie en entr´ee de
l’algorithme, si l’on note T (d) le nombre d’op´erations ´el´ementaires effectu´ees
par l’algorithme avec la donn´ee d en entr´ee et TM (d) le temps de calcul du
programme impl´ementant A avec la donn´ee d en entr´ee,
mT (d) ≤ TM (d) ≤ M T (d).
Soit, en utilisant les notations de Landau (voir section 8.1),
T = Θ(TM ).
On peut donc d´efinir la complexit´e en temps d’un algorithme comme le
nombre d’op´erations ´el´ementaires T (n) effectu´ees lors de son ex´ecution sur
des donn´ees de taille n. Il s’agit donc d’une fonction. On distingue
– la complexit´e dans le pire des cas (worst case complexity) : Tpire (n)
est le nombre d’op´erations maximal calcul´e sur toutes les donn´ees de
taille n ;
– la complexit´e dans le meilleur des cas (best case complexity) : Tmin (n)
est le nombre d’op´erations minimal calcul´e sur toutes les donn´ees de
taille n ;
– la complexit´e en moyenne (average case complexity) : Tmoy (n) le nombre
d’op´erations moyen calcul´e sur toutes les donn´ees de taille n, en supposant qu’elles sont toutes ´equiprobables.
Analyser un algorithme consiste `a ´evaluer la ou les fonctions de complexit´e qui lui sont associ´ees. En pratique, on cherche `a ´evaluer le comportement asymptotique de ces fonctions relativement `a la taille des entr´ees (voir
section 8.1). En consid´erant le temps d’ex´ecution, dans le pire des cas ou en
moyenne, on parle ainsi d’algorithmes
– en temps constant : T (n) = Θ(1),
– logarithmiques : T (n) = Θ(log n),
– polylogarithmiques : T (n) = Θ((log n)c ) pour c > 1,
– lin´eaires : T (n) = Θ(n),
– quasilin´eaires : T (n) = Θ(n log n),
– quadratiques : T (n) = Θ(n2 ),
– polynomiaux : T (n) = Θ(nk ) pour k ∈ N,
– exponentiels : T (n) = Θ(k n ) pour k > 1.
Si un traitement ´el´ementaire prends un millioni`eme de seconde, le tableau
suivant d´ecrit les temps d’ex´ecutions approximatifs de quelques classes de
probl`emes en fonction de leurs tailles
´ DES ALGORITHMES
2.2. COMPLEXITE
Taille n/ T (n)
10
100
1000
104
105
106
log2 n
0.003 ms
0.006 ms
0.01 ms
0.013 ms
0.016 ms
0.02 ms
n
0.01 ms
0.1 ms
1 ms
10 ms
100 ms
1s
13
n log2 n
0.03 ms
0.6 ms
10 ms
0.1 s
1.6 s
20 s
n2
0.1 ms
10 ms
1s
100 s
3 heures
10 jours
2n
1 ms
1014 siecles
D’un autre point de vue, le tableau ci-dessous donne la taille des probl`emes
de complexit´e T que l’on peut traiter en une seconde en fonction de la
rapidit´e de la machine utilis´ee (F est le nombre d’op´erations ´el´ementaires
ex´ecut´ees par secondes).
F /T (n)
106
107
109
1012
2n
20
23
30
40
n2
1.000
3.162
31.000
106
n log2 n
63.000
600.000
4.107
3.1010
n
106
107
109
log2 n
10300.000
103.000.000
En pratique, un algorithme est constitu´e d’instructions agenc´ees `a l’aide
de structures de contrˆ
ole que sont les s´equences, les embranchements et les
boucles (nous verrons plus tard comment traiter le cas particulier des fonctions r´ecursives, mais de toutes fa¸cons toute fonction r´ecursive s’´ecrit aussi
it´erativement).
– Le coˆ
ut d’une s´equence de traitements est la somme des coˆ
uts de
chaque traitement.
– Le coˆ
ut d’une structure it´erative est la somme des coˆ
uts des traitements effectu´es lors des passages successifs dans la boucle. Par exemple
il arrive fr´equemment que l’on effectue n fois une boucle avec des coˆ
uts
d´egressifs (Cn, C(n − 1),. . . , C). Dans ce cas
T (n) = C(n+(n−1)+(n−2)+. . .+1) = C
n
�
i=1
i = C
n(n + 1)
= Θ(n2 ).
2
– Le coˆ
ut d’un embranchement (si test alors traitement1 sinon
traitement2) est le coˆ
ut du plus coˆ
uteux des deux traitements.
14
2.2.1
CHAPITRE 2. ANALYSE DES ALGORITHMES
Exemples d’analyse d’algorithmes
Taille d’un tableau
Un tableau de n constantes de taille k (entiers, r´eels, . . .) a une taille
de kn. Mais on peut facilement d´emontrer que f (n) = Θ(g(n)) ssi f (kn) =
Θ(g(kn)), lorsque g est constante, lin´eaire, quasilin´eaire ou polynomiale.
Par ailleurs, si f (n) est exponentielle, c’est a fortiori aussi le cas de f (kn).
On pourra donc supposer, dans les calculs de complexit´e, que la taille d’un
tableau de n ´el´ements constants est n.
L’algorithme d’insertion d’un ´
el´
ement dans un tableau tri´
e
Dans le pire des cas, celui o`
u l’entier `a ins´erer est plus petit que tous les
´el´ements du tableau, l’algorithme InsertionOrdonn´
ee requiert
– 2n + 2 affectations,
– 2n + 1 comparaisons d’entiers,
– n soustractions et n + 1 addition,
– n + 1 ´evaluations d’une expression bool´eenne
pour un tableau de n ´el´ements.
En supposant de plus que chaque instruction ´el´ementaire s’ex´ecute en un
temps constant, on en d´eduit que Tpire (n) = Θ(n). L’algorithme d’insertion
ordonn´ee est lin´eaire dans le pire des cas : `a des constantes additives et
multiplicatives pr`es, le temps d’ex´ecution est ´egal au nombre d’´el´ements du
tableau.
On voit facilement que Tmin (n) = Θ(1) : en effet, dans le meilleur des
cas, l’´element `
a ins´erer est plus grand que tous les ´el´ements du tableau et la
boucle n’est pas ex´ecut´ee.
Si l’on suppose que l’´el´ement `a ins´erer et un ´el´ement pris au hasard dans
le tableau, son insertion n´ecessitera en moyenne n/2 comparaisons. On aura
donc, Tmoy (n) = Θ(n), soit une complexit´e moyenne du mˆeme ordre que la
complexit´e du pire des cas.
L’algorithme de tri par insertion
Dans le pire des cas, celui o`
u le tableau en entr´ee est d´ej`a tri´e, mais par
ordre d´ecroissant, l’algorithme n´ecessite
– n − 1 comparaisons et affectations pour la condition de la boucle Pour
– n − 1 appels `
a l’algorithme d’insertion ordonn´ee, pour des tailles de
tableaux variant de 1 `a n − 1.
´ DES ALGORITHMES
2.2. COMPLEXITE
15
A des constantes additives et multiplicatives pr`es, le temps d’ex´ecution
dans le pire des cas de l’algorithme de tri par insertion est donc ´egal `a
(n − 1) + 1 + 2 + . . . + (n − 1) = n − 1 +
n(n − 1)
= Θ(n2 )
2
soit en appliquant la remarque sur l’´egalit´e `a des constantes additives et
multiplicatives pr`es de la taille des donn´ees et du nombre d’´el´ements du
tableau,
Tpire (n) = Θ(n2 ).
On voit facilement que Tmin (n) = Θ(n), cas o`
u le tableau est d´ej`a ordonn´e par ordre croissant. En effet, chaque appel `a l’algorithme d’insertion
ordonn´ee est ex´ecut´e en temps constant.
Si tous les ´el´ements du tableau en entr´ee sont tir´es selon la mˆeme loi
de probabilit´es, on peut montrer que Tmoy (n) = Θ(n2 ). Autrement dit, s’il
peut arriver que le temps d’ex´ecution soit lin´eaire, il y a beaucoup plus de
chance qu’il soit quadratique en la taille des donn´ees en entr´ee.
L’algorithme de recherche dichotomique
Si le tableau contient un seul ´el´ement, l’algorithme ex´ecutera 2 comparaisons (coˆ
ut total : c1 )
Si le tableau contient n > 1 ´el´ements, l’algorithme ex´ecutera
– 3 op´erations arithm´etiques, une affectation et une comparaison entre
2 entiers (coˆ
ut total : c2 ), et
– un appel r´ecursif sur un tableau poss´edant �n/2� ou �n/2� ´el´ements,
soit �n/2� dans le pire des cas.
On en d´eduit que si n > 1,
Tpire (n) = Tpire (�n/2�) + c2 .
Cette ´equation est simple `
a r´esoudre lorsque n est ´egal `a une puissance
de 2 :
Tpire (2h ) = Tpire (2h−1 ) + c2 = Tpire (2h−2 ) + 2c2 = . . . = c1 + hc2 .
Dans le cas g´en´eral, soit
n = a h 2h + . . . + a 1 21 + a 0
l’´ecriture de n en base 2 : ah = 1 et 0 ≤ ai ≤ 1 pour 0 ≤ i < h. On a
2h ≤ n < 2h+1 et donc 2h−1 ≤ �n/2� ≤ 2h .
16
CHAPITRE 2. ANALYSE DES ALGORITHMES
On en d´eduit que
c1 + hc2 ≤ Tpire (n) ≤ c1 + (h + 1)c2 .
En remarquant que h = Θ(log2 n), on en d´eduit que Tpire (n) = Θ(log2 n).
La recherche dichotomique d’un ´el´ement dans un tableau tri´e se fait donc
en temps logarithmique.
L’analyse d’algorithmes conduit souvent `a des ´equations r´ecursives de la
forme
T (n) = aT (�n/b�) + f (n) ou aT (�n/b�) + f (n)
(2.1)
o`
u b > 1, a > 0 et f est une fonction. Le th´eor`eme 2 de la section 8.2 donne
la solution de ces ´equations dans le cas g´en´eral. Dans l’exemple pr´ec´edent,
on se trouve dans le cas (2) du th´eor`eme, avec a = 1 et b = 2 : on retrouve
que Tpire (n) = Θ(log2 n).
Il est essentiel de savoir utiliser ce th´eor`eme mais il est aussi utile de
pouvoir retrouver rapidement le r´esultat cherch´e. Nous d´ecrivons ci-dessous
quelques calculs approximatifs, `a partir de l’´equation simplifi´ee
T (n) = aT (n/b) + f (n),
(2.2)
qui recouvrent un grand nombre de cas courants.
– Si l’on it`ere k fois l’´equation 2.1, l’argument de T devient n/bk . On a
n/bk = 1 ssi k = logb n. Il faut environ logb n it´erations pour trouver
la constante de r´ef´erence T (1).
– Si a = 1, on a
T (n) = f (n) + f (n/b) + · · · + f (n/bk−1 ) + T (n/bk ).
– Si f (n) = c,
T (n) = kc + T (n/bk ).
On voit, en prenant k � logb n, que T (n) = θ(logb n).
– Si f (n) = n,
T (n) = n(1 + 1/b + · · · + 1/bk−1 ) + T (n/bk )
1
+ T (n/bk )
≤n
1 − (1/b)
b
=n
+ T (n/bk ).
b−1
On voit, en prenant k � logb n, que T (n) = θ(n).
´ DES ALGORITHMES
2.2. COMPLEXITE
17
– Si a = b, on a
T (n) = f (n) + bf (n/b) + · · · + bk−1 f (n/bk−1 ) + bk T (n/bk ).
– Si f (n) = c,
T (n) = 1 + b + · · · + bk−1 + bk T (n/bk ) =
bk − 1
+ bk T (n/bk ).
b−1
On voit, en prenant k � logb n, soit bk � n, que T (n) = θ(n).
– Si f (n) = n,
T (n) = n(1 + 1 + · · · + 1) + bk T (n/bk ) = nk + bk T (n/bk ).
On voit, en prenant k � logb n, que T (n) = θ(n logb n).
– Si a > b, on peut ´ecrire a = bh avec h > 1. On a
T (n) = f (n) + af (n/b) + · · · + ak−1 f (n/bk−1 ) + ak T (n/bk ).
– Si f (n) = c,
T (n) = 1 + a + · · · + ak−1 + ak T (n/bk ) =
ak − 1
+ ak T (n/bk ).
a−1
On voit, en prenant k � logb n, soit bk � n et ak � nh , que T (n) =
θ(nh ).
– Si f (n) = n,
T (n) = 1 + a/b + · · · + (a/b)k−1 + ak T (n/bk ) ≤ (a/b)k + ak T (n/bk ).
On voit, en prenant k � logb n, que T (n) = θ(nh ).
Ce que l’on peut r´esumer dans le tableau suivant,
T (n)
f (n) = c
f (n) = n
a=1
logb n
n
a=b
n
n logb n
Pour les autres cas, utilisez le th´eor`eme.
a = bh
nh
nh
18
CHAPITRE 2. ANALYSE DES ALGORITHMES
Le tri par fusion
Le tri par fusion est un algorithme qui applique la strat´egie “diviser pour
r´egner ”. Le tableau a` trier est divis´e en deux sous-tableau de mˆeme taille
(`
a un ´el´ement pr`es), l’algorithme est appel´e r´ecursivement sur chacun de ces
sous-tableaux, et les tableaux r´esultants sont alors fusionn´es.
Algorithme TriFusion: Tri par fusion
entr´
ee : T [1, n] est un tableau d’entiers, n ≥ 1.
r´
esultat : les ´el´ements de T sont ordonn´es par ordre croissant.
d´
ebut
si n > 1 alors
T1 := triF usion(T [1, �n/2�])
T2 := triF usion(T [�n/2� + 1, n])
T := F usion(T1 , T2 )
finsi
fin
On peut montrer que l’algorithme de fusion est lin´eaire en fonction du
nombre n d’´el´ements. Soit T (n) la complexit´e de l’algorithme en fonction de
n. L’´equation de r´ecurrence correspondante est
T (n) = T (�n/2�) + T (�n/2�) + n + c.
M´
ethode g´
en´
erale (voir le th´
eor`
eme 2 de la section 8.2). On est
dans le cas 2 puisque : f (n) = n + c, a = b = 2, logb a = 1 et f (n) = O(n).
Donc T (n) = Θ(n log2 n).
Solution en d´
eveloppant directement la r´
ecurrence.
On peut consid´erer l’´equation plus simple suivante : T (n) = 2T (n/2)+n.
On a :
T (n) = 2T (n/2) + n = 4T (n/4) + 2n = · · · = 2k T (n/2k ) + kn.
Les appels r´ecursifs se terminent lorsque n � 2k , soit k � log2 (n) : il y a
au plus log2 (n) appels r´ecursifs imbriqu´es. On en d´eduit que
T (n) � nc + n log2 (n).
Le terme dominant ´etant n log2 (n), on en d´eduit que
T (n) = Θ(n log2 (n)).
´ DES ALGORITHMES
2.2. COMPLEXITE
19
n
2x n
n/2
hauteur : �log2 n�
2x n
n/2
log n
n/4
n/8
1
n/4
n/8
1 1
n/8
n/4
n/8 n/8
2x n
n/4
n/8 n/8
n/8
....
Figure 2.1 – Arbre des appels r´ecursifs pour l’algorithme de tri par fusion.
Solution intuitive. On remarque que l’ex´ecution de la proc´edure produit
le parcours d’un arbre virtuel de profondeur �log2 n�, et qu’`a chaque niveau
de l’arbre on effectue Θ(n) traitements (2p noeuds `a chaque niveau, et des
suites de longueurs n/(2p ) ´el´ements en chaque noeud). On pressent donc
intuitivement que le coˆ
ut est quelque chose de la forme nlog2 n. Mais il peut
aussi y avoir des termes de classe inf´erieure. On va donc partir sur une forme
compl`ete de T (n) avec des constantes
T (n) = a · n log2 n + bn + c.
Nous essayons ensuite de fixer les constantes au moyen de l’´equation de
r´ecurrence et des premi`eres valeurs de T . On a :
T (n) = a · n log2 n + bn + c
= 2T (n/2) + n
= 2[a · n/2 log2 n/2 + bn/2 + c] + n
= a · n log2 n − an + bn + 2c + n.
On en d´eduit que a = 1 et c = 0. Si l’on sait que T (1) = 1, on peut
prendre b = 1. Donc
T (n) = n log2 n + n = Θ(n log2 n).
2.2.2
Exercices
Exercice 1 Montrez que
1. n log n = O(n2 ),
2. n log n = Ω(n),
3. n + sin(n) ∼ n.
20
CHAPITRE 2. ANALYSE DES ALGORITHMES
4. A t-on 2n = Θ(en ) ?
5. A t-on elog2 (n+1) = o(n) ?
Exercice 2 Quelles sont les classes de complexit´e des fonctions suivantes :
1. f (n) = 2n3 + 4n2 + 23 ,
2. f (n) = log (n2 + 3n − 1),
3. f (n) = 2
log2 (n2 +1)
2
.
Exercice 3 Quelle est la complexit´e de la fonction bidon suivante :
d´
ebut
pour i := 1 `
a n ∗ n faire
u := i
tant que u > 1 faire
u := u/2
fintq
finpour
fin
Exercice 4 Calculez la complexit´e de la fonction qui calcule le produit de
deux matrices carr´ees A et B de n lignes et n colonnes.
Exercice 5 Calculer la complexit´e de la fonction exp(x, n) qui calcule xn
a partir de la formule suivante :
`
�
n/2
(x2 )
si n est pair,
n
x =
n−1
x×x
si n est impair.
En utilisant ce principe, quel est le coˆ
ut de l’´el´evation d’une matrice `a
la puissance n.
´
Exercice 6 Ecrivez
un algorithme qui prend en entr´ee une matrice carr´ee
n × n et retourne la liste des coordonn´ees des cases dont la valeur est `a
la fois maximale sur leur ligne et minimale sur leur colonne. Quelle est la
complexit´e de cet algorithme ?
Exercice 7 : Calcul de l’´el´ement majoritaire d’un tableau.
Etant donn´e un ensemble E de n ´el´ements, on veut savoir s’il existe un
´el´ement majoritaire, c’est-`a-dire un ´el´ement dont le nombre d’occurrences k
est strictement sup´erieur `a n/2, et dans ce cas, le d´eterminer.
´ DES ALGORITHMES
2.2. COMPLEXITE
21
M´
ethode na¨ıve Proposez une m´ethode naive pour ce calcul. Quelle est sa
complexit´e ?
M´
ethode 2 : diviser pour r´
egner. On consid`ere maintenant l’approche
suivante, bas´ee sur le principe diviser pour r´egner : pour rechercher
l’´el´ement majoritaire ´eventuel dans l’ensemble E, on r´epartit les n
´el´ements de E dans deux ensembles (approximativement) de mˆemes
tailles E1 et E2 , et on recherche l’´el´ement majoritaire de chacun d’entre
eux. Un ´el´ement est majoritaire dans E si et seulement si
– il est majoritaire dans E1 et dans E2 , ou si
– il est majoritaire dans l’un d’entre eux et apparaˆıt suffisamment
souvent dans l’autre.
Ecrivez une proc´edure de calcul correspondant `a cette id´ee. Quelle est
sa complexit´e ?
Une troisi`eme m´ethode sera propos´ee au chapitre suivant.
22
CHAPITRE 2. ANALYSE DES ALGORITHMES