Upload
anas-el-akrami
View
222
Download
0
Embed Size (px)
Citation preview
8/3/2019 ProgDynamique
1/168
Algorithmique, graphes etprogrammation dynamique
Notes de Cours
Rapport de Travaux Pratiques
Laurent Canet
Le 2 juillet 2003
8/3/2019 ProgDynamique
2/168
Table des matieres
I IN202 - Algorithmique 6
1 Systeme formel de preuve de programme de OHare 81.1 Regles et axiomes . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2 Construction de programmes sur invariant . . . . . . . . . . . . . 9
2 Problemes de recherches 112.1 Remarques sur levaluation de complexite dun programme . . . . 112.2 Recherche dichotomique . . . . . . . . . . . . . . . . . . . . . . . 112.3 Recherche sequentielle . . . . . . . . . . . . . . . . . . . . . . . . 132.4 Recherche arriere . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3 Problemes de tris 163.1 Slowsort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.2 Quicksort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3 Complexite minimum dun algorithme de tri . . . . . . . . . . . . 21
4 Approche diviser pour regner 234.1 Diviser pour regner . . . . . . . . . . . . . . . . . . . . . . . . . . 234.2 Limites de lapproche diviser pour regner . . . . . . . . . . . . . . 24
5 Complexite des algorithmes 255.1 Expression du temps de calcul . . . . . . . . . . . . . . . . . . . . 255.2 Notations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265.3 Calculs courants dans le calcul des complexites . . . . . . . . . . . 275.4 Un peu de theorie de la complexite . . . . . . . . . . . . . . . . . 27
6 Programmation Dynamique 296.1 Cas concret : fibonnaci . . . . . . . . . . . . . . . . . . . . . . . . 296.2 Exemple : Multiplication de matrices . . . . . . . . . . . . . . . . 306.3 Exemple : Recherche du plus long sous-mot commun a 2 chaines . 33
1
8/3/2019 ProgDynamique
3/168
II IN311 - Programmation dynamique 36
7 Applications de la programmation dynamique 387.1 Un probleme dassortiment . . . . . . . . . . . . . . . . . . . . . . 387.2 Compression dimage . . . . . . . . . . . . . . . . . . . . . . . . . 407.3 Justification de Parapgraphes . . . . . . . . . . . . . . . . . . . . 43
III IN302 - Graphes et algorithmes 45
8 Notions de base 468.1 Premiere definition . . . . . . . . . . . . . . . . . . . . . . . . . . 468.2 Representation en memoire . . . . . . . . . . . . . . . . . . . . . . 478.3 Definitions complementaires . . . . . . . . . . . . . . . . . . . . . 508.4 Chemins, connexite . . . . . . . . . . . . . . . . . . . . . . . . . . 538.5 Representation matricielle . . . . . . . . . . . . . . . . . . . . . . 598.6 Graphe biparti . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
9 Arbre et arborescences 629.1 Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629.2 Exemples et applications . . . . . . . . . . . . . . . . . . . . . . . 649.3 Arbre de poids minimum . . . . . . . . . . . . . . . . . . . . . . . 679.4 Algorithmes de Kruskal . . . . . . . . . . . . . . . . . . . . . . 69
10 Plus courts chemins 7110.1 Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7110.2 Problematique du plus court chemin . . . . . . . . . . . . . . . . 7210.3 Algorithme de Floyd . . . . . . . . . . . . . . . . . . . . . . . . 7410.4 Algorithme de Bellman . . . . . . . . . . . . . . . . . . . . . . . 7510.5 Algorithme de Dikstra . . . . . . . . . . . . . . . . . . . . . . . 7810.6 Plus courts chemins (Exploration largeur) . . . . . . . . . . . . . 8010.7 Graphes sans circuits : GSC . . . . . . . . . . . . . . . . . . . . . 81
11 Cycles euleriens et hamiltoniens 8611.1 Cycle eulerien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
11.2 Cycle hamiltonien . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
12 Flots et reseaux de transport 8812.1 Modelisation dun reseau de transport . . . . . . . . . . . . . . . 8812.2 Proprietes dun reseau de transport . . . . . . . . . . . . . . . . . 8912.3 Algorithme de Ford et Fulkerson . . . . . . . . . . . . . . . . 90
2
8/3/2019 ProgDynamique
4/168
13 Resolutions de problemes en Intelligence artificielle et optimisa-tion 9413.1 Exemple : le probleme des 8 dames . . . . . . . . . . . . . . . . . 9413.2 Strategies de recherche . . . . . . . . . . . . . . . . . . . . . . . . 9513.3 Algorithme A et A . . . . . . . . . . . . . . . . . . . . . . . . . . 97
IV Annexes 99
A TP1 - Tri par tas 100A.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100A.2 Equations Booleennes . . . . . . . . . . . . . . . . . . . . . . . . . 100A.3 Tas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
A.4 Comparaison avec dautres algorithmes de tri . . . . . . . . . . . 106B TP2 - Arbres de recherche optimaux 110
B.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110B.2 Preliminaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111B.3 Recherche dans un arbre . . . . . . . . . . . . . . . . . . . . . . . 112B.4 Arbre binaire de recherche optimal . . . . . . . . . . . . . . . . . 114B.5 Optimisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
C TP3 - Sommes de sous-ensembles 130C.1 Premier algorithme . . . . . . . . . . . . . . . . . . . . . . . . . . 130
C.2 Deuxieme algorithme . . . . . . . . . . . . . . . . . . . . . . . . . 131C.3 Optimisation & parallelisation . . . . . . . . . . . . . . . . . . . . 135C.4 Code source commente . . . . . . . . . . . . . . . . . . . . . . . . 137
D TP IN311 : le sac a ados 141D.1 Position du probleme . . . . . . . . . . . . . . . . . . . . . . . . . 141D.2 Equation du recurrence . . . . . . . . . . . . . . . . . . . . . . . . 141D.3 Complexite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142D.4 Reconstruction de la solution . . . . . . . . . . . . . . . . . . . . 142D.5 Exemples dexecution . . . . . . . . . . . . . . . . . . . . . . . . . 142D.6 Programme complet et commente . . . . . . . . . . . . . . . . . . 144
E Corrections de TD IN302 147E.1 TD 1 : Recherche de circuits . . . . . . . . . . . . . . . . . . . . . 147E.2 Le probleme de laffectation . . . . . . . . . . . . . . . . . . . . . 149E.3 Le probleme de la carte routiere . . . . . . . . . . . . . . . . . . . 150E.4 Le probleme du voyageur de commerce . . . . . . . . . . . . . . . 150
F Graphes TP 2 - Analyse de trajectoires dans une chambre abulle 151
3
8/3/2019 ProgDynamique
5/168
G Graphes TP 3 - Ballades dans le metro 158
4
8/3/2019 ProgDynamique
6/168
Introduction
Ce texte na aucune valeur officielle de support pour les cours concernes. Ilcontient vraisemblablement beaucoup derreurs et dinexactitudes, le lecteur sereportera a un ouvrage de reference pour les verifications.
Le rapport de TP de programmation dynamique a ete co-ecrit avec monbinome Thibaut Varene. Les sujets et les rapports de travaux pratiques degraphes ont ete ecrit par Gilles Bertrand et Michel Couprie.
5
8/3/2019 ProgDynamique
7/168
Premiere partie
IN202 - Algorithmique
6
8/3/2019 ProgDynamique
8/168
Introduction au coursdalgorithmique
Ce document fut a lorigine mes notes du cours dIN202 de lESIEE Paris.Cette unite a pour but dinitier les eleves ingenieurs a lalgorithmique grace a des
exemples detaillees. Le cours etait divise en 2 grandes parties, dabord un apercude lalgorithmique ainsi que de la notion de complexite en sappuyant sur desexemples tels que le quicksort, puis une description de lapproche dite de pro-grammation dynamique. Des notions de programmation en C ainsi des connais-sances basiques en analyses sont requises pour comprendre ce cours. Dautresunites du tronc commun ou de la majeure informatique de lESIEE Paris elar-gissent et approfondissent le sujet.
Mes notes de cours datent de mi-2002. Durant lete de cette annee jai enrichile cours notament de la notion de classe de probleme ainsi que des demonstra-
tions, notament la complexite minimale dun algorithme de tri ; finalement jaidecide de les publier sur ma page web.
Ces notes de cours ne constituent en rien un support officiel, il faut impe-rativement se referer a un ou des ouvrages specialises qui seront cites dans unebibliographie (qui na pas encore ete faite).
Je nai en aucun cas la pretention de faire un document interessant, exactou precis. Neanmoins Si vous estimez que je racontre vraiment nimporte quoi,signalez le moi sur mon email : [email protected].
7
8/3/2019 ProgDynamique
9/168
Chapitre 1
Systeme formel de preuve deprogramme de OHare
On peut formaliser un programme en une forme logique dite de bote noire :
ELogique du 1er ordre
PProgramme
SLogique du 1er ordre
De la, plusieurs regles agissent sur ces enonces :
1.1 Regles et axiomes
Regle de la post-condition :
EP S ; S S EP S
Regle de la pre-condition :
EP S ; E E EP S
Regle du ou :
EP S ; EP S (E E)P S
Regle du et :EP S ; EP S EP(S S)
8
8/3/2019 ProgDynamique
10/168
Regle du si-sinon :
(E B)P S ; (E B)QS E {Si B alors P sinon Q} S
Remarque : Levaluation de B ne doit pas modifier E.
Regle du tant-que :
(E B)P E ; E{tant que B faire P}(E B)
Axiomes daffectation :
EP A ; AQS E{P; Q}S
Exemple : Demontrer :
EP S ; EP S (E E)P(S S)
1. EP S
2. EP S
3. E E E
4. (E E)P S (Precondition sur 1 et 3)
5. (E E)P S (Precondition sur 2 et 3)
6. (E E)P(S S) (Regle du ET sur 4 et 5)
7. (S S) (S S)
8. (E E)P(S S) (Postcondition sur 7 et 8)
1.2 Construction de programmes sur invariant
Construire un programme decrit par linvariant, cest utiliser une propositionbooleenne I(x1, x2, , xn), fonction de plusieurs variables xi, qui decrit le pro-bleme a un instant donne. Lorsque lon veut faire un algorithme qui resoud EP Sbase sur un invariant, on doit donner plusieurs propositions :
Invariant : Decrit la position du probleme en fonction de variables xi.
Initialisation : Ce sont des conditions sur les variables xi, tels que la propositionE soit verifie et I(xi) le soit egalement.
9
8/3/2019 ProgDynamique
11/168
Condition darret : Ce sont des conditions sur les variables xi, tels que la pro-position S soit verifiee. Lorsque la condition darret est verifiee, le pro-gramme doit avoir fini son traitement, et S est verifiee.
Implications : Elles sont de la forme I(x1, x2, , xn)
i(Pi vraies) I(x1, x
2, , x
3).
Ou Pi representent des propositions
On en deduit lexpression :
I(xi) TANTQUE(Condition darret)FAIRE Pi I(xi) (Condition darret)
1.2.1 Exemple : somme des elements dun tableau
Soit un programme realisant la somme de tous les elements de 0 a n 1 dun
tableau T. On veut un programme P verifiant lenonce suivant :
(n > 0) P
S =
n1i=0
T[i]
On se propose de decrire ce programme par linvariant :
Invariant : I(s, k) s =k1
i=0 T[i] . s est la somme des k premiers elements deT.
Initialisation : s = 0 et k = 0. En effet la somme des 0 premiers elements fait
0. Donc I(0, 0) est verifie.Condition darret : k = n. On sarrete lorsque lon a realisee la somme des n
premiers elements, comme demande.
Implication : I(s, k) (s = s + T[k]) I(s, k + 1).
En sortie du programme, on aura I(s, k) (k = n). La translation de cet algo-rithme en pseudo langage est tres simple :
s < - 0
k < - 0
// Ici on a I(0,0)
tant que (k != n) faire :s
8/3/2019 ProgDynamique
12/168
Chapitre 2
Problemes de recherches
Le probleme que nous nous posons est de rechercher un element (nombre,caractere ou autre) dans un tableau homogene delements. La particularite de cetableau est quil est deja trie dans lordre croissant (ce qui impose davoir unerelation dordre entre les elements).
2.1 Remarques sur levaluation de complexitedun programme
Dans ce paragraphe et ceux qui suivront, nous allons evaluer le temps dexe-cution des programmes en fonction de la taille n du probleme. Comparer 2 pro-
grammes, cest comparer les temps dexecution dans les pires des cas respectifs.Les constantes dependent de la machine qui executera lalgorithme.
Definition : Le programme P est de complexite O(f(n)) sil existe et n0tels que :
n n0 Tp(n) f(n)
Ou Tp(n) represente le temps dexecution du programme P dans le pire des cas.Remarque : Si le programme P est en O(n), alors il est aussi en O(2n), O( n2 ) ouO(n2).
2.2 Recherche dichotomique
Supposons que lon cherche un element note e dans un tableau T. Le pro-gramme de recherche dichotomique que nous allons mettre au point repond alenonce suivant :
(T[0] e T[n 1]) RD (T[k] e T[k + 1])
11
8/3/2019 ProgDynamique
13/168
Invariant : I(i, j) T[i] e T[j 1]
Condition darret : j = i + 2
Initialisation : (i = 0) (j = n)Implications : I(i, j) ((j i) > 2)
e < T[ i+j2 ]
I(i, i+j2 )
I(i, j) ((j i) > 2) (e T[ i+j2 ]) I(i+j
2 , i)
Ce programme se base sur le fait que le tableau est deja trie. On comparelelement a rechercher avec lelement du milieu du tableau. Si lelement que lonrecherche est inferieur, alors il se trouve dans le sous-tableau de gauche, sinondans celui de droite.On continue a appliquer le meme raisonnement de maniere iterative jusqua ceque lon a pu assez encadrer lelement.
2.2.1 Code Source
1
2 i=0;
3 j=n;
4
5 while( j-i > 2)
6 {
7 if (e < T[(i+j)/2]) // I(i,(i+j)/2)
8 j = (j+i)/2; // I(i,j)
9 else // I((i+j)/2,j)10 i = (j+i)/2; // I(i,j)
11 }
12 // Ici on a I(i,j)&&(j-i = 2)
On peut eventuellement faire une verification prealable sur les donnees (pourvoir si e T[0 n 1])
2.2.2 Complexite
On rappelle linvariant :
I(i, j) T[i] e T[j 1]
Precondition : T[0] e T[n 1]Postcondition : T[i] e T[i + 1]
Linitialisation se fait en temps constant (on suppose a). Levaluation de lacondition de la boucle est elle aussi en temps constant, note b. Le corps de laboucle est egalement en temps constant c.
12
8/3/2019 ProgDynamique
14/168
A chaque execution du corps de boucle, la taille du probleme restant a traiter estdivisee par 2. On a la suite valeurs n, n
2, n
4,..., 1.
Hypothese : La taille du probleme n est supposee etre un multiple de 2.n = 2p. Avec n = 2p le corps de boucle est execute p fois.
Trd = a + (p + 1)b + pc
Trd = (a + b) + p(b + c)
Trd = log2(n) +
Pour un probleme de taille n = 2p, la complexite de la recherche dichotomiqueest de forme logarithmique, mais supposons que la taille du probleme ne soit pasun multiple de 2.Pour 2p n 2p+1
log2(n) + Trd a + b(p + 2) + (p + 1)c
log2(n) + Trd log2(n) +
On peut en deduire que le facteur dominant du temps de calcul est en log2(n), larecherche dichotomique est (log2(n))Remarque : Le logarithme base 2 et le logarithme neperien (base e) ne differentque dune constante, par consequent la recherche dichotomique est O(log(n)).
2.3 Recherche sequentielle
La recherche sequentielle est une methode plus traditionnelle : on regardetous les elements du tableau sequentiellement jusqua ce que lon tombe sur e,lelement que lon cherchait.Lavantage de la recherche sequentielle est quelle est possible sur des tableauxnon-tries.
Invariant : I(k) e / T[0...k 1]
Initialisation : k = 0
Condition darret : T[k] = e
Implications : I(k) (T[k] = e) I(k + 1)
2.3.1 Code
1 k = 0 ;
2
3 while( T[k] != e)
13
8/3/2019 ProgDynamique
15/168
8/3/2019 ProgDynamique
16/168
Initialisation : (p = 0) (q = n 1) (x = 0)
Condition darret : (p = m) (q = 1)
Implications :I(x,p,q) (p = m) (q = 1) (T[p][q] = e) I(x + 1, p + 1, q 1)I(x,p,q) (p = m) (q = 1) (T[p][q] < e) I(x, p + 1, q)I(x,p,q) (p = m) (q = 1) (T[p][q] > e) I(x,p,q 1)
2.4.1 Code
1 int p = 0;
2 int x = 0;
3 int q = n-1;
4
5 while( (p != n) && (q != -1) )
6 {
7 if (T[p][q] == e) // I(x+1,p+1,q-1)
8 { x++; p++; q--; } // I(x,p,q)
9 else if (T[p][q] < e) // I(x,p+1,q)
10 { p++; } // I(x,p,q)
11 else // I(x,p,q-1)
12 { q--; } // I(x,p,q)
13 }
2.4.2 Complexite
Le corps de boucle est en temps constants (structure if, incrementations). Lacondition du while est elle aussi en O(1), le corps de boucle est evalue au plusm + n fois, donc la complexite de la recherche arriere est en (m + n)
15
8/3/2019 ProgDynamique
17/168
Chapitre 3
Problemes de tris
On veut trier un tableau T[0...n 1] = [t0...tn1] delements par ordre crois-sant. Pour cela, on etudiera plusieurs algorithmes : le slowsort, puis le quick-sort.
3.1 Slowsort
Invariant : I(k) T[0...k 1] trie T[0...k 1] T[k...n 1]
Condition darret : k = n
Initialisation : (k = 0) (I(0) est vrai)
Implications :I(k)(k = n)(t
m= min(T[k...n1]))(T[k] = t
m)(T[m] =
tk) I(k + 1)
3.1.1 Code
1 k=0; // I(0)
2 while(k != n)
3 {
4 m = min(T,k,n);
5 permuter(T[k], T[m]); // I(k+1)
6 k++; // I(k)
7 } // I(k) & (k=n)
3.1.2 Complexite
On suppose que les operations des lignes 1,5,6 sont en temps constants. Lacomparaison de la ligne 2 est aussi supposee en temps constant.Il reste a evaluer le temps dexecution de la ligne 4. On peut supposer que larecherche du minimum est en temps lineaire. Le temps de calcul du recherche du
16
8/3/2019 ProgDynamique
18/168
min sur un tableau T[k...n 1] secrit :
a(n k) + b Tmin(n k) a(n k) + b
Le corps de la boucle while est executee n fois pour k = 0, 1, 2,...,n 1.
an1i=0
i + nb + nc Twhile a
n1i=0
i + nb + nc
an(n 1)
2+ n(b + c) Twhile a
n(n 1)
2+ n(b + c)
n2 + n Twhile n2 + n
En resumant les constantes dinitialisation par , on peut evaluer la complexitedu slowsort par :
n2 + n + Tss(n) n2 + n +
Pour des grandes valeurs ainsi Tss(n) = O(n2).
3.2 Quicksort
Lalgorithme de tri rapide, ou quicksort a ete mis au point par OHare dansles annees 50. Il repose sur une approche dite diviser pour regner.
Cette approche consiste a separer de facon optimale le probleme en 2 (ou plus)problemes de taille inferieure.Le quicksort fonctionne ainsi :
1 procedure QS(Tableau T, entier i, entier j)
2 entier k
3 si (j-i > 1)
4 segmenter(T, i, j, k)
5 QS(T,i,k)
6 QS(T,k+1,j)
7 finsi
On remarque que lessentiel du travail est effectue a la ligne 4 par la proceduresegmenter. Cest cette procedure que nous nous attacherons a decrire. La fonctionsegmenter va choisir un element T[k] du tableau, appele le pivot et reorganiser letableau tel que :
T[i...k 1] T[k] T[k + 1...j]
17
8/3/2019 ProgDynamique
19/168
3.2.1 Segmenter
Cette procedure segmenter est batie sur linvariant suivant :
Invariant : I(k, k) T[i..k 1] < T[k] < T[k...k 1]
Initialisation : (k = i) (k = k + 1)
Condition darret : k = j
Implications :I(k, k) (T[k] > T[k]) I(k, k + 1)I(k, k) (T[k] < T[k]) (T[k] = tk) (T[k + 1] = tk) (T[k] = tk+1) I(k + 1, k + 1)
3.2.2 Code Source
1 void segmenter(T,i,j,k)
2 {
3 int k;
4 k = i ;
5 k= k+1;
6
7 while(k != j)
8 if (T[k] < T[k])
9 else {
10 permuter(T[k],T[k+1]);
11 permuter(T[k+1],T[k]);12 k++;
13 } k++;
14 }
3.2.3 Complexite du Quicksort
On remarque aisement que la complexite du corps de quicksort depend de lacomplexite de segmenter.
Complexite de segmenter
segmenter(T,i,j,k) est fonction lineaire de j i : (j i).
(j i) + Tseg (j i) +
18
8/3/2019 ProgDynamique
20/168
Complexite de quicksort
Il y a 2 cas de figures :
j i > 1 :
TQS(i, j) A1 + A2 + Tseg(j i) + TQS(i, k) + TQS(k + 1, j)
TQS(i, j) A1 + A2 + (j i) + + TQS(i, k) + TQS(k + 1, j)
j i 1 :TQS(i, j) = A1 + A2
On a une equation de recurrence dun majorant du temps de calcul de QS(T ,i ,j) : j i 1 TQS(j i) = B0 j i > 1 TQS(j i) TQS(k i) + TQS(j k) + A(j i) + B
Nous sommes en presence de 2 cas limites :
Hypothese 1 : A chaque segmentation T[i...j] est separe en 2 tableaux detaille identiques : T[i...k 1] et T[k...j 1] tels que k i = j k. Dans ce cas,puisque les 2 tableaux sont de taille identique, on peut affirmer que la taille duprobleme est n = 2p
Hypothese 2 : A chaque segmentation T[i...j] est separe en 2 tableaux detaille quelconque :
Traitons chacune des hypotheses :
Hypothese numero 1 :
j i = 1 = 20 TQS(20) = B0
j i > 2p>0 TQS(2p) TQS(2
p1) + TQS(2p1) + (A 2p + B)
Essayons pour n = 20, 21, 22, 23... :
n = 20 T(1) = B0
n = 21 T(21) T(20) + T(20) + (A 21 + B)
T(21) = 2T(20) + (A21 + B) = 2B0 + 2A + B
n = 22 T(22) 2T(21) + (A 22 + B)
T(22) = 22B0 + 22B + 23A
19
8/3/2019 ProgDynamique
21/168
Dune maniere generale, la complexite du quicksort pour un probleme de taillen = 2p est :
T(2p) = p 2p + 2p + T(n = 2p) = log2(n) n + 2
p +
(3.1)
Donc, sous lhypothese dun tableau separe en 2 parties egales la complexitedu quicksort est : TQS(n = 2
p) = O(n log2(n)).
Considerons le cas ou le tableau est deja trie par ordre croissant :
TQS(1) = A(constante)
TQS(n > 1) = B + Tseg(n) + TQS(1) + TQS(n 1)
TQS(n > 1) = B + (n + ) + A + TQS(n 1)
TQS(n > 1) = n + C+ TQS(n 1)
Si on devellope :
TQS(n) = n
i=2
i + (n 1)C+ A
TQS(n) = n(n + 1)
2
+ (n 1)C+ (A )
TQS(n) = n2
2
n + 2(n 1)
2+ (A C)
La complexite dun quicksort pour un tableau deja trie est donc en O(n2), cequi est beaucoup moins bon que la complexite originale en O(n log(n)) pour untableau quelconque.
3.2.4 Amelioration du quicksort
Nous avons vu que la complexite du quicksort dans le cas general est enO(n log(n)), tandis que celle dun tableau deja trie est en O(n2). La raison de
cette complexite en O(n2) (identique a un slowsort pour le meme tableau) estque la fonction segmenter coupe le tableau initial de taille n en 2 tableaux, lunde taille 1, lautre de taille n 1.Il faut donc ameliorer le quicksort pour effectuer une coupe plus egale. En effet,si le tableau initiale est coupe en 2 tableaux de taille n
2la complexite du quicksort
baisse a O(n log(n)).
Voici une amelioration possible, qui consiste a echanger le pivot (T[i]) par unautre element du tableau, tire au hasard.
20
8/3/2019 ProgDynamique
22/168
1 procedure QS(Tableau T, entier i, entier j)
2 entier k
3 si (j-i > 1)
4 segmenter(T, i, j, k)
5 a = tirage_aleatoire(T,i,j)
6 permuter(T[i], T[a])
7 QS(T,i,k)
8 QS(T,k+1,j)
9 finsi
On peut aussi remplacer le tirage aleatoire par un tirage plus recherche, enprenant par exemple, la valeur mediane. Dans tous les cas, ce tirage doit etre en(n log(n)) pour conserver la complexite du quicksort.
3.3 Complexite minimum dun algorithme detri
Nous avons vu que des algorithmes intuitifs (donc nafs), tels le slowsortou le bubble sort avaient des complexites de lordre de n2. Des algorithmesameliores, comme le quicksort ou le heapsort ont des complexites inferieures,en n log(n).On est en droit de se demander si ces algorithmes sont les plusoptimaux, cest a dire sil existe un algorithme de tri en O(f(n)) avec f(n) 1) = (n) + 2TF(n
2)
Le tri fusion est donc bien en (n log(n)). Le probleme est que ce tri vacouter tres cher en memoire.
23
8/3/2019 ProgDynamique
25/168
4.2 Limites de lapproche diviser pour regner
Lapproche diviser pour regner a ses limites : cest le recouvrement de sousproblemes.Si lon prend T(n) le temps de calcul du probleme de taille n, on a :
T(n) = T(f(n)) +
i
T(ni)
Si
i ni n lalgorithme est efficace, sinon le temps de calcul devient exponen-tielle ((2n)). Il faudra alors utiliser la programmation dynamique
24
8/3/2019 ProgDynamique
26/168
Chapitre 5
Complexite des algorithmes
Dans cette section, nous nous attacherons a evaluer la complexite des algo-rithmes.Evaluer la complexite dun algorithme consiste a determiner la forme du tempsde calcul asymptotique. En dautres termes il sagit de determiner quelle sera,dans lexpression du temps de calcul dun algorithme, le terme Ai = f(n) telsque tous les autres termes Aj=i soit negligeable devant Ai pour n = +.Cette recherche de la complexite dun algorithme se fait dans le pire des cas,cest a dire que larrangement des donnees du probleme, bien qualeatoire, pousselalgorithme dans ses limites.
5.1 Expression du temps de calculChercher lexpression du temps de calcul dun algorithme consiste a evaluer
une fonction f(n) donnant le temps de calcul dun algorithme en fonction de lataille n du probleme et de constantes Ci.La taille du probleme, note n, peut tres bien le cardinal de lensemble a trier pourun algorithme de tri. Il peut aussi sagir dun couple, ou dune liste de variables,par exemple lors des problemes traitant de graphes, on exprime f en fonction de(V, E), ou V et E sont le nombre de vertices (arcs) et E le nombre de places dansce graphe.
Pour determiner cette expression, on travaille habituellement sur le codesource du programme, ou sur une version en pseudo-langage detaillee. On prendssoin de ne pas prendre en compte les fonctions dentree/sorties (en C : printfet scanf).On prends chaque ligne de ce programme et on lui affecte une constante de coutci. Ce cout represente le temps dexecution de linstruction a la ligne i, et dependdes caracteristiques de lordinateur qui execute lalgorithme. On essaye devaluer
25
8/3/2019 ProgDynamique
27/168
egalement pour chaque ligne, le nombre de fois que cette ligne va etre executee,en fonction de n, et que lon va noter gi(n).Ainsi on obtient lexpression du temps de calcul en realisant la somme suivante :
f(n) =
pi=1
ci gi(n)
Letape suivante consiste a developper les fonctions gi(n) (lorsque celles-ci peuventetre developpes algebriquement, ou sommees lorsquelles sont sous la forme deserie numeriques), puis a ordonner selon les puissances de n decroissantes :
f(n) = C0 nk + C1 n
k1 + + Ck1 n + Ck
Lorsque le developpement presente des termes qui ne sont pas sous la formenk, on essaye de les encadrer, ou des les approximer, en tenant compte que lontravaille sur des valeurs de n assez grandes. Par exemple n2 > n log(n) > n, oun! > nk k.
Ce que lon appelle complexite de lalgorithme, se note sous la forme (F(n)).Avec F(n) tel que, (n > N f ix ), ( R) t.q. F(n) > f(n).Concretement, il sagit du premier terme du developpement de f(n) debarasse desa constante.
Exemples f(n) = A.n2 + B.n + C.n, alors lalgorithme est en (n2) donc egalement
en (5n2). f(n) = 50.n5 + n!, alors (n!).
En conclusion on peut dire que le temps de calcul dun programme ne dependpas uniquement de la complexite de lalgorithme sur lequel il se base. Dautresfacteurs interviennent, notamment les constantes que lon neglige, et les carac-teristiques de lordinateur. Neanmoins la complexite permet de se faire une ideede levolution du temps de calcul, independament de lordinateur utilise, lorsque
lon multiplie la taille du probleme, par 10 par exemple.Ainsi la complexite, permet en quelque sorte de juger de la performance desalgorithmes lorsque lon sattaque a des problemes de grande taille.
5.2 Notations
En plus de la notation (f(n)), on utilise egalement deux autres notations :la notation O (grand o), et la notation .
26
8/3/2019 ProgDynamique
28/168
La notation O(F(n)) designe un majorant du temps de calcul.De meme, la notation (F(n)) designe un minorant du temps de calcul.
En appellant Fi(n) lensemble des fonctions tels que lalgorithme soit en O(fi Fi) et Gi(n) la famille de fonction tels que lalgorithme soit en (gi Gi), onalors Fi Gi = i avec i la famille de fonctions de n tels que la complexite dela lalgorithme soit en (i i).
Exemple : On peut deduire dun algorithme qui est en O(3n2), O(0.5n3),(10n2) et (n), quil sera en (n2).
5.3 Calculs courants dans le calcul des complexi-tes
Certains calculs courants peuvent apparatre lors de levaluation du temps decalcul dun programme. Je nai pas la pretention de donner toutes les astucespermettant de donner la complexite dun programme tres facilement, car cela sefait au feeling avec lhabitude.Neanmoins, cerains resultats importants meritent detre retenus :
ni=1
i =n(n + 1)
2 = (n2)
x < 1+k=0
xk =1
1 x
n
i=11/i = ln(n) + O(1) = (ln(n))
5.4 Un peu de theorie de la complexite
Nota Bene : Partie non traitee en cours
Au dela des algorithmes, que lon peut classer par complexite, il y a les pro-blemes, auxquels les algorithmes repondent. Il existent plusieurs classes de pro-bleme.
27
8/3/2019 ProgDynamique
29/168
5.4.1 Solution ou pas
Il faut dabord differencier la solution dun probleme des solutions dun pro-
bleme. En effet, pour un probleme P auquel il y a une ou plusieurs solutions S.Chercher S est different de verifier si parmi toutes les propositions logiques s,s S.Prenons par exemple le cas de la factorisation dun entier N. Determiner len-semble des diviseurs premiers de N est different de verifier si une suite fini denombres premiers correspond bien a la factorisation de N.
5.4.2 Classes de problemes
La classe P : Cest la classe des problemes pour lesquels il existent une solutionque lon peut determiner integralement en temps polynomial, cest a direquil existe un algorithme pour ce probleme dont la complexite est en (nk).
La classe E : Cest la classe des problemes intrinsequement exponentiel, cest adire que tout algorithme sera de la forme (kn) avec k une constante.
La classe NP : (Abbreviation de Non-Deterministe Polynomiaux Cest la classedes problemes dont on peut verifier les solutions en temps polynomial, maisdont on ne connait pas forcement dalgorithme permettant de trouver lessolutions. Typiquement ce sont des problemes plus difficiles que ceux de P.
5.4.3 NP-CompletOn dit quun probleme est NP-Complet quand tous les problemes appartenant
a NP lui sont reductibles. Cest a dire si lon trouve une solution polynomial a unprobleme NP-Complet, alors tous les problemes NP-Complet peuvent etre resolusen temps polynomial aussi. Cest pourquoi les problemes dit NP-Complet sontgeneralement ceux qui sont les plus durs.Lorsque lon a affaire a un probleme NP-Complet, on essaye generalement dedevelopper un algorithme qui sapproche de la solution.
28
8/3/2019 ProgDynamique
30/168
8/3/2019 ProgDynamique
31/168
Un tel programme a une complexite exponentielle en O(2n). En pratique, lestemps de calcul depasse la seconde pour calculs dordre n > 40. Ceci est due ala relaive lourdeur de la recursivite : lordinateur va passer beaucoup de tempsa empiler et depiler les arguments de la fonction. La programmation dynamiquepropose un algorithme modifie :
T := Tableau dentier T[0...n]
T[0]
8/3/2019 ProgDynamique
32/168
Le cout total de cette methode est T = pqr + prs = pr(q + s).
Deuxieme methode (T = A (B C)) :
Ap,q (Bq,r Cr,s) qrs
pqs
Le cout total de cette methode est T = qrs + pqs = qs(p + r).
On a un cout total pour ces 2 methodes different. Prenons un exemple :
p = 10 ; q = 104 ; r = 1 ; s = 104
Premiere methode : T = 10(104 + 104) = 2 104
Deuxieme methode : T = 108(10 + 1) = 11 108
Le rapport est donc de 5, 5 103, ce qui est tres significatif, dou limportance duparenthesage.
6.2.2 Algorithme de calcul.
Cet algorithme va proceder en 2 temps :1 - Determiner le cout minimum du produit < A0 . . . An1 >.2 - Calculer < A0 . . . An1 > selon le parenthesage optimal.
6.2.3 Cout minimum
Notation : Soit mij le nombre minimum de multiplications scalaires pour mul-tipliers les matrices Ai . . . Aj1.
mi i+1 = 0 i.
On note m(k)ij le cout du produit parenthese (Ai . . . Ak1)(Ak . . . Aj1). On a
m(k)ij = mik + mkj + PiPkPj.
Pour tout i, j tels que j > i + 1, on note mij le cout optimal pour lamultiplication des matrices Ai Aj1. Ce cout est le plus petit mkij.
mij =min
i < k < j (mik + mkj + PiPkPj)
On peut en deduire le code source de cette fonction aisement :
31
8/3/2019 ProgDynamique
33/168
1 int m(int i, int j, tabDimMat P)
2 {
3 if (j == i+1) return 0;
4 else return min(m(i,k,P)+m(k,j,P)+P[i]*P[j]*P[k]);
5 }
Cette methode de calcul des couts minimum a un enorme probleme : il y a unrecouvrement des sous problemes : certains couts seront calcules plusieurs foisPour contrer cela, nous allons stocker dans un tableau les mij dans une matrice :
Mm0 Mm1 Mmn...
... Mii Mii+1...
. . . Mii Mii+1 Mii+1
... . . .
M00 M0n
Les elements Mii de la diagonale representent les couts des produits mii = 0. Ladiagonale est donc nulle De meme, la diagonale inferieure (Mi i+1) est nulle. Onutilise lalgorithme suivant pour remplir la partie inferieure du tableau :
// Calcul des problemes de taille 1
pour i allant de 0 a n-1
M[i][i+1] = 0
// Calcul par taille t croissantpour t allant de 2 a n
// calcul pour chaque taille t de tous les problemes de taille t
pour i allant de 0 a (n-t)
j = i+t
M[i][i+t] = min( M[i][k] + M[k][i+t] +P[i]*P[i+t]*P[k] )
Chaque diagonale t (elements du tableau m[i][i + t]) represente le cout dunprobleme de taille t.On peut maintenant etablir linvariant de lalgorithme de remplissage de la ma-trice des couts :
Invariant : I(,n,k) (m = min(M[i][n] + M[n][] + P[I] P[n] P[]) (k = argM[i][j])
Initialisation : ( = i + 2) (x = i + 1) (k = i + 1)
Arret : = j
Implications : I(,m,k) (m = M[i][] + M[][j] + P[i]P[]P[j]) (m m) I( + 1, m , k)I(,m,k) (m = M[i][] + M[][j] + P[i]P[]P[j]) (m < m) I( +1, m, k)
32
8/3/2019 ProgDynamique
34/168
6.2.4 Calcul optimal du produit
Nous venons de calculer les couts optimaux pour le produits de matrices. Ces
couts sont stockes dans la partie inferieure dune matrice MNous allons faire en sorte que la partie superieure de la matrice M contient lesvaleurs kij tels que lont ait le cout minimum mij . M[i][j] = mij ; M[j][i] = kij .Le cout m0n de la multiplication des n 1 matrices se trouve donc en M[0][n].Il nous reste donc maintenant a calculer effectivement le produits de ces n 1matrices en utilisant les informations sur le parenthesage optimal contenu dansM.
Calcul du produit Ai Aj
1 void multopt(matrice resultat, matrice_couts M, matrice *A, int i, int j)
2 {3 matrice P1, P2;
4
5 if (j=i+1) resultat= A[i];
6 else {
7 multopt(P1,M,A,M[j][i],j);
8 multopt(P2,M,A,i,M[j][i]);
9 mult_matrice(resultat,P1,P2);
10 }
11 }
Lappel initial a cette fonction est multopt(resultat, A, M, 0, n).
6.3 Exemple : Recherche du plus long sous-motcommun a 2 chaines
Soit 2 mots A et B. Ces mots sont composes de caracteres ai et bj .A a0a1a2 am1B b0b1b2 bm1
Le probleme que nous nous posons ici est de calculer le plus long sous mot Mcommun a 2 mots A et B.Soit L(x, y) la longueur du plus long sous-mot commun a A(x) et B(y) Ainsipour tout i, j on a les propositions suivantes :
i > 0 et j > 0 : ai1 = bj1 L(i, j) = max(L(i 1, j), L(i, j 1))
i > 0 et j > 0 : i > ai1 = bj1 L(i, j) = 1 + L(i 1, j 1))
i = 0 : L(0, j) = 0
j = 0 : L(i, 0) = 0
33
8/3/2019 ProgDynamique
35/168
6.3.1 Taille du probleme
Le but est de calculer L(m, n) longueur du probleme (A(m), B(n)). i, j,
L(i, j) sera calcule, par taille de probleme croissant.Il faut que chaque valeur L(i, j) ne soit calcule quune seule fois. Cest pourquoinous stockerons ces valeurs dans une matrice M[0 m][0 n].
6.3.2 Reconstruction de la solution
// Calcul des pbs de taille 0
pour i allant de 0 a m L[i][0] = 0
pour j allant de 0 a n L[0][j] = 0
// Calcul de tous les probl\emes par taille croissant
pour t allant de 1 a mpour i allant de t a m
si A[i-1]=B[t-1], alors L[i][t] = L[i-1][t-1] + 1
sinon L[i][t] = max( L[i-1][t], L[i][t-1] )
pour j allant de t a n
si A[t-1]=B[j-1], alors L[t][j] = L[t-1][j-1] + 1
sinon L[t][j] = max( L[t][j-1], L[t-1][j] )
La complexite de cet algorithme est (m n).
6.3.3 Exemple
Voici la matrice generee pour les deux chanes :
A = bca B = cabd
L =
3 0 1 2 2 22 0 1 1 1 11 0 0 0 1 10 0 0 0 0 0L 0 1 2 3 4
6.3.4 Affichage du plus long sous mot
Appelons M(p) le plus long sous-mot commun a A(m) et B(n). La longueurde de M(p) a deja ete calculee et se trouve a lemplacement (m, n) de la matriceL dont la construction vient detre detaillee.
M(p) = m0m1 mp1
34
8/3/2019 ProgDynamique
36/168
. En appelant M(k) le k-prefixe, et M(k) le k-suffixe : M(k) = m0m1 mk1M(k) = mpmp1 mpk
M(p) = M(k).M(k)
Nous allons construire le programme de reconstruction de la plus longue souschane commune, base sur linvariant suivant :
Invariant : I(k,i,j) (M(k) affiche)(M(k) = PLSM(A(i), B(j))reste a afficher)(M(k).M(k) = M(p))
Init : (k = L[m][n]) (i = m) (j = n)
Arret : k = 0
Implications : I(k,i,j) (k = 0) (L(i, j) = 1 + L(i 1, j 1)) (A[i
1]affiche) I(k 1, i 1, j 1)I(k,i,j) (k = 0) (L(i 1, j) > L(i, j 1)) I(k, i 1, j)I(k,i,j) (k = 0) (L(i 1, j) L(i, j 1)) I(k,i,j 1)
Le code source de ce programme secrit tout simplement grace a cet invariant :
1 int k = L[m][n];
2 int i = m;
3 int j = n;
4
5 while (k != 0)
6 {
7 if ( L[i][j] == L[i-1][j-1] )
8 {
9 printf("%c ", A[i-1]);
10 i--; j--; k--;
11 } else if (L[i-1][j] > L[i][j-1]) i--;
12 else j--;
13 }
On peut remarquer que ce programme affiche la plus longe sous-chane communedans lordre inverse. Toutefois, ce nest pas si grave car on sait inverser des chainesen temps lineaire.
35
8/3/2019 ProgDynamique
37/168
Deuxieme partie
IN311 - Programmationdynamique
36
8/3/2019 ProgDynamique
38/168
Introduction au cours deprogrammation dynamique
Extrait de la brochure Programme des enseignements de 3o Annee :
La programmation dynamique est une methode doptimisation operant parphases (ou sequences) dont lefficacite repose sur le principe doptimalite de Bell-man : toute politique optimale est composee de sous-politiques optimalesCette unite met laccent sur la diversite des domaines et des problemes dappa-rence tres eloignes qui lorsquils sont correctement modelises relevent de la memetechnique. Elle permet de mettre en pratique sur des problemes de traitement dusignal, de controle et dinformatique les concepts abordes dans les cours dinfor-matique logicielle et materielle des deux premieres annees du tronc commun.Resoudre un probleme doptimalite par la programmation dynamique est, dans
ce contexte precis, une mise en oeuvre significative de la diversite des compe-tences attendues dun ingenieur : modelisation du probleme, proposition duneequation de recurrence, proposition dun algorithme efficace de resolution du pro-bleme (modelisation informatique des donnees, evaluation de complexite) ; etudedes differentes optimisations possibles de lalgorithme ; programmation effective ;possibilites dimplantation sur architectures specifiques deduites de lalgorithmeet des contraintes de programmation.
37
8/3/2019 ProgDynamique
39/168
Chapitre 7
Applications de laprogrammation dynamique
7.1 Un probleme dassortiment
7.1.1 Sujet
On considere m objets, de format 1, 2, , m (tous les objets sont de formatsdifferents). Ces objets doivent etre empaquetes avec du papier demballage.Le papier demballage est disponible sous forme de feuilles chez le fabricant, etdans tous les formats convenables. Pour des raisons de cout de fabrication, la com-mande des m feuilles doit etre faite parmi n formats seulement. Le cout dune
feuille crot avec le format. Un format permet demballer tout objet de formatinferieur ou egal.Le probleme pose est celui du choix des n formats permettant dempaqueter lesm objets a moindre cout. Les donnees du probleme sont le nombre dobjets m,le nombre de formats n et, pour tout format f, 1 f n, son cout c(f).
On demande un algorithme calculant en temps polynomial le cout minimumde la commande et un assortiment de formats qui permette dobtenir ce coutminimum.
7.1.2 Resolution
On part du principe doptimalite de Bellman : Une solution optimale estcomposee de sous-solutions elles-memes optimales. On va raisonner ainsi par taillede problemes croissants.La taille du probleme est ici m, le nombre de formats a choisir.On note M(m, n) le cout minimum pour emballer les objets de taille 1...n avec mformats. Ce cout implique que les formats de feuilles demballage sont reparties
38
8/3/2019 ProgDynamique
40/168
au mieux pour emballer les objets les objets des n premieres tailles.
On note x(t) | t [1, n], le nombre dobjets pour une taille t.Si lon ne dispose quune seule feuille de taille n pour emballer tous les objets, ilest evident que celle-ci doit etre de la taille du plus grand objet a emballer. Dunemaniere generale, la plus petite taille permettant demballer le plus grand objetdoit etre choisie. Quelque soit lassortiment de feuilles choisies optimalement,celui-ci comporte la feuille de taille n.
7.1.3 Cas general
Nous savons deja place le dernier emballage, de taille n. Il nous reste donca placer m 1 emballages optimalement. Pour cela on place un emballage enposition k, ainsi on en revient a un probleme de taille m1, sur k tailles dobjets.
k n0
M(m-1,k)
Tailles d'emballges
En notant Ct le cout pour emballer les n emballages :
Ct = M(m 1, k) +n
t=k+1
(c(n) x(t))
De la, on tire lequation de recurrence :
1 < m n M(m, n) =m1kn1
min
M(m 1, k) +
nt=k+1
c(n) x(t)
La borne inferieure du minimum vient du fait quil ne faut pas quil y ait plusde formats que de tailles. Si k < m 1, le probleme ne serait pas optimal.
39
8/3/2019 ProgDynamique
41/168
On doit donc calculer M pour les problemes de taille 1 :
M(1, p) =
pt=1
c(p) x(t) p [1, n]
7.2 Compression dimage
7.2.1 Sujet
On considere une image en m niveaux de gris. Chaque pixel de limage a unniveau de gris compris entre 0 et m 1. On veut comprimer cette image enrestreignant a n le nombre de niveaux de gris de limage. Ces n niveaux sont achoisir parmi les m valeurs de limage dorigine.
Dans cette compression, le niveau de gris de chaque pixel est remplace par leniveau de gris le plus proche au sein des n niveaux choisis. La question posee estle choix de n niveaux de gris qui permettront cette compression avec le minimumderreur.Lerreur est ainsi definie :
pour chaque pixel lerreur est la distance entre sa valeur de niveau de griset le niveau de gris le plus proche parmi les n niveaux choisis.
lerreur de compression est la somme des erreurs des pixels de limage.Propose un algorithme calculant en temps polynomial lerreur de compression
minimum et un choix de n niveaux de gris permettant datteindre cette erreurminimum.
7.2.2 Histogramme
On dispose de lhistogramme de limage. Cette histogramme represente lafonction discrete t [0, m 1] f(t), ou f(t) represente le nombre de pixelsde couleur t.
7.2.3 Resolution du probleme
Le probleme est de choisir au mieux les n niveaux de gris pour representerlimage par les m niveaux deja present dans limage. Pour cela il faut minimiserlerreur.
40
8/3/2019 ProgDynamique
42/168
0 m
f(t)
niveaux de gris
nombrede
pixel
On peut representer la compression par une application entre les niveaux degris de limage originale et les niveaux de gris de limage compressee.
imageoriginale
m niveaux
imagecompressee
n niveaux
Compression
C
En notant cette application C(t)) t [0, m 1], on peut exprimer lerreurep commise pour chaque pixel p dont le niveau de gris est gp :
ep = |gp C(gp)|
Ainsi la qualite de la compression sexprime grace a lerreur totale E :
E =
pimage
ep =
pimage
|gp C(gp)|
Pour ameliorer la qualite il faut minimiser lerreur totale E.
41
8/3/2019 ProgDynamique
43/168
7.2.4 Equation de recurrence
On note lerreur X(N, M) lerreur commise en representant au mieux une
compression de M niveaux de gris sur N. Ainsi X(n, m) = Eminimal.
Calculons E(0, ), cest le cas ou lon nutilise aucun niveau de gris pourrepresenter les premier niveaux de gris de limage. Ainsi pour les niveaux degris 0 1 de limage, il y a une erreur de commise. En admettant quils soienttous representes par le niveau :
E(0, ) =
1g=0
f(g) |g |
On se place dans le cas ou lon a deja optimise le choix des niveaux de grispour minimiser la compression des m P derniers niveaux de gris de limage.Nous allons calculer X(t, P), lerreur commise en compressant P niveaux de grisen t.On admet que le niveau de gris k est choisi pour etre un representant. Les niveauxde gris entre k et P vont donc etre represente soit par k, soit par P, selon leurposition.
0 m
f(t)
niveaux de gris
nombrede
pixel
g
Pk
42
8/3/2019 ProgDynamique
44/168
Lerreur X(t, P) sera egale a lerreur commise pour la representation des pixelsdont le niveau se situe entre k et P plus lerreur X(t 1, k) commise pour repre-senter les k premiers niveaux de gris.
X(t, P) = e(k, P) + X(t 1, k)
Avec e(k, P) lerreur commise en representant les pixels dont la couleur est dansla partie inferieur de lintervalle [k, P] par k et les pixels dont la couleur se trouvedans la partie superieure par P.
e(k, P) =
k+P
2g=k
(f(g) |g k|) +P
g=k+P2
(f(g) |g k|)
De la, on peut tirer lequation de reccurence :
X(n, ) =k[n1,1]
min [e(k, ) + X(n 1, k)]
Lintervalle [n 1, 1] sexplique par le fait que la compression est une appli-cation : on ne peut pas compresser un pixel en lui donnant 2 representant, il faurdonc k n.
7.2.5 Cas particulier
Lequation de reccurence ne permet pas explicitement de placer le dernierrepresentant, a partir duquel seffectue tout lalgorithme. Ce niveau se calculeainsi :
E = X(n, m) =k[n1,m1]
min
X(n 1, k) +
m1g=k
f(g) |g k|
7.2.6 Programmation
Lequation de recurrence correspond au calcul dune erreur minimale. Pourchaque calcul de minima, on definit largument du min. comme etant la valeurde parametre permettant dobtenir ce cout minimum.Ici le parametre du minimum est k, chaque valeur de k que lon obtiendra cor-respondra a un niveau de gris compresse
7.3 Justification de Parapgraphes
7.3.1 Sujet
On considere n mots de longueurs l0, . . . ln1, que lon souhaire imprimer enune suite de lignes ayant chacune C caracteres, sauf la derniere qui peut en
43
8/3/2019 ProgDynamique
45/168
compter moins (le texte que vous lisez actuellement est un exemple du resultatescompte).Le nombre c de caracteres dune ligne est la somme des longueurs des mots qui lacomposent, plus les blancs qui separent les mots (un blanc entre tout couple demots). Pour une telle ligne, il faut ajouter C c blancs supplementaires entre lesmots pour quelle ait exactement C caracteres. Le cout de cet ajout est (C c)3.Le cout de la justification du paragraphe est la somme de ces couts sur toutes leslignes, sauf la derniere.Proposer un algorithme calculant cette justification de paragraphes en un tempspolynomial.
7.3.2 Algorithme
On a N mots de longueurs respectives l0, l1, , ln1.On se place dans le cas dune ligne (sauf la derniere, qui est un cas particulier).Cette ligne composee des mots mimi+1 mj , a pour longueur L :
L =
jk=i
(lk + (j i 1))
Cette ligne amene un cout supplementaire (C L)3. On va chercher a minimiserle cout total de formattage du document, cest a dire minimiser (C L)3 pourchacune des lignes.
On note e(k) le cout minimum de formattage des k premiers mots. Sur cesk premiers mots, on sautorise a mettre au plus k 1 retours chariots, soit klignes. Pour la derniere ligne, on va chercher a minimiser le cout :
e(N) = min(e(k))
Pour tout k tel que la longueur des mots k N soit inferieur a C (longueurmaximale dune ligne), soit
Ni=k
(li + (N k 1)) C
Pour la premiere ligne, le cout e(1) est :e(1) = (C li)
3
dune maniere generale, on a :
e(m) =k
min
e(k 1) +
C
mi=k
li + (m k 1)
3Avec k tel que
(li + (m k 1)) C
44
8/3/2019 ProgDynamique
46/168
Troisieme partie
IN302 - Graphes et algorithmes
45
8/3/2019 ProgDynamique
47/168
Chapitre 8
Notions de base
8.1 Premiere definitionSoit E un ensemble fini. On appelle graphe sur E un couple G = (E, ) ou
est une application de E P(E).
Exemple i:
Soit un graphe G tel que E = {1, 2, 3, 4}. est definie par : (1) = 1, 2, 4 (2) = 3, 1 (3) = 4
(4) =
Cette definition de est plutot difficile a imaginer. La representation sous formesdarcs fleches de la figure 8.1 est plus pratique.
2
1
4
3
Fig. 8.1 Graphe de lexemple 1
46
8/3/2019 ProgDynamique
48/168
Tout element de E est appele sommet. Tout couple ordonne (x, y) E E tel que y (x) est appele arc du graphe. Si (x, y) est un arc, on dit que y est un successeur de x. Si (x, y) est un arc, on dit que x est un predecesseur de y.
Le graphe G de lexemple i comporte 4 sommets et 6 arcs.
On designe par lensemble des arcs. Lensemble des arcs est une partie duproduit cartesien E E : = P(E E). On peut definir formellement par :
= {(x, y) E E / y (x)}
Remarque: On peut representer G par (E, ) ou par (E, ). On appellera egale-
ment graphe le couple (E, ).
8.2 Representation en memoire
Le probleme qui se pose est celui de la representation dun graphe dans unememoire informatique.
8.2.1 Representation des ensembles finis
On peut voir que lensemble des arcs peut etre represente par lensemble des
sucesseurs de chacun des sommets du graphe. Representer un graphe revient donca representer un ensemble fini. Soit E = 1, , n et tel que |E| = n. Commentrepresenter un sous-ensemble X de E?
Liste-tableau
Cette methode de representation dun sous-ensemble consiste a aligner leselements du sous ensemble a representer dans un tableau. Ce tableau a une taillefixe egale au cardinal de E (cardinal de la plus grande partie de E). Pour savoircombien delements comporte le sous-ensemble, on utilisera un caractere specialque lon definira comme etant la fin de la liste. On pourra egalement indiquer lenombre delements du sous ensemble en debut de liste.
Liste chanee
On utilise une liste chanee contenant les elements du sous-ensemble X.
47
8/3/2019 ProgDynamique
49/168
Tableau de booleens
On utilise un tableau de taille n (cardinal de E) et tel que la case i du tableau
vaut vrai (1) si lelement i appartient au sous ensemble X. Si lelement i de Enappartient pas a X, alors la cause vaut faux (0).
Exemple i:
Prenons n = 9 et X = {1, 2, 4}. Liste-tableau :
1 2 3 4 5 n
21 4 X ........
Liste chanee :
2 41
Tableau de booleens :
1 2 3 4 7 8 9
0 0 0 0 0 0
6
111
5
8.2.2 Operations sur un ensemble
Selon la representation memoire que lon prend, les complexite des operationselementaires sur lensemble vont etre changee. Le tableau suivant presente lesdifferentes operations elementaires sur un ensemble ainsi que leur complexite selonle type de representation memoire choisie.
Operation Liste chanee Tableau de booleensInitialisation X = O(1) O(n)Test dappartenance x X? O(n) O(1)Test non-vide ?x X O(1) O(n) 1
Ajout dun element X = X {x} O(n)/O(1) 2 O(1)
48
8/3/2019 ProgDynamique
50/168
Le choix dune representation memoire adaptee est un facteur a prendre encompte lors de la conception dalgorithmes.
8.2.3 Representation dun graphe
La representation liee a (E, ) est celle liee a lintegralite du graphe. Plusieursrepresentations sont possibles.
Deux tableaux
Cette representation consiste a choisir deux tableaux I et T de taille ||, telsque I(j) est le sommet initial de larc numero j et T(j) est le sommet terminalde larc numero j.
Tableaux de listes de chanees
Cela consiste a prendre un tableau M contenant n = |E| listes chanees et telque M(i) est la liste chanee des arcs partant du sommet numero i.
Matrice booleenne
Cest le type de donnees forme a partir des tableaux de booleens (8.2.1). Lamatrice M est telle que Mij = 1 arc entre i et j.
8.2.4 ComplexiteNous allons voir avec un exemple concret dalgorithme que le choix de la re-
presentation peut influer sur la complexite des programmes et donc leur efficacite.
Algorithme de recherche des successeurs dune partie
Lalgorithme suivant a pour but de rechercher les successeurs dune partie X dunensemble E.Donnees : G = (E, ), X E.Resultat : Y = ensemble des sommets de G qui sont successeurs des sommetsde X. On notera Y = (X).
Y =
y E , x X , (x, y)
1: Y
2: for all (x, y) do
3: if x X then
49
8/3/2019 ProgDynamique
51/168
4: Y = Y {y}
5: end if
6: end for
Selon le choix du type de donnes pour X et Y, la complexite de lalgorithmeprecedent peut varier. Prenons par exemple Y sous forme dun tableau de boo-leens et X sous forme de liste chanee.On note n = |E| et m = ||.
Linstruction dinitialisation de Y a la ligne 1 est en O(n). La boucle de la ligne2 a 6 est executee m fois et son evaluation est en temps constant O(1). Le testdappartenance ligne 3 est en O(n) car X est sous forme dune liste chanee, de
plus il est executee m fois. Lajout dun element a un tableau de booleens, ligne4, est en temps constant. on peut conclure que la forme de la complexite de cetalgorithme est en O(mn).Choisissons maintenant X sous forme dun tableau de booleens. Linstruction dela ligne 3 devient en temps constant O(1) ; le corps de boucle de la ligne 2-6 esten temps constant et est execute m fois. Lalgorithme est alors O(m + n) ce quiest bien meilleur que la complexite precedente qui est quadratique pour m n.
8.3 Definitions complementaires
8.3.1 SymetriqueSoit G = (E, ). On appelle symetrique de G le graphe G1 = (E, 1)
defini par :x E , 1 = {y , x (y)}
Exemple i:
A
B
C
graphe G
A
B
C
symtrique de G
Graphe et son symetrique
50
8/3/2019 ProgDynamique
52/168
Remarque: y 1(x) x (x)
Definition : Un graphe (E, ) est un graphe symetrique si 1 = .
Exemple ii:
G symetrique
A
B
C
Exemple iii:
G non symetrique
A
B
C
Fermeture symetrique
Soit G = (E, ). On appelle fermeture symetrique de G le graphe Gs =(E, s) defini par :
s(x) = (x) 1(x) x E
La fermeture symetrique forme un graphe non-oriente.
Une arete est un ensemble {x, y} (x E, y E) tel que (x, y) ou (y, x) .
Algorithme de calcul du symetrique
Donnees : (E, ),Resultat : 1.
51
8/3/2019 ProgDynamique
53/168
8/3/2019 ProgDynamique
54/168
8.3.3 Graphe complet
Un graphe G = (E, ) est dit complet si (x, y) E E , x = y (x, y) .
Exemple v:
G complet
A B
C
Les graphes complets a n sommets sont notes Kn.
8.4 Chemins, connexite
8.4.1 Chemins et chanes
Soit G = (E, ) et xi une famille de points de E. Un chemin de x0 a xk estdefini par (x0, x1, x2, , xk1, xk) telle que i [1, k], xi (xi1). (Chaquepoint xi du chemin est un sucesseur du point xi1 ).On definit k comme etant la longueur du chemin : cest le nombre darcs du che-min. Un chemin C est un circuit si x0 = xk.
Exemple i:
53
8/3/2019 ProgDynamique
55/168
12
3
4
(1, 2, 1) nest pas un chemin. (1, 2, 3) est un chemin. (1, 2, 3, 1, 2, 4) est un chemin.
Chemin elementaire
Un chemin C est dit elementaire si les sommets xi sont tous distincts (saufeventuellement x0 et xk ).
Proposition : Tout chemin C de x a y dans G contient (au sens suite extraite)
un chemin elementaire de x a y dans G.Proposition : Soit G = (E, ), avec |E| = n. La longueur dun chemin elemen-taire non-circuit dans G est inferieure a n 1. De meme la longueur dun circuitelementaire est inferieure a n.
Chanes et cycles
Definition : Soit G = (E, ), et s la fermeture symetrique de . On appellechane tout chemin dans (E, s).On appelle cycle tout circuit dans (E, s) ne passant pas 2 fois par la memearete.
Exemple ii:
54
8/3/2019 ProgDynamique
56/168
12
3
4
(4, 2, 1) nest pas un chemin. (4, 2, 1) est une chane.
Le tableau suivant resume les differentes definitions selon la nature du graphe :
Graphe oriente Graphe non-orientearc arete
chemin chanecircuit cycle
8.4.2 Composante connexe et fortement connexeComposante connexe
Definition : Soit G = (E, ) et x E. On definit Cx, la composanteconnexe de G contenant x par :
Cx = {y E , chane entre x et y} {x}
Exemple iii:
55
8/3/2019 ProgDynamique
57/168
12
3
46
7
8
5
C1 = {1, 2, 3, 4} = C2 = C3 = C4 C5 = {5} C6 = C7 = C8
La composante connexe contenant le sommet x est lensemble des points quilest possible dattendre par une chane a partir de x.
Composante fortement connexe
Definition : Soit G = (E, ) et x E. On definit Cx, la composantefortement connexe de G contenant x par :
Cx = {y E , chemin entre x et y} {x}
Exemple iv:
Dans le graphe de lexemple precedent : C1 = {1, 2, 3, 4} = C
2 = C
3
C4 = {4} C5 = {5}
8.4.3 Calcul des composantes fortement connexes et descomposantes connexes
Definitions preliminaires
Soit un graphe G = (E, ), on definit plusieurs familles de graphes sur E :
56
8/3/2019 ProgDynamique
58/168
0(x) = {x} 1(x) = (x)
2(x) = (
1)
p(x) = (p1)
(En utilisant la notation (X) cest a dire lensemble des sucesseurs de la partieX).De meme, on peut definir les predecesseurs 1p =
1(1p1).
Proposition : p = {y E , un chemin de x a ydans G de longueurp}Proposition : 1p = {y E , un chemin de y a x dans G de longueur p}Definition :
p =
pi=0
i
1p =
pi=0
1i
Proposition : p = {y E , un chemin de x a y dans G de longueur p}
{x}. La meme proposition sapplique aussi pour 1p . On definit aussi (x) parlensemble des y E tels quil existe un chemin de x a y dans G.La composante fortement connexe Cx de G contenant x se calcule par la formule :
Cx = 1
La composante connexe de G contenant x secrit :
Cx = s = s1
Remarque: En general s = = s1
.
Algorithme du calcul de la composante fortement connexe
Donnees : (E, , 1); a EResultat : Ca
1: (a) ; T {a};
2: while x T do
3: T T\{x}
57
8/3/2019 ProgDynamique
59/168
4: for all y (x) tel que y / (a) do
5: (a) (a) {y}
6: T T {y}
7: end for
8: end while
9: (a) , T {a};
10: while x T do
11: T T {x}
12: for all y 1(x) tel que y / (a) do
13: (a) (a) {y}
14: T T {y}
15: end for
16: end while
17: Ca
(a) (a)
{a}
Algorithme du calcul de la composante connexe
Donnees : (E, , 1); a E Resultat : Ca
1: Ca {a} ; T {a}
2: while x T do
3: T T\{x}
4: for all y (x) tel que y / Ca do
5: Ca Ca {y}
6: T T {y}
7: end for
8: for all y 1(x) tel que y / Ca do
9: Ca Ca {y}
10: T T {y}
11: end for
12: end while
58
8/3/2019 ProgDynamique
60/168
8.4.4 Degres
Soit un graphe G = (E, ) et un sommet x E. On definit le degre exterieur
de x, note d+(x) par :d+(x) = |(x)|
Le degre exterieur est le nombre de successeurs de x.On definit le degre interieur de G, note d(x) par :
d(x) = |1(x)|
Le degre interieur est le nombre de predecesseurs de x.
Le degre du sommet x est defini par d(x) = d+(x) + d(x). La somme des
degres de tous les sommets dun graphe G est paire.Proposition : Dans tout graphe, le nombre de sommets de degre impair est pair.
kregularite
Soit k un nombre entier positif, on dit que G est kregulier si le degre dechacun de ses sommets est egal a k.
8.5 Representation matricielle
Soit G = (E, ). G peut se representer par la matrice booleenne M = mijtelle que :
mij = 1 si j (i)mij = 0 sinon
Exemple i:
Soit le graphe G = (E, ) suivant :
2
1
4
3
59
8/3/2019 ProgDynamique
61/168
La matrice dadjacence M associee a G est la suivante :
1 2 3 4
1 1 1 0 12 1 0 1 03 0 0 0 14 0 0 0 0
Considerons le produit booleen de matrices et les operateurs (ou binaire)et (et binaire).Soit A = aij et B = bij deux matrices booleennes, alors C = A B = [cij ] est
defini par :
cij =n
k=1
(aik bkj )
Soit Mp = M M M, p fois la matrice booleenne associee au graphe G,Mpij = 1 un chemin de longueur p dans G de i a j.
Remarque: Pour tout graphe G, il nexiste pas de nombre k N tel que Mk =
Mk+1. (Par exemple, prendre 2 points A et B et 2 arcs AB et BA.
Soit Mp = M M2 Mp ; Mpij = 1 un chemin de longueur p dansG de i a j.
Remarque: Si |E| = n alors p n 1, Mp = Mn1 = M.
8.6 Graphe biparti
On dit quun graphe G = (E, ) est biparti si lensemble E des sommets peutetre partitionne (ou colorie) en deux sous-ensembles distincts E1 et E2 de tellesorte que :
u = (x, y) ,
x E1 y E2x E2 y E1
Exemple i:
60
8/3/2019 ProgDynamique
62/168
G1 = G2 =
1 2
3 4
5
1 2
3 4
5
On voit G1 est biparti avec E1 = {1, 4, 5} et E2 = {2, 3}. G2 nest pas biparti.
On peut montrer quun graphe est biparti si et seulement si il ne contient pascycle impair.Preuve : Soit un cycle C = x0, x1, xk avec x0 = xk puisque C est un cycle.
Dapres la definition dun graphe biparti, si x0 E1, alors x1 E2. Ainsi parreccurence, si on a xk E1, alors xk+1 E2.On peut poser que xk Ek(2)+1 cest a dire que xk appartient a lensemble Eiavec i egal a k modulo 2 (plus 1 car on a pose que x0 E1). On a alors :
xk
E1 si k pairE2 si k impair
Puisque C est un cycle, x0 = xk et donc si k impair on a xk = x0 E2 ce qui esten contradiction avec lhypothese de depart x0 E1. On ne peut donc avoir decycle de longueurs impaires dans un graphe biparti.
8.6.1 Algorithme
61
8/3/2019 ProgDynamique
63/168
Chapitre 9
Arbre et arborescences
9.1 Definitions
9.1.1 Isthme
Soit G = (E, ), u . On dit que u est un isthme si sa suppression de augmente le nombre de composantes connexes de G.Exemple i:
AB
C
D
E
F
G
Larc u = (A, B) est un isthme.
Si u est un isthme, u nappartient a aucun cycle de G.
Proposition : Soit G = (E, ), tel que |E| = n et || = m. Si G est connexe,m n 1. Si G est sans cycle, m n 1.
9.1.2 Arbre
Un arbre est un graphe connexe et sans cycle. Une foret est un graphe sanscycle.
Remarque: Un arbre ne comporte pas de boucles. Dans un arbre, chaque arc estun isthme.
62
8/3/2019 ProgDynamique
64/168
Proposition : Soit G = (E, ), tel que |E| = n 2 et || = m. Les proprietessuivantes sont equivalentes :
1. G est connexe et sans cycles,2. G est connexe et m = n 1,
3. G est sans cycles et m = n 1,
4. G est sans boucles et a E, b E, une chane elementaire uniqueentre a et b.
9.1.3 Racine
Soit G = (E, ), x E. x est une racine de G (resp. antiracine) si y E{x}, un chemin de x a y. (resp. y a x)
Exemple ii:
C
D
B
E
A
Ce graphe na pas de racine, et a pour antiracine B.
C
D
B
E
A
Ce graphe a pour racine D et na pas dantiracine.
9.1.4 Arborescences
G est une arborescence (resp. anti-arborescence) de racine r E si :
1. G est un arbre
2. r est une racine (resp. anti-racine) de G
63
8/3/2019 ProgDynamique
65/168
9.1.5 Decoupage en niveau
Une arborescence peut etre decoupee en niveaux (cf figure 9.1).
Niveau 1
Niveau 2
Niveau 3
Fig. 9.1 Representation en niveaux
9.2 Exemples et applications
9.2.1 les pieces de monnaie
Soit 8 pieces de monnaies, dont une est fausse (elle est plus legere que lesautres). On possede deux balances. La balance 1 permet de savoir quel plateauest le plus lourd ; la balance 2 possede 3 etats (>,
8/3/2019 ProgDynamique
66/168
! "# $% &'()
(1,2,3,4) (5,6,7,8)
(1,2) (3,4) (5,6) (7,8)
(1) (2) (3) (4) (5) (6) (7) (8)
1 2 3 4 5 6 7 8
Fig. 9.2 Arbre de decision de la balance 1
9.2.2 Arithmetique
On sinteresse a levaluation dexpressions arithmetiques, en respectant lespriorites des differents operateurs. Soit lexpression arithmetique (A) :
(A) =aex b(y + 1)
2
Le probleme est lordre devaluation, car a b = b a. Il est alors necessairedordonner.
Sur larbre de la figure 9.3 page suivante correpondant a lexpression (A),chaque sommet du graphe est soit une donnee (literale ou numerique), soit unoperateur. Les operateur possedent au minimum 2 successeurs (sauf operateurunaires). Les donnees nont aucun sucesseur ; ce sont les feuilles de larbre.
Arborescence ordonnee
Soit E un ensemble fini, on note O(E) lensemble des kuplets ordonneesdelements de E.
G = (E, ), ou est une application de E dans O(E) est un graphe ordonne surE.A tout graphe ordonne (E, ), on peut faire correspondre le graphe (E, ) telque (x) = { elements du kuplet (x)}. On a G = (E, ) une arborescenceordonnee (ou arborescence plane) si (E, ) est une arborescence.
65
8/3/2019 ProgDynamique
67/168
/
2
* *
bexpa
x y 1
+
Fig. 9.3 Arbre devaluation arithmetique
9.2.3 Arbre de recherche
Soit D un ensemble appele domaine, muni dune relation dordre totale (quelon notera ). Soit X D et n D. La question que lon se pose est de savoirsi appartient a lensemble X.On peut par exemple prendre D = { lensemble des mots de la langue francaise}, X une partie de ces mots (par exemple lensemble des mots dune page web),et lon prend lordre lexicographique usuel.
Si X est represente sous forme dune liste, la resolution du probleme n X?
seffectue en O(|X|). Si X est represente sous forme dun tableau de booleen, laresolution seffectue en O(1) mais lemcombrement memoire est en O(|D|). Si Xest sous forme dune arborescence binaire, la recherche seffectue dans le pire descas en O(|X|), mais si larborescence est equilibree, la recherche est en O(log|X|).On a alors realise un index
Exemple i:
66
8/3/2019 ProgDynamique
68/168
12
6 9
8 15
13 17
Arbre de recherche sur N, pour la relation . X = {6, 8, 9, 12, 15, 13, 17}
9.3 Arbre de poids minimum
9.3.1 Poids
Pour chaque arc , on associe une valeur, le poids de larc. Soit G = (E, ),
un graphe connexe et sans boucles. Soit P une application de R, telle queu , P(u) est appele poids de larc u.
Le graphe (E, , P) est appele graphe pondere. Soit un graphe partiel
de G, P() =
u P(u) definit le poids du graphe partiel.
Soit (E, ) un graphe partiel de G qui soit un arbre. On dit que (E, ) est un
arbre de poids maximum sur G, si tel que (E, ) soit un arbre, on a larelation suivante :
P() P()
Soit (E, ) un graphe partiel de G qui soit un arbre. On dit que (E, ) est un
arbre de poids minimum sur G, si tel que (E, ) soit un arbre, on a larelation suivante :
P() P()
Exemple i:
67
8/3/2019 ProgDynamique
69/168
3
4
3
5
6
35
6
Un graphe pondere et son arbre de poids maximum.
Un arbre de poids maximum pour G = (E,, P) est un arbre de poids minimumpour G = (E, , P).
Remarque: On peut se demander combien darbres peut-on construire a partir
dun graphe. Cayley a apporte la reponse en 1889. Soit G = (E, ) avec |E| = n,on peut construire nn2 arbres sur G
9.3.2 Proprietes des arbres de poids maximum
Soit (E, ) un graphe connexe et sans boucle. Soit P lapplication de ponde-
ration associe a ce graphe. SoitA
tel que (E,
A) soit un arbre.On prend u un arc appartenant a mais pas A, Cu designe lensemble des arcs
de A formant une chane entre les extremites de u.On prend v un arc appartenant a A, v designe lensemble des arcs de \ A ayant
leur extremites dans 2 composantes connexes differentes de (E, A\{v}).
les 2 proprietes suivantes sont equivalentes et caracterisent un arbre de poidsmaximum :
1. u \ A, P(u) minCu P().
2. v A, P(v) maxv P().
Exemple ii:
On se propose detudier le graphe suivant :
68
8/3/2019 ProgDynamique
70/168
v1
u1
3
2
v2 5
u3
6v3
5
u2
1
4
v4
3
u4
On veut verifier si larbre represente par les arcs en pointilles est bien un arbre
de poids maximum.
Cu1 = v1, v2 v1 = u1Cu2 = v2, v3 v2 = u1, u2, u3
Cu3 = v2, v3, v4 v3 = u2, u3, u4Cu4 = v3, v4 v4 = u3, u4
On a P(u1) = 3 > P(v1) = 2, la propriete 1 nest donc pas verifie. De plusP(v2) = 5 < P(u3) = 6, la propriete 2 nest pas verifiee. Larbre represente nestdonc pas un arbre de poids maximum
9.4 Algorithmes de Kruskal
Nous allons voir des algorithmes qui permettent dextraire les arbres de poidsmaximum dun graphe.
9.4.1 Algorithme de Kruskal-1
Soit G = (E, ) un graphe connexe et sans boucle, et P une application de
ponderation de sur R.On note = {u1, u2, un} avec i, P(ui) P(ui+1) (Les sommets sont triespar ordre decroissant).
Soit la famille i definie par :
0 =
i = i1 {ui} si (E, i1 {ui}) est sans cyclesi1 sinonAlors n est un arbre de pois maximum.Chaque i se construit en rajoutant larc ui a un nouveau graphe G
si le grapheG est sans cycle, cest a dire sil conserve ses proprietes darbre. Comme lonrajoute les arcs les plus valorisant au debut, on est sur davoir un arbre de poidsmaximum.On na pas forcement besoin de tout calculer, on peut sarreter quand |i| = n1.
69
8/3/2019 ProgDynamique
71/168
complexite
Il faut dabord constituer une liste triee par ordre decroissant des arcs du
graphe. Cette operation seffectue au mieux en O(nlog(n)). Le test pour savoir siun graphe est sans cycles et en O(n + m). Comme ce test est realise m fois aupire, la complexite de lalgorithme de Kruskal-1 est en :
O(m(m + n) + n log(n)) = O(m(m + n))
9.4.2 Algorithme de Kruskal-2
Cette algorithme procede de facon identique, mais au lieu de construire unnouveau graphe avec les arcs les plus couteux, il procede en enlevant du graphedorigine les arcs les moins valorisants. La condition de suppression dun arc ui ne
secrit plus tant que (E, i) est sans cycle mais tant que (E, \{ui}) est connexe.Pour la meme raison, les arcs doivent etre tries par ordre croissant. La complexitede lalgorithme de Kruskal-2 est la meme que celle de Kruskal-1.
9.4.3 Algorithme de Prim
Lalgorithme de Prim fonctionne ainsi :
1: T = , A = {x E}
2:while
|T| n 1do
3: e = (u, v), tel que u A et v / A et e de cout minimal.
4: A = A {v}
5: T = T e
6: end while
70
8/3/2019 ProgDynamique
72/168
Chapitre 10
Plus courts chemins
10.1 Definition
10.1.1 Reseau
Nous allons travailler sur un graphe sans boucle G = (E, , l) avec l lapplica-
tion poids ( R). Lapplication p associe a chaque arc un reel appele longueurde larc.(E, , l) est un reseau.
Soit = (x0, x1, xn) un chemin dans G. On definit la longueur de par :
l() =
xi,xi+1
l({xi, xi+1})
10.1.2 Plus court chemin
Soient x et y deux sommets de E. Dans la recherche dun plus court cheminde x a y, trois cas peuvent se presenter :
Il nexiste aucun chemin de x a y (si x et y appartiennent a deux compo-santes connexes differentes de G).
Il existe un chemin de x a y mais pas de plus court chemin.
Il existe un plus court chemin de x a y.Exemple i:
71
8/3/2019 ProgDynamique
73/168
x y
2
4
1
1
2
Il nexiste pas de plus court chemin de x a y. Cest a dire que pour tout chemin de x a y, on peut trouver un chemin tel que l() < l().
Remarque: Un plus court chemin dans G = (E, , l) est un plus long chemin
dans G = (E, , l), et reciproquement.
Circuit absorbant
Un circuit de longueur negative est appele cycle absorbant. Dans lexempleprecedent, il existe un cycle absorbant.Si une composante connexe presente un cycle absorbant, alors il nexiste pas deplus court chemin entre deux points de cette composante.
Soit R = (E, , l) un reseau. Soit s E, une condition necessaire et suffisantepour quil existe un plus court chemin entre s et tout point de E\{s} est :
1. s est une racine de (E, ) et,
2. Il ny a pas de circuit absorbant dans R.
10.2 Problematique du plus court chemin
Il y a 3 problematiques a la recherche dun plus court chemin : Soient x et y deux sommets de E, trouver un plus court chemin de x a y, Soit i E, trouver les longueurs (j) des plus courts chemin de i a j,
j E\{i}.
Trouver les longueurs des plus courts chemins de i a j, i, j E.Pour resoudre le probleme (1) on doit dabord resoudre (2) avec i = x.
72
8/3/2019 ProgDynamique
74/168
10.2.1 Graphe des plus courts chemin
Soit R = (E, , l) un reseau sans cycle absorbant, soit i E. On definit
i : E R {} definie par :i(x) = la longueur dun plus court chemin de i a x sil existei(x) = sinon
Soit (E, , l) le reseau defini par :
=
(x, y) , l({x, y}) = i(y) i(x)
(E, , l) est appele graphe des plus courts chemins de i. est constitue des arcs
faisant partie dun plus courts chemin de i a un sommet de E.Un plus court chemin de i a x dans R est un chemin de i a x dans (E, ).Exemple i:
x0 x1
x2 x3
x4
x5
x6
3
2
3
52
1
2
1
42
On peut construire lapplication x0(x)
x x0(x)x0 0x1 3x2 x3 7x4 5x5 6
x6 8Le graphe des plus court chemins est alors :
73
8/3/2019 ProgDynamique
75/168
x0 x1
x2 x3
x4
x5
x6
3
2
1
2
1
2
Arborescence de plus courts chemins
Soit R = (E, , l) un reseau sans cycles absorbant. Soit i E et (E, ) legraphe des plus courts chemins defini precedemment. On dit que (E, A) est une
arborescence des plus courts chemins pour R si : E = {x E, i(x) = } (E, A) est une arborescence ayant pour racine le sommet i.
A
Remarque: En general une arborescence des plus courts chemins nest pas un arbrede poids minimum.
10.3 Algorithme de Floyd
Cet algorithme permet de calculer la longueur du plus court chemin dans unreseau R = (E, , l), pour tout couple de sommets (x, y). On notera Ek lensembleconstitue des k premiers sommets de E(k n). On considere la matrice L0 = (l0ij )telle que l0ii = 0 et si i = j :
l0ij =
l(i, j) si (i, j) 0 si i = j+ sinon
On considere la matrice Lk = (lkij) ou lkij represente la longueur minimum des
chemins de i a j dont les sommets intermediaires sont dans Ek.
Pour k = 0, on pose Ek = , on voit alors que L
0
correspond bien a L
k
aveck = 0. Ainsi Ln constitue la solution du probleme, cest a dire que lnij est bien lalongueur du plus court chemin de i a j dans lensemble En = E.Pour calculer Lk on utilise lequation de recurrence suivante (on supposera quele graphe est sans circuit absorbant) :
lkij = min
lk1ik + lk1kj , l
k1ij
Ce probleme peut se resoudre en utilisant la programmation dynamique. Sa com-plexite est en O(n3) (avec n = |E|) en temps de calcul, et O(n2) en memoire.
74
8/3/2019 ProgDynamique
76/168
En effet on na pas besoin de memoriser chaque matrice Lk mais seulement lamatrice courante et la precedente.
Pour detecter la presence de circuit absorbant, il suffit de regarder sil existeun sommet x tel que l(x, x) 0. En supposant qua letat initial L0ii = 0, onapplique la relation de recurrence sur toute la matrice et lon regarde si deselements diagonaux sont inferieurs a 0.Lorsque lequation de recurrence a ete appliquee pour former les n matrices Ln,on a alors lnij qui est egal a la longueur dun plus court chemin du sommet i ausommet j (sil existe, sinon).
10.4 Algorithme de Bellman
Nous allons etudier lalgorithme de Bellman pour calculer les plus courtschemins dans un reseau a longueurs quelconques. Cet algorithme ainsi que celuide Dijkstra ne calculent pas la longueur du plus court chemin pour tout couplede point (x, y) G, mais seulement la longueur des plus courts chemin dunsommet inital i a tout autre sommet x du graphe.But : soit R = (E, , l), i E, calculer i.Lidee est quun chemin de i a x dans R passe necessairement par un y 1(x).La longueur dun plus court chemin de i a x passant par y est :
i(x) = i(y) + l(y, x)
Et donc :i(x) = min
y1(x){i(y) + l(y, x)}
10.4.1 Algorithme en pseudo language
Donnees : E, , 1, l , i EResultat : ,CIRCABS
1: CIRCABS= FAUX; 0(i) = 0 ; 1(i) = 0 ; k = 1
2: for all x E\{i} do3: 0(x) =
4: 1(x) =
5: end for
6: for all x E tel que i 1(x) do
7: 1(x) = l(i, x)
8: end for
75
8/3/2019 ProgDynamique
77/168
9: while k < n + 1 et x E tel que k(x) = k1(x) do
10: k = k + 1
11: for all x E do12: k = min
k1(x), k1(y) + l(y, x); y 1(x)
13: end for
14: end while
15: if k = n + 1 then
16: CIRCABS= V RAI
17: end if
Cet algorithme renvoit egalement dans la variable CIRCABS la presencedun cycle absorbant.
Complexite
Linitialisation de la ligne 1 est en temps constant O(1) La boucle dinitialisation des lignes 2 a 5 est en O(n) La boucle dinitialisation des lignes 6 a 8 est en O(n + m) Le corps de boucle principale est execute n + 1 fois au maximum. La com-
plexite de levaluation de la ligne 9 est en O(n) et le corps de la boucle 9 a14 est en O(n + m).
Au total, la complexite de lalgorithme de Bellman est O(n(n + m)).Remarque: La complexite de lalgorithme de Bellman dans le cas dun graphedense (m = n2) devient O(n3).
10.4.2 Exemple dexecution
Exemple i:
76
8/3/2019 ProgDynamique
78/168
1
2
3
4
5
6
7
8
2
2
2
2
1
4
2
3
Construisons k pas a pas pour lalgorithme de Bellman avec i = 1.
1 2 3 4 5 60 0 1 0 7 8 2 0 7 8 11 8 93 0 7 6 10 8 94 0 7 6 10 8 8
10.4.3 Justification
Lidee est que la longueur dun chemin du sommet i a nimporte quel sommetx est :
i(x) = miny1(x)
{i(y) + l(y, x)}
Cete formule locale marche pour tout le graphe, et il faut lappliquer jusqua sta-bilite (ou jusqua n iterations, dans ce cas il y a presence de cycle absorbant).
On appelle kchemin un chemin possedant au plus k arcs. Dans lalgorithme de
Bellman, ki (x) represente la longueur dun au plus kchemin de i a x (silexiste, sinon).Pour prouver cette proposition, nous allons proceder par recurrence.La propriete est trivialement verifiee pour k = 0 et k = 1. Supposons quelle estverifiee jusqua letape k 1 et placons-nous a letape k.Soit Ck lensemble des sommets y tels quil existe un kchemin de i a y.
77
8/3/2019 ProgDynamique
79/168
Si x / Ck, y 1(x), y / Ck1. Donc dapres lequation de recurrence aletape k, k(x) = k1(y)y
1(x) = . Si x C
ket x = i alors y 1(x) tel que y C
k1. Donc
k1(y) < .
Tout kchemin de i a x passe par un y 1(x). Un plus court kcheminde i a x est compose un plus court k 1chemin de i a un sommet y 1(x)et de larc (y, x) de longueur l. Il a pour longueur k1(y) + l(y, x). Lalongueur dun plus court kchemin de i a x est donc :
miny1(x)
k1i (y) + l(y, x)
Quand il existe, un plus court chemin de i a x possede au plus n 1 arcs (avecn = |E|). En effet un plus court chemin ne peut etre quun chemin elementaire(ne comportant pas de circuit).
Si a la fin de lalgo, k n, alors x E, il existe un plus court chemin de i a x. Ilny pas de circuit absorbant. Si pour k = n + 1, x E tel que n1(x) = n(x),alors il nexiste pas de plus court chemin entre i et x, donc le graphe presente uncycle absorbant.
Remarque: Pour implementer lalgorithme de Bellman, il suffit de 2 tableaux : courant et precedent. Les acces a ces tableaux se font par exemple grace aune instruction du type k%2 ou k%2 signifie k modulo 2.
10.5 Algorithme de Dikstra
Lalgorithme de Dijkstra permet de trouver le plus court chemin dans unreseau (E, , l) sans cycle absorbant. Dans un tel reseau on a lequivalence sui-vante :
i, x E2 un chemin de i a x un plus court chemin de i a x
Lalgorithme de Dijkstra necessite egalement que tous les arcs soient positifsou nuls.
Le principe de lalgorithme est le suivant : Soit R = (E, , l), pour tout u ,l(u) 0. Soit i E sommet initial de la recherche. S designe lensemble des
sommets x de E pour lesquelles la longueur dun plus court chemin de i a x a etecalcule.Initalement S = {i}. (i) = 0.
On appelle Schemin un chemin partant de i et ayant tous ses sommets dansS sauf le dernier.Soit Y = E\S, y Y, (y) est la longueur dun plus court Schemin de i a y.On selectionne y dans Y tel que (y) = minyY
(y).
78
8/3/2019 ProgDynamique
80/168
10.5.1 Algorithme en pseudo language
Donnees : E, , l , i E
Resultat : , S
1: S = {i}, (i) = 0, k = 1, x1 = i
2: for all x E\{i} do
3: (x) =
4: end for
5: while k < n et (xk) < do
6:for all y (xk) tel que y / S do
7: (y) = min [(y), (xk) + l(xk, y)]
8: end for
9: Extraire un sommet x / S tel que (x) = min[(y)y / S]
10: k = k + 1, xk = x, S = S {xk}.
11: end while
Complexite
Nous prendrons S sous la forme dun tableau de booleen Les boucles dinitialisation des ligne 1 et 2 a 4 sont en O(n) Le corps de la boucle principale (ligne 5 a 11) est execute n fois.
La complexite de lalgorithme de Dijsktra est en O(n2).
10.5.2 Exemple dexecution
Exemple i:
79
8/3/2019 ProgDynamique
81/168
a
b
c
d
e
f
2
8
5
3
1
41
1
1
1
Construisons S pas a pas pour lalgorithme de Dijkstra avec i = a.
S k x y{a} 1 a b, c
{a, b} 2 b c, d{a,b,d} 3 d c, e, f
{a,b,d,f} 4 f /{a,b,c,d,f} 5 c e
{a,b,c,d,e,f} 6 e /A la fin de lalgo, les valeurs des couts des plus courts chemins sont :
Sommet a b c d e f Cout 0 2 5 3 7 4
10.6 Plus courts chemins (Exploration largeur)
Nous nous placons dans le cas dun reseau R = (E, , l) tel que pour tout
arc u dans , lapplication de ponderation soit egale a une constante strictementpositive. On prendra l(u) = c = 1.
Pour trouver la longueur du plus court chemin dun sommet i a tout autresommet x (sil existe), il existe un algorithme en temps lineaire O(n+m) se basantsur la propriete de constance de lapplication de ponderation. Cest lalgorithmedit dexploration-largeur.Il consiste a parcourir le graphe par couches successives a partir de i et deproche en proche selon ses sucesseurs. La longueur du plus court chemin a x estalors le nombre minimal de couches parcourues pour aller de i a x (multiplie parla constante c).
80
8/3/2019 ProgDynamique
82/168
10.6.1 Algorithme en pseudo langage
On prendra pour cet algorithme l(u) = 1u
Donnees : E, , i EResultat : , S
1: (i) = 0, S = {i}, T = 0, k = 1
2: for all x E do
3: (x) =
4: end for
5: while S = do
6: for all x S do
7: for all y (x) tel que (y) = do
8: (y) = k
9: T = T {y}
10: end for
11: end for
12: S = T, T = 0
13: k = k + 1
14: end while
10.7 Graphes sans circuits : GSC
10.7.1 Definit