Licence Informatique Algorithmique des graphes 2019–2020
Flots
Ce document reprend les algorithmes vus au cours. Par convention, ils sont impl´ ement´ es sous la forme de fonctions avec un nom utilisant cette police . Si vous la voyez apparaˆıtre dans un algorithme, cela signifie donc qu’on fait appel ` a un autre algorithme d´ ej` a vu.
Algorithme 1 : FordFulkerson (G) Entr´ ees : un r´ eseau de flot G.
Sortie : un flot maximum pour G.
1
flot ← tableau associatif (cl´ es = G.arcs(), valeurs = 0);
2
source ← unique sommet de degr´ e entrant nul de G;
3
puits ← unique sommet de degr´ e sortant nul de G;
4
G
f← G; // au d´ epart, le r´ eseau et son r´ esiduel co¨ ıncident
5
chemin ← CheminAugmentant (G
f, source, puits);
6
tant que chemin 6= nil faire
7
AugmenterFlot (flot, chemin);
8
MettreAJourR´ esiduel (G, G
f, chemin.arcs(), flot);
9
chemin ← CheminAugmentant (G
f, source, puits);
10
renvoyer flot;
Algorithme 2 : AugmenterFlot (f , P ) Entr´ ees : un flot f , un chemin P .
R´ esultat : le flot f augmente au maximum le long du chemin P .
1
capacit´ e min ← min {c — (u, v, c) ∈ P .arcs()});
2
pour chaque (u, v, c) ∈ P .arcs() faire
3
si (u, v) ∈ f alors f [(u, v)] ← f [(u, v)]+ capacit´ e min ;
4
sinon f [(v, u)] ← f[(v, u)] − capacit´ e min ;
Page 1 / 4
Licence Informatique Algorithmique des graphes 2019–2020
Algorithme 3 : MettreAJourR´ esiduel (G, G
f, arcs, f )
Entr´ ees : un r´ eseau G, le r´ eseau r´ esiduel correspondant G
f, un ensemble d’arcs dans G
f, et un flot f .
R´ esultat : modifie les arcs de G
fsuivant l’augmentation de flot qu’ils ont subi.
// calculer les capacit´ es r´ esiduelles
1
c
f← tableau associatif;
2
pour chaque (u, v, c) ∈ arcs faire
3
si G.contient arc(v, u) alors ´ echanger u et v;
4
c
f[(u, v)] ← G.poids arc(u, v) − f [(u, v)] ;
5
c
f[(v, u)] ← f [(u, v)] ;
// remplacer les arcs concern´ es de G
fen supprimant ceux dont le poids devient nul
6
pour chaque (u, v) ∈ c
ffaire
7
si c
f[(u, v)] > 0 alors G
f.ajouter arc(u, v, c
f[(u, v)]) ;
8
sinon G
f.supprimer arc(u, v) ;
Algorithme 4 : ReconstruireChemin (G, d´ ebut, fin, parents)
Entr´ ees : un graphe orient´ e pond´ er´ e G, deux sommets d´ ebut et fin, et les parents des sommets du graphe.
Sortie : un chemin de d´ ebut ` a fin dans G, ou nil s’il n’en existe pas.
1
chemin ← GrapheOrient´ ePond´ er´ e();
2
v ← fin;
3
tant que v 6= d´ ebut faire
4
si parents[v] = nil alors renvoyer nil ;
5
chemin.ajouter arc(parents[v], v, G.poids arc(parents[v], v));
6
v ← parents[v];
7
renvoyer chemin;
Algorithme 5 : CheminAugmentant (G, source, puits)
Entr´ ees : un graphe orient´ e pond´ er´ e G, et deux sommets source et puits.
Sortie : un chemin de source ` a puits dans G, ou nil s’il n’en existe pas.
1
d´ ej` a visit´ es ← tableau(G.nombre sommets(), faux );
2
a traiter ← file();
3
a traiter.enfiler(source);
4
parents ← tableau(G.nombre sommets(), nil );
5
tant que a traiter.pas vide() faire
6
sommet ← a traiter.d´ efiler();
7
si sommet = puits alors arrˆ eter;
8
si ¬ d´ ej` a visit´ es[sommet] alors
9
d´ ej` a visit´ es[sommet] ← vrai ;
10
pour chaque suivant ∈ G.successeurs(sommet) faire
11
a traiter.enfiler(suivant);
12
si parents[suivant] = nil alors parents[suivant] ← sommet ;
13
renvoyer ReconstruireChemin (G, source, puits, parents);
Page 2 / 4
Licence Informatique Algorithmique des graphes 2019–2020
Algorithme 6 : Dinitz (G) Entr´ ees : un r´ eseau de flot G.
Sortie : un flot maximum pour G.
1
flot ← tableau associatif (cl´ es = G.arcs(), valeurs = 0);
2
source ← unique sommet de degr´ e entrant nul de G;
3
puits ← unique sommet de degr´ e sortant nul de G;
4
G
f← G;
5
G
L← DagLargeur (G, source, puits);
6
arcs ← FlotBloquant (G
L, f , source, puits);
7
tant que arcs 6= ∅ faire
8
MettreAJourR´ esiduel (G, G
f, arcs, flot);
9
G
L← DagLargeur (G
f, source, puits);
10
arcs ← FlotBloquant (G
L, f , source, puits);
11
renvoyer flot;
Algorithme 7 : FlotBloquant (G
L, f , source, puits)
Entr´ ees : un graphe orient´ e acyclique pond´ er´ e G
L, un flot f , une source et un puits.
R´ esultat : le flot f augmente au maximum le long de chaque chemin de G
L, qui est mis ` a jour au fur et ` a mesure; renvoie l’ensemble des arcs qui ont subi un changement de flot.
1
arcs ← ∅;
2
chemin ← CheminAugmentant (G
L, source, puits);
3
tant que chemin 6= nil faire
4
AugmenterFlot (f , chemin);
5
MettreAJourDAGLargeur (G, G
L, chemin.arcs(), f );
6
arcs ← arcs ∪ chemin.arcs();
7
chemin ← CheminAugmentant (G
L, source, puits);
8
renvoyer arcs;
Algorithme 8 : MettreAJourDAGLargeur (G, G
L, arcs, f )
Entr´ ees : un r´ eseau de flot G, un graphe orient´ e acyclique pond´ er´ e G
L, un ensemble d’arcs, et un flot f .
R´ esultat : le poids des arcs sp´ ecifi´ es de G
Lest mis ` a jour sur base de la valeur du flot associ´ e; les arcs dont le poids devient nul sont supprim´ es.
1
pour chaque (u, v, c) ∈ arcs faire
2
si G.contient arc(u, v) alors // arc original du r´ eseau
3
capacit´ e initiale ← G.poids arc(u, v); flot actuel ← f [(u, v)];
4
sinon // arc inverse du r´ eseau
5
capacit´ e initiale ← G.poids arc(v, u); flot actuel ← f [(v, u)];
6
si flot actuel = capacit´ e initiale alors G
L.supprimer arc(u, v) ;
7
sinon G
L.ajouter arc(u, v, capacit´ e initiale − flot actuel) ;
Page 3 / 4
Licence Informatique Algorithmique des graphes 2019–2020
Algorithme 9 : CouplageBiparti (G)
Entr´ ees : un graphe biparti connexe G = (V
1∪ V
2, E).
Sortie : un couplage maximum pour G.
1
H ← GrapheOrient´ ePond´ er´ e();
2
H .ajouter sommet(s);
3
H .ajouter sommet(t);
4
pour chaque {u, v} ∈ G.aretes() avec u ∈ V
1et v ∈ V
2faire
5
H .ajouter arc(s, u, 1); H.ajouter arc(u, v, 1); H .ajouter arc(v, t, 1);
6
flot ← Dinitz (H);
7