Der Kruskal-Algorithmus ist ein Greedy-Algorithmus, der für zusammenhängende gewichtete Graphen den minimalen Spannbaum ermittelt.
Idee
- Sortiere alle Kanten aufsteigend nach Gewicht
- Falls zwei Kanten das gleiche Gewicht haben, ist es egal, welche zuerst kommt
- Übernehme alle Knoten
- Füge die sortierten Kanten aufsteigend nacheinander ein
- Falls ein Zyklus entstehen würde, überspringe diese
Überprüfung auf Zyklen
- Beim stück-für-stück Verbinden der Knoten entstehen Teilgraphen.
- Jeder Teilgraph wird als Menge gespeichert. (Am Anfang besteht jeder Teilgraph aus nur einem Knoten)
- Für jede Kante wird überprüft, ob sie einen Knoten aus einer Menge mit einem Knoten aus der selben Menge verbindet.
- Wenn dem so ist, wird sie übersprungen.
- Wenn nicht, wird die Kante eingefügt, und die beiden Mengen werden vereinigt.
Laufzeitoptimierung
- Die Mengen können als verkettete Listen oder Felder implementiert werden.
ErzeugeMenge(v)hat immer die Laufzeit. - Dann ist die Worst Case-Laufzeit zum Finden der Menge
Menge(u)und zum MengenvereinigenVereinige(u, v)aber(schlecht). - Implementiert man die Mengen aber mit invertierten Bäumen, verbessert sich die Laufzeit.
Union-Find-Datenstruktur
Die Speicherung, Suche und Vereinigung von Mengen kann mittels invertierten Bäumen realisiert werden. Dabei ist jede Menge ein Baum, repräsentiert durch die Wurzel des Baumes.
Beispiel:
graph BT V1 --> V1 V4 --> V1 V0 --> V2 V3 --> V2 V2 --> V5 V5 --> V5
- Versuch, Kante
V3 - V5einzufügen würde fehlschlagen, da V3 Teil der Menge mit dem Repräsentanten V5 ist und V5 auch Teil der Menge mit dem Repräsentanten V5 ist. - Kante
V4 - V2einzufügen würde funktionieren, da V4 Teil der Menge V1 ist und V2 Teil der Menge V5 ist, also unterschiedliche Mengen.- Zeichne also die Kante
- Vereinige die Mengen V1 und V5: Füge die Bäume zusammen
graph BT V1 --> V5 V4 --> V1 V0 --> V2 V3 --> V2 V2 --> V5 V5 --> V5
Beachte
Die Bäume zur Mengenspeicherung sind nicht zu verwechseln mit dem entstehenden Spannbaum.
- Sind die invertierten Bäume möglichst breit und nicht tief, ist die Überprüfung auf Zyklen in Laufzeit
möglich.
Verbesserung bei der Vereinigung
- Geordnete Vereinigung: Beim Vereinigen wird der kleinere Baum an die Wurzel des höheren Baumes angehängt
- Pfadverkürzung: Beim sich “hochhangeln” wird das Blatt mitgenommen und direkt an die Wurzel gehängt, so dass für das nächste mal der Pfad zur Wurzel kürzer ist. Im Idealfall hängen alle Knoten, die zu einer Menge gehören, direkt an der Wurzel.
- Dabei ändert sich Laufzeittechnisch nur die Konstante, dennoch kann man insbesondere bei dichten Graphen davon profitieren.
Beide Varianten verbessern die Laufzeit auf
Implememtierung
Pseudocode
Seien
- Algorithmus MST_Kruskal(
, ) - Starte mit dem MST =
- Für jeden Knoten
: ErzeugeMenge(v)
- Sortiere Kanten aufsteigend ihres Gewichts
- Für jede Kante {u, v}
nach aufsteigendem Gewicht - Falls
Menge(u)Menge(v):- MST = MST
{{u, v}} Vereinige(u, v)
- MST = MST
- Falls
- Starte mit dem MST =
Laufzeit
- Für jeden Knoten Menge erzeugen -
mal - Kanten nach Gewicht sortieren (mit Merge Sort oder 2 Sortieralgorithmen) -
- Für jede Kante nach aufsteigendem Gewicht -
mal - Gleichheit der Mengen checken -
- Ggf. Kante zum Spannbaum hinzufügen -
- Ggf. Mengen vereinigen -
- Gleichheit der Mengen checken -
Insgesamt ergibt sich eine Laufzeit von: