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 CFC en utilisant deux passes DFS
Sélectionnez un algorithme et générez les étapes pour commencer la visualisation
L'algorithme de Kosaraju calcule les composantes fortement connexes d'un graphe orienté avec deux passes de parcours en profondeur, une sur le graphe original et une sur sa transposée (toutes les arêtes inversées). C'est conceptuellement l'algorithme de CFC linéaire le plus simple.
Le premier DFS enregistre les sommets par temps de fin décroissant. Le graphe est ensuite transposé, et un second DFS traite les sommets dans cet ordre ; chaque arbre formé à la seconde passe est exactement une composante fortement connexe. La correction vient du fait qu'inverser les arêtes préserve les CFC mais rompt les liens entre elles. Deux passes linéaires donnent O(V + E) au total.
L'algorithme de Kosaraju sert aux mêmes applications que celui de Tarjan : solveurs 2-SAT, analyse de compilateurs, structure de communautés dans les réseaux sociaux et condensation de dépendances. Sa structure en deux passes est plus facile à expliquer et à implémenter de zéro, ce qui en fait une réponse d'entretien populaire pour trouver les CFC.
Deux parcours en profondeur et un graphe transposé. Rien d'astucieux ne se produit à l'intérieur de chaque passe; tout le travail est accompli par l'ordre dans lequel la seconde s'exécute.
Kosaraju(graphe):
// Passe 1: enregistrer l ordre de fin
ordre = []
pour chaque u non visite: dfs1(u)
dfs1(u): marquer u visite
pour chaque arete (u,v): si non visite: dfs1(v)
ordre.ajouter(u) // a la fin
// Passe 2: DFS sur la transposee en ordre de fin inverse
gt = transposer(graphe) // inverser chaque arete
pour chaque u dans inverse(ordre):
si u non visite:
l arbre issu de u dans gt est une CFCPourquoi cela fonctionne: inverser toutes les arêtes laisse les composantes fortement connexes intactes, car si tu pouvais aller de x à y puis revenir, tu le peux toujours. Ce que l'inversion change, c'est la direction des arêtes entre composantes. Démarrer par le sommet terminé en dernier garantit que tu commences dans une composante source de la condensation, si bien que le second DFS ne peut s'en échapper vers une autre composante.
Exécute Kosaraju sur le graphe orienté déjà utilisé pour Tarjan, afin de comparer directement les 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 composantes sont {A, B, C}, puis {D, E}, puis {F}. Compare avec Tarjan sur le même graphe, qui émet {F}, puis {D, E}, puis {A, B, C}. Les deux sont corrects et trouvent les mêmes trois composantes, mais Kosaraju les émet dans l'ordre topologique direct de la condensation tandis que Tarjan les émet en ordre inverse. Si l'ordre importe à ton code en aval, cette différence est la raison de préférer l'un à l'autre.
Temps: O(V + E) · Espace: O(V + E)
Deux parcours en profondeur coûtent O(V + E) chacun, et construire le graphe transposé exige une passe sur toutes les arêtes, également O(V + E). La somme donne O(V + E) au total. C'est sur l'espace que Kosaraju perd réellement face à Tarjan: il doit stocker la structure d'adjacence transposée, soit une seconde copie complète de la liste d'arêtes en O(V + E), là où Tarjan ne nécessite que O(V) de comptabilité sur le graphe original. Sur un graphe de dizaines de millions d'arêtes cette différence devient déterminante, ce qui explique que Tarjan l'emporte généralement en production bien que les deux soient identiques en temps asymptotique.
Tous les algorithmes linéaires de CFC coûtent O(V + E). Les différences portent sur la mémoire, le nombre de passes et la facilité d'écrire un code correct.
| Alternative | À préférer quand | Coût |
|---|---|---|
| Algorithme de Tarjan | Une passe, pas de transposée, O(V) d'espace supplémentaire. Préférable quand la mémoire compte ou que le graphe est énorme. | O(V + E), une passe |
| CFC par chemins | Une passe comme Tarjan, mais avec deux piles explicites au lieu de l'arithmétique des low-link. Certains la trouvent plus facile à raisonner. | O(V + E) |
| Condensation en un DAG | Les composantes sont un moyen et non une fin. Kosaraju te les livre déjà en ordre topologique direct. | O(V + E) |
| Union-Find | Le graphe est non orienté, où les composantes connexes constituent un problème bien plus simple. | O(E·α(V)) |
Lire l'article complet: Graph Algorithms and Their Complexity
Algorithmes associés: CFC de Tarjan, Recherche en Profondeur (DFS)