Interaktives Graphentheorie-Lernen
Interaktives Graphentheorie-Lernen
Guest User
Using app without sign in
Finder für starke Zusammenhangskomponenten
Findet stark zusammenhängende Komponenten mit zwei DFS-Durchläufen
Wählen Sie einen Algorithmus und generieren Sie Schritte, um die Visualisierung zu beginnen
Der Algorithmus von Kosaraju berechnet die starken Zusammenhangskomponenten eines gerichteten Graphen mit zwei Tiefensuchen, einer auf dem Originalgraphen und einer auf seiner Transponierten (alle Kanten umgekehrt). Er ist konzeptionell der einfachste lineare SCC-Algorithmus.
Die erste DFS erfasst die Knoten in absteigender Reihenfolge ihrer Abschlusszeit. Dann wird der Graph transponiert, und eine zweite DFS verarbeitet die Knoten in dieser Reihenfolge; jeder im zweiten Durchlauf gewachsene Baum ist genau eine starke Zusammenhangskomponente. Die Korrektheit folgt daraus, dass das Umkehren der Kanten SCCs erhält, aber die Verbindungen zwischen ihnen auftrennt. Zwei lineare Durchläufe ergeben insgesamt O(V + E).
Der Algorithmus von Kosaraju dient denselben Anwendungen wie Tarjans: 2-SAT-Löser, Compiler-Analyse, Gemeinschaftsstruktur in sozialen Netzwerken und Abhängigkeitsverdichtung. Seine Zwei-Pass-Struktur ist leichter zu erklären und von Grund auf zu implementieren, was ihn zu einer beliebten Interviewantwort für das Finden von SCCs macht.
Zwei Tiefensuchen und ein transponierter Graph. In beiden Durchläufen geschieht nichts Raffiniertes; die ganze Arbeit leistet die Reihenfolge, in der der zweite läuft.
Kosaraju(graph):
// Durchlauf 1: Abschlussreihenfolge festhalten
ordnung = []
für jedes unbesuchte u: dfs1(u)
dfs1(u): markiere u besucht
für jede Kante (u,v): wenn unbesucht: dfs1(v)
ordnung.anhängen(u) // beim Abschluss
// Durchlauf 2: DFS auf der Transponierten, umgekehrt
gt = transponiere(graph) // jede Kante umdrehen
für jedes u in umgekehrt(ordnung):
wenn u unbesucht:
der in gt von u aus gewachsene Baum ist eine SCCWarum das funktioniert: Das Umdrehen aller Kanten lässt die starken Zusammenhangskomponenten unberührt, denn wenn du von x nach y und zurück kamst, kannst du das weiterhin. Was die Umkehrung sehr wohl ändert, ist die Richtung der Kanten zwischen den Komponenten. Beim zuletzt abgeschlossenen Knoten zu beginnen garantiert, dass du in einer Quellkomponente der Kondensation startest, sodass die zweite DFS nicht aus ihr heraus in eine andere Komponente entweichen kann.
Führe Kosaraju auf demselben gerichteten Graphen wie im Tarjan-Beispiel aus, damit sich beide unmittelbar vergleichen lassen.
Beispielgraph: Gerichtete Kanten A nach B, B nach C, C nach A, B nach D, D nach E, E nach D und C nach F.
Die Komponenten sind {A, B, C}, dann {D, E}, dann {F}. Vergleiche das mit Tarjan auf demselben Graphen, der {F}, dann {D, E}, dann {A, B, C} ausgibt. Beide sind korrekt und beide finden dieselben drei Komponenten, doch Kosaraju gibt sie in vorwärtsgerichteter topologischer Ordnung der Kondensation aus, Tarjan in umgekehrter. Wenn die Reihenfolge für deinen nachgelagerten Code eine Rolle spielt, ist das der Grund, sich für eines der beiden zu entscheiden.
Zeit: O(V + E) · Speicher: O(V + E)
Zwei Tiefensuchen kosten je O(V + E), und der Aufbau des transponierten Graphen erfordert einen Durchlauf über alle Kanten, ebenfalls O(V + E). In Summe ergibt das O(V + E). Beim Speicher verliert Kosaraju wirklich gegen Tarjan: er muss die transponierte Adjazenzstruktur vorhalten, also eine zweite vollständige Kopie der Kantenliste mit O(V + E), während Tarjan nur O(V) an Buchführung auf dem Originalgraphen benötigt. Bei einem Graphen mit zig Millionen Kanten ist dieser Unterschied ausschlaggebend, weshalb Tarjan im produktiven Einsatz meist gewinnt, obwohl beide zeitlich asymptotisch identisch sind.
Alle linearen SCC-Algorithmen kosten O(V + E). Die Unterschiede liegen in Speicher, Anzahl der Durchläufe und der Frage, wie leicht der Code korrekt wird.
| Alternative | Vorzuziehen, wenn | Kosten |
|---|---|---|
| Tarjan-Algorithmus | Ein Durchlauf, keine Transponierte, O(V) zusätzlicher Speicher. Vorzuziehen, wenn Speicher zählt oder der Graph riesig ist. | O(V + E), ein Durchlauf |
| Pfadbasierte SCC | Ein Durchlauf wie bei Tarjan, aber mit zwei expliziten Stapeln statt Low-Link-Arithmetik. Manche finden das leichter nachvollziehbar. | O(V + E) |
| Kondensation zu einem DAG | Die Komponenten sind Mittel zum Zweck. Kosaraju liefert sie bereits in vorwärtsgerichteter topologischer Ordnung. | O(V + E) |
| Union-Find | Der Graph ist ungerichtet, wo Zusammenhangskomponenten ein weit einfacheres Problem sind. | O(E·α(V)) |
Den ganzen Artikel lesen: Graph Algorithms and Their Complexity
Verwandte Algorithmen: Tarjan SCC-Algorithmus, Tiefensuche