Organisatorisches VL-16: Minimale Spannbäume • Vorlesung: Gerhard Woeginger (Zimmer 4024 im E1) Sprechstunde: Mittwoch 11:15–12:00 • Übungen: Tim Hartmann, David Korzeniewski, Björn Tauer Email: [email protected] (Datenstrukturen und Algorithmen, SS 2017) Walter Unger • Webseite: http://algo.rwth-aachen.de/Lehre/SS17/DSA.php • Nächste Vorlesung: Donnerstag, Jun 29, 10:15–11:45 Uhr, Aula 1 SS 2017, RWTH DSAL/SS 2017 VL-16: Minimale Spannbäume 1/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 2/48 Spannbaum Probleme Spannbaum Ein Spannbaum eines ungerichteten, zusammenhängenden Graphen G = (V , E ) ist ein Teilgraph von G, der (i) ein ungerichteter Baum ist und (ii) alle Knoten von G enthält. Minimale Spannbäume Beispiel (Spannbaum Probleme) • Bäume & Spannbäume • Algorithmus von Kruskal • Algorithmus von Prim • Implementierung & Komplexität DSAL/SS 2017 VL-16: Minimale Spannbäume 3/48 I Alle Kunden durch Glasfaserkabel verbinden I Computernetzwerke verkabeln I Verdrahtung von Schaltungen beim Chipdesign I Den Strassenbelag zwischen allen Flughafenterminals erneuern I ...... DSAL/SS 2017 VL-16: Minimale Spannbäume 4/48 Beispiel: Glasfasernetz Beispiel: Telefonleitungsnetz I Müssen alle Leitungen erneuert werden? I Wie wählt man die zu erneuernden Abschnitte aus? I Gibt es eine eindeutige Lösung? so dass DSAL/SS 2017 I Alle Kunden profitieren I Jeder mit jedem über Glasfaser kommunizieren kann I Sparsamkeit: keine doppelte Verbindungen VL-16: Minimale Spannbäume 5/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 6/48 Beispiel: Zwei Abdeckungen Ein wenig Mathematik Alle Kunden sind angeschlossen DSAL/SS 2017 . . . und sind miteinander verbunden VL-16: Minimale Spannbäume 7/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 8/48 Einige Fakten über Bäume (1) Einige Fakten über Bäume (2) Satz Satz Ein Baum ist (i) maximal kreisfrei und (ii) minimal zusammenhängend. Die folgenden vier Aussagen sind für T = (V , E ) äquivalent: (1) T ist ein Baum (2) Je zwei Knoten sind durch genau einen Weg verbunden (3) |E | = |V | − 1 und T ist zusammenhängend (4) |E | = |V | − 1 und T ist kreis-frei (1) ⇔ (2): • T zusammenhängend ⇔ mindestens ein Pfad zwischen u und v • T kreis-frei ⇔ höchstens ein Pfad zwischen u und v Fügt man eine Kante zu einem Baum hinzu, so entsteht ein Kreis. Löscht man eine Kante, so erhält man zwei Zusammenhangskomponenten. (1) ⇔ (3) und (1) ⇔ (4) folgen mit ähnlichen Argumenten DSAL/SS 2017 VL-16: Minimale Spannbäume 9/48 Einige Fakten über Bäume (3) DSAL/SS 2017 VL-16: Minimale Spannbäume 10/48 Anzahl der Spannbäume (1) Satz 1. Ein Baum mit n Knoten hat n−1 Kanten P 2. In einem Baum mit n Knoten gilt v ∈V deg(v ) = 2n − 2 3. Jeder Baum (mit n ≥ 2 Knoten) hat mindestens 2 Blätter Drei Spannbäume für n=3 Knoten Satz (Austauschsatz) Es sei T = (V , E 0 ) ein spannender Baum von G = (V , E ). Es sei e ∈ E − E 0 . Die Cayley Formel I Der Graph (V , E ∪ {e}) enthält einen einzigen Kreis C . Der vollständige Graph mit n Knoten hat nn−2 Spannbäume. I Für jede Kante f ∈ C gilt: (V , E 0 ∪ {e} − {f }) ist ein Baum. Beweis: Bijektion zwischen der Menge der Bäume mit Knotenmenge {1, 2, . . . , n} und der Menge der (n − 2)-Tupel über {1, 2, . . . , n} DSAL/SS 2017 0 VL-16: Minimale Spannbäume 11/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 12/48 Anzahl der Spannbäume (2) Anzahl der Spannbäume (3) 6 8 5 7 1 4 Wie man einen Baum in einen Prüfer-Code übersetzt 1 2 3 4 5 Repeat Bestimme Blatt x mit kleinster Nummer Loesche x und inzidente Kante {x , y } Speichere y im Tupel Until ( nur noch eine einzige Kante uebrig ) 2 • Knoten mit Grad d kommt genau (d − 1)-mal im Prüfer-Code vor • Verschiedene Bäume führen zu verschiedenen Prüfer-Codes DSAL/SS 2017 VL-16: Minimale Spannbäume Prüfer-Code: 13/48 DSAL/SS 2017 3 7, 4, 4, 1, 7, 1 VL-16: Minimale Spannbäume 14/48 Anzahl der Spannbäume (4) Prüfer-Code = (t(1), t(2), . . . , t(n − 2)) Wie man einen Prüfer-Code in einen Baum zurückübersetzt 1 2 3 4 5 6 7 8 9 DSAL/SS 2017 Setze t (n -1) := n ; Minimale Spannbäume For i =1 to n -1 do { Bestimme die kleinste Zahl b ( i ) , die weder unter b (1) ,... , b (i -1) noch unter t ( i ) ,... , t (n -1) vorkommt } Bilde Baum aus den n -1 Kanten { b ( i ) , t ( i ) } VL-16: Minimale Spannbäume 15/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 16/48 Nun kommen die Kosten ins Bild Beispiel: Leitungskosten Beispiel I Finde den kostengünstigsten Weg, um eine Menge von Flughafenterminals, Städten, . . . zu verbinden I Verdrahtung von Schaltungen mit geringstem Energieverbrauch I Verbinde alle Kunden kostengünstigst durch Glasfaserkabeln I Computernetzwerke verkabeln Das ist unsere Motivation für (kosten-)minimale Spannbäume! Verschiedene Umgebungen verursachen verschiedene Kosten für die Verlegung von Kabeln. DSAL/SS 2017 VL-16: Minimale Spannbäume 17/48 Geschichtlicher Rückblick (1) DSAL/SS 2017 It is evident that a solution of this problem could have some importace in electricity power-line network design; hence I present the solution briefly using an example. The reader with a deeper interest in the subject is referred to the above quoted paper. I shall give a solution of the problem in the case of 40 points given in Fig. 1. I shall join each of the given points with the nearest neighbor. Thus, for example, point 1 with point 2, point 2 with point 3, point 3 with point 4 (point 4 with point 3), point 5 with point 2, point 6 with point 5, point 7 with point 6, point 8 with point 9, (point 9 with point 8), etc. I shall obtain a sequence of polygonal strokes 1, 2, . . . , 13 (Fig. 2). Problem Gegeben n Punkte/Orte in der Euklidischen Ebene, verbinde sie durch ein Netz von minimaler Länge sodass je zwei Punkte entweder direkt oder über eine Folge anderer Punkte mit einander verbunden sind VL-16: Minimale Spannbäume 18/48 Geschichtlicher Rückblick (2) • 1920s: Elektrifizierung von Süd-West-Mähren • 1925/26: Jindřich Saxel von Západomoravské Elektrárny (West-Moravian Powerplants) kontaktiert Otakar Borůvka • Otakar Borůvka (1899–1995): Tschechischer Mathematiker aus Brno DSAL/SS 2017 VL-16: Minimale Spannbäume I shall join each of these strokes with the nearest stroke in the shortest possible way. Thus, for example, stroke 1 with stroke 2, (stroke 2 with stroke 1), stroke 3 with stroke 4, (stroke 4 with stroke 3), etc. I shall obtain a sequence of polygonal strokes 1, 2, . . . , 4 (Fig. 3) I shall join each of these strokes in the shortest way with the nearest stroke. Thus stroke 1 with stroke 3, stroke 2 with stroke 3 (stroke 3 with stroke 1), stroke 4 with stroke 1. I shall finally obtain a single polygonal stroke (Fig. 4), which solves the given problem. 19/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 20/48 Geschichtlicher Rückblick (3) Was ist ein minimaler Spannbaum? Kantengewichteter ungerichteter Graph Ein (kanten-)gewichteter Graph G ist ein Tripel (V , E , w ), wobei: I (V , E ) ein ungerichteter Graph ist, und I w : E → R Gewichtsfunktion. w (e) ist das Gewicht der Kante e. Gewicht eines Graphen Das Gewicht w (G 0 ) einesX Teilgraphens G 0 = (V 0 , E 0 ) des gewichteten Graphen G ist: w (G 0 ) = w (e). e∈E 0 Minimaler Spannbaum (MST) Ein Spannbaum des (ungerichteten, gewichteten, zusammenhängenden) Graphens G mit minimalem Gewicht heisst Minimaler Spannbaum (minimum spanning tree, MST) von G. DSAL/SS 2017 VL-16: Minimale Spannbäume 21/48 Minimaler Spannbaum: Beispiel (1) C 6 14 B 9 G 8 14 E 15 H B 4 5 A 2 3 C 6 F 10 22/48 Minimaler Spannbaum: Beispiel (2) D F 9 G 2 10 8 3 E 15 H D Wie sieht der minimale Spannbaum aus? DSAL/SS 2017 VL-16: Minimale Spannbäume 4 5 A DSAL/SS 2017 VL-16: Minimale Spannbäume Die roten Kanten zeigen einen MST mit Gesamtgewicht 46. In diesem Fall ist der MST eindeutig. 23/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 24/48 Tiefensuche? Breitensuche? C 6 14 B F 9 G 8 3 14 E 15 H 4 5 A 2 10 C 6 4 5 A F 8 3 D G 2 10 B 9 E 15 H Prim und Kruskal D Tiefensuchbaum (von A gestartet) Gesamtgewicht: 55 Breitensuchbaum (von A gestartet) Gesamtgewicht: 67 Der Tiefensuchbaum und der Breitensuchbaum sind zwar Spannbäume, aber nicht notwendigerweise minimale Spannbäume. DSAL/SS 2017 VL-16: Minimale Spannbäume 25/48 Zwei Algorithmen für MST (1) DSAL/SS 2017 VL-16: Minimale Spannbäume 26/48 Zwei Algorithmen für MST (2) Eingabe: ein gewichteter zusammenhängender Graph G mit n Knoten Ausgabe: ein minimaler Spannbaum von G Kruskal’s Algorithmus Kruskal’s Algorithmus wurde entdeckt: So lange noch keine n−1 Kanten markiert sind: 1. Wähle eine billigste unmarkierte Kante • 1956 von Joseph Kruskal (Amerikanischer Mathematiker) 2. Markiere sie, falls sie keinen Kreis mit anderen markierten Kanten schliesst Prim’s Algorithmus wurde entdeckt: • 1930 von Vojtech Jarnik (Tschechischer Mathematiker) • 1957 von Robert Clay Prim (Amerikanischer Mathematiker) • 1959 von Edsger Wybe Dijkstra (Niederländischer Mathematiker) Prim’s Algorithmus 1. Wähle einen Startknoten. Ist auch unter den Namen Prim-Jarnik und Prim-Dijkstra bekannt. 2. Markiere die billigste vom bereits konstruierten Baum ausgehende Kante, die keinen Kreis mit anderen markierten Kanten schliesst 3. Wiederhole Schritt 2., so lange noch keine n−1 Kanten markiert sind. DSAL/SS 2017 VL-16: Minimale Spannbäume 27/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 28/48 Beispiel: Das Inselreich der Algolaner Korrektheit von Prim und Kruskal Welche Fährverbindungen sollen durch Brücken ersetzt werden? DSAL/SS 2017 VL-16: Minimale Spannbäume 29/48 Das Hauptwerkzeug DSAL/SS 2017 VL-16: Minimale Spannbäume 30/48 Korrektheit des Algorithmus von Kruskal Definition Eine Kantenmenge F ⊆ E in Graphen G = (V , E , w ) heisst tschechisch, falls es einen MST gibt, der alle Kanten in F enthält. Satz Der Algorithmus von Kruskal bestimmt einen minimalen Spannbaum. Satz Es sei F ⊆ E eine tschechische Kantenmenge von G = (V , E , w ). Es sei U ⊆ V eine Zusammenhangskomponente von (V , F ). Es sei e eine Kante mit kleinstem Gewicht zwischen U und V − U. Dann gilt: F ∪ {e} ist ebenfalls tschechisch Beweis: Wir zeigen mit vollständiger Induktion über k ≥ 0, dass die ersten k von Kruskal ausgewählten Kanten jeweils eine tschechische Kantenmenge bilden. • k = 0: Die leere Kantenmenge ist tschechisch. Beweisskizze: Betrachte MST (V , F 0 ) mit F ⊆ F 0 . • (V , F 0 ∪ {e}) enthält Kreis C . Kreis C verwendet mindestens zwei Kanten e und f zwischen U und V − U. • w (f ) ≥ w (e) • Austauschsatz: (V , F 0 ∪ {e} − {f }) ist Baum • Ergo: w (f ) = w (e) und (V , F 0 ∪ {e} − {f }) ist MST • Ergo: F ∪ {e} ist tschechisch DSAL/SS 2017 VL-16: Minimale Spannbäume • Induktionsschritt: Die bisher ausgewählten Kanten bilden tschechische Kantenmenge F . Kruskal gibt die billigste Kante e zu F dazu, die mit F keinen Kreis schliesst. Hauptwerkzeug impliziert dass F ∪ {e} ebenfalls tschechisch ist 31/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 32/48 Korrektheit des Algorithmus von Prim Satz Der Algorithmus von Prim bestimmt einen minimalen Spannbaum. Beweis: Wir zeigen mit vollständiger Induktion über k ≥ 0, dass die ersten k von Prim ausgewählten Kanten jeweils eine tschechische Kantenmenge bilden. Implementierung & Komplexität • k = 0: Die leere Kantenmenge ist tschechisch. • Induktionsschritt: Die bisher ausgewählten Kanten bilden tschechische Kantenmenge F . Es sei U die Zusammenhangskomponente in (V , F ), die den Startknoten enthält. Prim gibt die billigste Kante e zu F dazu, die U mit V − U verbindet. Hauptwerkzeug impliziert dass F ∪ {e} ebenfalls tschechisch ist DSAL/SS 2017 VL-16: Minimale Spannbäume 33/48 Der Algorithmus von Prim: Übersicht 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Baumknoten: Knoten, im bis jetzt konstruierten Baum (BLACK) Randknoten: Nicht im Baum; adjazent zu Knoten im Baum (GRAY) Ungesehen: Alle anderen Knoten (WHITE) Grundkonzept von Prim: Fange mit einem Baum an, der nur aus Startknoten besteht I Finde billigste Kante, die den bisherigen Baum verlässt. I Füge den über diese Kante erreichten Randknoten dem Baum hinzu, zusammen mit der Kante. I Fahre fort, bis keine weiteren Randknoten mehr vorhanden sind. DSAL/SS 2017 VL-16: Minimale Spannbäume VL-16: Minimale Spannbäume 34/48 Prim’s Algorithmus: Grundgerüst Wir klassifizieren Knoten in drei Kategorien (BLACK, GRAY, WHITE): I DSAL/SS 2017 35/48 DSAL/SS 2017 // ungerichteter Graph G mit n Knoten void primMST ( Graph G , int n ) { initialisiere alle Knoten als ungesehen/ WHITE ; waehle Startknoten s und markiere s als Baum/ BLACK ; r ek la ss if i zi er e alle Nachbarn von s als Rand/ GRAY ; while ( es gibt Randknoten ) { waehle unter allen Kanten zwischen Baumknoten t und Randknoten v die billigste ; r ek la ss if i zi er e v als Baum/ BLACK ; fuege Kante (t, v ) zum Baum hinzu ; r ek la ss i fi zi er e alle zu v adjazenten ungesehenen Knoten als Rand/ GRAY ; } } VL-16: Minimale Spannbäume 36/48 Prim’s Algorithmus: Beispiel ADT zum Verhalten der Randknoten Die benötigten Operationen für den Algorithmus von Prim lauten: 4 6 4 5 14 9 9 2 10 I Finde billigste Kante zu einem Randknoten (Kantenkandidat). I Reklassifiziere Randknoten als Baumknoten (füge Kantenkandidaten zum Baum hinzu). I Ändere Kosten (Randgewicht) eines Randknotens, wenn günstigerer Kantenkandidat gefunden wird. Idee: Ordne Randknoten immer nach ihrem Randgewicht (= Priorität). Wir entscheiden uns für Prioritätswarteschlange als Datenstruktur 14 15 3 8 Prioritätswarteschlange (priority queue) 15 I PriorityQueue pq; 8 I pq.insert(int e, int k), int pq.getMin(), pq.delMin() setzt Schlüssel von Element e auf k; dabei muss k kleiner als der bisherige Schlüssel von e sein. I void pq.decrKey(int e, int k) DSAL/SS 2017 VL-16: Minimale Spannbäume 37/48 Komplexitätsanalyse (1) DSAL/SS 2017 VL-16: Minimale Spannbäume 38/48 Komplexitätsanalyse (2) Im Worst-Case passiert folgendes: I Jeder Knoten muss zur Prioritätswarteschlange hinzugefügt werden. I Auf jeden Knoten muss wieder zugegriffen werden und er muss wieder gelöscht werden. I Die Priorität eines Randknotens muss nach jeder gefundenen Kante angepasst werden. n·T (insert)+n·T (getMin)+n·T (delMin)+m·T (decrKey) Die Prioritätswarteschlange kann so organisiert werden (VL-09), dass die Operation insert, getMin, delMin, decrKey jeweils nur O(log n) Zeit benötigen. Satz Der Algorithmus von Prim findet für einen Graphen mit n Knoten und m Kanten den MST in O(m log n) Zeit. Für einen Graphen mit n Knoten und m Kanten ergibt sich dann für die Zeitkomplexität T (n, m) von Prim’s Algoritmus: T (n, m) ∈ O (n·T (insert)+n·T (getMin)+n·T (delMin)+m·T (decrKey)) DSAL/SS 2017 VL-16: Minimale Spannbäume 39/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 40/48 Algorithmus von Prim: Implementierung 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Der Algorithmus von Kruskal: Übersicht Prim - MST (G ,w , start ) { for each u in V ( G ) do { key [ u ] = infty ; parent [ u ] = nil } key [ start ] = 0; insert all vertices u in V ( G ) into pq while (! pq . isEmpty () ) { u = pq . getMin () ; pq . delMin () ; for each neighbor v of u do { if ( w (u , v ) < key [ v ]) { pq . decrKey (v , w (u , v ) ) ; parent [ v ] = u ; } } } I Wir sortieren die Kanten zuerst ansteigend nach ihrem Gewicht. Das kostet O(m log m) Zeit. I Dann beginnen wir mit den n Knoten (ohne Kanten) und versuchen der Reihe nach die Kanten in den Baum einzufügen I Falls Kante zwei Knoten in zwei verschiedenen Zusammenhangskomponenten verbindet: Kante einfügen I Falls Kante zwei Knoten in derselben Zusammenhangskomponente verbindet: Kante überspringen Wichtiges Unterproblem: Wir müssen schnell testen können, ob (im bisher konstruierten Wald) zwei Knoten zur selben Zusammenhangskomponente gehören oder nicht } DSAL/SS 2017 VL-16: Minimale Spannbäume 41/48 Union-Find Datenstruktur DSAL/SS 2017 Implementierung der Union-Find Datenstruktur I Für jede Zusammenhangskomponente werden die Knoten in einem Baum gespeichert. I Dieser Baum ist (im allgemeinen) kein Binärbaum; jeder Knoten kann beliebig viele Kinder haben. I Jeder Knoten (innerer Knoten oder Blatt) hat Zeiger zu Vater. Wir brauchen keine Zeiger zu den Kindern. I Name der Zusammenhangskomponente ist Knoten in Wurzel Operationen: Find: Bestimme Zusammenhangskomponente für Knoten v . Union: Vereinige die beiden Zusammenhangskomponenten für Knoten v und für Knoten v in eine einzige Zusammenhangskomponente VL-16: Minimale Spannbäume 42/48 Union-Find Datenstruktur: Implementierung (1) Zur Verwaltung der Zusammenhangskomponenten brauchen wir eine Datenstruktur, die die folgenden Operationen unterstützt: DSAL/SS 2017 VL-16: Minimale Spannbäume 43/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 44/48 Union-Find Datenstruktur: Implementierung (2) Union-Find Datenstruktur: Implementierung (3) Bessere Implementierung: • Speichere für jeden Baum Anzahl der Knoten in Wurzel • Hänge immer kleinen Baum unter grossen Baum Implementierung von Find(u) Starte in Knoten u, und laufe bis zur Wurzel. Bessere Implementierung von Union(u,v) 1. Starte in Knoten u, und laufe bis zur Wurzel wu mit Knotenzahl nu . 2. Starte in Knoten v , und laufe bis zur Wurzel wv mit Knotenzahl nv . 3. Falls nu ≤ nv : Mache wu zum Kind von wv . Falls nu > nv : Mache wv zum Kind von wu . 4. Knotenzahl des neuen Baumes = nu + nv Implementierung von Union(u,v) 1. Starte in Knoten u, und laufe bis zur Wurzel wu . 2. Starte in Knoten v , und laufe bis zur Wurzel wv . 3. Mache wu zum Kind von wv . Laufzeit: • Hängt stark von der Höhe der Bäume ab. • Falls Baum aus einem einzigen Ast besteht: Laufzeit = Θ(n) • Lineare Laufzeit ist zu langsam DSAL/SS 2017 VL-16: Minimale Spannbäume Es seien Hu und Hv die Höhen der beiden Bäume. Beobachtung Falls Hu 6= Hv : Höhe des neuen Baumes = max{Hu , Hv } Falls Hu = Hv : Höhe des neuen Baumes = Hu + 1 45/48 Union-Find Datenstruktur: Implementierung (4) DSAL/SS 2017 VL-16: Minimale Spannbäume 46/48 Organisatorisches Satz Baum mit Höhe H enthält mindestens 2H Knoten. Beweis: Induktion über H plus Beobachtung • Nächste Vorlesung: Donnerstag, Jun 29, 10:15–11:45 Uhr, Aula 1 Folgerung In der besseren Implementierung braucht jede Find Operation und jede Union Operation nur O(log n) Zeit. • Webseite: http://algo.rwth-aachen.de/Lehre/SS17/DSA.php Satz Der Algorithmus von Kruskal findet für einen Graphen mit n Knoten und m Kanten den MST in O(m log n) Zeit. DSAL/SS 2017 VL-16: Minimale Spannbäume 47/48 DSAL/SS 2017 VL-16: Minimale Spannbäume 48/48