Licence Informatique Algorithmique des graphes 2019–2020
Graphes orient´ es
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 : ParcoursProfondeurOrient´ eRec (G, d´ epart, d´ ej` a visit´ es)
Entr´ ees : un graphe orient´ e G, un sommet de d´ epart, et un tableau bool´ een d´ eja visit´ es de |V | cases.
Sortie : les sommets de G accessibles ` a partir du sommet de d´ epart dans l’ordre o` u le parcours en profondeur les a d´ ecouverts.
1
r´ esultat ← liste();
2
r´ esultat.ajouter en fin(d´ epart);
3
d´ ej` a visit´ es[d´ epart] ← vrai ;
4
pour chaque v ∈ G.successeurs(d´ epart) faire
5
si ¬ d´ ej` a visit´ es[v] alors
6
r´ esultat.ajouter en fin( ParcoursProfondeurOrient´ eRec (G, v, d´ ej` a visit´ es));
7
renvoyer r´ esultat;
Algorithme 2 : ParcoursLargeurIt´ eratifOrient´ e (G, d´ epart, d´ ej` a visit´ es= nil )
Entr´ ees : un graphe non-orient´ e G et un sommet de d´ epart; ´ eventuellement, un tableau d´ ej` a visit´ es de |V | cases indiquant les sommets d´ ej` a trait´ es.
Sortie : la liste des sommets de G accessibles depuis le d´ epart dans l’ordre o` u le parcours en largeur les a d´ ecouverts.
1
r´ esultat ← liste();
2
si d´ ej` a visit´ es = nil alors d´ ej` a visit´ es ← tableau(G.nombre sommets(), faux );
3
a traiter ← file();
4
a traiter.enfiler(d´ epart);
5
tant que a traiter.pas vide() faire
6
sommet ← a traiter.d´ efiler();
7
si ¬ d´ ej` a visit´ es[sommet] alors
8
r´ esultat.ajouter en fin(sommet);
9
d´ ej` a visit´ es[sommet] ← vrai ;
10
pour chaque voisin dans G.successeurs(sommet) faire
11
si ¬ d´ ej` a visit´ es[voisin] alors a traiter.enfiler(voisin) ;
12
renvoyer r´ esultat;
Page 1 / 3
Licence Informatique Algorithmique des graphes 2019–2020
Algorithme 3 : ContientCycleOrient´ e (G, sommet, statuts)
Entr´ ees : un graphe orient´ e G, un sommet de d´ epart, et un tableau statuts de |V | cases.
Sortie : vrai si un cycle de G est accessible ` a partir du sommet de d´ epart, faux sinon.
1
si statuts[sommet] = “gris” alors renvoyer vrai ;
2
si statuts[sommet] = “noir” alors renvoyer faux ;
3
statuts[sommet] ← “gris”;
4
pour chaque v ∈ G.successeurs(sommet) faire
5
si ContientCycleOrient´ e (G, v, statuts) alors renvoyer vrai ;
6
statuts[sommet] ← “noir”;
7
renvoyer faux ;
Algorithme 4 : FermetureTransitive (G) Entr´ ees : un graphe orient´ e connexe G.
Sortie : la fermeture transitive de G.
1
F ← GrapheOrient´ e(G.sommets());
2
pour chaque u ∈ G.sommets() faire
3
pour chaque v ∈ ParcoursLargeurIt´ eratifOrient´ e (F , u) faire
4
si u 6= v alors F.ajouter arc(u, v) ;
5
renvoyer F;
Algorithme 5 : ProfondeurDates (G) Entr´ ees : un graphe orient´ e G.
Sortie : les dates de fin de parcours en profondeur de chaque sommet du graphe.
1
dates ← tableau(G.nombre sommets(), −1);
2
instant ← 0;
3
pour chaque v ∈ G.sommets() faire
4
si dates[v] = −1 alors
5
ParcoursProfondeurOrient´ eDatesRec (G, v, dates, instant);
6
renvoyer dates;
Algorithme 6 : ParcoursProfondeurOrient´ eDatesRec (G, d´ epart, dates, instant) Entr´ ees : un graphe orient´ e G, un sommet de d´ epart, un tableau de dates, et un instant.
R´ esultat : dates contient les dates de fin de visite des sommets de G accessibles ` a partir du sommet de d´ epart dans l’ordre o` u le parcours en profondeur les a d´ ecouverts.
1
dates[d´ epart] ← 0; // marquer le d´ ebut de l’exploration;
2
pour chaque v ∈ G.successeurs(d´ epart) faire
3
si dates[v] = −1 alors
4
ParcoursProfondeurOrient´ eDatesRec (G, v, dates, instant);
5
dates[d´ epart] ← instant; // marquer la fin de l’exploration;
6
instant ← instant + 1;
Page 2 / 3
Licence Informatique Algorithmique des graphes 2019–2020
Algorithme 7 : KosarajuSharir (G) Entr´ ees : un graphe orient´ e G.
Sortie : les composantes fortement connexes de G.
1
CFC ← liste();
2
dates ← ProfondeurDates (G);
/* parcours du graphe renvers´ e par date de fin d´ ecroissante */
3
G
0← renverser arcs(G);
4
d´ ej` a visit´ es ← tableau(G.nombre sommets(), faux );
5
pour chaque v ∈ renverser(trier sommets par date(G
0.sommets(), dates)) faire
6
si ¬ d´ ej` a visit´ es[v] alors
7
CFC.ajouter en fin( ParcoursProfondeurOrient´ eRec (G
0, v, d´ ej` a visit´ es));
8
renvoyer CFC;
Algorithme 8 : Kahn (G)
Entr´ ees : un graphe orient´ e acyclique G.
Sortie : les sommets de G ordonn´ es topologiquement.
/* stocker les degr´ es entrants et les sources */
1
r´ esultat ← liste();
2
sources ← pile();
3
degr´ es entrants ← tableau(G.nombre sommets(), 0);
4
pour chaque v ∈ G.sommets() faire
5
degr´ es entrants[v] ← G.degr´ e entrant(v);
6
si degr´ es entrants[v] = 0 alors sources.empiler(v);
/* d´ epiler les sources, les ajouter au r´ esultat, et empiler les nouvelles sources
*/
7
tant que sources.pas vide() faire
8
u ← sources.d´ epiler();
9
r´ esultat.ajouter en fin(u);
10
pour chaque v ∈ G.successeurs(u) faire
11
degr´ es entrants[v] ← degr´ es entrants[v] −1;
12
si degr´ es entrants[v] = 0 alors sources.empiler(v);
13