7. Graphen mit Kantenkosten
7.3 Minimale Spannbäume und Kruskals Algorithmus
Wir schreiben das Jahr 2059. Nachdem im Jahre 2055 ein effizienter Algorithmus für das NP-vollständige Problem SAT entdeckt worden war und somit alle bekannten kryptographischen Protokolle gebrochen werden konnten, verfolgt die europäische Union ein ehrgeiziges Projekt: sie will mit Quantenkryptographie verschlüsselte Kommunikationskanäle bauen und damit alle Hauptstädte verbinden. Hierzu müssen spezielle Leitungen verlegt werden. Und die sind teuer. Nach zwei Jahren hat eine Kommission aus Fachleuten, Politikern und Lobbyisten folgenden Vorschlag ausgearbeitet:
Anmerkung des Autors: ich hatte die entsprechenden Lehrmaterialien circa 2015 ausgearbeitet und zwei Jahre später, also nach dem Brexit, London aus dieser Karte gelöscht. Diesem fiktiven Szenario aus dem Jahre 2059 habe ich aus Bequemlichkeit den Stand der EU im Jahre 2024 zugrunde gelegt. Auf Spekulationen, wie die EU im Jahre 2059 aussehen wird, habe ich verzichtet, obwohl einige Beitrittskandidaten deutlich auf der Karte zu sehen sind.
Leider hat das europäische Parlament diesen Vorschlag abgelehnt. Nach weiteren zwei Jahren hat ein neues Expertengremium folgenden Vorschlag vorgelegt:
Alle sind begeistert, und das Projekt erhält die benötigten Mittel. Nun fragen sich alle: wie hat das Expertengremium es nur geschafft, eine solch effiziente, kostengünstige Lösung zu finden? Nur ein paar Protestparteien im Parlament behaupten, dies sei nicht die optimale Lösung. Wie können wir Skeptiker davon überzeugen, dass dies wirklich die optimale ist?
Minimale Spannbäume als graphenalgorithmisches Problem
Formulieren wir obiges Problem in der Sprache der Graphentheorie. Wir
haben einen ungerichteten Graphen
Um in graphentheoretischer Sprache zu formulieren, was unser Ziel ist, müssen wir ein paar Begriffe einführen:
Ein Graph
Ein Subgraph
Ein aufspannender Subgraph von
Ein Spannbaum von
Definition 7.3.1 Sei
- Ein Subgraph von
ist ein Graph mit und . -
Ein aufspannender Subgraph von
ist ein Subgraph . Also ein Subgraph, der alle Knoten enthält. -
Ein Spannbaum von
ist ein aufspannender Subgraph, der gleichzeitig ein Baum ist.
Erinnern Sie sich: ein Baum ist ein zusammenhängende azyklischer Graph.
Wenn wir eine Kantenkostenfunktion
Algorithmisches Problem 7.3.2
- Minimum Spanning Tree.
Gegeben ein zusammenhängender Graph
Kruskals Algorithmus
Kruskals Algorithmus ist recht einfach zu beschreiben: wir sortieren
die Kanten des Graphen von billig nach teuer. Dann starten wir mit
einem leeren Graphen
Algorithmus 7.3.3 - Kruskals Algorithmus.
Eingabe: ein Graph
- Sortiere
aufsteigend nach : - for
in dieser Reihenfolge:- if
azyklisch:
- if
- return
Übungsaufgabe 7.3.1
Beweisen Sie: wenn
Übungsaufgabe 7.3.2
Wenn
Korrektheit von Kruskals Algorithmus
Wir zeigen nun, dass Kruskals Algorithmus korrekt ist. Dass er also
immer einen minimalen Spannbaum (sprich: geringstmögliche Kosten) berechnet.
Hierfür brauchen wir einige Definitionen. Ein Spannbaum
Definition 7.3.4 Sei
Umgangssprachlich:
Definition 7.3.5 (Cut). Sei
Hier ein paar Beispiele von Cuts und Mengen, die keine Cuts sind:
Ein Graph
Ein Cut
Noch ein Cut
Kein Cut: mehrere Kanten kreuzen
Kein Cut:
Das folgende Lemma ist das Hauptwerkzeug in unserem Korrektheitsbeweis.
Lemma 7.3.6 (Cut Lemma). Sei
Beweis. Wir schreiben
Die Kante
Wir betrachten die Kantenmenge
Was ist
Dieser Pfad existiert in
Die Pfade
Da
Theorem 7.3.7 Kruskal findet einen minimalen Spannbaum.
Beweis.
Wir verwenden die Beweismethode der Schleifeninvariante:
Anfangs gilt dies offensichtlich:
Wenn
Behauptung:
Beweis: Sei
Wir können nun das Cut-Lemma anwenden und schließen: die Menge
Übungsaufgabe 7.3.3
Ich habe überall
Übungsaufgabe 7.3.4
Sie verwenden eine Bibliotheksfunktion minimumSpaningTree
,
die sehr schnell ist, allerdings einen Fehler ausgibt, wenn in der Eingabe
negative Kantenkosten vorkommen. Ihr Anwendungsfall hat jedoch nun
mal auch negative Kosten, und Sie sind zu faul, selbst einen
Algorithmus zu implementieren. Wir können Sie rumtricksen und
minimumSpaningTree
dennoch erfolgreich verwenden?
Übungsaufgabe 7.3.5
Sei
und
Zeigen Sie: wenn
Übungsaufgabe 7.3.6
Sei
Zeigen Sie:
Warnung: das Argument Kruskal hat ja nie die Wahl, weil es nur eine gültige Sortierung gibt zieht nicht, weil Sie ja nicht wissen, ob auf irgendeine Nicht-Kruskal-Weise nicht doch ein alternativer minimaler Spannbaum entsehen könnte.
Übungsaufgabe 7.3.7 (minimale Spannbäume zählen).
Wieviele Spannbäume (egal ob minimal oder nicht minimal) hat ein
gegebener Graph? Hierfür gibt es einen effizienten Algorithmus, den wir
aber an dieser Stelle nicht besprechen. Nenne wir ihn
CountSpanningTrees
.
Entwickeln Sie einen effizienten Algorithmus
CountMinimalSpanningTrees
, der die Anzahl
minimaler Spannbäume berechnet, wobei der
CountSpanningTrees
als Subroutine verwenden darf.
Laufzeitanalyse
Die Laufzeitanalyse von Kruskals Algorithmus
scheint einfach zu sein:
In Zeile 1 sortieren wir die Kanten. Dies braucht
Dies ist allerdings nicht das Ende, sondern erst der Anfang einer
recht spannenden Geschichte. Wir müssen nämlich in Zeile gar nicht
einen Pfad von