Algorithmus von Kruskal
Der Algorithmus von Kruskal ist ein Algorithmus der Graphentheorie mit dessen Hilfe man minimale Spannbäume in zusammenhängenden, ungerichteten, kantengewichteten Graphen berechnen kann. Der Algorithmus wurde von Joseph Kruskal geschrieben und erschien erstmals 1956 in der Zeitschrift „Proceedings of the American Mathematical Society“.
Wendet man den Algorithmus auf unzusammenhängende Graphen an, so berechnet er einen minimalen Wald, also minimal spannende Bäume für jede Zusammenhangskomponente des Graphen.
Algorithmus
Die Grundidee ist, die Kanten in Reihenfolge aufsteigender Kantengewichte zu durchlaufen und jede Kante zur Lösung hinzuzufügen, die mit allen zuvor gewählten Kanten keinen Kreis bildet. Es werden somit sukzessiv sogenannte Komponenten zum minimalen Spannbaum verbunden.
Input
Als Eingabe dient ein zusammenhängender kantenbewerteter Graph . bezeichnet die Menge der Ecken (vertices), die Menge der Kanten (edges). Die Gewichtsfunktion ordnet jeder Kante ein Kantengewicht zu.
Output
Der Algorithmus liefert einen minimalen Spannbaum mit .
Algorithmus
Der Algorithmus von Kruskal arbeitet nicht deterministisch, d.h. er liefert unter Umständen beim wiederholten Ausführen unterschiedliche Ergebnisse. Alle diese Ergebnisse sind minimale Spannbäume von .
: ein zusammenhängender, ungerichteter, kantengewichteter Graph
kruskal(G)
1 Sortiere die Kanten von aufsteigend nach ihrem Kantengewicht.
2
3
4 solange
5 wähle eine Kante mit kleinstem Kantengewicht
6 entferne die Kante aus
7 wenn der Graph keinen Kreis enthält
8 dann
9 ist ein minimaler Spannbaum von .
Derselbe Algorithmus lässt sich analog für einen maximalen Spannbaum anwenden. Dazu müssen in Zeile 1 die Kanten absteigend sortiert und in Zeile 5 muss eine Kante mit größtem Kantengewicht gewählt werden.
Beispiel
Korrektheitsbeweis
Hinweis: Der Beweis ist zur Zeit falsch, da der Algorithmus umgeschrieben worden ist!
Um die Korrektheit des Algorithmus von Kruskal zu beweisen, muss folgendes gezeigt werden:
- der Algorithmus terminiert (er enthält keine Endlosschleife).
- der Algorithmus erzeugt einen Spannbaum des vorgegebenen Graphen.
- der vom Algorithmus erzeugte Stammbaum ist minimal.
Im Folgenden werden nun dieses Aussagen alle einzeln bewiesen:
- Terminiertheit
- In jedem Schritt wird ein Knoten des Eingabe-Graphen dem Ausgabe-Graphen hinzugefügt. Da der Eingabe-Graph nur endlich viele Knoten enthält, enthält der Ausgabe-Graph nach endlich vielen Schritten alle Knoten und der Algorithmus determiniert.
- Der Algorithmus erzeugt einen Spannbaum des Eingabe-Graphen
- Dass keine Kreise besitzt (d.h. ein Baum ist), ist nach Schritt 3 klar. Ohne die Einschränkung bei solange in Pkt 3 würde irgendwann jeder Punkt, der überhaupt an einer Kante beteiligt ist, mit verbunden. Um zu zeigen, dass der Algorithmus nicht zu früh terminiert, beachten wir, dass die Anzahl der Kanten in einem Spannbaum gleich mit als Anzahl der Zusammenhangskomponenten beträgt.
- Der erzeugte Spannbaum ist minimal
- Der Einfachheit halber nehmen wir an, dass alle Kantengewichte verschieden sind (das kann durch beliebig kleines Verändern der Gewichte erreicht werden). Angenommen, ist die an einem gewissen Punkt im Algorithmus gefundene Kantenmenge, und die danach hinzugefügte Kante liegt nicht in einem minimalen Spannbaum (wir nehmen also an, der Algorithmus ist nicht korrekt). Der Graph hat dann einen Kreis (Spannbaum plus Kante kann kein Baum mehr sein). In diesem Kreis muss es noch eine Kante geben, die nicht in liegt, sonst würde das Hinzufügen von einen Kreis erzeugen. Herausschneiden von aus und Ersetzen durch erzeugt wieder einen Spannbaum, der jedoch von kleinerem Gewicht ist (sonst hätte an dieser Stelle im Algorithmus anstelle von verwendet werden müssen). Es folgt, dass kein minimaler Spannbaum sein kann, und der Algorithmus ist doch korrekt.
Zeitkomplexität
Im folgenden sei die Anzahl der Kanten und die Anzahl der Knoten. Die Laufzeit des Algorithmus beruht im wesentlichen auf dem notwendigen Sortieren der Kanten nach ihren Gewichten und beträgt . Insbesondere bei Graphen mit vielen Kanten ist insofern der Algorithmus von Prim effizienter.
Der Algorithmus von Kruskal arbeitet schneller, wenn die Kanten bereits vorsortiert sind. Um dann in konstanter Zeit zu ermitteln, ob eine Kante zwei Komponenten verbindet, wird zu jedem Knoten ein Verweis auf seine Komponente gespeichert. Die Vereinigung von Komponenten ist amortisiert in möglich. Dazu wird zu jeder Komponente ihre Größe gespeichert, so dass bei einer Vereinigung immer die kleinere Komponente der größeren hinzugefügt werden kann. Insgesamt kann somit jeder Knoten höchstens log(n)-mal in eine andere Komponente verschoben werden.
Literatur
- J. B. Kruskal: On the shortest spanning subtree and the traveling salesman problem. In: Proceedings of the American Mathematical Society. 7 (1956), S. 48–50
Weblinks
- Vollständiger Beweis zur Korrektheit des Algorithmus von Kruskal, Ronny Harbich, 2006
