Apprentissage interactif de la théorie des graphes
Apprentissage interactif de la théorie des graphes
Guest User
Using app without sign in
Détecteur de composantes fortement connexes
Trouve les composantes fortement connexes en utilisant DFS
Sélectionnez un algorithme et générez les étapes pour commencer la visualisation
L'algorithme de Tarjan trouve toutes les composantes fortement connexes (CFC) d'un graphe orienté en un seul parcours en profondeur. Une composante fortement connexe est un ensemble maximal de sommets où chaque sommet peut atteindre tous les autres par des chemins orientés.
Pendant un DFS, l'algorithme attribue à chaque nœud un indice de découverte et une valeur low-link, le plus petit indice atteignable depuis son sous-arbre en utilisant au plus une arête de retour. Les nœuds sont empilés à leur visite. Quand un nœud se termine avec un low-link égal à son propre indice, il est la racine d'une CFC, et la pile est dépilée jusqu'à ce nœud pour émettre la composante. Tout se fait en O(V + E) en une seule passe.
La décomposition en CFC condense un graphe orienté en un graphe orienté acyclique, première étape pour résoudre 2-SAT, analyser les graphes d'appels dans les compilateurs, détecter les interblocages et trouver les cycles de dépendance mutuelle dans les gestionnaires de paquets ou les tableurs. Les valeurs low-link de Tarjan sont un sujet d'entretien classique et difficile.
Un seul DFS, une pile, deux nombres par sommet. L'idée clé est que toute composante fortement connexe possède une racine unique: le sommet de la composante découvert en premier.
connexionForte(u):
dec[u] = low[u] = ++temps
pile.empiler(u); surPile[u] = vrai
pour chaque arete (u, v):
si v non visite:
connexionForte(v)
low[u] = min(low[u], low[v])
sinon si surPile[v]:
low[u] = min(low[u], dec[v])
// sinon: v est dans une CFC close, on ignore
si low[u] == dec[u]: // u est racine d une CFC
depiler jusqu a u inclus
cet ensemble depile est une CFCLe test surPile est ce qui distingue Tarjan d'un schéma naïf de low-link. Une arête vers un sommet visité déjà affecté à une composante close n'apprend rien sur ta propre composante et doit être ignorée; l'inclure fusionnerait deux CFC réellement distinctes. Note aussi l'asymétrie: une arête d'arbre intègre low[v], une arête arrière intègre dec[v], et les confondre constitue l'autre bogue classique.
Exécute Tarjan sur un graphe orienté contenant un cycle de trois sommets, un cycle de deux et un sommet n'appartenant à aucun des deux.
Graphe d'exemple: Arêtes orientées A vers B, B vers C, C vers A, B vers D, D vers E, E vers D, et C vers F.
Les low-link finaux sont A 1, B 1, C 1, F 4, D 5, E 5, et les composantes sortent dans l'ordre {F}, puis {D, E}, puis {A, B, C}. Deux points méritent attention. Les composantes sont émises dans l'ordre topologique inverse de la condensation, ce qui explique que Tarjan soit l'étape préalable habituelle pour 2-SAT. Et F, atteignable depuis le cycle mais sans retour possible, forme correctement sa propre composante au lieu d'être absorbé dans {A, B, C}.
Temps: O(V + E) · Espace: O(V)
Un unique parcours en profondeur visite chaque sommet une fois et examine chaque arête orientée exactement une fois, d'où O(V + E). Chaque sommet est empilé une fois et dépilé une fois, les opérations de pile totalisent donc O(V) sur l'ensemble de l'exécution. L'état supplémentaire comprend la date de découverte, le low-link et l'indicateur sur-pile par sommet, plus la pile de récursion, le tout en O(V). Tarjan y parvient en une seule passe, là où Kosaraju exige deux parcours complets plus la construction du graphe transposé, raison pour laquelle Tarjan est généralement préféré en pratique bien que les deux soient linéaires.
Les trois algorithmes linéaires de CFC ont le même coût asymptotique, le choix porte donc sur les constantes, la mémoire et la facilité d'écrire un code correct.
| Alternative | À préférer quand | Coût |
|---|---|---|
| Kosaraju | Tu veux l'algorithme le plus simple à expliquer et à implémenter. Deux passes de DFS plus une transposée. | O(V + E), deux passes |
| CFC par chemins | Tu veux un algorithme en une passe comme Tarjan mais avec deux piles au lieu de l'arithmétique des low-link. | O(V + E) |
| Union-Find | Le graphe est non orienté. Les composantes connexes sont bien plus simples que les composantes fortement connexes. | O(E·α(V)) |
| Condensation puis tri topologique | Tu veux le DAG des composantes et pas seulement les composantes. Tarjan les émet déjà en ordre topologique inverse. | O(V + E) |
Algorithmes associés: CFC de Kosaraju, Recherche en Profondeur (DFS), Tri Topologique