Vous êtes sur la page 1sur 238

Algorithmique et structures de donnes

Hicham Bensaid

Plan

Prliminaires
Algorithmique et analyse des algorithmes
Structures de donnes
Stratgies

Premire partie
Prliminaires

Plan

Motivations
Qu'est ce qu'un algorithme ?
Algorithmique

Introduction

Nous allons traiter dans ce cours les notions suivantes :


Algorithmes,
algorithmique et
structures de donnes.
Le cours est largement fond sur (et inspir de) les livres :
Fundamentals of Algorithmics, G. Brassard and P. Bratley
Introduction to Algorithms, Third Edition, T. H. Cormen, C.
E. Leiserson, R. L. Rivest and C. Stein

Plan

Motivations
Qu'est ce qu'un algorithme ?
Algorithmique

Un algorithme c'est quoi ? : les origines

Origine du nom : le mathmaticien AL KHAWARIZMI

(premire

formalisation

de

mthodes systmatiques

de

rsolution (de 6 types) d'quations de manire algbrique)

ax 2
ax 2
bx
ax 2 + bx
ax 2 + c
bx + c

=
=
=
=
=
=

bx
c
c
c
bx
ax 2

Un ensemble de rgles pour eectuer un calcul ( la main ou


par une machine) : mthode systmatique de rsolution.
Le rsultat du calcul doit tre correct.
Exemples : les mthodes pour faire des additions, des
soustractions, des multiplications, ... (ou de rsolution
d'quations)
Un exemple trs clbre (et trs ancien) : l'algorithme
d'Euclide de calcul du pgcd de 2 entiers

Un algorithme c'est quoi ? : la correction et le dterminisme

L'excution d'un algorithme doit rendre un rsultat correct


L'excution d'un algorithme ne doit normalement pas contenir
de dcisions subjectives

pas d'intuition ni crativit

Une recette de cuisine peut tre considre comme un


algorithme si elle dcrit prcisment comment raliser un
certain plat

(en donnant exactement les quantits et les instructions


dtailles, le temps de cuisson, . . . )

En revanche, si elle inclut des notions vagues comme ajouter


du sel selon le got ou faire cuire jusqu' ce que a soit tendre,
on ne peut plus parler d'algorithme

Algorithmes probabilistes

Une exception la rgle prcdente


Un algorithme probabiliste peut faire des choix alatoires
mais alatoire 6= arbitraires
alatoire = selon une loi de probabilit
On utilise pour cela des gnrateur pseudo-alatoires

Algorithmes approximatifs

Les rgles de calcul d'un algorithme doivent (si appliques


correctement) retourner un rsultat correct.
Mais parfois (dans certaines circonstances) des algorithmes
approximatifs peuvent tre utiles.
e.g. aucunpalgorithme ne peut retourner une valeur dcimal
exacte de 2

mais un algorithme qui fournit une rponse aussi prcise que


souhaite est trs utile

Heuristiques

Plus encore, certains problmes n'ont pas d'algorithmes


pratiques connus
utiliser un des algorithmes disponibles demande beaucoup trop
de temps (des sicles)

Dans ce cas on doit chercher un ensemble de rgles (calcul) qui


donneraient (en tout cas on l'espre) une

bonne approximation

du rsultat correct et ce dans un temps raisonnable.

Si on peut prouver que le rsultat calcul n'est pas trop

mauvais c'est bien

Parfois mme ceci n'est pas possible : on dpend de la


chance :o)

Ce genre de procdures fondes largement sur

support thorique minimal


algorithme heuristique ou heuristique.

souvent avec un

l'optimisme

s'appelle

et

Algorithmes approximatifs vs heuristiques

La dirence majeure entre algorithmes d'approximation et


heuristiques :
avec un algorithme approximatif on peut spcier l'erreur
qu'on accepte
avec une heuristique on ne peut pas contrler l'erreur (mais on
peut estimer son importance)

Plan

Motivations
Qu'est ce qu'un algorithme ?
Algorithmique

Algorithmique (1)

L'algorithmique est l'tude des algorithmes


En particulier comment choisir le bon algorithme pour
rsoudre un problme quand plusieurs sont disponibles ?

e. g. celui qui utilise le moins de temps, le moins d'espace, le


plus simple programmer, . . .

La rponse peut dpendre de plusieurs facteurs :

e.g. les donnes concerns, la manire de prsenter le


problme, la vitesse et taille de stockage de la machine, . . .

Parfois (souvent) aucun algorithme disponible n'est


compltement adquat pour rsoudre un problme donn

il faut alors concevoir un nouvel algorithme.

Algorithmique (2)

L'algorithmique est la science qui permet d'valuer les eets de


ces multiples facteurs externes sur les algorithmes disponibles

objectif : choisir l'algorithme le plus adquat dans une


situation donne

L'algorithmique est aussi la science qui montre comment


concevoir un algorithme pour une tche donne.
L'algorithmique tudie galement les mthodes pour prouver
qu'un algorithme fait bien ce qu'il est cens faire.

Exemple : la multiplication des entiers

La mthode classique

1
9
2

2
9
8
1

1
3
9
6
1
0

9
2
9
4
2

8
3
2
3

1
4
4

La multiplication l'amricaine
(et la marocaine)

9
1

8
9
2

1
1
6
9
3
0

9
2

2
4
9
5

8
3

3
2
5

1
4

4
4

La multiplication l'anglaise

Exemple : la multiplication des entiers


La multiplication la russe
981
490
245
122
61
30
15
7
3
1

1234
2468
4936
9872
19744
39488
78976
157952
315904
631808

1234
4936
19744
78976
157952
315904
631808
1210554

1234 + 4936 + 19744 + 78976 + . . . + 631808 = 1210554

Exemple : la multiplication des entiers


La multiplication la russe
Algorithme utilis dans les calculatrices
Pas besoin de mmoriser les tables de multiplications

oprations ncessaire : additions + division par

981 1234

L'ide :

=
=
=
=
=
=
...

((490 2) + 1) 1234
(490 (2 1234)) + 1234
((245 2) (2 1234)) + 1234
(245 (4 1234)) + 1234
((122 2 + 1) (4 1234)) + 1234
(122 (8 1234)) + (4 1234) + 1234

Exemple : la multiplication des entiers


La multiplication par la stratgie diviser pour rgner
Prcondition : les deux oprandes ont le mme nombre de
chires qui doit tre une puissance de 2 (sinon on ajoute des 0
en tte)
L'ide :

0981 1234 = 09.102 + 81.100 12.102 + 34.100

= 09.102 12.102 + 09.102 34.100 +

81.100 12.102 + 81.100 34.100

= (09 12) .104 + (09 34) 102 +

(81 12) .102 + (81 34) .100

En
gnral :

n
n
n
A.10 2 + B C .10 2 + D = A.C .10n + (A.D + B.C ) .10 2 + B D

... mais on peut faire mieux ... :

= A.C .10n + ((A B ) (D C ) + AC + B D) .10 2 + B.D

c'est mieux ?)

(pourquoi

Exemple : la multiplication des entiers


0981 1234 par la stratgie diviser pour rgner

i
ii
iii
iv

Multiplier Dcaler
09
09
81
81

12
34
12
34

Rsultat
1 0 8
3 0 6
9 7 2
2 7
1 2 1 0 5

4
2
2
0

5
5

4
4

09 12 par la stratgie diviser pour rgner

i
ii
iii
iv

Multiplier Dcaler
0
0
9
9

1
2
1
2

2
1
1
0

Rsultat
0
0
9
1
1 0

8
8

Exemple : la multiplication des entiers

Le problme a t rduit d'une multiplication de deux entiers


de 4 chires en 4 (ou 3 selon la version) additions de
multiplications de 2 chires
La multiplication de 2 entiers de deux chires peut se faire
exactement de la mme manire (rduction vers une
multiplication de 2 entiers d'un chire)

Ce qu'il faut retenir de l'exemple

Mme pour un exemple d'arithmtique lmentaire trs simple


on peut avoir plusieurs algorithmes :

L'avantage du premier : la familiarit

L'avantage du deuxime : les instructions lmentaires utiliser

L'avantage du troisime : l'ecacit (la version 3 additions)

l'algorithmique est la science qui aide faire le bon choix !


l'algorithmique s'intresse galement au problme : comment
prouver qu'un algorithme agit correctement ?

Preuve de correction

Deuxime partie
Algorithmique et analyse des algorithmes

Plan
Algorithmique lmentaire
Problmes et instances
Correction des algorithmes
L'ecacit des algorithmes
Notations asymptotique
Notation asymptotique standard
Notation asymptotique conditionnelle
Analyse des algorithmes
Analyse des structures de contrle
Rsolution des formules de rcurrence
Rcurrences homognes
Changement de variable

Problmes et instances

Nous avons vu plusieurs mthodes pour multiplier deux entiers


981 1234

Ces mthodes ne dpendent pas de l'exemple pris


Elle fournissent une solution gnrale au problme de
multiplication de deux entiers
(981, 1234) est une instance de ce problme ((302, 789) est une
autre instance)
Les problmes les plus intressants ont une innit d'instances
(des exceptions intressantes existent)
Un algorithme doit se comporter correctement sur toutes les
instances de son domaine de dnition

contre-exemple

correction d'un algo : besoin de preuve

indpendance des limites physiques sur les donnes (donnes


abstraites)

algo incorrect.

Correction des algorithmes : le tri par insertion comme


exemple
Comment prouver qu'un algorithme est correcte ?

1
2

Entre : un tableau T d'entiers


trier
Resultat : Le tableau T tri
procedure triParInsertion(T [1..n])
for i = 2 to n do

3
4
5
6
7

x = T [i ]
j = i 1
while j > 0 et x < T [ j ]
T [ j + 1] = T [ j ]
j = j 1

T [ j + 1] = x

do

Algorithme 1 : Tri par insertion

(ligne 2) est l'index de


l'lment courant insrer
Au dbut de chaque itration
indexe par i le sous tableau
T [1..i 1] est tri
T [i + 1..n] reste trier
T [1..i 1] est une
permutation des lments
initialement entre les
positions 1 et i 1
Ces proprits de T [1..i 1]
peuvent tre formules par
un invariant de boucle :
i

Invariants de boucle
Invariant de boucle P : Au dbut de chaque itration (les lignes
entre 2 et 5) T [1..i 1]contient les lments initiaux de T [1..i 1]
mais dans le bon ordre
Les invariants de boucle pour prouver qu'un algorithme est
correct
3 choses dmontrer propos d'un invariant de boucle P :
Initialisation P est vrai avant la premire itration
Maintenance Si P est vrai avant une itration alors P reste vrai
avant la prochaine itration
Terminaison la sortie de la boucle, P fournit une proprit utile
pour prouver la correction de l'algorithme

Correction du tri par insertion


Theorem (Correction du tri par insertion)
Le tri par insertion est correct.

Dmonstration.
preuve en utilisant l'invariant de boucle P
Initialisation i = 2. T [1..i 1] = T [1]. P est trivialement vrie
(T [1..1] est tri et est l'lment initial de T [1..1])
Maintenance de manire informelle la boucle for dcale vers la
droite les lments T [i 1], T [i 2], T [i 3], . . . et
remplace le trou par T [i ]
Terminaison la n i = n + 1 donc T [1..n] contient exactement les
lments initiaux de T tris dans le bon ordre, CQFD.

L'ecacit des algorithmes

Plusieurs solutions pour un mme problme

comment choisir la

meilleure ?

Parfois ce n'est pas important (une ou deux petites instances


d'un problme simple)
Mais en gnral (si plusieurs instances de tailles direntes +
problme complexe) il faut savoir faire le bon choix

Approches

Empirique (a posteriori)

Programmer les direntes solutions et les tester sur plusieurs


instances sur machine

Thorique (a priori)

dterminer

mathmatiquement

la quantit des ressources

ncessaires pour chaque algorithme comme fonction de la


taille des instances considres.

les ressources les plus intressantes = temps d'excution +


occupation mmoire

On s'intresse dans ce cours la comparaison des algos selon


leurs temps d'excution

Taille d'une instance

La taille d'une instance = nombre de bits ncessaires pour


reprsenter l'instance sur une machine (en utilisant un schma
de codage compact)
Pour des raisons de clart, dans ce cours nous serons moins
formels : le mot taille dsignera un entier qui en quelque sorte
mesure le nombre de composants dans l'instance
Exemple : nombre d'lments d'une liste, nombre de nuds et
d'artes dans un graphe, ...
Pour des algos sur les entiers, on utilise directement les valeurs
des entiers (au lieu de leurs tailles en nombre de bits)

a priori vs a posteriori

Avantages de l'approche thorique :


indpendance par rapport aux machines, langages de
programmation et comptence du programmeur
analyse universelle (pour toutes les tailles)
gain du temps : pas la peine de perdre du temps tester des
mthodes inecaces ...

Comment mesurer le temps d'excution ?

Pour mesurer l'occupation mmoire d'un programme : le bit


(indpendance % la machine)
Pour mesurer l'ecacit en terme de temps d'excution, la
rponse est moins vidente

en secondes ? mais par rapport quelle machine ?

La rponse : le principe d'invariance

Principe d'invariance

2 implmentations d'un mme algorithme ne dirent en


ecacit que par un facteur multiplicatif
Si 2 implmentations d'un mme algorithme prennent t1 (n) et
t 2 (n) secondes resp. alors n 0 N et c, d N constantes tq :

n > n 0 t 1 (n) c.t 2 (n)

et

t 2 (n) d .t 1 (n)

Ce principe ne peut pas tre dmontr mais est toujours


observable
Principe universel la machine, le langage de programmation,
la comptence du dveloppeur ...
Un changement de machine (ou de langage ou de dveloppeur)
peut amliorer la vitesse d'un algo par un facteur constant
Un changement d'algo en revanche (et uniquement un
changement d'algo) permet des amliorations (parfois
spectaculaires) en fonction de la taille des instances

Quelle unit pour reprsenter l'ecacit ?

Principe d'invariance pas d'unit pour cela

le temps d'excution est reprsent % une constante


multiplicative

Denition (Ordre du temps d'excution)


Soit un algorithme A qui rsout un problme P . Le temps
d'excution de A est en (ou dans l'ordre de) t (n) o t est une
fonction s'il existe une constante c et une implmentation I de A
capable d'excuter I sur n'importe quelle instance de taille n en un
temps qui ne dpasse pas c.t (n) [secondes].

Quelle unit pour reprsenter l'ecacit ?

l'usage des secondes est arbitraire (on aurait pu utiliser des


heures, jours, annes, . . . )
Nous tudierons plus en dtail cette notion fondamentale
connue sous le nom de notation asymptotique.
Certains ordres largement utiliss ont un nom : linaire (c.n ),
quadratique (c.n 2 ), cubique (c.n3), . . .
Attention aux constantes multiplicatives . . . l'ecacit
considre est asymptotique ...

Analyse des algorithmes

Analyse d'un algo = estimation des ressources dont il a besoin

mmoire, bande passante, matriel sont parfois important

mais souvent on s'intresse au temps de calcul

Permet de comparer entre plusieurs algos ...


Un modle de la technologie d'implmentation est ncessaire

On utilisera le modle RAM

Le modle RAM

un modle mono-processeur, avec mmoire RAM (Random


Access Memory) :
Contrle + Donnes
Les instructions sont excutes squentiellement, sans
concurrence
Les instructions supportes :

arithmtiques : addition, soustraction, multiplication, division,


reste, partie entire

transfert de donnes : charger, stocker, copier

contrle : tests conditionnels, appels de sous routines, retour

Chacune de ces instructions prend un temps constant

Les types de donnes : entiers et ottants

L'analyse en moyenne et au pire cas

1
2
3
4
5
6
7
8
9
10

Le temps (ou l'espace) ncessaire un algorithme peut varier


considrablement entre deux instances de mme taille
Exemple : tri par insertion vs tri par slection
Entre : un tableau T d'entiers trier
Resultat : Le tableau T tri
procedure triParInsertion(T [1..n])
for i = 2 to n do
x = T [i ]
j = i 1
while j > 0 et x < T [ j ]
T [ j + 1] = T [ j ]
j = j 1

do

end

T [ j + 1] = x

end

Algorithme 2 : Tri par insertion

L'analyse en moyenne et au pire cas


1
2
3
4
5
6
7
8
9
10
11
12
13

Entre : un tableau T d'entiers trier


Resultat : Le tableau T tri
procedure triParSelection(T [1..n])
for i = 1 n 1 do
mi n j = i
mi n x = T [i ]
for j = i + 1 to n do
if T [ j ] < mi n x then
mi n j = j
mi n x = T [ j ]

end
end

T [mi n j ] = T [i ]
T [i ] = mi n x

end

Algorithme 3 : Tri par selection

L'analyse en moyenne et au pire cas

: ordre croissant
= [7, 6, 5, 4, 3, 2, 1] : ordre dcroissant

U = [1, 2, 3, 4, 5, 6, 7]

C'est la

plus mauvaise conguration

pour les deux algorithmes

Tri par selection


Indpendence du nombre d'oprations (temps) du tri par
selection % l'ordre initial du tableau trier :

le test  if

T [ j ] < mi n x 

est excut le mme nombre de fois

la cong

La variation dpend du nombre de fois o le corps du if est


excut (mais c'est ngligeable)

L'analyse en moyenne et au pire cas

: ordre croissant
= [7, 6, 5, 4, 3, 2, 1] : ordre dcroissant

U = [1, 2, 3, 4, 5, 6, 7]

Tri par insertion


Comme x < U [ j ] est toujours fausse excution rapide et
temps linaire
Pour V : pour chaque i on excute i 1 fois le test de boucle

tremps quadratique

Pn

i =1 (i

1) = a.n 2 + b.n.c

La variation entre les temps d'excution de U et V est


importante

Analyse du tri par insertion

1
2
3
4
5
6
7
8
9

le temps de calcul T (n) du tri par insertion dpend de la taille


des donnes et de leur conguration
Le temps d'excution d'un algo sur une instance est le nombre
d'oprations primitives (pas) excutes.
Pour l'instant
chaque ligne de l'algo a besoin d'un temps
P
constant ni=2 t j

for i = 2 to n do
/* cot : c1 n
x = T [i ] ;
/* cot : c2 (n 1)
j = i 1 ;
/* cot : c3 (n 1)
P
while j > 0 et x < T [ j ] do
/* cot : c4 ni=2 t j
Pn
T [ j + 1] = T [ j ] ;
/* cot : c5 i =2 (t j 1)
P
j = j 1 ;
/* cot : c6 ni=2 (t j 1)
end
T [ j + 1] = x ;
/* cot : c8 (n 1)
end
Algorithme 4 : Tri par insertion

*/
*/
*/
*/
*/
*/
*/

Analyse du tri par insertion

T (n) = c 1 n + c 2 (n 1) + c 3 (n 1) + c 4
P
c 6 ni=2 (t j 1) + c 8 (n 1)

Pn

i =2 t j

+ c5

Pn

i =2 (t j

1) +

Dans le cas le plus favorable (T est tri dans le bon ordre) :


i , t i = 1 et donc
T (n) = (c 1 + c 2 + c 3 + c 4 + c 8 )n (c 2 + c 3 + c 4 + c 8 )

Dans le cas le plus dfavorable (T est tri dans l'ordre


inverse) : i , ti = i et donc T (n) = An + B n +C
En gnral, on s'intresse l'analyse dans le cas le plus
dfavorable
On utilise parfois l'analyse en moyenne galement (cf. variation
du tri par insertion)

Ordre de croissance (des fonctions)

Dans l'exemple prcdent, abstraction des ci :


T (n) = An + B n +C

n+C
2
comme n
lim BAn
2 = 0 : B n +C = o(A.n ) et peut tre ignor
(pour n assez grands)
par principe d'invariance, A peut galement tre ignor.
On dira que T (n) = (n )
Un algorithme T1 est plus ecace qu'un algorithme T2 si le
temps d'excution dans le cas le plus dfavorable de T1 a un
ordre de croissance infrieur celui de T2

Ecacit asymptotique

Mais attention aux termes ngligeables et autres constantes


pour les petites valeurs de n

Plan
Algorithmique lmentaire
Problmes et instances
Correction des algorithmes
L'ecacit des algorithmes
Notations asymptotique
Notation asymptotique standard
Notation asymptotique conditionnelle
Analyse des algorithmes
Analyse des structures de contrle
Rsolution des formules de rcurrence
Rcurrences homognes
Changement de variable

Notation asymptotique

Fonctions de domaine N

les tailles en gnral correspondent des entiers : nombres


d'lments, de bits, valeurs des entiers, ...

Asymptotique car on va traiter le comportement des fonctions


la limite

Pour des paramtre susement grands

L'analyse peut devenir inutile (ou errone) pour des petites


valeurs des paramtres
L'analyse asymptotique est quand mme utile car un
algorithme asymptotiquement meilleur est souvent (mais pas
toujours) meilleur pour des donnes intermdiaires

La notation
(g (n)) = { f (n)|c 1 , c 2 constanteset n 0 , 0 c 1 .g (n) f (n)
c 2 .g (n), n n 0 }

Pour une constante (ou fonction constante) : (1)


On crit f (n) = (g (n)) pour signier f (n) (g (n))

La notation O
La notation borne une fonction par le haut et par le bas
Quand nous n'avons qu'une borne suprieure asymptotique,
nous utilisons la notation O
O(g (n)) = { f (n)|c constanteet n 0 , f (n) c.g (n), n n 0 }
On crit f (n) = O(g (n)) pour signier f (n) O(g (n)) ( f (n) est dans
dans l'ordre de g (n))

La notation

La notation fournit une borne infrieure asymptotique

(g (n)) = { f (n)|c constanteet n 0 , c.g (n) f (n), n n 0 }


On crit f (n) = (g (n)) pour signier f (n) (g (n))

Thorme
Soient f (n), g (n) deux fonctions. f (n) = (g (n)) ssi f = O(g (n)) et
f (n) = (g (n)).

o et

o(g (n)) = { f (n)|c > 0, n 0 , 0 f (n) < c.g (n), n n 0 }


f (n)
lim g (n) = 0

ou bien

(g (n)) = { f (n)|c > 0, n 0 , 0 c.g (n) < f (n), n n 0 }


f (n)
lim g (n) =

ou bien

f (n) (g (n))

ssi

g (n) o( f (n))

Comparaisons asymptotiques de fonctions (positives)


Transitivit

et g (n) = (h(n)) f (n) = (h(n))


f (n) = O(g (n)) et g (n) = O(h(n)) f (n) = O(h(n))
f (n) = (g (n)) et g (n) = (h(n)) f (n) = (h(n))
f (n) = o(g (n)) et g (n) = o(h(n)) f (n) = o(h(n))
f (n) = (g (n)) et g (n) = (h(n)) f (n) = (h(n))
f (n) = (g (n))

Symtrie

f (n) = (g (n))

ssi

g (n) = ( f (n))

Comparaisons asymptotiques de fonctions (positives)

Rexivit

f (n) = ( f (n))

f (n) = O( f (n))

f (n) = ( f (n))

Symtrie transpose

ssi g (n) = ( f (n))


f (n) = o(g (n)) ssi g (n) = ( f (n))
f (n) = O(g (n))

Analogie avec les oprateurs de comparaison

f (n) = O g (n) comme a b

f (n) = g (n) comme a b

f (n) = g (n) comme a = b

f (n) = o g (n) comme a < b

f (n) = g (n) comme a > b

Notation asymptotique conditionnelle

L'analyse de certains algorithmes est plus simple si on se


restreint des instances dont le taille vrie une certaine
condition (e.g. puissance de 2)

exemple de la multiplication

(
T (n) =

diviser pour rgner

si

4 T (dn/2e) + b.n

sinon

des entiers :

n=1

Les techniques systmatiques de rsolution des rcurrences


(que nous verrons plus tard) ne permettent pas de rsoudre
directement cette quation conditionnelle (en raison de
l'oprateur de)
Si on ne considre que des puissances de deux le problme est
rgl . . . (avec nos techniques on trouve
T (n) = (a + b) n bn ) (pour n 2N ) et donc

T (n) n 2 |n 2N

Notation asymptotique conditionnelle


Denition (Notation assymptotique conditionnelle)
Soit f : N R0 une fonction de N dans R0 et
P : N {vr ai , f aux} un prdicat (proprit) sur N.

t : N R0 | c R+ et (n 0 N) n nO , P (n) t (n) c. f (n)

f (n) |P (n) =

t : N R0 | c R+ et (n 0 N) n nO , P (n) t (n) c. f (n)

f (n) |P (n) =

t : N R0 | a, b R+ et (n 0 N) n nO , P (n) a. f (n) t (n) b. f (n)

O f (n) |P (n) =

Par abus de notation on utilise O f (n) |P (n) mme si f non dnie


ou ngative sur un sous ensemble (ventuellement inni) de P
L'intrt de cette notation est qu'elle peut tre limine aprs
son utilisation pour faciliter l'analyse

Croissance borne

Denition (Fonction ventuellement non dcroissante)


Une fonction f : N R0 est ventuellement non dcroissante ssi
n 0 N tel que n n 0 , f (n) f (n + 1)
Soit par induction n0 n m f (n) f (m)
Denition (Croissance borne paramtre)
Soit b 2 un entier. Une fonction f est croissance b -borne ssi :
1. f est ventuellement non dcroissante

2. f (b.n) O f (n)

i.e. n0 tel que n n0

f (b.n) c. f (n)

Croissance borne

Denition (Croissance borne)


Une fonction est croissance borne ssi elle est croissance
b -borne pour tout entier b 2

Exemples de fonctions croissance bornes : lg (n) , n lg (n) , n 2


ou n'importe quel polynme coecient principal positif
Exemples de fonctions non croissance bornes : n lg(n) , 2n , n!

(lg(2)+lg(n)) = 2(1+lg(n)) .n (1+lg(n)) = 2.n.n.n lg(n) =


(2n)lg(2n) = (2n)
lg(n)
2 lg(n)
2n .n
6 O n

Croissance borne
Proprit de la croissance borne
Si f est croissance b -borne (pour un entier b 2) alors f est
croissance borne.
Dmonstration.
Soient a, b 2 deux entiers et f une fonction croissance
b -borne. Nous montrons que f est croissance a -borne.
Soit c une constante et n0 tels que f (bn) c f (n) et
f (n) f (n + 1) n n 0 .

Soit i = logb (a) . a =b logb(a) b dlogb (a)e = b i .


Pour chaque n n O f b i n c i f (n) (preuve facile par induction)
or f (an) f b i n (car f est ventuellement non dcroissante)
Donc f (an) c f (n) o c = c i .

Rgle de croissance borne


Theorem (Rgle de croissance borne)
Soient f : N R0 une fonction croissance borne et t : N R0
une fonction ventuellement non dcroissante. Soit b 2 un entier.

t (n) f (n) |n b N t (n) f (n)

Cette rgle est galement valable pour et O

Exemple
Dans la multiplication
des entiers il est plus simple d'obtenir

T (n) n 2 |n 2N . En revanche si n 6 2N c'est trs dicile


(impossible) traiter.
Or n 2 croissance borne ((2n)2 = 4.n 2 ) et T (n) ventuellement
non dcroissante (par induction)
Donc on peut dduire que T (n) n 2

Rgle de croissance borne


Dmonstration.

une fonction croissance borne, t : N R0 une


fonction ventuellement non dcroissante,

b 2 un entier tels que t (n) f (n) |n b N et a, d deux


constantes.
f : N R0

Soit n0 le plus grand seuil tel que m n0 puissance de b :


f (m) f (m + 1),t (m) t (m + 1),
f (bm) c f (m) et d . f (m) t (m) a f (m) .
Soient n N, n = b blogb (n)c (la plus grande puissance de b non
suprieur n ) et n = bn . Par dnition n/b < n n < n et n b N .
donc n max (1, bn0 ),




t (n) t n a f bn = a f bn ac f n ac f (n)

Donc

t (n) O f (n) .

t (n) f (n) est similaire

Plan
Algorithmique lmentaire
Problmes et instances
Correction des algorithmes
L'ecacit des algorithmes
Notations asymptotique
Notation asymptotique standard
Notation asymptotique conditionnelle
Analyse des algorithmes
Analyse des structures de contrle
Rsolution des formules de rcurrence
Rcurrences homognes
Changement de variable

Analyse des algorithmes

L'algorithmique c'est :

Comment concevoir un

bon

algorithme pour rsoudre un

problme

Comment s'assurer que la solution propose est bonne

Quand on a plusieurs algorithmes, comment choisir le


meilleur

L'analyse des algorithmes est un outil qui s'intresse ce


dernier point
Pas de formule magique systmatique mais demande du bon
sens, de l'intuition et de l'exprience (un peu comme pour
faire des maths ...)
Certaines techniques basiques existent ... (traiter les structures
de contrle et les rcurrences)

Analyse des structures de contrle

Procde de l'intrieur vers l'extrieur


On commence par dterminer le temps ncessaire pour les
instructions individuelles (souvent en (1))
Ensuite ces temps sont combins selon les structures de
contrles utilises dans l'algorithme

Le squencement

et P 2 deux fragments d'un algorithme


t i le temps d'excution de P i (i {1, 2})
La rgle de squencement :

P1

T ("P 1 ; P 2 ") = t 1 + t 2 = (max (t 1 , t 2 ))

BP1 et P2 peuvent tre interdpendant et donc de mme

pour

t1

et t2 .

Calculer donc
tre erron ...

t2

indpendamment de

t1

(et vice versa) peut

Boucle For

1
2

for i = 1 to m do
P (i )

Taille de l'instance : n 6= m
Le cas le plus simple : T (P (i )) ne dpend pas de i

T (P (i )) = m t

mais . . . on a oubli le temps pour contrler la boucle

Boucle For
Formulation quivalente
1 i =1
2 while i = 1 m
3
P (i )
4
i = i +1

do

le temps d'excution, t = T (P (i )). m t l (on fait plus de


choses que excuter P (i ))
l
c
pour i = 1
+
(m + 1).c
pour les test i m
+
m.t
pour les excutions de P (i )
+
m.c
pour les excutions de i = i + 1
+
m.c
pour les oprations de squencement

(t + 3c)m + 2c

l = (m.t )

Bne pas confondre ecacit asymptotique et la possibilit

m=0

Boucle For : T (P (i )) dpend de i

Si m 1 le temps de contrle peut tre nglig (souvent mais


pas toujours)
l=

Pm

i =1 t (i )

1 function boIter(n )
2 i =1
3 j =0
4 for k = 1 to n do
5
j =i +j
6
i = j i
7

return

Si toutes les oprations arithmtiques en (1) alors complexit


en (n)
mais . . . si n l'addition est-elle en (1) ?

Boucle For : T (P (i )) dpend de i

Rponse : non. En fait la complexit de j = j + i dpend de i


(et de j )

plus prcisment : T j = max | j |, |i |


Or j = f k et i = f k1 (preuve par rcurrence)
p

f k = p1 k ()k o = 1+2 5 (le nombre d'or)


5

donc | f k | = (k) (|n| =

lg (n) ) T (k) = (k)



P
P
T nk=1 ck = c nk=1 k = O n 2 (en ngligeant le

boucle + avant et aprs)



Un mme raisonnement donne : T = n 2

Donc T = n 2

contrle de

BLa complexit des oprations arithmtiques lmentaires


est cruciale ! !

Appels rcursifs

L'analyse dans ce cas est gnralement simple

1
2
3
4
5

La structure de l'algorithme fournit une relation de rcurrence

Des techniques existent pour une rsolution asymptotique

function boRec(n )
if n 2 then
return n
else
return boRec(n 1) + boRec(n 2)
si n {0, 1}
T (n 1) + T (n 2) + h (n) sinon
h (n) le temps ncessaire l'addition et au contrle

T (n) = f n (on verra aprs pourquoi) et donc complexit
exponentielle . . .
(

T (n) =

Boucles while et repeat

Plus diciles analyser :

le nombre d'itrations n'est pas connu forcment

La mthode standard : trouver une fonction f des variables


(compteurs) impliques dont la valeur dcroit chaque
itration

Pour prouver que la boucle termine il sut de montrer que

mais pour calculer le temps d'excution, il faut comprendre

f 0

comment f

dcrot

Autre alternative : traiter les boucles while comme un


algorithme rcursif

Exemple : recherche dichotomique


1

function
rechercheDicho(T [1..n], x )

2 i =1
3 j =n
4 while i < j do
5
// T [i ] x T [ j ]
6
k = i + j 2
7
switch x T [k] do
8
case 1
9
j = k 1
10
case 0
11
i = j =k
12
return k
13
14
15

case 1

i = k +1

return i


f i, j = d = j i +1

f i , j : de n 0 (quand i j )

Exemple : recherche dichotomique


mthode standard

d,i, j

itration
=

d, i, j

( j i +1) = d
(i + j )

i + j 2i 2 i
2
2

d = j i + 1 = j i + j 2 j (i + j 1) = ( j i +1) =
2
2

1 d2

d
2

si

x < T [k]

si

x > T [k]

si

x = T [k]

Donc, d et donc f & et donc la boucle termine ( f 0)


`
itration donc dl 21 dl 1 et
d l valeur de d aprs la l i eme
d
2

d0 = n

1
n (par induction) donc il y a [lg (n)] + 1 itrations au
2l
plus (la boucle s'arrte quand l 1)

dl

Comme chaque itration


prend
un temps constant, la

complexit est en O lg (n)

de mme on peut dmontrer qu'elle est galement en lg (n)

complexit en lg (n)

Exemple : recherche dichotomique


traitement rcursif

En approche rcursive, l'algorithme revient diviser chaque pas le


problme en deux parts gales
t (d ) le temps maximum ncessaire pour excuter une itration
quand (j i + 1 d (d la taille du tableau)
c
si d = 1
t (d ) =
b + t (d 2) sinon

complexit en lg (n) (On verra juste aprs pourquoi)

La mthode intuitive

mthode dicilement automatisable


repose sur la comptence, l'intuition, l'exprience, . . .
Ide : partir de l'quation de rcurrence, deviner une solution
et prouver que c'est la bonne . . .

si n = 0
3T (n 2) + n sinon
Problme : dicult traiter la partie entire . . .
Solution : se restreindre 2N et utiliser la rgle de croissance
borne ...

Exemple : T (n) =

(
0

La mthode intuitive : exemple

On calcule les premires valeurs (puissances de 2)


n

16

32

T (n)

19

65

211

665

Peut-on trouver une gnralisation ?


Par machine : oui en utilisant l'encyclopdie en ligne des suites
d'entiers : http ://oeis.org. oei s (n) = 3n 2n .
Or T (n) = oei s (n + 1) (oeis commence partir
de 0) donc T (n) = 3n+1 2n+1
la main : pas vraiment . . . il faut analyser plus nement
comment est obtenu T (n)

T (1) = 0 + 1 et T (2) = 3 1 + 2 et
T (4) = 3 T (2) + 4 = 3 (3 1 + 2) + 4 = 32 1 + 3 2 + 4

La mthode intuitive : exemple


n
1
21
22
23
24
25

T (n)
1
31+2
32 1 + 3 2 + 22
33 1 + 32 2 + 3 22 + 23
34 1 + 33 2 + 32 22 + 3 23 + 24
35 1 + 34 2 + 33 22 + 32 23 + 3 24 + 25

P
P i
T 2k = ki=0 3ki 2i = 3k ki=0 32 donc

k+1


/ 1 32
T 2k = 3k 1 23

Finalement : T 2k = 3k+1 2k+1
n = 2k donc k = lg (n) et T (n) = 3lg(n)+1 2lg(n)+1 = 3n lg 3 2n
ln(n)
ln(3)
(lg n = ln(n)
ln(2) = ln(3) ln(2) = lg3 (n) lg 3 et donc

3lg n = 3lg3 (n)lg 3 = n lg 3 )

Donc T (n) = n lg 3 |n 2N

soit T (n) =

lg 3
n

par rgle de C.B.

Rcurrences homognes

Formules de rcurrence de la forme F :


a 0 t n + a 1 t n1 + . . . + a k t nk = 0

Les ai des constantes et ti les lments de la suite recherchs


En plus de la formule, il faut les valeurs t0 , t1 , . . . tk1
(conditions initiales)
Il s'agit d'une rcurrence linaire, homogne coecients
constants.
e.g. la suite de Fibonacci f n = f n1 + f n2 : k = 2, a0 = 1 et
a 1 = a 2 = 0 ( f n f n1 f n2 = 0)
Toute combinaison linaire de solutions de F est galement
solution de F

quation caractristique

Essayer la main quelques exemples de F peut suggrer de


chercher des solutions de la forme tn = x n
x est une constante inconnue dcouvrir
F devient : F 0 : a 0 x n + a 1 x n1 + . . . + a k x nk = 0
x = 0 est une solution triviale, sinon F 0
a 0 x k + a 1 x k1 + . . . + a k = 0

p (x) = a 0 x k + a 1 x k1 + . . . + a k

la rcurrence.

est l'quation caractristique de

i =1 (x r i ) o les r i C sont les racines de


y a pas d'autres racines)

p (x) =

Qk

p (x)

(il n'

Racines distinctes

satisfait la rcurrence pour chaque choix de


constantes ci .
En fait F n'a que des solutions de ce type et c'est la solution
la plus gnrale si toutes les r i sont distinctes (On admet ce
rsultat)
Les ci peuvent tre obtenues partir des conditions initiales (il
faudrait alors rsoudre un systme linaire de dimension k )
tn =

Pk

n
i =1 c i r i

Exemple : application la suite de Fibonacci


Fibonacci
(
fn =

si n {0, 1}
f n1 + f n2 sinon
f n f n1 f n2 = 0 donc p (x) = x 2 x + 1 qui admet deux
racinespdistinctes : p
r 1 = 1+2 5 et r 2 = 12 5
La solution gnrale est f n = c1 r 1n + c2 r 2n
n

comme

donc c1 = p15 et c2 = p15

fn =

p1
5

f0 = 0

et

f1 = 1

on a

p n p n i
1+ 5
12 5
2

c1
r 1 c1

+ c2
+ r 2 c2

= 0
= 1

Racines multiples

Certaines racines ont une multiplicit > 1 donc


p (x) = (x r )2 q (x)

La forme gnrale de de la solution n'est plus la mme :

u n (x) = a 0 x n + a 1 x n1 + . . . + a k x nk = x nk p (x)
v n (x) = a 0 nx n + a 1 (n 1) x n1 + . . . + a k (n k) x nk
v n (x) = x.u n0 (x)

0
u n0 (x) = (x r )2 x nk q (x) =

0
(x r ) 2x nk q (x) + (x r ) x nk q (x)
u n0 (r ) = 0 et v n (r ) = 0 :
a 0 nr + a 1 (n 1) r n1 + . . . + a k (n k) r nk = 0
n
ainsi t n = nr est aussi une solution
En fait si la multiplicit de r est m alors
t n = r n , t n = nr n , t n = n 2 r n , . . . , t n = n m1 r n sont
donc

solutions distinctes de la rcurrence

toutes des

Racines multiples

i 1
c i j n j r in
La solution gnrale : tn = li =1 mj =0
Les constantes ci j , 1 i l et 0 j mi 1 sont dtermines
grce aux k conditions initiales
Il y a k constantes ci j :

1,0 c 1,0 + 1,1 c 1,1 + . . . + 1,m1 1 c 1,m1 1 # = m 1


|
{z
}

i =1

+ 2,0 c 2,0 + 2,1 c 2,1 + . . . + 2,m2 1 c 1,m2 1 # = m 2

|
{z
}
m 1 +. . .+m l = k
i =2

+
...

l ,0 c 1,0 + l ,1 c l ,1 + . . . + l ,ml 1 c l ,ml 1 # = m l

|
{z
}

i =l

(la somme des multiplicits = le nombre total des racines)


On utilise des constantes c 1 , c 2 , . . . , c k

Exemple
tn =

(
n

5t n1 8t n2 + 4t n3

La rcurrence s'crit : tn 5tn1 + 8tn2 4tn3 = 0


Le polynme caractristique : x 3 5x 2 + 8x 4 = (x 1) (x 2)2
Les racines : r 1 = 1 avec multiplicit m1 = 1 et r 2 = 2 avec
multiplicit m2 = 2
La solution gnrale : tn = c1 1n + c2 2n + c3 n2n
Les conditions initiales :
c1
c1
c1

si n {0, 1, 2}
sinon

+ c2
+ 2c 2
+ 4c 2

+ 2c 3
+ 8c 3

= 0
= 1
= 2

n=0
n=1
n=2

La rsolution donne : c1 = 1, c2 = 2 et c3 = 21
Donc : tn = 2n+1 n2n1 2

Rcurrences non homognes

On s'intresse d'abord des rcurrences du type :


a 0 t n + a 1 t n1 + . . . + a k t nk = b n p (n)

constante
p (n) polynme de degr d
La partie gauche est identique au cas homogne
Pour rsoudre la rcurrence
on utilise le polynme

caractristique : r (x) = a0 x k + a1 x k1 + . . . + ak (x b)d +1 (on


admet ce rsultat)
P Pmi 1
t n = li =1 j =0
c i j n j r in o les r i sont les racines de r (x)
mais les constantes ne sont plus dnies uniquement grce aux
conditions initiales. Il faut tenir compte de la rcurrence
galement . . .
b

Exemple

tn =

si n = 0
4t n1 2
sinon
La rcurrence s'crit :

(
1

ici

b=2

et

t n 4t n1 = 2n

p (x) = 1 (d = 0)

Le polynme caractristique : (x 4) (x 2)
La solution gnrale : tn = c1 4n + c2 2n

BOn peut penser que tn = (4n ) mais ...

en remplaant : 2n = tn 4tn1 = c2 2n et donc c2 = 1


1 = t 0 = c 1 + c 2 = c 1 + 1. Donc c 2 = 0 et t n = (2n )

Changement de variable

Transformer la formule de rcurrence en une forme plus simple


par un changement de variable
Cette technique permet (entre autres) de rsoudre le problme
rcursif (trs important) suivant :
T (n) = l T (n/b) + c.n k

n 0 1, l 1, b 2

T : N R+

(n > n 0 ) n n 0 .b N

et k 0 des constantes entires et c R>0


fonction non ventuellement dcroissante

Changement de variable

(n > n 0 ) n n 0 .b N

T (n) = l T (n/b) + c.n k

On utilise le changement de variable : n = b i n0 .


i

On a ti l ti 1 = cn0k b k
On retrouve la forme des rcurrences non homognes a i p (i )
avec a = b k et p (i ) = cn0k (polynme constant de degr 0)

La solution gnrale de ti : ti = c1 l i + c2 b k
Il faut revenir T (n) : i = logb (n/n0 ) et donc d i = (n/n0 )logb d

d > 0

ti = T b i n0

donc

T (n) =

logb l

c1/n 0

n logb l + c 2 /n 0k n k

= c 3 n logb l + c 4 n k

Changement de variable

Les constantes sont obtenues en remplaant dans la formule


k
de rcurrence : T (n) l T (n/b) = cn
c4 =

c
1 blk

Pour exprimer T (n) en notation asymptotique il sut de ne


garder que le terme dominant
3 cas distinguer :

k

T (n) = n k logb n

n logb l

si l < b k
si l = b k
si l > b k

Changement de variable

Pourquoi le rsultat prcdent ?


k
si l < b alors c4 > 0 et k > logb l .

T (n) = n k |n n 0 b N

et donc


T (n) = n k

(par rgle de

croissance borne)

si l > b k alors c4 < 0 et k < logb l .

c3

est alors positive (sinon

T (n) < 0)

et donc

T (n) = n logb l

(par rgle de croissance borne)

si l = b k alors problme : (c4 indnie) . . . mais dans ce cas le


polynme caractristique a une seule racine de multiplicit 2.
i
i
ti = c5 b k + c6 i b k
T (n) = c 7 n k + c 8 n k logb (n/n 0 )

Solution :

soit

en remplaant dans la formule de rcurrence : c 8 = c et donc

T (n) = n k logb n (par rgle de croissance borne)

Inquation de rcurrence

Si au lieu d'avoir

T (n) =l T (n/b) + c.n k


T (n) l T (n/b) + c.n k

On a :

(n > n 0 ) n n 0 .b N

(n > n 0 ) n n 0 .b N

O n

T (n) = O n k logb n

O n logb l

si l < b k
si l = b k
si l > b k

on a

Gnralisation : le Master Theorem


Theorem (Master Theorem)
Soit
T (n) = l T (nb) + f (n)

(n > n 0 )

n 0 1, l 1, b 2 et k 0 des constantes entires et c R>0


T : N R+ fonction non ventuellement dcroissante

f (n) = n k

Alors :

k

T (n) = n k logb n

n logb l

si l < b k
si l = b k
si l > b k

Troisime partie
Structures de donnes

Plan
Introduction
Tableaux, piles et les
Listes
Graphes
Arbres
Arbres binaires de recherche et tri par ABR
Arbres AVL et tris par AVL
Files de priorit et tas
Tas et le de priorit
Tas et tri par tas
Dictionnaire et tables de hachage

Introduction

Les ensembles sont aussi importants en informatique qu'en


mathmatiques
Les ensembles manipuls par des algorithmes peuvent :

ensembles dynamiques
les oprations les plus frquentes :

croitre, diminuer ou changer durant le temps

insertion, suppression et recherche (test d'appartenance)

un ensemble qui supporte ces oprations est un dictionnaire


d'autres oprations sont bien entendu possibles (tri, extraire
l'lment minimum, . . . )
Entre autres choses on s'intresse la complexit de ces
oprations

Type de donnes abstrait et structures de donnes

Un type = ensemble de valeurs (ensemble)


Un type de donnes (TD) = type + oprations sur le type
Un lment est un membre d'un TD
Un type de donnes abstrait (TDA) = dnition d'un TD
uniquement en terme de valeurs et d'oprations sur le TD
l'implmentation

Pas de dtails sur

exemple : le dictionnaire

Une structure de donnes = implmentation d'un TDA


L'algorithmique permet de choisir la bonne implmentation
pour un TDA

Structures de donnes lmentaires

Structure de donnes non ensemblistes (reprsentent un seul


lment)
Variables : lecture, modication en O(1)
Pointeurs : lecture, modication en O(1)
Enregistrements : accs (lecture,criture) aux champs en O(1)

struct, record, classe

Plan
Introduction
Tableaux, piles et les
Listes
Graphes
Arbres
Arbres binaires de recherche et tri par ABR
Arbres AVL et tris par AVL
Files de priorit et tas
Tas et le de priorit
Tas et tri par tas
Dictionnaire et tables de hachage

Tableau

Structure de donne ensembliste lmentaire


Reprsente un ensemble contenant un nombre x d'lments
du mme type
Stocks (souvent) comme emplacements adjacents dans la
mmoire d'une machine
accs index par un entier (le rang dans l'emplacement
adjacent) : T [i ]
L'adresse d'un lment (l'accs un lment) est calcule en
temps constant : Opration lmentaire en O(1)
Une opration qui concerne tous les lments d'un tableau
(chercher le maximum, modier tous les lments, dcaler,
recopier . . . ) est en (n)

TDA Pile

TDA St ack : lments ajouts et supprims en LIFO


dnit par :
E un ensemble de valeur (type)
Oprations :

i ni t : St ack
push : E St ack St ack
t op : St ack ; E
pop : St ack ; E
empt y : St ack {vr ai , f aux}
si ze : St ack N

Peut tre implmente avec un tableau


Peut tre galement implmente avec une liste
Complexit en fonction de l'implmentation

TDA File

TDA Queue : lments ajouts et supprims en FIFO


dnit par :
E un ensemble de valeur (type)
Oprations :

i ni t : Queue
enqueue : E Queue St ack
head : Queue ; E
d equeue : Queue ; E
empt y : Queue {vr ai , f aux}
si ze : Queue N

Peut tre implmente avec un tableau


Peut tre galement implmente avec une liste
Complexit en fonction de l'implmentation

Plan
Introduction
Tableaux, piles et les
Listes
Graphes
Arbres
Arbres binaires de recherche et tri par ABR
Arbres AVL et tris par AVL
Files de priorit et tas
Tas et le de priorit
Tas et tri par tas
Dictionnaire et tables de hachage

TDA Liste

Collection d'lments d'information rangs selon un ordre


Le nombre n'est pas x
Flexibilit % tableau
TDA dnit par :
E un ensemble de valeur (type), nil E
Oprations

i ni t : Li st (constructeur)
empt y : Li st E
conc at enat e : E Li st Li st
append : Li st Li st Li st
head : Li st {nil} E
t ai l : Li st {nil} Li st

Plusieurs oprations possibles : recherche, tri, insertion,


suppression, copie, . . .
Implmentation : On utilise un enregistrement qui contient la
valeur et un peinture sur le prochain lment de la liste t ai l )
Complexit dirente pour chaque opration . . .

Listes chaines

Implmentation du TDA Liste

Cot des oprations :

Insertion (en tte de liste) :

Suppression :

Recherche :

(n)
(n)

O(1)

(il faut trouver la cellule supprimer)

Plan
Introduction
Tableaux, piles et les
Listes
Graphes
Arbres
Arbres binaires de recherche et tri par ABR
Arbres AVL et tris par AVL
Files de priorit et tas
Tas et le de priorit
Tas et tri par tas
Dictionnaire et tables de hachage

Graphes

Intuitivement, un graphe est un ensemble de nuds (sommets)


relis par des liens (ou artes)
Les liens peuvent tre orients (graphe orient) ou non (graphe
non orient)
Formellement : un graphe est un couple (V, E )

V un ensemble (de sommets)


E V V un ensemble (d'artes) si le graphe
sinon E {u, v|u, v V } (graphe non orient)

Extrmits d'une arte : e = (u, v) E


e = (u, v) E u et v sont adjacents
e = (u, v) E e est incident v

2 S.D pour implmenter un graphe :

est orient

collection de listes d'adjacence et matrice d'adjacence

Matrice d'adjacence

Si V

S.D. pour reprsenter un graphe dense G = (V, E ) (|E | |V |2 )


= {e 1 , . . . , e |V | }

alors :

Matrice d'adjacence : M {0, 1}|V ||V | = (ai j )i , j [1..|V |]


a =
(i j
1 ou

un poids w si graphe pondr


si (ai , a j ) E
0 ou nil ou un poids si graphe pondr sinon

Si u, v V , alors (u, v) E en O(1)


Complexit spatiale : (n 2 )
Symtrique si graphe non orient
Ecace pour les graphe non pondrs : un bit sut

Listes d'adjacence

S.D. compacte pour reprsenter un graphe G = (E ,V ) trs peu


dense (|E | |V |2 )
C'est un tableau Ad j de |V | listes (une liste pour chaque
sommet)
u i V , Ad j [i ] = liste contenant tous les sommets v V tels
que (u, v) E
P |
|Ad j [i ]| = |E |
Si G est orient : |V
i =1
P|V |
Si G est non orient : i =1 |Ad j [i ]| = 2.|E |
Complexit spatiale en (|V | + |E |)
Possibilit de stocker le poids (dans chaque cellule) dans le cas
d'un graphe pondr
Avantage : exibilit (pour reprsenter des variantes de graphe)

Inconvnient : (u, v) E relativement couteuse

Exemple

Exemple de reprsentation d'un graphe non orient

Exemple de reprsentation d'un graphe orient

Plan
Introduction
Tableaux, piles et les
Listes
Graphes
Arbres
Arbres binaires de recherche et tri par ABR
Arbres AVL et tris par AVL
Files de priorit et tas
Tas et le de priorit
Tas et tri par tas
Dictionnaire et tables de hachage

Arbres binaires de recherche

Structure de donne qui supporte des oprations ensemblistes


dynamiques :
rechercher, minimum, maximum, prdcesseur, successeur,
insrer et supprimer

peut tre utilis pour implmenter un dictionnaire ou une

le de priorit

complexit (dans le pire cas) des opration proportionnelle la


hauteur de l'arbre (entre O(lg(n)) et O(n))
complexit en moyennes des oprations en O(lg(n))

Un ABR c'est quoi ?

C'est un arbre binaire (chaque nud a au maximum deux ls)


chaque nud contient une valeur (la cl) en plus d'attributs
droit, gauche et pre qui pointent vers SAG, SAD et pre
si le nud n'a pas de ls, celui-ci est dsign par nil
` e = nil)
la racine est le seul nud qui n'a pas de pre (p er
L'arbre vrie la proprit ABR :

x un nud d'un ABR. y g auche(x), y.cl e x.cl e


y d r oi t e(x), y.cl e x.cl e

Soit

et

ABR : exemple

Un ABR : {6, 4, 7, 2, 5, 8}

Un contre-exemple :

p 6 >>
ppp
>>
p
p
>>
pp
p
p
p
>
p
p
pw
7>
4>
>>
>>
>>
>>
>>
>>
 2

5
8

Un autre ABR {6, 4, 7, 2, 5, 8}

2>
>>
>>
>>


4 NNN
NNN
NNN
NNN
NN'

7>
>>
>>

pp 6 >>
>>
ppp
p
p
>>
p
p
p
p
>
wppp
7>
4>
>>
>>
>>
>>
>>
>>


8

Parcours d'un ABR

1
2
3
4
5

La proprit ABR permet d'avoir toutes les cls d'un ABR


tries.
on utilise un parcours inx (gauche, nud, droite)

Entre : un ABR (noeud) x


Resultat : eectue un parcours inx de x
procedure parcoursInxe(x )
if x 6= nil then
parcoursInxe(x.g auche(x))
imprimer(x.cl e )
parcoursInxe(x.d r oi t e(x))
Algorithme 5 : parcoursInxe

complexit en (n)

Requtes sur les ABRs

Besoin de chercher une cl dans un ABR


On s'intresse aux oprations :

minimum, maximum, successeur et prdcesseur

Complexit de toutes ces oprations en (h) o h la hauteur


de l'arbre

La recherche

1
2
3
4
5
6
7

Version rcursive :
Entre : un ABR (noeud) x et une cl k
Resultat : un noeud de cl k ou nil sinon
function rechercherABR(x, k )
if x = nil or k == x.cl e then
return x
if k < x.cl e then
return rechercherABR(x.g auche(x), k )
else
return rechercherABR(x.d r oi t e(x), k )
Algorithme 6 : rechercherABR

La recherche
Version itrative (plus ecace en pratique) :

1
2
3
4
5
6
7

Entre : un ABR (noeud) x et une cl k


Resultat : un noeud de cl k ou nil sinon
function rechercherIterABR(x, k )
while x 6= nil and k 6= x.cl e do
if k < x.cl e then
x = x.g auche(x)

else
x = x.d r oi t e(x)

return x

Algorithme 7 : rechercherIterABR

Le minimum et le maximum
Les deux oprations en (h)

1
2
3
4

1
2
3
4

Entre : un ABR (noeud) x 6= nil


Resultat : le noeud ayant la cl minimale
function minimumABR(x, k )
while x.g auche(x) 6= nil do
x = x.g auche(x)

return x

Algorithme 8 : minimumABR

Entre : un ABR (noeud) x 6= nil


Resultat : le noeud ayant la cl maximale
function maximumABR(x, k )
while x.d r oi t e(x) 6= nil do
x = x.d r oi t e(x)

return x

Algorithme 9 : maximumABR

Le successeur et le prdcesseur
Complexit en O(h)

1
2
3

Entre : un ABR (noeud) x 6= nil


Resultat : le noeud ayant la plus petite cl suprieure x.cl e
function successeurABR(x, k )
if x.d r oi t e 6= nil then
return minimumABR(x.d r oi t e(x))

` e
4 y = x.p er
5 while y 6= nil and x == y.d r oi t e(x)
6
x=y
` e(x)
7
y = y.p er
8

return

do

Algorithme 10 : maximumABR

L'insertion

1
2
3
4
5
6

Complexit en O(h), h la hauteur de l'arbre


Entre : un ABR A et un noeud z tel que z.g auche = z.d r oi t e = nil
Resultat : A est modi en A0 = A z et A0 est un ABR
procedure insererABR(x )
y = nil
x = A.r aci ne
while x 6= nil do
y = x if z.cl e < x.cl e
x = x.g auche

then

else

x = x.d r oi t e

11

` e=y
z.p er
y == nil then // A est vide
A.r aci ne = z

12

else if

9
10

13
14
15

if

else

z.cl e < y.cl e


y.g auche = z

then

y.d r oi t e = z

Algorithme 11 : insererABR

La suppression

La suppression : le remplacement
Algorithme de remplacement d'un sous arbre u par un sous arbre

1
2
3

Entre : un ABR A , un sous-arbre u de


sous-arbre v pour remplacer u
Resultat : A est modi
procedure remplacer( A, u, v )
` e == nil then
if u.p er

remplacer et un

A.r aci ne = v

4
5
6
7

else if

8
9

if

` e.g auche
u == u.p er
`
u.p er e.g auche = v

then //

u est sous-arbre gauche

else

` e.d r oi t e = v
u.p er
v 6= nil then
` e = u.p er
` e
v.p er

Algorithme 12 : remplacer

La suppression

Algorithme de suppression d'un nud


en O(h), h la hauteur de A .

(a)

(b)

(d)

d'un ABR A . Complexit

Entre : un ABR A et un noeud z supprimer


Resultat : A est modi
procedure supprimer( A, z )
if z.g auche == nil then
remplacer( A, z, z.d r oi t e )
else if z.d r oi t e == nil then
remplacer( A, z, z.g auche )
else
y = mimumABR(z.d r oi t e )
if y.p er` e 6= z then
remplacer( A, y, y.d r oi t e )
y.d r oi t e = z.d r oi t e
` e=y
y.d r oi t e.p er

(c,d)

remplacer( A, z, y )

y.g auche = z.g auche


` e=y
y.g auche.p er

Algorithme 13 : remplacer

Arbres AVL

Problme avec les ABRs : complexit dpend de la hauteur


2 extrmes :

arbre parfaitement quilibr en

arbre linaire en

O lg(n)

O(n)

Comment s'assurer que l'arbre est quilibr ? (est-ce toujours


possible ?)
plusieurs solutions : la plus ancienne historiquement les arbres
AVL (Adelson-Velskii et Landis)

Arbres AVL

Proprit
AVL : pour chaque noeud n ,

|h n.g auche h (n.d r oi t e) | 1

Theorem

Soit A un arbre AVL. h (A) = O lg (n)

Oprations sur les AVL

recherche : trs ecace, complexit en O lg (n)

insertion et suppression : galement en O lg (n) . . . c'est bien . . .


mais . . . risque de dsquilibrage de l'arbre
la proprit AVL peut ne plus tre
vrie
la solution : rquilibrer l'arbre en
utilisant les rotations

Dsquilibrage aprs insertion

A : Arbre initial (c'est un AVL)

?>=<
89:;
3

@ABC
GFED
21
BB
~
BB
~
~
BB
~~
BB
~
~
~

89:;
?>=<
@ABC
GFED
5
25
@@
@@
@@
@@

@ABC
GFED
19

A aprs insertion de 15

@ABC
GFED
21
BB
|
BB
|
|
BB
||
BB
|
|
|
~
h=2 ?>=<
h=0
@ABC
GFED
89:;
25
5 B
BB
~
~
BB
~~
BB
~~
B
~
~~
89:;
?>=<
@ABC
GFED
3
19
|
|
||
||
|
~|
GFED
@ABC
15

Dsquilibrage aprs suppression

A : Arbre initial (c'est un AVL)

A aprs suppression de 25

@ABC
GFED
@ABC
GFED
21
21
AA
BB
}
|
A
BB
}
|
AA
}
|
BB
}
AA
}
||
BB
}
|
A
}
|
~
}
~|
h=2 ?>=<
h=0
?>=<
89:;
GFED
@ABC
89:;
@ABC
GFED
5
25
5 B
25
AA
B
B
~
BB
AA
BB
~~
BB
~~
AA
BB
~~
BB
~~
~
A
BB
~
~
B
A
~ ~
~~
?>=<
89:;
@ABC
GFED
GFED
@ABC
89:;
?>=<
@ABC
GFED
3
19
30
3
19
}
|
}
|
}}
||
}}
||
|
~}}
~|
@ABC
GFED
@ABC
GFED
15
15

Procdure de rotation

Procdure locale dans un arbre qui prserve la proprit ABR


2 types de rotations : gauche et droite
Complexit en O(1)

?>=<
89:;
y


?>=<
89:;
x
??
??


??


??




<<
<<
<<
<<


ks _
_ _
_ _
_ _
_ _
_ _
_ __ __ __
r ot at i onG auche(A,x)

_ _ _ _ _ _ _ _ _ +3
r ot at i onDr oi t e(A,x)


?>=<
89:;
x
 >







Procdure de rotation : rotation gauche

1
2
3
4
5
6
7

Entre : un ABR A, un sous-arbre x de A


Resultat : A est modi
procedure rotationGauche( A, x )
y = x.d r oi t e
x.d r oi t e = y.g auche
y.g auche 6= nil
` e=x
y.g auche.p er

if

then

` e = x.p er
` e
y.p er

if x.p er` e == nil then


A.r aci ne = y

8
9
10
11
12
13
14

else if x == x.p er` e.g auche then


` e.g auche = y
x.p er

else

` e.d r oi t e = y
x.p er
y.g auche = x
` e=y
x.p er

Algorithme 14 : rotationGauche

// TODO

Procdure de rotation : rotation droite

1
2
3
4
5
6
7
8
9
10
11
12
13
14

Entre : un ABR A, un sous-arbre x de A


Resultat : A est modi
procedure rotationDroite( A, x )
x = y.g auche
y.g auche = x.d r oi t e
x.d r oi t e 6= nil
` e=y
x.d r oi t e.p er

if

then

` e = y.p er
` e
x.p er
` e == nil
y.p er
A.r aci ne = x

if

then

else if
else

` e.d r oi t e
y == y.p er
`
y.p er e.d r oi t e = x

then

` e.g auche = x
y.p er
x.d r oi t e = y
` e=x
y.p er

Algorithme 15 : rotationDroite

// TODO

quilibrage
Pour insrer dans un AVL, on insre le nud comme dans un
ABR puis on quilibre partir de ce nud en remontant vers
la racine
Entre : un sous-arbre x tel que x.g auche et x.d r oi t e sont quilibrs mais

|x.g auche.h x.d r oi t e.h| = 2

Resultat : A est quilibr


procedure equilibrer(x )
if x.d r oi t e.h > x.g auche.h then
if x.d r oi t e.d r oi t e.h x.d r oi t e.g auche.h then
rotationGauche(x, x )
else
rotationDroite(x, x.d r oi t e )
rotationGauche(x, x )

else

1
2
3
4
5
6

9
10
11
12
13

if

x.g auche.g auche.h x.g auche.d r oi t e.h


rotationDroite(x, x )

else

rotationGauche(x, x.g auche )


rotationDroite(x, x )

then

Insertion
Entre : un arbre AVL

A et un neoud z tel que


z.g auche = z.d r oi t e = nil et z.h = 0
Resultat : A z est quilibr
1 function inserer( A, z )
2 if A == nil then
3
return z
4
5
6

else
if

A.cl e z.cl e then


A.g auche = inserer( A.g auche, z )

7
8

else

return equilibrer( A )
Algorithme 17 : equilibrer

A.d r oi t e = inserer( A.d r oi t e, z )

Pour insrer un nud

on appelle : inserer(A.r aci ne, z).

Plan
Introduction
Tableaux, piles et les
Listes
Graphes
Arbres
Arbres binaires de recherche et tri par ABR
Arbres AVL et tris par AVL
Files de priorit et tas
Tas et le de priorit
Tas et tri par tas
Dictionnaire et tables de hachage

TDA File de priorit

Le tas (Heap)

S. D qui implmente ecacement la le de priorit


S. D. implmente par un tableau qui peut tre vu comme un
arbre binaire presque complet
L'arbre est compltement rempli chaque niveau sauf le plus
bas qui est rempli depuis la gauche
@ABC
GFED
16 : 1
RRR
RRR
lll
l
l
RRR
l
l
u l
) GFED
l
@ABC
GFED
@ABC
14 : 2
10 : 3
F
FFF
F
x
x
F
x
x
F
F"
x
x
|x
"
|x
@ABC
GFED
@ABC
GFED
@ABC
GFED
@ABC
GFED
8:4
7:5
9:6
3:7
FFF
FFF
x
z
x
z
F
F
x
z
"
|z
"
|x
@ABC
GFED
GFED
@ABC
GFED
@ABC
2:8
4:9
1 : 10
16

14

10

Le tas

La racine de l'arbre est A[1]


A partir d'un indice i d'un nud on peut donner :
` e(i ) = A[[i /2]]
p er
g auche(i ) = A[2.i ]
droit : d r oi t e(i ) = A[2.i + 1]

son pre :

son ls gauche :

son ls

2 types de tas (en fonction de la proprit du tas) :


` e(i )] A[i ]. (utile
max-heap : pour chaque nud i , A[p er
pour le tri)
` e(i )] A[i ]. (utile
min-heap : pour chaque nud i , A[p er
pour les les de priorit)
hauteur d'un tas : le nombre de liens du plus long chemin
entre la racine et une feuille

la hauteur est en

(lg(n))

Oprations sur les tas


Opration fondamentale pour le tas
maxHeapify : O(lg(n)). permet de maintenir la proprit
max-heap
Oprations utiles pour le tri
buildMaxHeap : O(n). produit un max-heap partir d'un
tableau non tri
heapsort : O(n lg(n)) : procdure de tri
Oprations utiles pour la le de priorit toutes en O(lg(n))
maxHeapInsert
heapExtractMax
heapIncreaseKey
heapMaximum

maxHeapify
Entre : un tableau T et un noeud i tel que f g (i ) et f d (i ) sont
des max-heap mais T [i ] peut tre infrieur ses ls
Resultat : T est rendu tas
procedure maxHeapify(T, i )

1
2 g = g auche(i )
3 d = d r oi t e(i )
4 if l T.heapSi ze and T [g ] > T [i ]
5
pl usGr and = g
6 else
7
pl usGr and = i

then

8
9

if

r T.heapSi ze and T [r ] > T [pl usGr and ]


pl usGr and = r

10
11
12

if

pl usGr and 6= i then


changer T [i ] avec T [pl usGr and ]
maxHeapify(T, pl usGr and )

then

Algorithme 18 : maxHeapify

maxHeapify

Analyse du temps d'excution sur un sous-arbre de taille n


avec racine = i :
Il faut (1) oprations de comparaisons avec T [g auche(i )] et
T [d r oi t e(i )] et ceux avec T.heapSi ze
le temps d'excution de l'appel rcursif est major par T ( 32 n)
(la taille du sous arbre dans le cas le plus dfavorable est 32 n )
donc T (n) T ( 23 n) + (1) et donc T (n) = O(lg(n))

Files de priorit

la le de priorit est la plus populaire utilit du tas

ecacit des les de priorit base de tas

2 types de les de priorit : les de priorit max et les de


priorit min
On s'intresse aux les max (utilisent des max-heaps)

File de priorit max

Structure de donne pour maintenir un ensemble S d'lments


A chaque lment est associe une valeur (la cl)
Supporte les oprations suivantes :

er M ax(S, x) : insre l'lment x dans S


i ns er
maxi mum(S) : retourne l'lment qui a la plus grande cl
ext r ai r eM ax(S) : supprime et retourne l'lment qui a la plus
grande cl

aug ment er C l e(S, x, k)


k.

: augmente la cl de l'lment

nouvelle valeur est

la fonction maximum en O(1)


toutes les autres oprations en O(lg(n))

x.

Sa

Oprations de la le de priorit

1
2

maximum : O(1)

Entre : un tas T
Resultat : le maximum de T
function heapMaximum(T )
return T [1]

extraireMax : O(lg(n))

Entre : un tas T
Resultat : T est modi en en supprimant le max
function heapExtraireMax(T )
if T.t ai l l eTas < 1 then error "le tas est vide" ;

1
2
3 max = T [1]
4 T [1] = T [T.t ai l l eTas]
5 T.t ai l l eTas = T.t ai l l eTas
6 maxHeapify(T, 1)
7 return max

Oprations de la le de priorit

1
2
3

augmenterCle : O(lg(n))

Entre : un tas T , un lment x et sa nouvelle cl k


Resultat : la cl de x devient k dans T
procedure heapAugmenterCle(T, x, k )
if T [x].cl e > k then
error "le nouvelle cl est infrieure l'ancienne"

4 T [x].cl e = k
5 while x > 1 and T [per e(x)].cl e < T [x].cl e
6
changer T [per e(x)] et T [x]
7
x = per e(x)

do

Oprations de la le de priorit

insererMax : O(lg(n))

Entre : un tas T et une nouvelle cl k


Resultat : T augment de k
procedure insererMax(T, k )

1
2 T.t ai l l eTas = T.t ai l l eTas + 1 T [T.t ai l l eTas] =

heapAugmenterCle(T, T.t ai l l eTas, k )

Le tri par tas (heapsort)

Le tas sert aussi dans le tri


Complexit en O(n lg n) (Comme le tri par fusion mais
contrairement au tri par insertion
heapsort trie sur place (sur le mme tableau d'entre) (Comme
le tri par insertion mais contrairement celui par fusion)

heapsort combine les meilleurs proprits des deux algorithmes


nouvelle technique (ou stratgie) de conception des
algorithmes :

l'utilisation des structures de donnes pour grer l'information

Construire un tas

Objectif : transformer un tableau T [1..n] en un tas


On utilise max-heapify du bas vers le haut
ide : les lments T [[ n2 + 1]..n] constituent les feuilles de
l'arbre

chaque lment est un tas d'un lment avec lequel on

commence

la procdure de construction itre sur les autres lments en


appelant max-heapify sur chacun

algorithme de construction d'un tas


Entre : un tableau T
Resultat : T est rendu tas
procedure buildMaxHeap(T )

1
2 T.t ai l l eTas = T.t ai l l e
3
4

for i = [ T.t ai2 l l e ] + 1 downto 1 do


maxHeapify(T, i )
Algorithme 19 : build-max-heap
correction : On utilise l'invariant de boucle : Au dbut de chaque
itration, chaque nud i + 1, i + 2, . . . , n est la racine
d'un max-heap.

Complexit de buildMaxHeap

chaque max-heapify est en O(lg(n))


on rpte max-heapify O(n) fois
complexit en O(n lg(n))
Mais ... on peut faire mieux ... :

complexit de max-heapify dpend de la hauteur :

O(h)

hauteur du nud

n lments = lg(n)
h+1
chaque hauteur h au plus [n/2
]+
nuds (pourquoi ?)

1P

P[lg(n)]
[lg(n)] h
h+1
C (n) =
[n/2
]
+
1
.O(h)
=
O
n.
h
h=0 2
h=0
P
x
k
(
k.x
=
si |x| < 1)
2
h=0
P(1x)
h

C (n) = O n.
= O(2.n) = O(n)
h=0 2h

la hauteur d'un tas de

la

algorithme de tri par tas (heapsort)


Entre : un tableau T
Resultat : T est tri
procedure heapsort(T )
build-max-heap(T )

1
2
3 T.t ai l l eTas = T.t ai l l e
4 for i = T.t ai l l e downto 2 do
5
echanger T [1] avec T [i ]
6
T.t ai l l eTas = T.t ai l l eTas 1
7
maxHeapify(T, 1)

Algorithme 20 : heapsort
Complexit en O(n lg(n)) :
complexit de build-max-heap en O(n)
complexit de max-heapify en O(lg(n))
max-heapify est appele n 1 fois
Heapsort est un excellent algorithme mais moins bon en
pratique que Quicksort ...

Plan
Introduction
Tableaux, piles et les
Listes
Graphes
Arbres
Arbres binaires de recherche et tri par ABR
Arbres AVL et tris par AVL
Files de priorit et tas
Tas et le de priorit
Tas et tri par tas
Dictionnaire et tables de hachage

Dictionnaires et tables de hachage

ADT Dictionnaire (o Table o Table associative)


Un ensemble de cls

modlise un ensemble qui permet


objet de

et un ensemble d'objets

d'associer

E,

nil E

une cl de

un

Oprations :

i ni t : Di c t i onnar y (constructeur)
i nser er : K E Di c t i onnar y
r echer cher : K Di c t i onnar y E
suppr i mer : K Di c t i onnar y Di c t i onnar y
mod i f i er : K Di c t i onnar y Di c t i onnar y

Exemple : table des identiants dans un compilateur


La table de hachage est une structure de donnes trs ecace
pour implmenter un Dictionnaire
La recherche d'un lment au pire cas en (n)
En pratique les T. H se comportent beaucoup mieux
Sous certaines hypothses raisonnables la complexit de la
recherche en moyenne est en O(1)

Table de hachage

Une table de hachage est une implmentation d'un dictionnaire


Concrtement c'est un tableau indices entier de taille m
2 problmes :

Si

K 6 [0..m 1]

: comment associer une cl un entier ?

Fonction de hachage : fonction h : K [0..m 1]. A chaque cl


on associe un entier

|U | > |K | : k 1 , k 2 K tels que h(k 1 ) = h(k 2 )


k 1 6= k 2 (principe des tiroirs ou pigeonhole)

Si

et

Problme de collisions : il faut une stratgie pour rsoudre les


collisions

Rsolution des collisions par chainage

La solution la plus simple


Tous les lments e E qui ont le mme code de hachage sont
mis dans une mme liste chaine
La case j contient un pointeur sur la tte de la liste chaine
qui contient tous les lments e tels que h(e) = j
Si aucun lment e associ j alors T [ j ] = nil

Oprations

1
2

Entre : une table de hashage T et un lment x


Resultat : x est insr dans T
procedure insertChainedHash(T, x )
insrer x en tte de la liste T [h(x.cl )]
Algorithme 21 : insertChainedHash

1
2
3

Insertion :

Recherche :

Entre : une table de hashage T et une cl k


Resultat : recherche si un lment x de cl k est dans T
function searchChainedHash(T, k )
chercher x dans la liste T [h(k)] tel que x.cl = k
return x
Algorithme 22 : searchChainedHash

Oprations

1
2

Entre : une table de hashage T et une cl k


Resultat : recherche si un lment x de cl k est dans T et le
modie
procedure deleteChainedHash(T, k )
supprimer x de la liste T [h(k)] tel que x.cl = k
Algorithme 23 : deleteChainedHash

1
2
3

Suppression

Modication

Entre : une table de hashage T et une cl k


Resultat : recherche si un lment x de cl k est dans T et le
supprime
procedure modifyChainedHash(T, k )
x = modifyChainedHash(T, k )
modier x
Algorithme 24 : modifyChainedHash

Analyse du hachage avec chainage

Pour l'insertion : cot en O(1)


Pour les autres oprations = cot de la recherche
Soit une table de m cases pour stocker n lments
= n/m : le facteur de charge

= E [N ]

le nombre d'lments stocks dans la mme

liste (chaine)

Analyse en fonction de ( [0, 1[{1}]1, [)


La recherche dans le cas le plus dfavorable en (n) (+ le
temps de calcul du hachage)
Les performances en moyenne dpendent de la distribution en
moyenne des cls par rapport aux m cases

Analyse du hachage avec chainage


Hypothses
hachage uniforme simple

Chaque lment est hach en une case de manire


quiprobable indpendamment du hachage des autres lments

j [0..m 1], n j est

n = n 0 + n 1 + . . . + n m1

E [n j ] = = n/m

cot du hachage de k est en O(1)

la taille de la liste T [ j ]

la recherche d'un lment


T [h(k)] = (|T [h(k)]|)

avec cl

dans

On s'intresse l'esprance du nombre d'lments examins

Il s'agit en fait du nombre d'lments de


pour voir si une cl =

T [h(k)]

examins

Analyse du hachage avec chainage


Une recherche infructueuse est en (1 + )
Il faut parcourir toute la liste dont la taille moyenne est
(plus le hachage)
Pour une recherche avec succs c'est un peu plus compliqu . . .
On suppose que la probabilit de rechercher un lment x
parmi tous les lments stocks dans la table est uniforme
Le nombre d'lments examins = 1+ le nombre d'lments
insrs aprs x ayant le mme hachage . . .
`
x i le i eme
lment insr dans la table, ki = xi .cl e

X i j = I {h(k i ) = h(k j )}

Sous l'hypothse de hachage uniforme simple :


P r (h(k i ) = h(k j )) = 1/m

E [X i j ] = 1/m

Analyse du hachage avec chainage


E

=
=
=
=

h P
1 n

Pn

j =i +1 X i j
n i =1

Pn
1 Pn
1
+
E
[X
]
i
j
j =i +1
n i =1
1
n

Pn
i =1

1
1 + nm

1+

1+

1
j =i +1 m

Pn

1
i =1 (n i ) = 1 + nm

Pn

Pn1
k=0

1
1 + 2nm
.n(n 1) = 1 + n1
2m

1 + /2 + /(2n)

(1 + )

Si = n/m = O(1) (si le nombre de cases est proportionnel)


alors la recherche est en O(1)

Fonctions de hachage

La complexit en O(1) repose sur l'hypothse de hachage


simple uniforme
Problme : comment assurer cette hypothse ?

La distribution de probabilit des cls peut tre inconnue

L'indpendance des cls n'est pas forcment vrie

Si les cls sont indpendantes et uniformment rparties entre


[0, 1[ alors :

h(k) = bk.mc

vrie l'hypothse

Mais comment faire en gnral ?

Heuristiques : mthode de division, mthode de multiplication

Une bonne approche doit calculer le code hachage


indpendamment des patrons existants dans les donnes

Les cls sont supposes N, sinon on utilise un codage

e.g. codage ASCII : p=112 et t=116


tp=(116.128)+112=14960

La mthode de division

h(k) = k mod m

exemple : m = 12, k = 100 h(k) = 4


Avantage : mthode rapide. Il sut de diviser
Il faut viter certaines valeurs de m

m 6 2N sinon h(k) reprsente les p bits les


petits de k
l'idal c'est que h(k) dpende de tous les bits de k
exemple :

plus

Un nombre premier non trop proche d'une puissance de 2 est


gnralement un bon choix

Un bon exemple

Un bon exemple : table de hachage avec rsolution des


collisions par chainage
La table doit contenir peu prs 2000 chaines de caractres
Un caractre fait 8 bits
Examiner une moyenne de 3 lments dans une recherche
infructueuse est acceptable

= n/m = 3

On va choisir m = 701 car :


2000/3

nombre premier proche de

mais non proche d'aucune puissance de

h(k) = k mod 701

Un mauvais exemple
Mais attention, les choses ne sont pas toujours simples . . .

m = 2p 1
k une chaine de
P
k 0 = nj=0 a j 2 j p

caractre code dans la base

j > 0, a j 2 j p mod (2p 1) = a j mod (2p 1)

En eet, a j 2 j p = a j (2 j p 1 + 1) = a j + a j (2p ) j 1
P j 1
a j 2 j p = a j + (2p 1)( i =0 (2p )i ) et donc a j 2 j p
mod (2p 1) = a j mod (2p 1)
P
P
k 0 = nj=0 a j 2 j p donc k 0 mod (2p 1) = nj=0 a j mod (2p 1)

Btoutes les permutations d'une chaine k produisent le


mme code de hachage !

La mthode de multiplication

Problme de la mthode de division : la valeur de m est


critique (exemple prcdent)
La mthode de division permet de rsoudre ce problme
Mthode en deux temps :

h(k) = bm. (A.k mod 1)c

A ]0, 1[

une constante

En pratique on choisit m 2N : facilite l'implmentation

Hypothse :
la taille d'un mot sur la machine est w bits et k tient dans un
seul mot
On prend A = sw o s ]0..2w [ (s est un entier)
2

La mthode de multiplication

La mthode de multiplication

La mthode marche en principe A mais elle est encore


meilleure pour certaines valeurs
Le choix optimal dpend des caractristiques des donnes
haches

p
D. Knuth suggre que A 5 1 /2 est un bon choix

Exemple : k = 123456, p = 14, m = 214 = 16384,


p

On choisit A = s/232 proche de


5 1 /2

s = 2654435769
et

k.s = 327706022297664
32
k.s = 76300
+ 17612864
| {z }.2
| {z }
r1

r0

r 0 = 00000001000011
{z
}001100000001000000
|

00000001000011 3 + 64 = 67

h(k) = 67

14

bits

w = 32

Adressage ouvert

Dans l'adressage ouvert, tous les lments occupent la table


de hachage elle mme

Pas de chaine et pas d'lment l'extrieur de la table

Chaque case contient ou bien un lment ou bien nil


La table se remplit jusqu' ce que = 1 (plus aucune case
libre)
L'avantage : on conomise l'espace occup par les pointeurs
(et cellules) de la liste pour stocker directement des lments

plus de cases avec moins de collisions et recherche plus rapide

Insertion

Principe : pour insrer un lment, on examine la table


successivement jusqu' trouver une case libre pour stocker la
cl
La squence des positions examines dpend de la cl (et non
0 1 . . . m 1)
La fonction de hachage est tendu :
h:

U
|{z}

{0, 1, . . . , m 1}
{z
}
|

{0, 1, . . . , m 1}
|
{z
}

univers des cls rang de la tentative case dans la table


Pour chaque cl k la squence {h(k, 0), h(k, 1), . . . , h(k, m 1)}
est une permutation de {0, 1, . . . , m 1}

Ordre des examens

Insertion
Entre : un tableau T et une cl k
Resultat : k insre dans T si non prsente
procedure openAddressHashInsert(T, k )

1
2 i =0
3 repeat
4
j = h(k, i )
5
if T [ j ] == nil
6
T [j] = k
7
return j
8
9
10
11

then

else

i = i +1

until i == m ;
error "dbordement de la table de hachage"
Algorithme 25 : openAddressHashInsert

Recherche

L'algorithme de recherche d'une cl k examine la mme


squence examine lors de l'insertion de k
Si on trouve une case vide chec (sinon k aurait t insre
dans cette case)
une cl supprime ne libre pas sa case

Entre : un tableau T et une cl k


Resultat : la case qui contient k ou nil si non prsente
procedure openAddressHashSearch(T, k )

1
2 i =0
3 repeat
4
j = h(k, i )
5
if T [ j ] == k
6
return j
7
8
9

i = i +1

then

until T [ j ] == nilori == m ;
return nil
Algorithme 26 : openAddressHashSearch

Suppression

Cl k supprime la case

Sinon

contenant k est marque deleted

ne peut plus tre trouve

Il faut modier openAddressHashInsert pour traiter une case


deleted comme une case vide
Ce n'est pas la peine de modier openAddressHashSearch
Problme : le temps de recherche ne dpend plus du facteur

Quand l'opration de suppression est ncessaire on utilise le


chainage

Construction des squences d'examen

On souhaite avoir la proprit de hachage uniforme :

la probabilit d'avoir une squence d'examen d'une cl


1
les m! permutation est
m!

parmi

C'est une gnralisation de la notion de fonction de hachage


simple :

au lieu de produire un entier, on produit une squence


d'examen

Il est trs dicile de construire des vraie squences uniformes :

En pratique, on utilise des approximations

On va prsenter 3 techniques d'approximation : examen


linaire, examen quadratique et double hachage

Examens linaire et quadratique

h 0 : U {0, 1, . . . , m 1}

: fonction de hachage auxiliaire

Examen linaire

h(k, i ) = h 0 (k) + i mod m

Avantage : simple programmer


Problme : clusterisation primaire

Une case libre prcde de

cases pleines sera rempli la

prochaine tape avec la probabilit :

(i + 1)/m

Examen quadratique

h(k, i ) = h 0 (k) + c 1 i + c 2 i 2 mod m

se comporte mieux que l'examen linaire


mais soure du clustering secondaire

h(k 1 , 0) = h(k 2 , 0) h(k 1 , i ) = h(k 2 , i )

Double hachage

L'une des meilleures mthodes disponibles

h(k, i ) = (h 1 (k) + i .h 2 (k)) mod m

deux fonctions de hachage auxiliaires


L'examen initial vrie T [h1 (k)]
Les examens suivants sont des dcalages % la position
prcdente avec une valeur h2 (k)
h1 , h2

La squence dpend de

au dmarrage et par la suite (vs

examen linaire/quadratique)

h 2 (k)

doit tre relativement premier avec m


m premier et h 2 (k) ]0..m[
h 1 (k) = k mod m et h 2 (k) = 1 + (k mod m 0 )
0
de m (e.g. m = m 1)

sinon on peut choisir

exemple :
proche

m0

Exemple

Exemple d'insertion par double hachage

m = 13

h 1 (k) = k mod 13

h 2 (k) = 1 + k mod 11

h(k, i ) = (h 1 (k) + i .h 2 (k))


mod m

14 1[13]

et 14 3 mod [11]
h(14, 0) = 1 (la case 1 occupe
on passe)
h(14, 1) = (1 + 1.4) mod 13 (la
case 5 occupe on passe)
h(14, 2) = 9 la case est vide on y
insre 14

Complexit du hachage adressage ouvert


Theorem (Nombre moyen d'examens dans une recherche
infructueuse)
Soit une table de hachage adressage ouvert de facteur de charge
< 1. Le nombre moyen d'examens dans une recherche
infructueuse est d'au plus 1/(1 ) en supposant un hachage
uniforme

Theorem (Nombre moyen d'examens dans une recherche


fructueuse)
Soit une table de hachage adressage ouvert de facteur de charge
< 1. Le nombre moyen d'examens dans une recherche fructueuse
1
est d'au plus 1 . ln 1

Pour rsumer

Adressage ouvert :
meilleure utilisation de la mmoire (pas de pointeurs en plus)
Chainage :
moins sensible aux fonctions de hachage

AO doit faire attention aux problme de clustering

moins sensible au facteur de charge

AO se dgrade pour

> 0.7

et ne peut dpasser

=1

Quatrime partie
Stratgies

Plan

Programmation dynamique
Algorithmes gloutons
Diviser pour rgner
Tri par fusion
Tri rapide (quicksort)
Exploration des graphes

Stratgies

Nous allons aborder 3 techniques importantes de conception


algorithmes :

Programmation dynamique
Algorithmes gloutons
Diviser pour rgner
Nous avons dj vu d'autres techniques :
Approche incrmentale (tri par insertion)
Exploitation des proprits des S.D.
Rcurrence

des

Plan

Programmation dynamique
Algorithmes gloutons
Diviser pour rgner
Tri par fusion
Tri rapide (quicksort)
Exploration des graphes

Programmation dynamique

Rsout les problmes en combinant les solutions des sous


problmes (un peu comme diviser pour rgner)
Utile quand les sous problmes chevauchent (contrairement
DpR)
La programmation dynamique rsout chaque problme 1 seule
fois et stocke le rsultat pour d'autre usages (d'o l'intrt du
chevauchement)
Utile dans les problmes d'optimisation

tapes de la programmation dynamique

1.
2.
3.
4.

Caractriser la structure d'une solution optimale


Dnir rcursivement la valeur d'une solution optimale
Calculer la valeur d'une solution optimale
Construire une solution optimale partir de la valeur (info)
calcule

Programmation dynamique travers l'exemple

Problme de dcoupe optimale de tiges de fer


Problme du plus cours chemin (algorithme de Belleman-Ford)
Problme de la plus longue sous squence commune deux
squences

Premier exemple : dcoupe optimale de tiges de fer

Tiges de fer de mme taille standard


Si on dcoupe un l, chaque morceau a un prix
Comment maximiser le gain (la somme des prix) aprs
dcoupe ?
taille i
prix p i

1 2 3 4 5 6 7 8 9 10
1 5 8 9 10 17 17 20 24 30

Dcoupe optimale
Exemple : des tiges de taille = 4

La solution optimale dans ce cas est de dcouper en 2 pices de


taille identique = 2
Le gain maximal = 5 + 5 = 10
Le problme : algorithme pour rsoudre le problme (et non pas
l'instance)

Dcoupe optimale

1re solution (nave) : numrer tous les dcoupages possibles

n1
Problme : complexit exponentielle. Il y a 2
= 2n /2

Pk=n k k nk
n
C x y
dcoupage possibles ... (x + y) =
k=0 n

Sinon ... on analyse le problme


caractriser
la solution optimale :

r n = max p n , r 1 + r n1 , r 2 + r n2 , . . . , r n1 + r 1

Problme initial dcompos en plusieurs problmes similaires


mais sur des instances plus petites

la solution optimale globale utilise des solutions optimales des


sous problmes dnis (solvables indpendamment)

Le problme de dcoupe optimale prsente une sous

structure optimale

rn

peut tre encore simplie : r n = max

p i + r ni

Solution rcursive
La formule r n = max p i + r ni suggre d'utiliser diviser pour
rgner (solution rcursive)

1
2
3

Entre : un tableau p et un entier n indiquant la longueur o


couper
Resultat : le gain maximum
function couperTigeRec(p, n )
if n == 0 then
return 0

4 q =
5 for i = 1 to n do

6
q = max q, p[i ] + couperTigeRec(p, n i )
7

return q
Complexit ?

Algorithme 27 : couperTigeRec

Analyse de la complexit de la solution rcursive


On caractrise T (n) le cot de recherche d'une solution optimale
sur une tige de taille n :
T (n) = 1 +
T (n) +

Pn1
i =0

Pn1
i =0

T (i )

T (i ) = 1 + 2.

Pn1
i =0

T (i )

S(n) = 1 + 2.S(n 1) S 0 (n) = 2.S 0 (n 1)


S 0 (n) = 2n

et donc S(n) = 2n 1 et T (n) +

donc 2.T (n) =2n (puisque 1 +


nalement T (n) = 2n1

Complexit exponentielle

Pn1
i =0

Pn1
i =0

T (i ) = 2n 1

T (i ) = T (n))

La programmation dynamique la rescousse

Le problme avec DpR : on calcule la mme chose plusieurs


fois :

89:;
?>=<
jjj 4 <U<UUUUUUU
j
j
j
UUUU
<
jj
UUUU
jjjj
j
j
u
*?>=<
89:;
?>=<
89:;
?>=<
89:;
3 I
2
1
m
m
I
<
m
II
m
<

m
m
<

I
m
m



I
$
vmmm
89:;
?>=<
?>=<
89:;
89:;
?>=<
89:;
?>=<
?>=<
89:;
89:;
?>=<
0
0
0
2
1
1
 <<<




89:;
?>=<
?>=<
89:;
?>=<
89:;
89:;
?>=<
0
0
0
1

?>=<
89:;
0

Solution : faire en sorte de ne le faire qu'une fois

&?>=<
89:;
0

Approches

Approche top-down : utilise la technique de mmoisation

une fois une valeur calcule, on la mmorise (dans un tableau


par exemple) pour usage ultrieur

pas besoin de recalculer

Approche bottom-up : repose sur une relation d'ordre sur la


taille du sous problme :

dans l'exemple prcdent le calcul de


tous les

ri

tels que

on calcule

r0

rk

ncessite le calcul de

i <k

ensuite

r1

puis

notion de tri topologique

r2

puis

r3,

...

Version mmoise

1
2
3
4
5
6
7
8
9

Entre : un tableau p et un entier n indiquant la longueur o


couper et un tableau r
Resultat : le gain maximum
function couperTigeMemAux(p, n, r )
if r [n] 0 then
return r [n]
if n == 0 then
q =0

else

q =

for i = 1 to n do

q = max q, p[i ] + couperTigeMemAux(p, n i , r )

10 r [n] = q
11 return q

Algorithme 28 : couperTigeMemAux

Version mmoise

1
2
3
4
5

Entre : un tableau p et un entier n indiquant la taille de la tige


Resultat : le gain maximum
function couperTigeMem(p, n )
Soit r [0..n] un nouveau tableau
for i = 1 to n do
r [i ] =

return couperTigeMemAux(p, n, r )
Algorithme 29 : couperTigeMem
Complexit en O

2
n

Version bottom-up
Entre : un tableau p et un entier n indiquant la taille de la tige
Resultat : le gain maximum
function couperTigeBotUp(p, n, r )
Soit r [0..n] un nouveau tableau

1
2
3 r [0] = 0
4 for j = 1 to n do
5
q =
6
for i = 1 to j do

7
q = max q, p[i ] + r [ j 1]
8

r [j] = q

return r [n]

Algorithme 30 : couperTigeBotUp

Complexit en O

2
n

Plan

Programmation dynamique
Algorithmes gloutons
Diviser pour rgner
Tri par fusion
Tri rapide (quicksort)
Exploration des graphes

Algorithmes gloutons

Un problme d'optimisation = squence d'tapes


Dans chaque tape il faut faire un choix parmi plusieurs
possibilits
Cela ressemble aux problmes traits par la programmation
dynamique
la programmation dynamique est justement parfois
disproportionne
Un algorithme glouton choisit chaque tape l'option qui
semble la meilleure parmi celles possibles

Une sorte de suite d'optimisations locales successives vers une


optimisation globale

Exemples : arbre de recouvrement minimal d'un graphe, plus


court chemin dans un graphe acyclique (Dijkstra), codes de
Human, . . .

Exemple explicatif : problme de choix de tches

Problme de planication de plusieurs tches concurrentes


Une ressource partage entre toutes les tches accessible en
exclusion mutuelle

A un instant donne, une seule tche peut tre active

Objectif : choisir le plus grand nombre de tches mutuellement


compatibles
S 1 = {a 1 , . . . , a n } ensemble de tches
Chaque tche ai a un instant de dbut si et de n f i

Une tche est active pendant si , f i

a i et a j sont mutuellement compatibles ssi s i , f i s j , f j = ;


Hypothse de simplication : f 1 f 2 . . . f n

Instance du problme

10

11

si
fi

1
4

3
5

0
6

5
7

3
9

5
9

6
10

8
11

8
12

2
14

12
16

{a 3 , a 9 , a 11 }

optimale

tches mutuellement compatibles mais non

est plus grande (elle est en fait optimale)


{a 2 , a 4 , a 9 , a 11 } est une autre solution optimale

{a 1 , a 4 , a 8 , a 11 }

Rsolution du problme
On va rsoudre le problme en plusieurs tapes
1. Essayer de rchir une solution de type programmation
dynamique

plusieurs choix pour choisir les sous problmes de la solution


optimale

2. Pour cet exemple, on verra qu'il sut de considrer un seul


choix

le choix glouton

3. Solution rcursive du problme


4. Transformation de la solution rcursive en itrative

Sous structure optimale du problme

: ensemble de tches qui dmarrent aprs la n de


qui se terminent avant le dbut de a j

Si j

ai

et

S i j = ak | f i sk f k s j

On cherche une ensemble maximal A i j de tches compatibles


dans S i j
Soit ak A i j
A i j = A i k {a k } A k j o A i k = A i j S i k et A k j = A i j S k j

|A i j | = |A i k | + |A k j | + 1

A i j contient galement les solution optimales de S i k et S k j


( A i k et A k j sont des solutions optimales pour S i k et S k j )

Sinon on aurait

Ai j

A i k {a k } A k j

solution de

Si j

et suprieure

La programmation dynamique une bonne solution ?

c i , j = c (i , k) + c k, j + 1

Comme on ne connait pas exactement quel



c i, j =

0
max {c (i , k) + c (i , k) + 1}
a k S i j

ak

choisir :

si S i j = ;
sinon

Problme solvable en programmation dynamique (algorithme


rcursif + mmosation)
Mais . . . est ce qu'on ne peut pas faire mieux ? . . .

Faire le choix glouton

L'ide pour faire mieux est d'essayer de ne considrer qu'un


seul choix (le choix glouton)
Problme : il faut une condition susante pour que le choix
glouton implique une solution optimale
Par exemple, intuitivement si on choisit systmatiquement la
tche qui se termine le plus tt, on laisse plus de temps pour
plus de tches . . .
Aprs le choix glouton,
il reste un seul sous problme :

S k = a i S|s i f k (toutes les tches qui dmarrent aprs la


n de ak )
La question est : est-ce que l'intuition (choisir la tche la
premire nir) est correcte ?

Correction de l'intuition
Theorem

Soient S k 6= ; un sous-problme et am S k telle que am est la


premire terminer (dans S k ).
a m appartient une sous-ensemble maximum de tches de S k
mutuellement compatibles

Dmonstration.

un ensemble maximum solution de S k .


a j A k est celle qui termine la premire
Si a j = am alors c'est OK (am A k )
0
Sinon, soit A k = A k {a j } {am }
0
Les tches de A k sont disjointes : celles de
la premire terminer dans A k et f m f j
Ak

(toutes les autres tches


donc aprs

|A k | = |A k |

a i 6= a j

fm )

et donc

Ak

est maximal

de

Ak

Ak

le sont et a j est

dmarrent aprs

fj

et

Algorithme glouton rcursif

On choisit la tche ak qui termine la premire


On ne garde que les tches compatibles avec ak
On rpte jusqu' la n des tches
Les instants de n sont croissants
Une tche n'est considre qu'une seule fois

Algorithme glouton rcursif


Entre : un tableau s des instants de dbut, un tableau f des
instants de n, un indice k pour dnir le sous-problme
S k rsoudre et la taille n du problme d'origine
Resultat : un sous ensemble de tches mutuellement compatibles
maximum
function tchesCompatiblesMax( f , s, k, n )

1
2 m = k +1
3 while m n and s[m] < f [k]
4
m = m +1
5
6
7
8

if

do

then
return am tchesCompatiblesMax( f , s, m, n )
else
return ;
Algorithme 31 : tchesCompatiblesMax
On appelle tchesCompatiblesMax( f , s, 0, n )
Si les f i sont tris alors complexit en (n) (durant tous les
appels rcursifs, une tche n'est traite qu'une seule fois)
mn

Une autre faon de voir les algorithmes gloutons

Rsolution d'un problme de manire optimale. Pour construire


la solution du problme, on a un ensemble (ou liste) C de
candidats (les direntes tches e.g. )
Lors du droulement de l'algorithme on accumule deux
ensembles :

Un ensemble

des candidats dj traits et retenus (ils ne

seront plus traits)

Un ensemble

des candidats dj traits et rejets (ils ne

seront plus traits)

Il existe une fonction sol ut i on qui vrie si un ensemble de


candidats fournit une solution au problme (sans tenir compte
de l'optimalit)

Une autre faon de voir les algorithmes gloutons

Une autre fonction f ai sabl e vrie si un ensemble de


candidats peut tre tendu avec un nouvel lment vers une
solution
Une fonction de slection sel ect i on indique tout moment
quel est le candidat non encore trait le plus prometteur (a
sera le choix glouton)
Enn une fonction objectif qui donne le rsultat trouv

Algorithme glouton gnral itratif


Entre : un ensemble C
Resultat : un sous-ensemble S de C optimal
function gloutonIteratif (C )
; // C est l'ensemble de candidats

1
2
3 S = ; // Le sous-ensemble solution
4 while C 6= ; and not sol ut i on(S) do
5
x = sel ec t i on(C )
6
C =C x
7
if f ai sabl e(S x) then
8
S =Sx
9
10
11
12

if

sol ut i on(S)
return S

est construit dans S

then

else
return "Pas de solution"
Algorithme 32 : gloutonIteratif

Application notre exemple

C = {a 1 , . . . , a n }

sol ut i on a i 1 , . . . , a i l = vr ai ssi les a i j mutuellement


compatibles et C = ; (ceci est un cas particulier)
sel ec t i on (C )

encore traite

f ai sabl e

retourne la premire tche terminer non

ai 1 , . . . , ai l

ssi les

a i j mutuellement

compatibles

Exemple : Problme du sac dos

Problme du sac dos (version simple)


Un ensemble d'articles U = {u 1 , u 2 , . . . , u N }
Chaque article a un poids p i et une valeur v i (p i , v i N)
Le poids maximum que peut contenir le sac dos P
Comment choisir des fractions des articles mettre dans le sac
dos pour maximiser la valeur globale transporte ?

Problme du sac dos : construire une solution gloutonne

Chaque article i choisi contribue avec xi p i dans le poids total


et avec xi v i dans la valeur globale transporte
Il s'agit de rsoudre :

Pn

i =1 x i v i
sous la contrainte P

avec

maximiser

P
ni=1 x i p i
v i > 0, p i > 0 et 0 x i 1

Solution gloutonne : les candidats sont les dirents objets


La solution = {x1 , . . . , xn } est faisable si elle respecte les
contraintes
la fonction objectif = valeur totale transporte
P
Remarque
: si ni=1 p i P alors la solution est triviale . . . et si
Pn
i =1 x i p i < P alors on peut toujours ajouter une fraction pour
remplir
P
dans une solution optimale : ni=1 x i p i = P

Algorithme glouton
1
2
3
4
5
6
7
8
9
10
11
12

Entre : un ensemble C et un poids maximimum P du sac dos


Resultat : une conguration x1 , . . . , xn opt i mal e
function sacADosGlouton(C , P )
// C est un ensemble
S =;
for i = 1 to n
x[i ] = 0
poi d s = 0

while C 6= ; and poi d s < P do


c = sel ect i on(C )
C =C c
if poi d s + c.poi d s P then
x[i ] = 1
poi d s = poi d s + c.poi d s

else

x[1] = (P poi d s)/c.poi d s


poi d s = P

13
14
15

do

d'articles
// Le sous-ensemble solution est construit dans S
// initialisation

return x

Algorithme 33 : sacADosGlouton

Algorithme glouton

La question est comment choisir le bon candidat ?


chaque fois au moins trois possibilits :

Choisir l'article restant ayant la plus grande valeur

Choisir l'article restant le plus lger

Choisir l'article restant ayant le meilleur rapport

v i /p i

Exemple : pour n = 5 et P = 100


p
v
v/p

10 20 30 40 50
20 30 66 40 60
2.0 1.5 2.2 1.0 1.2

slection
max v i
min p i
max v i /p i

valeur

xi
0
1
1

0
1
1

1
1
1

0.5
1
0

1
0
0.8

146
156
164

Solution optimale

Les deux premiers critres ne sont pas optimaux, le troisime


l'est-il ?
La rponse est oui.
Pourquoi ? : le thorme suivant

Theorem

Si les articles sont choisis dans l'ordre dcroissant des v i /p i alors


sacADosGlouton trouve une solution optimale.

Dmonstration.
On suppose (s.p.g.) que v 1 /p 1 v 2 /p 2 . . . v n /p n .
X = (x 1 , . . . , x n ) solution optimale.

Solution optimale
Dmonstration.
(suite)
Si tous les x i = 1 alors la solution est optimale
Sinon, soit j le plus petit indice tq x j < 1
Pn
i < j x i = 1 et i > j x i = 0 et
i =1 x i p i = P

Pn
Soit Y = y 1 , . . . , y n une solution ralisable. donc
i =1 y i p i P
Pn
et i =1 (xi y i )p i 0
Pn

y i )p i . pv ii

V (X ) V (Y ) =

On va montrer que (xi y i )(v i /p i ) (xi y i )(v j /p j )

Si

Si

si

i =1 (x i

i < j , x i = 1 et donc (x i y i ) 0 et v i /p i v j /p j
i > j , x i = 0 et donc (x i y i ) 0 et v i /p i v j /p j
i = j , x i = y i et donc (x i y i )(v i /p i ) = (x i y i )(v j /p j )

V (X ) V (Y ) (v j /p j )

Pn

i =1 (x i

y i )p i 0

Aucune solution ralisable n'est meilleure que V (X )

Limites de l'approche gloutonne

Le problme du sac dos entier est une variation du problme


prcdent
Pas de fractions : ou bien un article est retenu ou bien il ne
l'est pas
Exemple : n = 3 et P = 50
p
v
v/p

10 20
30
60 100 120
6
5
4

Une stratgie gloutonne commencerait par choisir l'article 1


160
180

ou bien 1 + 2 : valeur =

ou bien 1 + 3 : valeur =

Solutions non optimales ! !

La solution optimale dans ce cas est 2 + 3 : valeur = 220


La programmation dynamique permet de rsoudre le problme
Mais c'est un problme trs coteux (on ne lui connait aucune
solution polynomiale)

Plan

Programmation dynamique
Algorithmes gloutons
Diviser pour rgner
Tri par fusion
Tri rapide (quicksort)
Exploration des graphes

Tri par fusion : la fusion


Complexit linaire : (n)

Entre : un tableau T , trois indices p, q, r

tels que

T [p..q]

sont tris

1
2
3
4
5
6
7
8
9
10
11
12
13
14

Resultat : T [p..r ] est tri


procedure fusion(T, p, q, r )
n1 = q p + 1
n2 = r q
Soient G[1..n 1 + 1] et D[1..n 2 + 1]
G[1..n 1 ] = T [p..n 1 ]
G[1..n 1 ] = T [q..n 2 ]
G[n 1 + 1] =
D[n 2 + 1] =
i = j =1
k=p
r
G[i ] D[ j ]
T [k] = G[i + +]

for

to do

if

deux nouveaux tableaux

then

else

T [k] = D[ j + +]

Algorithme 34 : fusion

et

T [q + 1, r ]

Tri par fusion


Complexit en (n lg n) : si n 2N alors

1
2
3
4
5
6

t (n) = 2t (n/2) + (n)

Entre : un tableau T , deux indices p, r


Resultat : T est tri
procedure triFusion(T, p, r )
if p < r then
q = (p + r )/2

triFusion(T, p, q )
triFusion(T, q + 1, r )
fusion(T, p, q, r )
Algorithme 35 : triFusion

Quicksort

algorithme de tri de complexit dans le pire cas en (n 2 )


mais en pratique c'est le meilleur :

complexit moyenne en

(n lg(n))

et constantes caches faibles

eectue le tri sur place


fond sur la stratgie diviser pour rgner
diviser : partitionner en rarrangeant T [p..r ] en 2 sous
tableaux T1 = T [p..q 1] et T2 = T [q + 1..r ] tq
T [i ] T [q] T [ j ] pour i [p..q 1] et
j [q + 1..r ]. Le calcul de q est le rsultat de
cette procdure
rgner : trier T1 et T2 rcursivement par quicksort
combiner : il n'y a rien faire ...

Quicksort : l'algorithme

1
2
3
4
5

Entre : un tableau T , deux indices p, r


Resultat : T [p..r ] tri
procedure quicksort(T, p, r )
if p < r then
q = partitionner(T, p, r )
quicksort(T, p, q 1)
quicksort(T, q + 1, r )
Algorithme 36 : quicksort
Pour trier un tableau T il sut d'excuter quicksort(T, 1, T.t ai l l e )

Quicksort : partitionner
Entre : un tableau T , deux indices p, r
Resultat : q la position du pivot
function partitionner(T, p, r )

1
2 x = T [r ]
3 i = p 1
4 for j = 1 to r 1 do
5
if T [ j ] x then
6
i = i +1
7
changer T [i ]
8 q = i +1
9 changer T [q]
10 return q

et T [ j ]

et T [r ]

Algorithme 37 : partitionner

Exemple

est le pivot x
Les lments en gris clair =
premire partition (tous x )
Les lments en gris fonc =
deuxime partition (tous > x )
Les autres ne sont pas encore
traits
(Le dernier lment est le pivot)
A la dernire tape on change
T [r ] et T [i + 1]
T [r ]

Quicksort : comment a marche ?

Si T [ j ] > x , on incrmente j
Si T [ j ] x on incrmente i , puis on change T [i ] et T [ j ]
enn on incrmente j

Quicksort : complexit dans le pire cas

On va dmontrer que dans le pire cas T (n) = (n 2 )


On dmontre que T (n) = O(n 2 ) et T (n) = (n 2 )
Dans le pire cas on a l'quation de rcurrence

T (n) = max

0qn1

S. q. T (k) ck 2

T (q) + T (n q 1) + (n)

k n 1

et remplaons dans la rcurrence

T (n) max (c q + c(n q 1)2 ) + (n) =


0qn1

c. max (q 2 + (n q 1)2 ) + (n)


0qn1

Le maximum est atteint pour q = 0 ou q = n 1


donc max (q 2 + (n q 1)2 ) (n 1)2
0qn1

et T (n) cn 2 c(2n 1) + (n) cn 2 en prenant c


susamment grande pour que c(2n 1) domine le terme en
(n)

Attention aux conditions aux limites ! ! !


Donc T (n) = O(n 2 )

Quicksort : complexit dans le pire cas

On dmontre que T (n) = (n 2 )


Dans le pire cas on a l'quation de rcurrence

T (n) = max

0qn1

S. q. T (k) d k 2

T (q) + T (n q 1) + (n)

k n 1

et remplaons dans la rcurrence

T (n) max (d .q + d .(n q 1)2 ) + (n) d .(n 1)2 + (n)


0qn1

et T (n) d .n 2 d (2n 1) + (n) d n 2 en prenant d


susamment petite pour que d (2n 1) soit domin par le
terme en (n)
Attention aux conditions aux limites ! ! !
Donc T (n) = (n 2 )

Conclusion : T (n) = (n 2 ) dans le pire cas

Quicksort : complexit dans le meilleur cas


On va dmontrer que dans le meilleur cas T (n) = (n lg n)
Dans le meilleur cas :

T (n) = min

0qn1

T (q) + T (n q 1) + (n)

S. q. T (k) c.k lg k

k n 1 et remplaons dans la rcurrence

T (n) min c.q lg q + c.(n q 1) lg(n q 1) + (n)


0qn1

avec

T (n) c.q 0 lg q 0 + c.(n q 0 1) lg(n q 0 1) + (n)


q 0 = (n 1)/2

T (n)
c. ((n 1)/2) lg ((n 1)/2) + c. ((n 1)/2) lg ((n 1)/2) + (n)

donc T (n) c.(n 1) lg(n 1) c.(lg 2.)(n 1) + (n)


et T (n) c.n. lg(n) (car n lg n %) en choisissant c telle que
c.(lg 2.)(n 1) domine la fonction en (n)
Attention aux conditions aux limites (il faut les vrier) . . .
Donc T (n) = O(n lg n) dans le meilleur cas

Quicksort : complexit dans le meilleur cas


On va dmontrer que dans le meilleur cas T (n) = (n lg n)

T (q) + T (n q 1) + (n)

T (n) = min

S. q. T (k) c.k lg k

0qn1

k n 1 et remplaons dans la rcurrence

T (n) min c.q lg q + c.(n q 1) lg(n q 1) + (n)

f 0 (q) = c.q lg q + c.(n q 1) lg(n q 1) = lg q/(n q 1)

0qn1

lim f 0 (q) =

q0+

et

lim f 0 (q) = +

qn1

et

f 00 (q) = (n 1)(n 1 q)/(n q 1)2 0


et traverse 0 en q0 tq f 0 (q0 ) = 0

donc

f 0 : % 0 %+

Quicksort : complexit dans le meilleur cas

est donc : & q0 % (minimum atteint en q0 )


q 0 = n q 0 1 q 0 = (n 1)/2 : l'optimum est atteint quand
on divise le tableau en deux
f

T (n)
c. ((n 1)/2) lg ((n 1)/2) + c. ((n 1)/2) lg ((n 1)/2) + (n)

donc T (n) c.(n 1) lg(n 1) c.(lg 2.)(n 1) + (n)


et T (n)

c.n lg n + c.(n 1) lg(n 1) cn lg n c.(lg 2.)(n 1) + (n)

Quicksort : complexit dans le meilleur cas

or c.(n 1) lg(n 1) cn lg n = n lg (1 + 1/(n 1)) lg(n 1)


et lg (1 + 1/(n 1)) 1/(n 1) (D. L. de log au voisinage de 1)
donc c.(n 1) lg(n 1) cn lg n 1 lg(n 1) lg(n)
donc c.(n 1) lg(n 1) cn lg n c.(lg 2.)(n 1) + (n)
lg(n) c n + (n)

on choisissant c susamment petite pour que la fonction en


(n) domine lg(n) + c n
On a T (n) c.n. lg(n)
Attention aux conditions aux limites (il faut les vrier) . . .
Donc T (n) = (n lg n) dans le meilleur cas

Donc T (n) = (n lg n)

Quicksort : complexit en moyenne

On suppose que les lments sont quitablement rpartis

Probabilit pour choisir un lment comme pivot parmi


lments =

1/n

Temps d'excution de Quicksort domin par les appels


par t i t i on

Chaque appel par t i t i on choisit un pivot


un pivot choisit n'est plus jamais choisi aprs
au plus n appels par t i t i on

Quicksort : complexit en moyenne


Complexit de par t i t i on
O(1) : toutes les oprations
sauf la boucle for (lignes 4
7)
1
2
une quantit proportionnelle
au nombre d'itration de la 3
4
boucle for (lignes 4 7)
Chaque itration eectue une 5
comparaison entre le pivot et 6
un autre lment du tableau 7
(ligne 5)
8
Il faut donc compter le
9
nombre total de
10
comparaisons

Entre : un tableau T , deux


indices p, r
Resultat : q la position du pivot
function partitionner(T, p, r )
x = T [r ]
i = p 1
for j = 1

to r 1 do
if T [ j ] x then
i = i +1

changer T [i ] et T [ j ]
q = i +1

changer T [q] et T [r ]
return q
Algorithme 38 : partitionner

Quicksort : relation entre la complexit et le nombre de


comparaison

Lemme
Soit X le nombre de comparaisons excutes dans la ligne 5 de
par t i t i on durant toute la dure d'une excution de qui cksor t
sur un tableau de taille n
Le temps d'excution de qui cksor t est O(n + X )
Dmonstration.
Preuve immdiate

Quicksort : valuation de X

On va compter le X global (et non pas combien de


comparaisons chaque itration)
`
Z = {z 1 , . . . z n } o z i est le i eme
plus petit lment

Zi j = {z i , z i +1 , . . . , z j }

Quand est ce qu'on compare zi et z j ?


chaque paire est compare au plus une fois

X i j {0, 1} variable alatoire


zj
P
Pn
X = n1
i =1
j =i +1 X i j

et

on ne compare qu'avec le pivot qui n'est utilis qu'une fois

de l'vnement comparaison de

zi

Quicksort : valuation de X

hP
i
n1 Pn
X
E [X ] = E
i
j
i =1
j =i +1

Pn1 Pn
E [X ] = i =1 j =i +1 E X i j

P
Pn
E [X ] = n1
i =1
j =i +1 P r z i est

compar z j
z i est compar z j ssi z i ou z j est le pivot de Zi j

P r z i soit choisit comme pivot = j i1+1 (les lments sont


quiprobables)
Pn
P
1
donc E [X ] = 2. in1
=1
j =i +1 j i +1 soit par changement de
variable (k = j i )
1
k=1 k

Pn1 Pn

E [X ] = 2.

E [X ] = O(n lg n)

i =1

Plan

Programmation dynamique
Algorithmes gloutons
Diviser pour rgner
Tri par fusion
Tri rapide (quicksort)
Exploration des graphes

Vous aimerez peut-être aussi