X, Petite classe 5 X, Petite classe 9
Plan
• Tri topologique
• Composantes fortement connexes d'un graphe
• Algorithme de Roy-Warshall
• Algorithme de Floyd
Tri topologique
Un graphe est dit sans circuit si sa fermeture transitive est une relation d'ordre partielle sur l'ensemble des sommets.
Prop. Toute relation d'ordre partielle admet une extension linéaire (relation d'ordre total).
Effectuer un tri topologique sur un graphe sans circuit consiste à trouver une extension linéaire.
1
2
3
4 5 6
7
1 < 2 < 3 <4 < 5 < 6 < 7
X, Petite classe 5 X, Petite classe 9
Tri topologique
On peut le réaliser à partir du parcours (récursif) en profondeur dans le graphe dual en partant d'un sommet sur lequel aucun arc n'aboutit.
Il suffira d'ajouter un
printf("%d", v)
à la fin de la procédure Tremeaux . Analogue au parcours suffixe d'un arbre.
1 < 2, 1 < 3, 2 < 3, 2 < 4, 2 < 6, 3 < 5, 3 < 7, 4 < 7, 5 < 6
3
2 4
5 6
1
2
3
4 5
6
7
Graphe dual
On part de 7 : 1 2 3 4 7 On repart de 6 : 5 6
Ordre total : 1 < 2 < 3 < 4 < 7 < 5 < 6
2 1
4 5
6
7
X, Petite classe 5 X, Petite classe 9
Composantes fortement connexes Soit G un graphe. On pose
x ≡G y ⇔ il existe un chemin de x à y et de y à x
{
Les classes de cette relation d'équivalence sont les composantes fortement connexes .
1
2
3 4
7
5 8
11 12
13 6 10
9
14 15
Soit G un graphe et T une arborescence de Trémaux dans G.
1
2
3 4
7
5 8
11 12
13 6 10
9
14 15
R R
D
D
T
T
T
T
(0) Arcs de T.
(1) Arcs inaccessibles.
(2) Arcs de descente : (x,y) avec y descendant de x.
(3) Arcs retour : x descendant de y.
(4) Arcs transverses : x non descendant de y et y non descendant de x.
X, Petite classe 5 X, Petite classe 9
Points d'attache
Point d'attache d'un sommet x de T : plus petit y tel qu'il existe un chemin de x à y (éventuellement vide) contenant au plus un arc retour ou transverse.
Thm. Si un sommet est égal à son point d'attache at(x), et si pour tout descendant y de x dans T, on a at(y) < y, alors l'ensemble des descendants de x forme une composante fortement connexe.
Algorithme : Trouver une composante fortement connexe.
La retirer et recommencer.
1
2
3 4
7
5 8
11 12
13 6 10
9
14 15
R R
D
D
T
T
T
T
1 5
1
1 1 1
5
5
10
11 8
Calcul des points d'attache
On trouvera successivement les composantes {11}, {10} et {1, 2, 3, 4, 5, 6, 7, 8, 9}.
X, Petite classe 5 X, Petite classe 9
Problèmes de connections
On veut tester si deux sommets sont dans la même composante connexe.
Si ce n'est pas le cas, on veut
pouvoir rajouter facilement l'arête manquante.
--> Algorithme "Union-Find"
2 1
6
3
4
7 5
8 9
10 11
12 13
1 2
3
4 6 5
7
8 9
10
11
12 13
14
15 16 17
int SontConnectes(Sommet x, Sommet y, int AConnecter, Arbo pere)
{ Sommet i = x, j = y;
while (pere[i] > 0) i = pere[i];
while (pere[j] > 0) j = pere[j];
if (AConnecter && (i != j)) pere[j] = i;
return (i == j);
}
Arêtes : (1,7), (1,2), (1,3), (12,13), (10,13), (10,12), (10,11), (4,7), (4,6), (8,9), (5,6), (1,6), (5,7), (3,7), (8,7), (10,7), (12,7)
Pere[1] = 4 Pere[2] = 1 Pere[3] = 1 Pere[4] = 5 Pere[5] = 8 Pere[6] = 4 Pere[7] = 1 Pere[8] = 10 Pere[9] = 8 Pere[10] = 0 Pere[11] = 10 Pere[12] = 10 Pere[13] = 12
X, Petite classe 5 X, Petite classe 9
Améliorations
Dans le pire des cas, on obtient un arbre filiforme… Pour l'éviter :
(1) équilibrer l'arbre : on mémorise la taille des sous-arbres issus de chaque nœud. Lorsqu'on rajoute une arête (i, j) on prend comme racine celui des deux sommets qui a le plus grand sous-arbre.
(2) comprimer les chemins : on rattache toutes les feuilles directement à la racine!
Point d'articulation
Sommet d'un graphe, qui, si on le supprime, disconnecte le graphe.
Pont
Arête d'un graphe, qui, si on la supprime, disconnecte le graphe.
Composantes 2-connexes
Deux arêtes sont dans la même composante 2-connexe s'il existe un circuit les contenant.
Les ponts d'un graphe
Les points d'articulation d'un graphe
1 2
6
3
4
7 5
8 9
10 11
12 13
2 1
6
3
4
7 5
8 9
10 11
12 13
Si on supprime un point d'articulation, le graphe n'est plus connexe
4
7
6
1
3 5 2
7
Les composantes 2-connexes
2 1
6
3
4
7 5
8 9
10 11
12 13
8 9
10 11
12 13
Il existe deux chemins distincts entre deux sommets.
X, Petite classe 5 X, Petite classe 9
Recherche des points d'articulation
Un parcours en profondeur et son arbre. Un sommet s (autre que la racine) n'est pas point d'articulation si chaque fils t de s possède un descendant connecté à un ancêtre de s (par un arc en bleu).
La racine est point d'articulation si elle posséde deux fils au moins.
2 1
6
3
4
7 5
8 9
10 11
12 13
Algorithme en O(n+m)
On effectue un parcours récursif en profondeur (en rouge) en calculant le rang du sommet "retour" le moins élevé (nombre bleu).
Les points d'articulation (autre que la racine) sont ceux dont au moins un des fils a les deux nombres égaux.
2 1
6
3
4
7 5
8 9
11
12 13
6 1
1 1 3 1
8 8 9 9
4 1 10 4 11 11
7 4
12 4 5 1
2 2
13 10
10
X, Petite classe 5 X, Petite classe 9
Algorithme en O(n+m)
Les ponts (en gras) sont les arêtes dont le sommet d'arrivée a les deux nombres égaux :
(1, 2), (7, 8), (10, 11), (8, 9).
2 1
6
3
4
7 5
8 9
11
12 13
6 1
1 1 3 1
8 8 9 9
4 1 10 4 11 11
7 4
12 4 5 1
2 2
13 10
10
(1) (k, +, 0) est un monoïde commutatif : l'addition est commutative et admet 0 comme élément neutre.
(2) (k, ×, 1) est un monoïde : la multiplication admet 1 comme élément neutre
(3) distributivité : ∀ a,b,c ∈ k
(a + b) × c = a × c + b × c et c × (a + b) = c × a + c × b
(4) 0 est absorbant. Pour tout a ∈ k, 0 × a = a × 0 = 0
Semi-anneau
Ensemble k muni de deux opérations associatives, + et ×, et de deux éléments distingués 0 et 1, tels que
X, Petite classe 5 X, Petite classe 9
Exemples de semi-anneaux (1) Tous les anneaux.
(2) (N ∪ {+ ∞}, min, +, + ∞, 0)
(3) (N ∪ {- ∞, + ∞}, max, +, - ∞, 0) avec (- ∞) + (+ ∞) = (+ ∞)
(4) (N ∪ {- ∞, + ∞}, min, max, {+ ∞}, {- ∞})
(5) ({Vrai, Faux}, OU, ET) (6) (P(E), ∪, ∩)
(7) Les matrices carrées de
dimension n sur un semi-anneau
Semi-anneau complet
Semi-anneau dans lequel on peut définir des sommes infinies que l'on peut manipuler comme des sommes finies (associativité et distributivité comprises).
(On peut donner une définition plus rigoureuse!)
Soit a un élément d'un semi- anneau complet. On pose
a* = 1 + a + a2 + ... + ak + ...
Exemples. Dans (N, min, +) a* = min(0, a, 2a, ...) = 0
Dans (N ∪ {- ∞, + ∞}, max, +) a* = max(0, a, 2a, ...) = + ∞ si a
> 0
X, Petite classe 5 X, Petite classe 9
Soit M une matrice n × n à coefficients dans un semi-anneau idempotent complet. On pose
M* = I + M + M2 + ... + Mk + ...
Algorithme (Jordan). Notons M(0), ..., M(n) les matrices définies par M(0) = I + A et, pour 1 ≤ k ≤ n
Mi,j = Mi,j + Mi,k × (Mk,k )* × Mk,j Alors M* = M(k)
Note : dans le semi-anneau (N, min, +), la formule devient
Mi,j = min(Mi,j , Mi,k + Mk,j )
(k) (k-1) (k-1) (k-1) (k-1)
(k) (k-1) (k-1) (k-1)
Relation d'accessibilité (fermeture transitive)
Soit S = {1, 2, …, n} les sommets.
Soit G0 le graphe initial, complété d'une boucle en chaque sommet.
On note Gk le graphe (S, Ak) avec (i, j) Ak ssi il existe dans G0 un chemin de i à j dont les sommets internes sont dans {1, 2, …, k}
Proposition
• On a (i, j) Ak ssi (i, j) Ak-1 ou (i, k) Ak-1 et (k, j) Ak-1
• Pour j = k, on trouve
(i, k) Ak ssi (i, k) Ak-1
X, Petite classe 5 X, Petite classe 9
1 2
3
4 5
0 1 0 0 0 0 0 1 0 0 A = 1 0 0 1 1 0 0 0 0 1 0 0 0 1 0
Matrice d'adjacence
1 1 0 0 0 0 1 1 0 0 A0 = 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0
0 1 1 0 0 A1 = 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1
1 1 1 0 0 0 1 1 0 0 A2 = 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 1
1 1 1 1 1 A3 = 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1
1 1 1 1 1 1 1 1 1 1 A4 = 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1
Programme
void RoyWarshall(GrapheMat *g, int n) { int i, j, k;
for (i = 0; i < n; i++) (*g)[i][i] = 1;
for (k = 0; k < n; k++) for (i = 0; i < n; i++)
if ((*g)[i][k])
for (j = 0; j < n; j++)
(*g)[i][j] = (*g)[i][j] ||
((*g)[i][k] && (*g)[k][j]);
}
Complexité : O(n3)
X, Petite classe 5 X, Petite classe 9
Justification
On suppose qu'à l'étape k, i, j,
M[i,j] contient Mi,j avant la ligne
M[i,j] := M[i,j] or (M[i,k] and M[k,j])
Alors M[i, k] contient
Mi,k si k ≥ j et Mi,k si k < j et M[k, j] contient
Mk,j si k ≥ i et Mk,j si k < i D'après la proposition, on aura dans tous les cas :
M[i,j] = Mi,j or (Mi,k and Mk,j )
= Mi,j
(k-1)
(k-1) (k)
(k-1) (k)
(k-1) (k-1) (k-1)
(k)
Complexité
• Le parcours en profondeur conduit à un algorithme pour la fermeture transitive en
O(n(m + n)) (listes)
O(n3) (matrices)
• L'algorithme de Roy-Wrathall est en O(n3).
X, Petite classe 5 X, Petite classe 9
Chemins de valeur maximale
Il s'agit de trouver les chemins
élémentaires de valeur maximum.
Soit Mi,j la valeur maximale des chemins élémentaires de i à j dont les sommets intérieurs sont dans {1, 2, …, k}.
M(0)i,j = {
e si (i, j) A et i ≠ j, 0 si i = j,
- ∞ sinon.
(k)
Mi,j(k) = max {Mi,j(k-1) , M(k-1)i,k + M(k-1)k,j } 0 1 - ∞ -3 - ∞ 0 - ∞ 2 -1 - ∞ 0 - ∞ - ∞ - ∞ 2 0
1 2
3 4
1 -3 2
2 -1
Floyd
type
matrice = array [1.. NMax, 1.. NMax ] of integer;
procedure Floyd(var M : matrice, n : integer);
var i, j, k : Sommet;
begin
for i := 1 to n do M[i, i] := 0 ;
for k := 1 to n do for i := 1 to n do
for j := 1 to n do
M[i,j] := Max(M[i,j], M[i,k] + M[k,j]) end;
L'algorithme de Floyd est en O(n3).
X, Petite classe 5 X, Petite classe 9
1 2
3
4 5
Résultat
0 1 * * *
* 0 2 * * A0 = -3 * 0 2 1
* * * 0 -4
* * * 3 0
0 1 * * *
* 0 2 * * A1 = -3 -2 0 2 1
* * * 0 -4
* * * 3 0 0 1 3 * *
* 0 2 * * A2 = -3 -2 0 2 1
* * * 0 -4
* * * 3 0
0 1 3 5 4 -1 0 2 4 3 A3 = -3 -2 0 2 1
* * * 0 -4
* * * 3 0 0 1 3 5 4
-1 0 2 4 3 A4 = -3 -2 0 2 1
* * * 0 -4
* * * 3 0 1
-3 2
2 1
-4 3
0 1 3 7 4 -1 0 2 6 3 A5 = -3 -2 0 4 1
* * * 0 -4
* * * 3 0
Plus court chemin
Il s'agit de trouver les chemins les plus courts.
Soit Mi,j la valeur maximale des chemins élémentaires de i à j dont les sommets intérieurs sont dans {1, 2, …, k}.
M(0)i,j = {
e si (i, j) A et i ≠ j, 0 si i = j,
+ ∞ sinon.
(k)
Mi,j(k) = min {M(k-1)i,j , M(k-1)i,k + M(k-1)k,j } 0 1 + ∞ 3 + ∞ 0 + ∞ 2 1 + ∞ 0 + ∞ - ∞ + ∞ 2 0
1 2
3 4
1 3 2
2 1
X, Petite classe 5 X, Petite classe 9
type
matrice = array [1.. NMax, 1.. NMax ] of integer;
procedure PlusCourtChemin(var M : matrice, n : integer);
var i, j, k : Sommet;
begin
for i := 1 to n do M[i, i] := 0 ;
for k := 1 to n do for i := 1 to n do
for j := 1 to n do
M[i,j] := Min(M[i,j], M[i,k] + M[k,j]) end;
L'algorithme est en O(n3).
Plus court chemin
1 2
3
4 5
Résultat
0 1 * 3 *
* 0 2 * * A0 = 3 * 0 4 1
* * * 0 2
* * * 2 0
0 1 * 3 *
* 0 2 * * A1 = 3 4 0 4 1
* * * 0 2
* * * 2 0 0 1 3 3 *
* 0 2 * * A2 = 3 4 0 4 1
* * * 0 2
* * * 2 0
0 1 3 3 4 5 0 2 6 3 A3 = 3 4 0 4 1
* * * 0 2
* * * 2 0 0 1 3 3 4
5 0 2 6 3 A4 = 3 4 0 4 1
* * * 0 2
* * * 2 0 1
3 2
4 1
2 2
0 1 3 3 4 5 0 2 5 3 A5 = 3 4 0 3 1
* * * 0 2
* * * 2 0 3