Modèles et Algorithmes des Graphes
Modèles et Algorithmes des Graphes
Modèles et Algorithmes pour les Graphes 1. Généralités sur les graphes : exemples de graphes comme modèles de
situations concrètes, et questions associées pour découverte des notions
(chemins, PCC, fermeture transitive, descendance, clique, CFC, arbres, etc.).
2/220 2/220
Bibliographie
Obtention d’un diplôme Master d’informatique : suite 1 Obtention d’un diplôme Master d’informatique : suite 2
1. Quel est le nombre minimum de semestres pour obtenir ce master ? La construction d’un pavillon demande la réalisation d’un certain nombre de tâches.
La liste des tâches à effectuer, leur durée et les contraintes d’antériorités à respecter
sont données dans le table ci-dessus. Le travail commençant à la date 0, on cherche
un planning des opérations qui permet de minimiser la durée totale.
Un chemin P dans un graphe orienté G est une suite d’arcs dont les extrémités
droites/gauches coïncident de la façon suivante :
P = ((u0 , u1 ), (u1 , u2 ), (u2 , u3 ), . . . , (uk −1 , uk )). La longueur du P est le nombre Soit le graphe orienté G = (V , E ).
d’arcs (ici k ).
Pour un arc (x , y ) ∈ E, x est l’origine et y est l’extrémité de l’arc.
Si u0 = uk , le chemin est appelé circuit. On dit aussi que y est successeur de x, ou que x est prédécesseur de y .
Un chemin élémentaire est défini par une suite de sommets sans répétition (sauf Γ+ (x ) = {y ∈ V | (x , y ) ∈ E } est l’ensemble des successeurs de x.
pour le premier et le dernier sommet).
Γ−1 (x ) = {z ∈ V |(z , x ) ∈ E } est l’ensemble des prédécesseurs de x.
Si le graphe est non orienté, on utilise chaîne et cycle à la place de chemin et
d + (x ) = |Γ(x )| est le degré extérieur de x.
circuit.
d − (x ) = |Γ−1 (x )| est le degré intérieur de x.
Un graphe sans cycle/circuit est appelé acyclique / sans circuit.
d (x ) = d + (x ) + d − (x ) est le degré de x.
Un graphe non orienté tel que chaque couple de sommets est connecté par une
chaîne est dit connexe. Un chemin P allant de x à y , dont on ne précise pas les sommets intermédiaires,
sera noté : P = x ; y . y est alors un descendant de x et x un ascendant de y .
Un graphe orienté tel que chaque couple de sommets (u , v ) est connecté par un
chemin dans les deux sens (c.-à-d. de u à v et de v à u) est dit fortement
connexe. On dit aussi que les sommets u et v sont mutuellement accessibles.
Un graphe, non orienté, connexe et acyclique est dit arbre.
Planning d’examen
Les cinq étudiants : Dupont, Dupond, Durand, Duval et Duduche doivent passer
certaines épreuves parmi les suivants : Français, Anglais, Dessin, Couture,
On construit le graphe G = (V , E ) tel que V = {F , A, D , C , M , S } (un sommet par
Mécanique et Solfège. L’examen se déroulant par écrit, on désire que tous les
épreuve) et une arête relie deux solmmets si et seulement si un même candidat doit
étudiants qui doivent subir une même épreuve le fassent simultanément. Chaque
subir les épreuves correspondants.
étudiant ne peut se présenter qu’à une épreuve au plus chaque jour. Ci-dessous la
liste des épreuves que doit passer chaque étudiant : Dupont : Français, Anglais, 1. Le nombre maximal d’épreuves que l’on peut organiser le même jour est donné
Mécanique ; Dupond : Dessin, Couture ; Durand : Anglais, Solfège ; Duval : Dessin, alors par le cardinal du stable maximum {F , S , C }, donc 3.
Couture, Mécanique ; Duduche : Dessin, Solfège. 2. Pour trouver le nombre minimal de jours nécessaires à l’organisation de toutes
1. Quel est le nombre maximal d’épreuves que l’on peut organiser le même jour ? les épreuves on peut appliquer l’algorithme suivant : tant qu’il y un graphe
non-vide, on trouve le stable max et on enlève du graphe ; sur le graphe ainsi
2. Quel est le nombre minimal de jours nécessaires à l’organisation de toutes les
réduit on applique la même stratégie. La réponse est trois jours dans le cas
épreuves ?
consideré ; le 1e jour on organise {F , S , C }, le 2e jour on organise {A, D }, le
dernier jour on organise {M },
On appelle chaîne eulérienne (resp. cycle eulérien) une chaîne (resp. un cycle)
qui emprunte une fois et une seule chaque arête du graphe.
Théorème d’Euler : Un graphe connexe a une chaîne eulérienne si et
seulement si tous ses sommets ont un degré pair ou tous ses sommets ont un
degré pair sauf deux sommets.
On peut démontrer que :
si le graphe n’a pas de sommet impair, alors il a un cycle eulérien.
un graphe ayant plus de deux sommets impairs ne possède pas de chaîne
eulérienne (donc non pour le graphe de la ville de Königsberg).
La ville de Königsberg sur le Pregel et ses 7 ponts. Déterminer s’il existe ou non une si le graphe a deux sommets impairs, ce sont les extrémités de la chaîne eulérienne.
promenade dans les rues de Königsberg permettant, à partir d’un point de départ au
choix, de passer une et une seule fois par chaque pont, et de revenir à son point de
départ. Ce problème (résolu par Leonhard Euler en 1736) est considéré comme
l’origine de la théorie des graphes.
1 2 3 4
1 2 3 4
5 6 7 8 9
5 6 7 8 9
10 11 12 13 14 15
10 11 12 13 14 15
F IGURE 3 – Les sommets jaunes et verts ne sont pas joignables à partir des sommets rouges.
F IGURE 2 – Le plan de sens uniques du centre-ville. Les trois zones coloriées en rouge, jaune et vert sont des Composantes Fortements Connexes
(CFC)
Soit G = (V , E ) un graphe. Rappel : Soit R = (X , U , C ) un graphe connexe orienté (réseau). A ∀ arc u on affecte une
Un couplage M est un ensemble d’arêtes deux à deux non adjacentes. valeur (capacité) cu qui est une borne supérieure du flux sur l’arc.
Une couverture par sommets C est un ensemble de sommets tel que chaque Soit deux sommets particuliers s ∈ X (source) et t ∈ X (puits). Considérons le
arête est incidente avec au moins un sommet de C. graphe G0 = (X , U 0 ) où U 0 = U ∪ {t , s}.
Soit un graphe biparti G(U ∪ V , E ). L’ensemble des arêtes représente les couples
la loi de conservation du flot doit être satisfaite pour chaque sommet.
compatibles. Il s’agit de trouver le couplage maximum (un couplage contenant le plus
grand nombre possible d’arêtes) . Ci-dessous le problème de mariage modélisé comme un problème du flot
maximum. Les capacités sont fixées à 1 partout.
F IGURE 5 – Il s’agit de marier ces personnes en satisfaisant les contraintes des couples
compatibles. On peut voir ici (par énumération) qu’on ne peut marier que trois couples.
u1 u2 u3 u4 u5
s +1 +1 0 0 0
A= t 0 0 0 −1 −1
a −1 0 +1 +1 0
b 0 −1 −1 0 +1
Remarque : les valeurs en bleu sont les poids (longueurs) des arcs.
LP formulation for Shortest/Longest path problem (SPP/LPP) : Example LP formulation for Shortest/Longest path problem (SPP/LPP)
Any path from s to t can be represented by the vector x where xe = 1 if the arc e belongs to the
path, xe = 0 otherwise and under the conditions
xsu xsv xuv xut xvt Let A be the node-arc incidence matrix and denote by ai its ith row. The flow
s +1 +1 0 0 0 conservation law for any intermediate vertex i is written :
A= t 0 0 0 −1 −1
u −1 0 +1 +1 0 ai x = 0 (6)
v 0 −1 −1 0 +1
The linear program is :
Left : Values in red are the weights. Right : A denotes the node-arc incidence matrix for this
example. let d ∈ R n be defined as
a flow of value 1 exits the vertex s :
max(min) ∑ xe we (7)
+1 i =s e∈E
xsu + xsv = 1 (1) di = −1 i =t Ax =d (8)
a flow of value 1 enters the vertex t : 0 otherwise
∀e ∈ E , xe ∈ {0, 1} (9)
xut + xvt = 1 ⇔ −xut − xvt = −1 (2) Exemple :
flow conservation law for the intermediate vertex u :
xsu = xuv + xut ⇔ −xsu + xuv + xut = 0 (3) xsu xsv xuv xut xvt
flow conservation law for the intermediate vertex v :
s +1 +1 0 0 0
A= t 0 0 0 −1 −1
xsv + xuv = xut ⇔ −xsv − xuv + xut = 0 (4)
u −1 0 +1 +1 0
the goal is to maximize/minimize the total weight : v 0 −1 −1 0 +1
max(min)z = xsu + 2xsv + 2xuv + 3xut + xvt (5)
Values in red are the weights.
31/220 31/220 32/220 32/220
LP formulation for Shortest/Longest path problem (SPP/LPP) Le problème du flot maximum
a flow of value 1 exits the vertex s and enters the vertex t : ∑ φ(u ,v ) = ∑ φ(v ,u ) (13)
(u ,v )∈Γ+ (u ) (v ,u )∈Γ− (u )
∑ xsv = 1 et ∑ xut = 1 (11) La valeur du flot est notée par φ0 . Elle est définie par
(s,v )∈E (u ,t )∈E
max(min)z = ∑ xuv wuv (12) But : Trouver dans G0 un flot compatible φ0 = [φ0 , φ1 , φ2 , . . . φM ] (c.-à-d.
(u ,v )∈E
0 ≤ φu ≤ cu , ∀u =∈ U (15)
Equations (10), (11) and (12) represent a linear program (LP).
et tel que φ0 soit maximale.
Soit le tableau T de taille m × n, dont certaines cases sont dites “admissibles” (les
autres sont “non admissibles”. On se donne également m + n entiers positifs ou nuls
l1 , . . . , lm , c1 . . . , cn . Il s’agit d’affecter des nombres entiers aux cases admissibles (et à
celles-ci seulement) de telle sorte que :
la somme des nombres affectés aux cases d’une ligne i soit inférieure ou égale
à li (i = 1, 2, . . . , m).
la somme des nombres affectés aux cases d’une colonne j soit inférieure ou
égale à cj (j = 1, 2, . . . , n).
F IGURE 6 – Exemple du problème de cases admissibles. Les cases interdites sont en gris.
la somme des nombres affectés aux cases du tableau soit maximum.
L’exploration d’un graphe (c.-à-d. la visite de tous les sommets joignables à partir
d’un sommet de départ) est une opération fréquente et importante.
elle ressemble à l’exploration d’un labyrinthe
pour explorer un labyrinthe il faut :
une craie : pour noter les carrefours/couloirs déjà visités
un fil : pour pouvoir retourner sur ses pas (backtrack)
Algorithm 1 DFS(G,s) (utilise une pile P et suit la stratégie LIFO (Last In First Out )).
L’algorithme (1) est appliqué sur le graphe G de la Fig. (35) à partir du sommet S. Les
Require: G=(V,E), start vertex s. valeurs v .in (v .out) seront indiquées en haut à gauche(droite) du sommet v (une fois
Ensure: [Link] = true for all vertices v ∈ V reachable from s. calculées).
1: Initialisation : ∀v ∈ V : [Link] ← false ; clock ← 1 ; previsit(s) ; P ← [s] ;
2: u ← P .head () ( u reçoit le sommet de la pile P )
3: while (u 6= nil ) do
4: if (∃(u , v ) ∈ E | v .visited = false ) then
5: { previsit(v) ; [Link](v) } { v est inséré dans P }
6: else
7: { postvisit(u) ; delete(u,P) } { le sommet u est supprimé de P }
8: end if
9: u ← P .head () { u reçoit le sommet de la pile P }
10: end while
F IGURE 11 – L’état de la pile P après les
premiers quatre coups d’horloge (clock). La F IGURE 12 – Le graphe G après les premiers
pile contient les quatre sommets S , A, B , C quatre coups d’horloge. Les valeurs v .in
where : qui sont empilés l’un après l’autre sur la pile. correspondent au moment de la
previsit(v)={[Link] ← true ; [Link] ← clock ; clock ← clock+1} La tête de la pile correspond au sommet de visite/découverte du sommet v .
la pile (C à l’occurence).
postvisit(v)={[Link] ← clock ; clock← clock+1}
L’algorithme (1) est appliqué sur le graphe G de la Fig. (35) à partir du sommet S. L’algorithme (1) est appliqué sur le graphe G de la Fig. (35) à partir du sommet S.
F IGURE 13 – L’état de la pile P après les F IGURE 14 – Le graphe G après les premiers F IGURE 16 – Le graphe G après les premiers six
F IGURE 15 – L’état de la pile P après les
premiers cinq coups d’horloge (clock). La cinq coups d’horloge. C .out = 5 : c’est le coups d’horloge. Les valeurs v .in correspondent
premiers six coups d’horloge. La pile
pile contient les trois sommets S , A, B. Le moment quand le sommet C a été dépilé de la au moment de la visite/découverte du sommet
contient les deux sommets S , A. Le sommet
sommet B est actuellement la tête de la pile. pile. v . Les valeurs v .out indiquent le moment de
A est actuellement la tête de la pile.
l’enlèvement du sommet v de la pile.
L’algorithme (1) est appliqué sur le graphe G de la Fig. (35) à partir du sommet S. . L’algorithme (1) est appliqué sur le graphe G de la Fig. (35) à partir du sommet S.
F IGURE 18 – Le graphe G après les sept coups F IGURE 19 – L’état de la pile P après les
F IGURE 17 – L’état de la pile P après sept d’horloge. Les valeurs v .in correspondent au premiers huit coups d’horloge. La pile ne F IGURE 20 – Le graphe G après les premiers
coups d’horloge (clock). La pile ne contient moment de la visite/découverte du sommet v . contient que les sommets S , D. Le sommet huits coups d’horloge.
que le sommet S qui est la tête de la pile. Les valeurs v .out indiquent le moment de D est la tête de la pile.
l’enlèvement du sommet v de la pile.
L’algorithme (1) est appliqué sur le graphe G de la Fig. (35) à partir du sommet S.
L’algorithme (1) est appliqué sur le graphe G de la Fig. (35) à partir du sommet S. .
F IGURE 21 – L’état de la pile P après les F IGURE 22 – Le graphe G après les premiers
premiers neuf coups d’horloge. La pile F IGURE 24 – L’arbre de l’appel DFS (G, S ).
neuf coups d’horloge. Tous les sommets ont été F IGURE 23 – Tous les sommets ont éte visités.
contient les sommets S , D , E. Le sommet E Le graphe G a été parcouru en profondeur
visités. Les valeurs v .in correspondent au La pile P est vide.
est la tête de la pile. d’abbord. Les lignes pointillées indiquent
moment de la visite/découverte du sommet v .
des testes/vérifications éffectuées dans le
code.
Algorithm 2 BFS(G,s) (utilise une file F et suit la stratégie FIFO (First In First Out) ).
L’algorithme (2) est appliqué sur le graphe G de la Fig. (32) à partir du sommet S. Les
Require: G=(V,E), start vertex s. valeurs v .in (v .out) seront indiquées en haut à gauche(droite) du sommet v (dès
Ensure: to be discovered qu’elles soient calculées).
1: Initialisation : ∀v ∈ V : [Link] ← false ; clock← 1 ; previsit(s) ; F ← [s] ;
2: u ← P .head () (u reçoit le sommet de la file F )
3: while (u 6= nil ) do
4: if (∃(u , v ) ∈ E | v .visited = false) then
5: { previsit(v) ; [Link](v) } {v est inséré dans F }
6: else
7: { postvisit(u) ; delete(u,F) } {le sommet u est supprimé de F }
8: end if
9: u ← F .head () {u reçoit le sommet de la file F }
10: end while
F IGURE 25 – L’état de la file F après les
premiers cinq coups d’horloge. La file F IGURE 26 – Le graphe G après les premiers
contient le sommet S et les quatre sommets cinq coups d’horloge. Les valeurs v .in
where : qui lui sont adjacents A, C , D , E. La tête de correspondent au moment de la
previsit(v)={[Link] ← true ; [Link] ← clock ; clock ← clock+1} la file n’a pas bougé et pointe sur le sommet visite/découverte du sommet v .
S.
postvisit(v)={[Link] ← clock ; clock← clock+1}
L’algorithme (2) est appliqué sur le graphe G de la Fig. (32) à partir du sommet S.. L’algorithme (2) est appliqué sur le graphe G de la Fig. (32) à partir du sommet S..
F IGURE 28 – Le graphe G après les premiers six F IGURE 30 – Le graphe G après les premiers
F IGURE 29 – L’état de la file F après les
F IGURE 27 – L’état de la file F après les sept coups d’horloge. Les valeurs v .in
coups d’horloge. Les valeurs v .in correspondent premiers sept coups d’horloge. La tête de la
premiers six coups d’horloge. Le sommet S correspondent au moment de la
au moment de la visite/découverte du sommet file pointe sur le sommet A. Le sommet B
a été enlevé et la tête de la file pointe sur le visite/découverte du sommet v . Les valeurs
v . Les valeurs v .out indiquent le moment de qui lui est adjacent est ajouté(enfilé) dans la
sommet A. v .out indiquent le moment de l’enlèvement du
l’enlèvement du sommet v de la file. file F .
sommet v de la file.
L’algorithme (1) est appliqué sur le graphe G de la Fig. (32) à partir du sommet S.
L’algorithme (2) est appliqué sur le graphe G de la Fig. (32) à partir du sommet S..
Une application Parcours en largeur d’abord et calcul des PCC de s aux autres sommets
Remarque : tous les chemins partant de la racine s sont des PCC (c.-à-d. que ceci
est un arbre des PCC de s à tous les autres sommets).
Algorithm 4 Explore(G,v).
Analyse de complexité :
∀v ∈ V Explore(G,v) est appelée une seule fois (grâce à l’étiquette [Link]).
Chaque arête (u,v)∈ E est examiné exactement deux fois : la première fois lors
d’Explore(G,u) et une deuxième fois lors d’Explore(G,v).
Sous l’hypothèse que previsit et postvisit prennent un temps constant, DFS(G)
nécessite un temps Θ(|V | + |E |) (linéaire).
Forêt couvrante associée à un parcours en profondeur d’abord Calcul la numérotation [in, out] ([pre, post])
Les valeurs in/out peuvent être calculées dans les procédures previsit et
postvisit.
On utilise pour ce faire le compteur « clock » initialisé à 1 et défini comme suit.
previsit(v)={[Link] ← clock ; clock ← clock+1}
postvisit(v)={[Link] ← clock ; clock ← clock+1}
Proposition : Pour chaque couple de sommet u et v, les intervalles [[Link],[Link]] et
[[Link],[Link]] sont soit complètement disjoints, soit l’un est entièrement inclus dans
l’autre.
Preuve : L’intervalle [[Link], [Link]] indique le temps durant lequel le sommet u est
présent dans la pile. La stratégie LIFO explique alors la propriété ci-dessus.
Lors du parcours, chaque sommet v est muni de deux étiquettes ([Link], [Link]). On
utilise aussi les notations (pre[v], post[v]) 1 . [Link] indique le moment de la
première visite du sommet v. [Link] indique le moment quand la procédure DFS a
définitivement quitté le sommet v (il a été donc complètement exploré).
1. Dans la terminologie de ce cours la numérotation [pre, post] est une autre dénomination de la
numérotation [in, out] (c.-à-d. pre(u)=[Link] et post(u)=[Link])
63/220 63/220 64/220 64/220
Parcours en profondeur dans les graphes orientés Parcours en profondeur dans les graphes orientés : classification des arcs
DFS(G) s’applique d’une façon similaire dans les graphes orientés. En raison de
l’orientation des arcs, les arbres de parcours engendrés sont plus complexes
(appelés aussi arborescences).
Relations entre le type d’arc et la numérotation [pre, post] ([in, out]) Application de DFS : tri topologique (linéaire)
Le parcours en profondeur peut être utilisé pour effectuer un tri topologique (ou tri
linéaire) d’un graphe orienté sans circuit. Le tri topologique d’un DAG (graphe orienté
acyclique) G = (V , E ) consiste à ordonner linéairement tous ses sommets de telle
sorte que si G contient l’arc (u,v) alors, u apparaisse avant v .
Dans une forêt DFS, le sommet u est un ancêtre du sommet v ssi u est visité le
premier et v est visité lors de l’appel explore(u) (c.-à-d. pre(u) < pre(v) <
post(v) < post(u)).
Dans une forêt DFS, le sommet u est un descendant du sommet v ssi v est visité
le premier et u est visité lors de l’appel explore(v) (c.-à-d. pre(v) < pre(u) <
post(u) < post(v)).
On peut alors donner la classification suivante pour l’arc (u,v) :
pre(u) < pre(v) < post(v) < post(u) ssi l’arc (u,v) est de type arc
couvrant/arc en avant.
pre(v) < pre(u) < post(u) < post(v) ssi l’arc (u,v) est de type arc retour.
les intervalles [pre(v), post(v)] et [pre(u), post(u)] sont disjoints ssi l’arc
(u,v) est de type arc croisé.
Proposition : La numérotation post d’un DAG obtenue lors d’un parcours DFS
Les propositions suivantes sont utilisées pour effectuer un tri topologique. satisfait l’inégalité post (u ) > post (v ) pour chaque arc (u, v).
Proposition : Un graphe orienté G contient un circuit, ssi la forêt engendrée Preuve : Les seuls arcs (u , v ) pour lesquels post (u ) < post (v ) dans l’arbre DFS
pars le parcours DFS(G) contient un arc retour. sont les arcs retour. Or, il n’y pas de tels arcs dans un DAG.
Preuve :
Evident si le parcours DFS(G) contient un arc retour. Algorithm 6 Premier algorithme pour linéariser un DAG.
Supposons maintenant que G contient un circuit C : v0 → v1 → v2 → . . . → vk → v0 .
Soit vi le premier sommet du C qui a été visité durant le parcours DFS. Tous les Require: G=(V,E), DAG
autres sommets de C sont des descendants de vi dans l’arbre de parcours et alors Ensure: List vertices in linear order.
vi −1 → vi est un arc retour (si i = 0 alors vk → v0 ).
1: Perform a DFS search and obtain the number post (v ) for any vertex v ∈ V .
2: List vertices in order of decreasing post (v ) values.
Linéarisation d’un DAG par l’algorithme 6 Application de DFS : linéarisation d’un DAG (suite)
Les deux dernières tâches E et F peuvent être exécutées dans un ordre quelconque.
L’ordre d’exécution des tâches est donné par l’odre d’enlèvement des
sommets-sources : B, D, A, C, E, F.
73/220 73/220 74/220 74/220
1 2 3 4
1 2 3 4
5 6 7 8 9
5 6 7 8 9
10 11 12 13 14 15
10 11 12 13 14 15
F IGURE 48 – Les sommets jaunes et verts ne sont pas joignables à partir des sommets rouges.
F IGURE 47 – Le plan de sens uniques du centre-ville. Les trois zones coloriées en rouge, jaune et vert sont des Composantes Fortements Connexes
(CFC)
Le plan donc n’est pas acceptable puisque le graphe associé contient trois CFC.
Soit le graphe orienté G = (V , E ). G est dit fortement connexe, si pour chaque La détection des c.f.c. se fait facilement grâce aux propriétés du parcours DFS.
couple de sommets (u , v ), il existe un chemin de u à v , noté (u ; v ), et un
Propriété 1 : La procédure explore(G,u) ne se termine que si tous les sommets
chemin de v à u, noté (v ; u).
accessibles à partir de u soient visités/explorés (c.-à-d. après avoir exploré toute
Cette définition définit une relation binaire dans V . la descendance Γ∗u du sommet u).
uRv ≡ (u ∈ Γ∗v ) ∧ (v ∈ Γ∗u ) (16) Ainsi, si la procédure explore(G, v ) est exécutée à partir d’un sommet v
appartenant à une c.f.c. puits (une c.f.c. sans arcs sortants), alors elle visiterait
où Γ∗v indique la descendance du sommet v . exactement cette c.f.c. La dernière pourrait être alors enlevée du graphe G, et le
0
C’est une relation d’équivalence dont les classes s’appellent compostantes processus continuerait sur le graphe résultant G .
fortement connexes (c.f.c.). Illustrer cette propriété avec les deux meta-sommets {D} et {G,H,I,K,J,L} du
Elle partitionne V en ensembles disjoints (appelés c.f.c.). graphe de la figure (53).
Application de DFS : Composantes fortement connexes (suite) Application de DFS : Composantes fortement connexes (suite)
Grace à la propriété 3, nous savons comment trouver une c.f.c. source dans G.
Déterminer les sommets appartenant aux c.f.c. nécessite que le parcours
commence à partir d’une c.f.c. puits. Comment trouver une telle c.f.c. ?
Idée : Renverser le graphe (c.-à-d. changer l’orientation de tous les arcs). Le
graphe ainsi obtenu sera noté GR . F IGURE 53 – a) Un graphe orienté G et ses c.f.c. b) Le graphe réduit G̃
Alors les c.f.c. ne changent pas (facile à vérifier). Mais les sommets puits se
transforment en sources et vice versa. Le graphe G̃ se renverse aussi (voir les
graphes des figures (53) et (54).
La linéarisation du DAG G̃R permet de trier topologiquement les sommets de
DAG G̃ dans l’ordre des sommets-puits vers les sommets-sources.
Application de DFS : Algorithme de Kosaraju pour la détection des CFC Application de l’algorithme de Kosaraju (algorithme 8) : suite
Require: G=(V,E)
Ensure: Detect the strongly connected components (SCC) of G
1: Reverse all the edges in G, yielding digraph GR .
2: Run DFS on GR , obtaining the post (v ) numbers for all vertices v .
3: k ← 1.
4: Run EXPLORE(G,v) in G from the vertex v that has the highest post (v ) value in
GR , and has not yet been assigned to any SCC. Assign all vertices mapped out by
the exploration into SCC k .
5: Set k ← k + 1 and repeat from step 4, until all vertices have been assigned to
SCCs.
F IGURE 56 – Le graphe GR = (V , ER )
avec la numérotation [pre, post ]
F IGURE 55 – Le graphe G = (V , E ). obtenue avec un parcours
Complexité : linéaire. DFS (GR , A).
Calcul des PCC de s aux autres sommets dans le cas {le > 0 : e ∈ E } Algorithme de Dijkstra (suite)
Require: Graph G=(V,E) with positive edge weights {le > 0 : e ∈ E }, vertex s ∈ V
Ensure: ∀u ∈ V , dist (u ) is set to the shortest distance from s to u ; prev (u ) points
to the previous of u on this shortest path
1: Initialisation : ∀u ∈ V : dist (u ) ← ∞ and prev (u ) ← nil ; dist (s ) ← 0 ; Algorithm 10 dist_update(u,v).
2: P ← 0 / , (P contient les sommets v , tq dist (v ) est calculée définitivement)
1: if dist (v ) > dist (u ) + l (u , v ) then
3: T ← V (T contient des sommets v , tq dist (v ) n’est qu’une borne supérieure)
2: dist (v ) = dist (u ) + l (u , v )
4: while T is not empty do
3: prev (v ) ← u
5: u ← argmin dist (v )
v ∈(T ) 4: end if
S
6: P ← P {u }
7: T ← T \{u } Exemple :
8: for all edges (u , v ) ∈ E do
9: dist_update(u,v)
10: end for
11: end while
où
3
A 1 3 1 A 1
4 3
Soit le graphe G = (V , E , le > 0 : e ∈ E ). On cherche les PCC(s;u) : les plus
2 2 courts chemins de s aux autres sommets u ∈ V \{s}. Définissons dist ∗ (u )
C E C E comme la longueur du PCC(s;u).
5
L’algorithme procédera en |V | − 1 ittérations. Au début de chacune des itérations
itér P T
V est partinionné en deux sous-ensembles P et T , avec s ∈ P.
A B C D E Chaque sommet u ∈ V est affecté d’une étiquette dist (u ) qui vérifie les
propriétés suivantes ;
0 ∅ 0 ∞, nil ∞, nil ∞, nil ∞, nil
si u ∈ P : dist (u ) = dist ∗ (u )
1 {A} — 4, A 2, A ∞, nil ∞, nil si u ∈ T : dist (u ) = min dist (v ) + l (v , u )
2 {A; C } — 3, C — 6, C 7, C v ∈P ,v ∈Γ−1 (u )
Le tas binaire (Binary heap) est une file de priorité importante fréquemment
utilisée pour améliorer la complexité des algorithmes comme le tri par tas, l’alg.
de Dijkstra, l’alg. de Prim ....
Définition : Soit π(j ) la clé associée avec l’élément j de la file F. F est un tas
binaire si la condition suivante est satisfaite (relation entre le père et ses deux
fils) : F IGURE 60 – L’arbre parfait qui visualise un tas binaire avec 10 éléments. Seules les clés sont
j indiquées. Ci-dessous le tableau π associé avec ce tas binaire.
π(j ) ≥ π(b c) ∀j (20)
2
⇐⇒ π(j ) ≤ π(2j ) and π(j ) ≤ π(2j + 1) ∀j j 1 2 3 4 5 6 7 8 9 10
π(j ) 3 10 5 11 12 6 8 15 20 13
On représente le tas binaire par un arbre parfait partiellement ordonné :
∀ niveau est rempli de gauche à droite ; On a les règles suivantes :
∀ niveau est complètement rempli avant de commencer le niveau suivant ;
la condition (25) est satisfaite (l’élément contenu dans tout nœud est inférieur ou π(1) est la racine qui contient l’élément le plus petit ;
égal aux éléments contenus dans les fils de ce nœud). π(2j ) and π(2j + 1) sont les deux fils, s’ils existent, de π(j ). En plus,
Le tas est facile à implémenter en tableau. π(j ) ≤ π(2j ) and π(j ) ≤ π(2j + 1). ;
exemple j = 4 : π(4) = 11, π(8) = 15, π(9) = 20 ;
π(b 2j c) est le père de π(j ) pour j > 1 ;
exemple j = 9 : π(9) = 20, π(b 92 c) = π(4) = 11 ;
93/220 93/220 94/220 94/220
Arbres parfaits partiellement ordonnés et tas binaire : propriétés Arbres parfaits partiellement ordonnés et tas binaire : illustration du
fonctionnement
F IGURE 61 – (a) : un tas binaire avec 10 éléments. Seules les clés sont indiquées. (b)-(d) :
illustration de l’opération « insertion ». (e)-(g) : illustration de l’opération « extraction et
suppression du minimum ».
95/220 95/220 96/220 96/220
Version tas binaire de l’alg. de Dijkstra Version tas binaire de l’alg. de Dijkstra (suite)
Algorithm 12 Dijkstra_bis(G,l,s).
Require: Graphe G=(V,E) directed or undirected, with positive edge weights {le : e ∈ Algorithm 13 dist_update_bis(Q,(u , v )).
E } ; vertex s ∈ V
Require: Priority queue Q using dist as keys ; an edge (u , v ) ∈ E
Ensure: For all vertices u ∈ V , dist (u ) is set to the shortest distance from s to u ;
Ensure: Q is updated if the value of dist (v ) has been modified
prev (u ) points to the previous of u on this shortest path
if dist (v ) > dist (u ) + l (u , v ) then
1: ∀u ∈ V : initialize dist (u ) ← ∞ and prev (u ) ← nil
dist (v ) ← dist (u ) + l (u , v )
2: dist (s ) ← 0
prev (v ) ← u
3: P ← {s } {P contient les sommets v pour lesquels la valeur dist (v ) est calculée
ChangeKey(Q,v) {Q is updated according to the new value of dist (v ) }
définitivement}
end if
4: T ← makequeue(V) {créer une file de priorité T avec dist (v ), v ∈ (T ) comme
clés}
5: while T is not empty do Analyse de complexité de la version tas binaire de l’alg. de Dijkstra
6: u ← ExtractMin(T)
S
7: P ← P {u } makequeue(V) nécessite O (|V | log |V |) opérations.
8: T ← T \{u }
la boucle WHILE) (line 6) nécessite O (|V |) ExtractMin plus O (|E |) ChangeKey
9: for all edges (u , v ) ∈ E do
(updates) : O ((|V | + |E |) log |V |) opérations.
10: dist_update_bis(T,(u , v ))
11: end for En total : O ((|V | + |E |) log |V |).
12: end while
Les valeurs dist (.) dans l’alg. de Dijkstra sont soit des valeurs exactes, soit des
bornes supérieurs. La valeur dist (u ) équivaut dist ∗ (u ) à condition que tous les
sommets intermédiaires du chemin s;u sont dans P. Les valeurs dist (.) peuvent être
vues comme une suite des mises à jours :
Calcul des chemins les plus courts dans les graphes Algorithm 14 Procédure update((u , v ) ∈ E).
Une autre approche est d’utiliser la fonction multivoque Γ−1 et l’observation que le
Algorithm 15 Procédure Bellman-Ford (G,l,s). (PCC(s;v)) passe par un des prédécesseurs u ∈ Γ−1 (v ). On doit donc avoir
Require: Graphe G=(V,E) directed, edge weights {le : e ∈ E } with no negative cycles ; dist (v ) = min {dist (u ) + l (u , v )} = min{dist (v ), min {dist (u ) + l (u , v )}}
u ∈Γ−1 (v ) u ∈Γ−1 (v )
vertex s ∈ V
(21)
Ensure: For all vertices u ∈ V reachable from s, dist (u ) is set to the shortest distance
On obtient la variante suivante.
from s to u ;
1: for all u ∈ V do Algorithm 16 Procédure Bellman-Ford_bis (G,l,s).
2: dist (u ) ← ∞
3: prev (u ) ← nil Require: Graphe G=(V,E) directed, edge weights {le : e ∈ E } ; vertex s ∈ V
4: end for Ensure: dist k (u ) is set to the shortest distance from s to u over all paths with at most
5: dist (s ) ← 0 k arcs. It also detects the presence of negative cycle.
0 0
6: k ← 1 1: Initialisation : ∀u ∈ V : dist (u ) ← ∞ ; dist (s ) ← 0 ; stable ← false ; k ← 1 ;
2
4 Calcul des chemins les plus courts/longues dans les
2 5
graphes
1
7
−2 L’approche programmation dynamique
1 2
2 3
3 6
2
Alg. de Bellman-Ford dans le contexte de la programmation dynamique Illustration pour l’algorithme de Bellman-Ford
L’équation (22) permet de calculer la valeur dist (v ) sous l’hypothèse que les valeurs
dist (u ), ∀u ∈ Γ−1 (v ) sont calculées. Ce qui nécessite de résoudre des sous-
problèmes possedant un arc de moins par rapport au problème originel. Notons
dist k (v ) la valeur du PCC (s ; v ) qui contient au plus k arcs et réécrivons (22) :
dist k (v ) = min{dist k −1 (v ), min dist k −1 (u ) + l (u , v )} (23)
u ∈Γ−1 (v )
« multiplication ».
107/220 107/220 108/220 108/220
Algorithmes pour linéariser un DAG (graphe orienté sans circuit) (rappel) Linéarisation d’un DAG par l’algorithme 6
Application de l’ordre topologique/linéaire pour la détermination les chemins les Application de l’ordre topologique/linéaire pour la détermination des chemins
plus courts/longs dans un DAG plus courts/longs dans un DAG
Require: DAG G=(V,E), edge weights {le : e ∈ E }, vertex s∈ V Algorithm 21 Procédure dag-shortest-paths(BIS)(G,l,s).
Ensure: For all vertices u reachable from s, dist (u ) is set to the distance from s to u Require: DAG G=(V,E), edge weights {le : e ∈ E }, vertex s∈ V
1: for all u ∈ V do Ensure: For all vertices u reachable from s, dist (u ) is set to the distance from s to u
2: dist (u ) ← ∞ 1: for all u ∈ V do
3: end for 2: dist (u ) ← ∞
4: dist (s ) ← 0 3: end for
5: linearize G 4: dist (s ) ← 0
6: for all u ∈ V , in linearized order do 5: linearize G
7: for all edges (u , v ) ∈ E do 6: for all v ∈ V \ {s }, in linearized order do
8: dist (v ) = min{dist (v ), dist (u ) + l (u , v )} 7: for all edges (u , v ) ∈ E do
9: end for 8: dist (v ) := min{dist (v ), dist (u ) + l (u , v )}
10: end for 9: end for
10: end for
Obtention d’un diplôme Master d’informatique : suite 1 Obtention d’un diplôme Master d’informatique : suite 2
1. Modéliser les prérequis à l’aide d’un graphe. 1. Quel est le nombre minimum de semestres pour obtenir ce master ?
F IGURE 68 – On calcule d’abord la fonction rang, on obtient ainsi les valeurs rank . Les modules
F IGURE 67 – Modélisation à l’aide d’un graphe : les sommets correspondent aux modules, les sont alors ordonnancés dans l’ordre croissant de leur numéro rank . Le graphe est représenté
arcs - aux prérequis. par niveau, chaque niveau correspond aux sommets ayant la même valeur rank .
F IGURE 69 – Au moins 4 semestres sont nécessaires pour obtenir ce master. Cela peut se
calculer par un algorithme du plus long chemin dans un graphes sans circuit (DAG).
F IGURE 70 – Le nombre maximum de modules qu’il devra suivre simultanément vaut 2 : c’est le
nombre maximum de sommets dans un niveau (colonne) du graphe représenté par niveau, où
chaque niveau correspond aux sommets ayant la même valeur rank .
Cas des graphes sans circuit (DAG) : calcul de la fonction rang Calcul de la fonction rang : Illustration de l’algorithme vertex-rank(G)
Algorithm 23 Vertex-rank-shortest-paths(G,l,s).
Application l’ordre topologique/linéaire pour calculer les chemins les plus Application l’ordre topologique/linéaire pour calculer les chemins les plus
longs/courts longs/courts
Algorithm 24 Procédure dag-shortest-paths(G,l,s). Require: DAG G=(V,E), edge weights {le : e ∈ E }, vertex s∈ V
Ensure: For all vertices u reachable from s, dist (u ) is set to the distance from s to u
Require: DAG G=(V,E), edge weights {le : e ∈ E }, vertex s∈ V 1: for all u ∈ V do
Ensure: For all vertices u reachable from s, dist (u ) is set to the distance from s to u 2: dist (u ) ← ∞
1: for all u ∈ V do 3: end for
2: dist (u ) ← ∞ 4: dist (s ) ← 0
3: end for 5: linearize G
4: dist (s ) ← 0 6: for all v ∈ V \ {s }, in linearized order do
5: linearize G 7: for all edges (u , v ) ∈ E do
6: for all u ∈ V , in linearized order do 8: dist (v ) = min{dist (v ), dist (u ) + l (u , v )}
7: for all edges (u , v ) ∈ E do 9: end for
8: dist (v ) = min{dist (v ), dist (u ) + l (u , v )} 10: end for
9: end for
10: end for
2 1
1 2
C D
3
Attention aux appels récursifs naïfs ! ! ! ! La distance de Levenshtein (distance d’édition, de similarité)
Le symbole « _ » indique une omission (« gap »). On peut en utiliser tant que l’on
veut.
Le coût d’un alignement équivaut le nombre de colonnes où les caractères
divergent.
La distance de Levenshtein correspond au coût du meilleur alignement.
Et ce sous-problème sera résolu maintefois !. Pour L(n) la taille de l’arbre sera
exponentielle. Cela s’explique par les dépendances entre les problèmes L(j ) et Si A, B sont deux mots, la distance de Levenshtein est le nombre minimum de
L(j − 1) ; ils sont presque de la même taille. remplacements, ajouts et suppressions de lettres pour passer du mot A au mot
Pour améliorer l’efficacité il faut mémoriser les solutions des sous-problèmes B.
résolus, et les calculer dans le bon ordre (cela évoque déjà la programmation
dynamique).
131/220 131/220 132/220 132/220
La distance d’édition par la programmation dynamique La distance d’édition par la programmation dynamique
La distance d’édition par la programmation dynamique La distance d’édition par la programmation dynamique
E (i , j ) est découpé donc en trois sous-problèmes : E (i − 1, j ), E (i , j − 1), Algorithm 27 Dynamic programming algorithm for edit distance.
E (i − 1 , j − 1 ).
1: for i = 0 to m do
Pour trouver la meilleure solution il suffit de prendre le min : 2: E (i , 0) = i
3: end for
E (i , j ) = min{1 + E (i − 1, j ), 1 + E (i , j − 1), diff(i,j) + E (i − 1, j − 1)}
4: for j = 0 to n do
où diff(i,j)=0, si x [i ] = y [j ], 1 sinon. 5: E (0, j ) = j
6: end for
Pour se faire, on mémorisera les solutions des sous-problèmes E (i , j ) dans une
7: for i = 0 to m do
table 2D. Cette table sera parcourue de façon que les sous-problèmes
8: for j = 0 to n do
E (i − 1, j ), E (i , j − 1), E (i − 1, j − 1) sont calculés avant E (i , j ).
E (i , j ) = min{1 + E (i − 1, j ), 1 + E (i , j − 1), diff(i,j) + E (i − 1, j − 1)}
Valeurs initiales : on pose E (i , 0) = i (puisque c’est la distance d’édition entre 9: end for
une séquence vide et les i premiers caractères de x). On pose aussi E (0, j ) = j. 10: end for
On obtient ainsi l’algorithme suivant. 11: return E (m, n)
2. " Arbre Couvrant Minimal" est un racourci pour " Arbre Couvrant de poids Minimal". Tous les arbres
couvrants comportent exactement |V | − 1 arêtes.
141/220 141/220 142/220 142/220
Arbre Couvrant Minimal : Illustration Une application des arbres couvrants minimaux
a b c d e
a 10 1 2 5
b 10 6 4 3
c 1 6 8 9
d 2 4 8 7
e 5 3 9 7
Pour mener à bien cette exploitation il est nécessaire de tracer un réseau de chemins
de coût de construction minimum qui permette de circuler entre tous les bosquets.
Les coûts de construction de ces chemins sont proportionnels à leurs longueurs.
F IGURE 75 – Un graphe connexe. Les arêtes de l’arbre couvrant sont grisées. Le poids total de Enumérer les algorithmes vus en cours pouvant résoudre ce problème. Donner
l’arbre montré est 37. L’arbre n’est pas unique : on peut remplacer l’arête (b, c ) par l’arête (a, h) la complexité de ces algorithmes pour un graphe quelconque G = (V , E ).
et on obtient un autre arbre de même poids.
etc. (cf. le sujet d’examen du décembre 2011 )
Théorème de l’arête minimale qui traverse la coupure : preuve Algorithme générique pour la construction d’un ACM
Arbres parfaits partiellement ordonnés et tas binaire (Binary heap) Arbres parfaits partiellement ordonnés et tas binaire : implementation en
tableau
Le tas binaire (Binary heap) est une file de priorité importante fréquemment
utilisée pour améliorer la complexité des algorithmes comme le tri par tas, l’alg.
de Dijkstra, l’alg. de Prim ....
Définition : Soit π(j ) la clé associée avec l’élément j de la file F. F est un tas
binaire si la condition suivante est satisfaite (relation entre le père et ses deux F IGURE 78 – L’arbre parfait qui visualise un tas binaire avec 10 éléments. Seules les clés sont
fils) : indiquées. Ci-dessous le tableau π associé avec ce tas binaire.
j
π(j ) ≥ π(b c) ∀j (25)
2
j 1 2 3 4 5 6 7 8 9 10
⇐⇒ π(j ) ≤ π(2j ) and π(j ) ≤ π(2j + 1) ∀j π(j ) 3 10 5 11 12 6 8 15 20 13
On représente le tas binaire par un arbre parfait partiellement ordonné :
∀ niveau est rempli de gauche à droite ; On a les règles suivantes :
∀ niveau est complètement rempli avant de commencer le niveau suivant ; π(1) est la racine qui contient l’élément le plus petit ;
la condition (25) est satisfaite (l’élément contenu dans tout nœud est inférieur ou
égal aux éléments contenus dans les fils de ce nœud). π(2j ) and π(2j + 1) sont les deux fils, s’ils existent, de π(j ). En plus,
π(j ) ≤ π(2j ) and π(j ) ≤ π(2j + 1). ;
Le tas est facile à implémenter en tableau.
exemple j = 4 : π(4) = 11, π(8) = 15, π(9) = 20 ;
π(b 2j c) est le père de π(j ) pour j > 1 ;
exemple j = 9 : π(9) = 20, π(b 92 c) = π(4) = 11 ;
Chaque élément d’un tas binaire est caractérisé par le couple (nom, valeur
numérique) (v , clef (v )).
la racine contient le plus petit élément. L’opération « accès à la racine » se fait en
Θ(1) ;
l’opération « insertion » se fait en Θ(log2 k ) ;
l’opération « suppression du minimum » se fait en Θ(log2 k ).
F IGURE 79 – (a) : un tas binaire avec 10 éléments. Seules les clés sont indiquées. (b)-(d) :
illustration de l’opération « insertion ». (e)-(g) : illustration de l’opération « extraction et
suppression du minimum ».
153/220 153/220 154/220 154/220
Algorithme de Prim pour la construction d’un ACM (version tas binaire) Algorithme de Kruskal pour la construction d’un ACM ACM_Kruskal
Algorithm 31 ACM_Prim (G(V,E),w,r) (G(V,E),w) : Illustration
Require: Un graphe G = (V , E ) avec des poids we , e ∈ E. r est le sommet initial.
Ensure: Un ACM défini par les pointeurs prev (v ), ∀v ∈ V .
Arête Poids Garder count
1: Initialisation : ∀u ∈ V : clef (u ) ← ∞ and prev (u ) ← nil ; clef (r ) ← 0 ;
considérée l’arête
2: F ← makequeue(V) {crée une file de priorité F (binary heap) }
(B,C) 1 Oui 1
3: while F is not empty do
(C,D) 2 Oui 2
4: u ← ExtractMin(F)
(B,D) 2 Non 2
5: for all edges (u , v ) ∈ E do
6: if clef (v ) > w (u , v ) then (C,F) 3 Oui 3
7: clef (v ) ← w (u , v ) (A,D) 4 Oui 4
8: prev (v ) ← u (D,F) 4 Non 4
9: ChangeKey(F,v) {F is updated according to the new value of clef (v ) } (E,F) 4 Oui 5
10: end if (A,B) 5 Non -
11: end for (C,E) 5 Non -
12: end while (A,C) 6 Non -
13: return prev c)
Complexité :
La ligne (2) s’exécute en O (|V | log |V |). F IGURE 80 – a) un graphe G = (V , E ) ; b) son l’ACM de poids 14 ; c) Illustration du
pour un sommet u donné par la ligne 4 on fait d (u ) mises à jour de la clef. fonctionnement de l’alg. de Kruskal pour ce graphe. L’algorithme s’arrête quand le conteur count
En total, pour ∀v ∈ V , on fait O (|E |) mises à jour de la clef. Donc la boucle (3-11) s’exécute en atteint la valeur |V | − 1.
|E | log |V | puisque chaque mise à jour se fait en O (log |V |).
On obtient en total : O (|V | log |V | + |E | log |V |) = O (|E | log |V |).
155/220 155/220 156/220 156/220
Algorithme de Kruskal pour la construction d’un ACM Opérations et structures de données pour les ensembles disjoints
Opérations et structures de données pour les ensembles disjoints (suite) Opérations et structures de données pour les ensembles disjoints (suite)
Algorithm 33 procedure makeset (x) Algorithm 36 procedure union (x,y)
Ensure: crée un nouvel ensemble dont le seul élément (et donc le représentant) est Require: Deux ensembles dynamiques Sx et Sy représentés par leurs racines x et y .
x. Sx et Sy sont supposés disjoints avant l’opération.
π(x ) ← x Ensure: Réunit les ensembles dynamiques Sx et Sy dans Sx ∪ Sy . On fait pointer la
rank (x ) ← 0 racine du moindre rang sur celle de rang supérieur au moment de l’union. Comme
les ensembles de la collection sont obligatoirement disjoints, on supprime les en-
Algorithm 34 function find(x) sembles Sx et Sy .
rx ← find(x)
Ensure: retourne un pointeur vers le représentant de l’ensemble (unique) contenant
ry ← find(y)
x.
if rx = ry then
while x6= π(x ) do
return
x ← π(x )
end if
end while
if rank(rx ) > rank(ry ) then
return x π(ry ) ← rx
Algorithm 35 function find_bis(x) else
π(rx ) ← ry
Ensure: effectue une compression du chemin lors de l’opération find if rank(rx ) = rank(ry ) then
if x6= π(x ) then rank(ry ) ← rank(ry ) + 1
π(x ) ←find(π(x )) end if
end if end if
return π(x )
159/220 159/220 160/220 160/220
Illustration pour les opérations sur les ensembles disjoints Illustration pour les opérations sur les ensembles disjoints
F IGURE 81 – Résultat des opérations makeset et union sur des ensembles disjoints
Analyse de complexité des opérations sur les ensembles disjoints Algorithme de Prim versus l’algorithme de Kruskal
F IGURE 84 – (a) visualise les quatre premières arêtes ajoutées par l’algorithme de Prim à partir
du sommet r ; (b) visualise les quatre premières arêtes ajoutés par l’algorithme de Kruskal. Pout
les deux cas la ligne indiquée en pointillés est la suivante à être ajoutée.
163/220 163/220 164/220 164/220
Réseaux : définitions
F IGURE 88 – Les valeurs en rouges sont les F IGURE 89 – Les valeurs en bleu visualisent
poids des arcs. le flot sur les arcs.
3. On dit aussi un chemin élémentaire. C’est un chemin qui passe au plus une fois par chaque sommet.
171/220 171/220 172/220 172/220
Algorithme de Ford et Fulkerson : illustration Algorithme de Ford et Fulkerson : illustration (suite)
Algorithme de Ford et Fulkerson : illustration (fin) La relation entre le flot maximum et la coupe minimale
Théorème : Soit φ un flot compatible dans le réseau G. Les conditions suivantes sont
équivalentes :
1. φ est un flot maximum dans G.
2. Le réseau résiduel Ḡ(φ) ne contient aucun chemin améliorant.
3. La valeur du flot φ est égale à la capacité d’une coupe de capacité minimale
séparant s et t.
Démonstration :
(1) ⇒ (2) : Evident
(2) ⇒ (3) : On définit L = {v ∈ X : ∃ un chemin de s à v dans Ḡ(φ)}.
Soit R = X \ L. La partition (L, R ) est une coupe : de façon triviale s ∈ L et t ∈ R.
Par hypothèse, pour chaque arc (u , v ) tq u ∈ L et v ∈ R on a φ(u , v ) = c (u , v ).
D’autre part, pour chaque arc (v , u ) tq v ∈ R et u ∈ L on a φ(v , u ) = 0 .
Donc, size(φ) = C (L, R ).
F IGURE 96 – Les figures e) et f) visualisent les dernières itérations de l’algorithme de Ford et
Fulkerson. Le flot de valeur 7 (la figure (f) à gauche) est l’optimal. L’optimalité est démontrée par (3) ⇒ (1) : Conséquence du lemme : La valeur maximale d’un flot de s à t
le fait qu’il n’existe pas de chemin (s ; t ) dans le graphe d’écart Ḡ(φk ) (la figure (f) à droite). Il compatible avec cu n’excède jamais la capacité d’une coupe séparant s et t.
n’y a que les sommets a et b qui sont joignables à partir du sommet s. Une coupe de capacité
minimale, égale à la valeur du flot, est visualisée.
Le cas où la valeur de chaque capacité est une valeur entière ≥ 1 Analyse de complexité : les capacités sont des entiers ≥ 1
1: Initialisation : set φ(e) = 0, ∀e ∈ E to be the initial flow Pour démontrer la terminaison de l’algorithme, nous allons expliciter une borne
2: while there is an s ; t path in the residual graph Ḡ(φ) do supérieure des valeurs du flot.
3: Let π be the current s ; t path in Ḡ(φ) Supposons que tous les arcs sortants de s et entrant dans t soient saturés ; la
4: φ0 = augment (φ, π) valeur du flot dans ce cas devrait être égale à C = min( ∑ ce , ∑ ce ).
5: Update φ to be φ0 e∈Γ+ (s) e∈Γ− (t )
6: Update the residual graph Ḡ(φ) to be Ḡ(φ0 )
Nous avons ainsi v (φ) ≤ C pour chaque flot s ; t.
7: end while
8: Return φ
Theorem
L’algorithme de Ford-Fulkerson effectue au plus C itérations de la boucle tant que .
Theorem
A chaque étape intermédiaire les valeurs du flot φ(e) et des capacités résiduelles Theorem
Ḡ(φ) sont entières. L’algorithme de Ford-Fulkerson s’exécute en O (mC ) temps.
F IGURE 98 – Le réseau routier d’une île. Pour exprimer leur mécontentement, les agriculteurs
Applications décident de bloquer toute possibilité d’aller de A à B. Pour réduire la gêne occasionnée, on
envisage bloquer seulement les routes, pas les agglomérations.
Proposer une méthode générale pour déterminer où placer les barrages routiers.
Déterminer le nombre minimal de barrages nécessaires et leur emplacement.
Les forces publiques de la vile A ont décidé de surveiller les routes au départ de
A. Toute possibilité de dresser un barage sur ces routes est donc exclue.
Déterminer à nouveau le nombre minimal de barrages nécessaires et leur
emplacement.
F IGURE 102 – Le flot trouvé est le flot maximum puisqu’il n’existe pas de chemin dans le graphe
F IGURE 100 – Le flot trouvé est le flot maximum puisqu’il n’existe pas de chemin dans le graphe résiduel. La coupe associée (donnée par la partition des sommets en sommets rouges et
résiduel. La coupe associée (donnée par la partition des sommets en sommets rouges et blancs) est la coupe minimale. Elle suggère l’emplacement des barages – en l’occurrence sur
blancs) est la coupe minimale. Elle suggère l’emplacement des barages – en l’occurrence sur les arcs (1, 5), (13, B ), (14, B ).
les arcs (A, 1), (13, B ), (14, B ).
185/220 185/220 186/220 186/220
Construction d’autoroutes
a d
[4]
[2]
[2] [2]
[3] [3] [7]
S b e T
[7] [4] [6]
[1]
[9] [5] [5]
c f
[3]
La Programmation par Contrainte est très efficace sur les problèmes hautement Les solveurs SAT n’utilisent que la Forme Normale Conjonctive (CNF) sur des
combinatoires comme l’ordonnancement ou la planification. Elle utilise des variables variables booléennes. Cette simplicité leur permet une grande rapidité et un
entière et des algorithmes de filtrage sur leurs domaines pour trouver une ou apprentissage des conflicts rencontrés pendant la résolution (CDCL).
plusieures solutions.
Très rapides (un problème à 4 millions de clauses peut être résolu en moins
Très efficace sur les problèmes hautement combinatoires. d’une seconde)
Un très grand nombre de contraintes différentes (plus de 500 contraintes Apprentissage de clause depuis les conflits rencontrés (CDCL)
référencées dans le catalogue de contraintes).
La modélisation en CNF peut être un peu difficile
Exemple :
Exemple : ^ _
AllDifferent({X1 , . . . , Xn }) xijk
Decreasing({X1 , . . . , Xn }) i ,j k ∈( q )
q −1
AtLeastNValue(N , {X1 , . . . , Xn }) ^
Cumulative({X1 , . . . , Xn }, {h1 , . . . , hn }, {d1 , . . . , dn }, c ) (¬xijk ∨ ¬xijk 0 ∨ ¬xijk 00 )
Among(c , {X1 , . . . . , Xn }, D ) i ,j ,k ,k 0 ,k 00 ;k 6=k 0 6=k 00
Soit un PL : max{cx | Ax ≤ b, x ≥ 0}
La programmation linéaire est dans les fondements de la recherche L’espace des solutions admissibles/réalisables/faisables défini par
opérationnelle (RO) ou aide à la décision : propose des modèles conceptuels l’intersection d’un nombre fini de contraintes linéaires est un polyèdre
pour analyser des situations complexes et permet aux décideurs de faire les convexe P = {x | Ax ≤ b, x ≥ 0} ⊆ Rn .
choix les plus efficaces. (P est convexe si x ∈ P, y ∈ P et 0 ≤ λ ≤ 1 alors λx + (1 − λ)y ∈ P).
1940 P. Blackett dirige 1re équipe de RO :
prix Nobel de implantation optimale
physique (1948) de radars de surveillance
1939-45 L. Kantorovich programmation linéaire
1947 G. Dantzig algorithme du simplexe
(le fondateur) " one of the top 10 algorithms of the
century", CSE, 2 :1, 2000
2005 décès de Dantzig convexe non convexe
Aujourd’hui : développement considérable grâce aux solveurs très Un vecteur x ∈ S ⊆ Rn est un point extrême(sommet de S) si on ne peut pas
performants (Gurobi, CPLEX) et langages de modélisation AMPL, JuMP, l’exprimer comme une combinaison convexe de deux autres points de S
Pyomo, PuLP. (@(y ∈ S , z ∈ S , α, 0 < α < 1) tq x = αy + (1 − α)z).
En France : Société Française de Recherche Opérationnelle et d’Aide à la
Décision (ROADEF). Résultat principal : L’optimum, s’il existe, est atteint en au moins un sommet
du polyèdre P.
195/220 195/220 196/220 196/220
Points extrêmes du P ⊂ Rn L’approche graphique pour les programmes linéaires
x2 ≥ 0 2x1 + x2 ≤
x1 0
(6,2) (18,0)
(8,0) ≥
(0,0) (7,0)
x2 ≥ 0
Approche naïve : On est sûr de trouver la solution optimale dans un sommet. Donc il
suffit de parcourir tous les sommets et de prendre le meilleur.
Amélioration dans l’algorithme du simplexe : Parcourir les sommets de P de façon F IGURE 104 – Les valeurs de la fonction objectif sont visualisées par des lignes droites
plus intelligente (on vera cela ultérieurement). parallèles en pointillés.
197/220 197/220 198/220 198/220
L’approche graphique pour les programmes linéaires L’approche graphique pour les programmes linéaires
Maximiser z = x1 + 2x2
s. c. −x1 + x2 ≤ 2
x2 ≤ 3
x1 , x2 ≥ 0
Exercice 3 :
Maximiser z = 5x1 + 8x2
s. c. x1 + x2 ≤ 2
F IGURE 105 – Un programme linéaire peut avoir : (a) plusieurs points d’optimum ou ; (b) ne pas
x1 − 2x2 ≤ 0
avoir d’optimum. Dans ce deuxième cas la fonction objectif n’est pas bornée.
−x1 + 4x2 ≤ 1
x1 , x2 ≥ 0
B [94.5]
vertex x1 x2 x3 x4 z
C [102] A 0 0 0 0 0
product1 product 2 product 3 product 4 stock F [129]
A [0] B 0 10.5 0 0 94.5
E [127]
ressource A 2 4 5 7 42 C 0 0 0 6 102
ressource B 1 1 2 2 17 D 17 0 0 0 119
D [119]
ressource C 1 2 3 3 24 E 11.67 0 0 2.67 127
benefice 7 9 18 17 F 13 4 0 0 129
G [135]
G 0 3 6 0 135
Maximize z = 7x1 + 9x2 + 18x3 + 17x4 H 0 0 7 1 143
I 0 0 8 0 144
s. c. 2x1 + 4x2 + 5x3 + 7x4 ≤ 42 H [143]
I [144] J 4 1 6 0 145
x1 + x2 + 2x3 + 2x4 ≤ 17 J [145]
K [146,5] K 3 0 6.5 0.5 146.5
x1 + 2x2 + 3x3 + 3x4 ≤ 24 L 3 0 7 0 147
x1 , x2 , x3 , x4 ≥ 0
L [147]
F IGURE 107 – Les ponts extrêmes du domaine (il y en a douze) et les valeurs de la fonction
objectif correspondantes. Le parcours de l’alg de simplexe est visualisé en rouge. Deux
itérations suffisent pour trouver l’optimum.
Le problème du plus court chemin dans un graphe vu comme un PL Le problème du PCC dans un graphe vu comme un PL : formulation bis
Rappel :
esu esv euv eut evt
s +1 +1 0 0 0
Algorithm 38 Procédure Bellman-Ford (G,l,s) (summary)
A= t 0 0 0 −1 −1
Require: G=(V,E) directed, weights {le : e ∈ E } with no negative cycles ; vertex s ∈ V u −1 0 +1 +1 0
Ensure: ∀u ∈ V reachable from s, dist (u ) is set to the shortest distance from s to u ; v 0 −1 −1 0 +1
1: dist (s ) ← 0, u ∈ V {s } : dist (u ) ← ∞
F IGURE 108 – G = (V , E , l ), les valeurs en
2: for all edges (u , v ) ∈ E do F IGURE 109 – La matrice d’incidence
rouge sont les longueurs le , e ∈ E.
3: dist (v ) ← min{dist (v ), dist (u ) + l (u , v )} sommet-arc du G.
4: end for
Chaque chemin de s à t peut être représenté par un vecteur x tel que xe = 1 si l’arc e
Approche PL : Soit le graphe G = (V , E , l ) et un sommet s ∈ V . On cherche le plus appartient au chemin, xe = 0 sinon ; et les conditions suivantes :
court chemin (PCC) de s au sommet t ∈ V . Pour chaque sommet v ∈ V on introduit la le sommet s est le début du chemin ;
variable distv ≥ 0 : la distance la plus petite de s à v . xsu + xsv = 1 (34)
min distt (31) le sommet t est la fin du chemin ;
xut + xvt = 1 ⇔ −xut − xvt = −1 (35)
dists = 0 (32) la loi de conservation pour le sommet intermédiaire u :
distv ≤ distu + l (u , v ), ∀(u , v ) ∈ E (33) xsu = xuv + xut ⇔ −xsu + xuv + xut = 0 (36)
La relation (33) est une expression du critère d’arrêt de l’alg. de Bellman-Ford : la loi de conservation pour le sommet intermédiaire v :
l’inégalité du triangle doit être satisfaite pour chaque arc du graphe. xsv + xuv = xut ⇔ −xsv − xuv + xut = 0 (37)
207/220 207/220 208/220 208/220
Le problème du PCC/PLC dans un graphe vu comme un PL Le problème du flot maximum comme un PL
esu esv euv eut evt But : Trouver dans G0 un flot compatible φ0 = [φ0 , φ1 , φ2 , . . . φm ] (c.-à-d.
s +1 +1 0 0 0
A= t 0 0 0 −1 −1 0 ≤ φu ≤ cu , ∀u =∈ E (45)
u −1 0 +1 +1 0
v 0 −1 −1 0 +1 et tel que φ0 soit maximale.
Le problème du flot maximum comme un PL La forme matricielle du problème du flot maximum (MF)
esu esv euv eut evt
s +1 +1 0 0 0
esu esv euv eut evt
A= t 0 0 0 −1 −1
s +1 +1 0 0 0
u −1 0 +1 +1 0
A= t 0 0 0 −1 −1
v 0 −1 −1 0 +1
u −1 0 +1 +1 0
v 0 −1 −1 0 +1
F IGURE 110 – Un graphe G = (V , E , c ) F IGURE 111 – La matrice d’incidence
avec des capacités ce , e ∈ E. sommet-arc du G. F IGURE 112 – Un graphe G = (V , E , c ) F IGURE 113 – La matrice d’incidence
Le flot est représenté par un vecteur [φ1 , φ2 , . . . φm ]T tel que 0 ≤ φu ≤ cu , ∀u ∈ E et qui satisfait avec des capacités ce , e ∈ E. sommet-arc du G.
les conditions suivantes :
un flot de volume φ0 sort du sommet s ;
Soit ai la ligne i de la matrice A. La loi de conservation pour chaque sommet intermédiaire
φsu + φsv = φ0 (46) i:
un flot de volume φ0 entre dans sommet t ; ai φ = 0 (51)
F IGURE 116 – Les affinités entre les membres de deux groupes peuvent être visualisées par des Les équations (57), (58) et (59) représentent un programme linéaire (PL).
graphes bipartis. Tentons à marier ces personnes en satisfaisant les contraintes des couples
compatibles.
Donner le programme linéaire pour le problème de couplage
Montrer que ce problème se réduit au problème du flot maximum.
213/220 213/220 214/220 214/220
Application : Le problème de mariage (couplage) Le problème du flot maximum : un grand classique du domaine
Soit un graphe biparti G(U ∪ V , E ). L’ensemble des arêtes représente les couples
Soit un graphe biparti G(U ∪ V , E ). L’ensemble des arêtes représente les couples compatibles.
compatibles. Il s’agit de trouver le couplage maximum (un couplage contenant le plus Ci-dessous le problème de mariage modélisé comme un problème du flot
grand nombre possible d’arêtes). On peut montrer que ce problème se réduit au maximum. Les capacités sont fixées à 1 partout.
problème du flot maximum.
F IGURE 117 – Il s’agit de marier ces personnes en satisfaisant les contraintes des couples
compatibles. On observe par énumération qu’on ne peut marier que trois couples.
Problème des cases admissibles : continuation Problème des cases admissibles vu comme un problème de flot maximum
On utilise un graphe biparti G = (U ∪ V , E ) où U = {C1, C2, C3, C4, C5} et
Considérons l’instance suivante :
V = {L1, L2, L3, L4} et l’ensemble E contient les cases admissibles. Les capacités
des arcs sortants de S sont données par les bornes sup. associées aux colonnes.
Les capacités des arcs entrants en T sont données par les bornes sup. associées
aux lignes. On considère que les capacités des arcs intermédiaires ne peuvent pas
bloquer la solution (ici 15 par exemple). Le flot maximum trouvé dans ce graphe
donnera la solution du problème des cases admissibles.
F IGURE 120 – Exemple du problème de cases admissibles. Les cases interdites sont en gris.
Taille du tableau : m = 4 et n = 5.
Valeurs des lignes : l1 = 9, l2 = 10, l3 = 15, l4 = 2. F IGURE 121 – Les capacités des arcs sont
écrites entre crochets. Par construction, F IGURE 122 – Un flot de valeur 27 est visualisé
Valeurs des colonnes : c1 = 7, c2 = 5, c3 = 9, c4 = 4, c5 = 8.
chaque flot dans ce graphe est acceptable en bleu. Est-ce que c’est le flot maximum ?
Cases interdites : t13 , t14 , t15 , t22 , t25 , t31 , t33 , t34 , t41 , t42 , t44 . pour le problème des cases admissibles.