Chapitre 418 minIntermédiaire
Fermeture transitive : sommes booléennes et algorithme de Roy-Warshall
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- définir la fermeture transitive d'un graphe ;
- la calculer par une somme de puissances booléennes ;
- appliquer l'algorithme de Roy-Warshall pas à pas ;
- compter les arcs à ajouter et repérer les circuits.
4 exercices corrigés1 schéma
La fermeture transitive d'un graphe G est le graphe Ĝ qui a les mêmes sommets que G, avec un arc de x vers y chaque fois qu'il existe dans G un chemin (de longueur quelconque, au moins 1) de x vers y. Sa matrice M̂ répond d'un coup à la question « peut-on aller de x à y ? » pour tous les couples de sommets. On l'obtient par une somme de puissances booléennes de la matrice d'adjacence, ou plus vite avec l'algorithme de Roy-Warshall. Ce chapitre présente les deux méthodes, la lecture de la fermeture (circuits, arcs à ajouter) et ses usages en informatique.
Définition et exemple
On reprend le graphe G du ticket (arcs A → B, A → E, B → A, B → C, C → C, C → D, D → C, D → E). Depuis A, on peut atteindre B (directement), E (directement), C (par A → B → C), D (par A → B → C → D) et A lui-même (par A → B → A). Dans la fermeture transitive Ĝ, A a donc pour successeurs A, B, C, D, E.
En faisant de même pour chaque sommet, on obtient la matrice de Ĝ :
| M̂ | A | B | C | D | E |
|---|---|---|---|---|---|
| A | 1 | 1 | 1 | 1 | 1 |
| B | 1 | 1 | 1 | 1 | 1 |
| C | 0 | 0 | 1 | 1 | 1 |
| D | 0 | 0 | 1 | 1 | 1 |
| E | 0 | 0 | 0 | 0 | 0 |
Interprétation pour les tickets : depuis l'état nouveau (A) ou attribué (B), un ticket peut atteindre n'importe quel état ; depuis l'état en cours (C) ou résolu (D), il ne peut plus revenir à nouveau ou attribué, mais peut atteindre C, D et E ; un ticket clos (E) n'atteint plus rien.
Méthode 1 : la somme des puissances booléennes
Un chemin de x vers y a une longueur 1, ou 2, ou 3… Or M^[p] signale les chemins de longueur p (chapitre 3). La somme booléenne de toutes ces matrices signale donc les chemins de longueur quelconque. Et il suffit de s'arrêter à la puissance n, le nombre de sommets :
Pourquoi n suffit-il ? Un chemin qui repasse par un sommet contient un circuit qu'on peut supprimer pour obtenir un chemin plus court ayant la même origine et la même extrémité. Entre deux sommets différents, on peut donc toujours trouver un chemin élémentaire, de longueur au plus n − 1 ; pour revenir à son point de départ, un circuit sans répétition a au plus n arcs.
Sur le graphe G (n = 5), les matrices M, M^[2] et M^[3] ont été calculées au chapitre 3. Leur somme booléenne :
- ligne A : (0 1 0 0 1) ⊕ (1 0 1 0 0) ⊕ (0 1 1 1 1) = (1 1 1 1 1) ;
- ligne B : (1 0 1 0 0) ⊕ (0 1 1 1 1) ⊕ (1 0 1 1 1) = (1 1 1 1 1) ;
- ligne C : (0 0 1 1 0) ⊕ (0 0 1 1 1) ⊕ (0 0 1 1 1) = (0 0 1 1 1) ;
- ligne D : (0 0 1 0 1) ⊕ (0 0 1 1 0) ⊕ (0 0 1 1 1) = (0 0 1 1 1) ;
- ligne E : que des 0.
On obtient déjà M̂. Ajouter M^[4] et M^[5] ne change plus rien.
Méthode 2 : l'algorithme de Roy-Warshall
Calculer toutes les puissances demande beaucoup de produits. L'algorithme de Roy-Warshall (publié par Bernard Roy en 1959 et Stephen Warshall en 1962) obtient la fermeture transitive en travaillant directement sur les lignes de la matrice.
Le principe. On traite les sommets un par un, dans l'ordre. Quand on traite le sommet k, on autorise k comme sommet intermédiaire : tout sommet i qui atteint k atteint aussi tout ce que k atteint.
L'algorithme.
- Pars de la matrice M.
- Pour chaque sommet k, dans l'ordre :
- repère les lignes i qui ont un 1 dans la colonne k ;
- remplace chacune de ces lignes par sa somme booléenne avec la ligne k (ligne i ⊕ ligne k).
- Après le dernier sommet, la matrice obtenue est M̂.
En pseudo-code :
pour k allant de 1 à n
pour i allant de 1 à n
si M[i][k] = 1 alors
pour j allant de 1 à n
M[i][j] ← M[i][j] OU M[k][j]
Sur le graphe G, en partant de M :
| Étape | Lignes ayant un 1 dans la colonne k | Ce qui change |
|---|---|---|
| k = A | B | ligne B ← (1 0 1 0 0) ⊕ (0 1 0 0 1) = (1 1 1 0 1) |
| k = B | A, B | ligne A ← (0 1 0 0 1) ⊕ (1 1 1 0 1) = (1 1 1 0 1) ; ligne B inchangée |
| k = C | A, B, C, D | lignes A et B ← (1 1 1 1 1) ; ligne D ← (0 0 1 0 1) ⊕ (0 0 1 1 0) = (0 0 1 1 1) |
| k = D | A, B, C, D | ligne C ← (0 0 1 1 0) ⊕ (0 0 1 1 1) = (0 0 1 1 1) |
| k = E | A, B, C, D | la ligne E est nulle : rien ne change |
La matrice finale est bien M̂. Remarque que chaque étape utilise la matrice telle qu'elle est à ce moment-là : à l'étape k = B, la ligne B a déjà été enrichie à l'étape k = A, et c'est cette ligne enrichie qu'on ajoute à la ligne A.
En Python, l'algorithme tient en quelques lignes :
def roy_warshall(M):
"""Matrice de la fermeture transitive (M n'est pas modifiée)."""
n = len(M)
F = [ligne[:] for ligne in M] # copie de M
for k in range(n):
for i in range(n):
if F[i][k] == 1:
F[i] = [F[i][j] | F[k][j] for j in range(n)]
return F
M = [[0, 1, 0, 0, 1],
[1, 0, 1, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 1, 0, 1],
[0, 0, 0, 0, 0]]
for ligne in roy_warshall(M):
print(ligne)
# [1, 1, 1, 1, 1]
# [1, 1, 1, 1, 1]
# [0, 0, 1, 1, 1]
# [0, 0, 1, 1, 1]
# [0, 0, 0, 0, 0]
L'opérateur | est le « ou » bit à bit de Python : sur des 0 et des 1, c'est exactement la somme booléenne.
Lire une fermeture transitive
Les arcs à ajouter. Les arcs de Ĝ qui ne sont pas dans G sont les cases à 1 dans M̂ et à 0 dans M. Pour G : M̂ contient 5 + 5 + 3 + 3 + 0 = 16 coefficients égaux à 1, M en contient 8, donc on ajoute 8 arcs : (A, A), (A, C), (A, D), (B, B), (B, D), (B, E), (C, E) et (D, D). Au sujet de l'E3 2026, la question « combien d'arcs faut-il ajouter pour obtenir la fermeture transitive ? » se traitait exactement ainsi.
Les circuits. Un 1 sur la diagonale de M̂, en (x, x), signifie qu'il existe un chemin de x vers x : x appartient à un circuit. Dans G, A, B, C et D sont sur des circuits, pas E.
Les sommets qui s'atteignent mutuellement. Si M̂ a un 1 en (x, y) et en (y, x), alors x et y sont sur un même circuit : on peut aller de l'un à l'autre et revenir. Dans G, A et B s'atteignent mutuellement, C et D aussi, mais pas A et C (on va de A à C, pas de C à A).
Les sommets accessibles depuis tout le monde. Une colonne de M̂ remplie de 1 (sauf éventuellement pour des puits) désigne un sommet que tous les autres peuvent atteindre. Dans G, la colonne E a des 1 pour A, B, C, D : un ticket finit toujours par pouvoir être clos.
Ce que cela donne en informatique
- Accessibilité réseau : dans le graphe des communications autorisées par des règles de pare-feu, la fermeture transitive dit quelles machines peuvent joindre quelles autres, directement ou par rebond. C'est la question que se pose un attaquant qui a pris pied sur un poste.
- Groupes imbriqués : dans un annuaire Active Directory, un utilisateur membre d'un groupe lui-même membre d'un autre groupe hérite des droits des deux. Les droits effectifs se lisent dans la fermeture transitive du graphe « est membre de ».
- Dépendances logicielles : installer un paquet installe toute la fermeture transitive de ses dépendances, ce que fait un gestionnaire comme apt ou npm.
- Bases de données : une requête SQL récursive (
WITH RECURSIVE) parcourt une hiérarchie stockée dans une table, par exemple tous les subordonnés directs et indirects d'un manager : elle calcule une ligne de la fermeture transitive (CTE récursives).
Exercices
Exercice 1 sur 4 Fermeture par les sommes booléennes Réussi À revoir
On reprend le graphe K (arcs (A, B), (A, D), (B, C), (C, A), (C, D), (D, D)).
- Calcule M^[2] et M^[3].
- Déduis-en la matrice de la fermeture transitive de K, en justifiant l'arrêt du calcul.
- Combien d'arcs faut-il ajouter à K pour obtenir sa fermeture transitive ?
- Quels sommets sont sur un circuit ?
Voir la réponseMasquer la réponse de l'exercice 1
- Avec M (lignes A : 0 1 0 1 ; B : 0 0 1 0 ; C : 1 0 0 1 ; D : 0 0 0 1) :
| M^[2] | A | B | C | D |
|---|---|---|---|---|
| A | 0 | 0 | 1 | 1 |
| B | 1 | 0 | 0 | 1 |
| C | 0 | 1 | 0 | 1 |
| D | 0 | 0 | 0 | 1 |
| M^[3] | A | B | C | D |
|---|---|---|---|---|
| A | 1 | 0 | 0 | 1 |
| B | 0 | 1 | 0 | 1 |
| C | 0 | 0 | 1 | 1 |
| D | 0 | 0 | 0 | 1 |
- M ⊕ M^[2] ⊕ M^[3] :
| M̂ | A | B | C | D |
|---|---|---|---|---|
| A | 1 | 1 | 1 | 1 |
| B | 1 | 1 | 1 | 1 |
| C | 1 | 1 | 1 | 1 |
| D | 0 | 0 | 0 | 1 |
On peut s'arrêter : la ligne D vaut (0 0 0 1) dans toutes les puissances (le seul arc qui part de D est la boucle), et les trois autres lignes sont déjà remplies de 1. M^[4] ne peut rien ajouter. (Le théorème garantit de toute façon qu'on peut s'arrêter à M^[4], car K a 4 sommets.) 3. M̂ compte 4 + 4 + 4 + 1 = 13 coefficients égaux à 1, M en compte 6 : il faut ajouter 7 arcs, à savoir (A, A), (A, C), (B, A), (B, B), (B, D), (C, B), (C, C). 4. La diagonale de M̂ ne contient que des 1 : les quatre sommets sont sur un circuit (A, B, C sur le circuit (A, B, C, A), D sur sa boucle).
Tu avais trouvé ?
Exercice 2 sur 4 Roy-Warshall pas à pas Réussi À revoir
Applique l'algorithme de Roy-Warshall à la matrice de K, en donnant la matrice après chaque étape. Compare avec l'exercice précédent.
Voir la réponseMasquer la réponse de l'exercice 2
- k = A : seule la ligne C a un 1 en colonne A. Ligne C ← (1 0 0 1) ⊕ (0 1 0 1) = (1 1 0 1).
- k = B : les lignes A et C ont un 1 en colonne B. Ligne A ← (0 1 0 1) ⊕ (0 0 1 0) = (0 1 1 1) ; ligne C ← (1 1 0 1) ⊕ (0 0 1 0) = (1 1 1 1).
- k = C : les lignes A, B, C ont un 1 en colonne C. Ligne A ← (0 1 1 1) ⊕ (1 1 1 1) = (1 1 1 1) ; ligne B ← (0 0 1 0) ⊕ (1 1 1 1) = (1 1 1 1) ; ligne C inchangée.
- k = D : toutes les lignes ont un 1 en colonne D, mais la ligne D, (0 0 0 1), n'ajoute rien.
Matrice finale : lignes A, B, C remplies de 1, ligne D = (0 0 0 1). On retrouve la même fermeture transitive qu'avec les sommes booléennes, avec beaucoup moins de calculs.
Tu avais trouvé ?
Exercice 3 sur 4 Les dépendances d'une application Réussi À revoir
On reprend le graphe des dépendances du chapitre 1 : arcs (W, P), (W, D), (P, D), (P, L), (D, S), (L, S), où (x, y) signifie « x a besoin de y ». Sommets dans l'ordre D, L, P, S, W.
- Détermine la matrice de la fermeture transitive.
- Interprète la ligne W de cette matrice.
- Ce graphe a-t-il un circuit ? Que se passerait-il, pour le démarrage des services, s'il en avait un ?
Voir la réponseMasquer la réponse de l'exercice 3
- Par exemple avec Roy-Warshall. k = D : les lignes P et W ont un 1 en colonne D ; on leur ajoute la ligne D, (0 0 0 1 0) : P devient (1 1 0 1 0), W devient (1 0 1 1 0). k = L : la ligne P a un 1 en colonne L, on lui ajoute (0 0 0 1 0), elle ne change pas. k = P : la ligne W a un 1 en colonne P, on lui ajoute (1 1 0 1 0) : W devient (1 1 1 1 0). k = S : la ligne S est nulle, rien ne change. k = W : aucune ligne n'a de 1 en colonne W.
| M̂ | D | L | P | S | W |
|---|---|---|---|---|---|
| D | 0 | 0 | 0 | 1 | 0 |
| L | 0 | 0 | 0 | 1 | 0 |
| P | 1 | 1 | 0 | 1 | 0 |
| S | 0 | 0 | 0 | 0 | 0 |
| W | 1 | 1 | 1 | 1 | 0 |
- Ligne W : (1 1 1 1 0). L'application a besoin, directement ou indirectement, de tous les autres services : base de données, annuaire, serveur d'applications et stockage. Si l'un d'eux tombe, l'application est touchée. C'est l'analyse d'impact qu'on fait avant une maintenance.
- La diagonale de M̂ ne contient que des 0 : pas de circuit. S'il y en avait un (par exemple si le stockage avait besoin de l'application), aucun des services du circuit ne pourrait démarrer en premier : chacun attendrait l'autre. C'est un interblocage.
Tu avais trouvé ?
Exercice 4 sur 4 Les groupes imbriqués Réussi À revoir
Dans un annuaire, Alice est membre du groupe Compta, Bob du groupe Paie, le groupe Paie est membre du groupe Compta, et le groupe Compta est membre du groupe Lecteurs-Partage, qui donne accès en lecture au dossier partagé des factures.
- Représente ces appartenances par un graphe orienté (arc (x, y) : « x est membre de y »).
- Calcule la fermeture transitive.
- Bob peut-il lire les factures ? Alice est-elle membre du groupe Paie ?
Voir la réponseMasquer la réponse de l'exercice 4
- Sommets : Alice, Bob, Compta, Paie, Lecteurs. Arcs : (Alice, Compta), (Bob, Paie), (Paie, Compta), (Compta, Lecteurs).
- On ajoute les arcs qui correspondent à un chemin : (Alice, Lecteurs) par Compta ; (Bob, Compta) par Paie ; (Bob, Lecteurs) par Paie et Compta ; (Paie, Lecteurs) par Compta. La fermeture a 4 + 4 = 8 arcs.
- (Bob, Lecteurs) est un arc de la fermeture : oui, Bob peut lire les factures, par imbrication. (Alice, Paie) n'en est pas un : non, Alice n'est pas membre de Paie (l'appartenance « monte », elle ne « descend » pas). C'est ce calcul qu'il faut faire lors d'une revue des droits : un droit donné à un groupe profite à tous les membres de sa fermeture.
Tu avais trouvé ?