Kapitel 4: Bäume / Graphen Gliederung 1. Motivation / Grundlagen 2. Sortierverfahren 3. Elementare Datenstrukturen / Anwendungen 4. Bäume / Graphen 5. Hashing 6. Algorithmische Geometrie 4/6, Folie 1 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Motivation (Teil 1) gegeben: seien n Städte (/* hier A,B, ...,E */) und damit ein ungerichteter Graph G (/* in dem zwischen je zwei Städten eine Kante vorkommt */) B A C D gesucht: 4/6, Folie 2 © 2014 Prof. Steffen Lange E Teilgraph G‘ von G, in dem es eine Verbindung von jeder Stadt zu jeder anderen Stadt gibt (/* Telefon- bzw. Stromleitungsnetz */) - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Motivation (Teil 1, cont.) ... mögliche Lösungen B B A C D 4/6, Folie 3 © 2014 Prof. Steffen Lange D E - HDa/FbI A C - Datenstrukturen E Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Grundbegriffe • es sei G = (V,E) ein ungerichteter Graph • G ist zusammenhängend, falls es zu je zwei Knoten x,y ∈ V einen Weg w = (v1,v2,...,vn-1,vn) von x nach y in G gibt (/* d.h. v1 = v und vn = v‘ und { vi,vi+1 } ∈ E für alle i mit 1 ≤ i ≤ n - 1 */) G hat einen Kreis, falls es einen Knoten x ∈ V und einen Weg w = (v1,v2,...,vn-1,vn) mit n > 3 von x nach x gibt (/* d.h. v1 = vn =x */), in dem jeder Knoten außer x nur einmal vorkommt • • es sei der Graph G‘ = (V‘,E‘) ein Teilgraph von G (/* d.h. es gilt E‘ ⊆ V‘×V‘, V‘ ⊆ V, und E‘ ⊆ E */) G‘ = (V‘,E‘) ist ein aufspannender Baum von G, falls gilt: • V‘ = V • G‘ ist kreisfrei • G‘ ist zusammenhängend. 4/6, Folie 4 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Illustration B B A C A C D D E E B A C D 4/6, Folie 5 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen E Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u eine einfache Beobachtung • es sei G = (V,E) ein ungerichteter Graph mit n Knoten und G‘ = (V‘,E‘) ein aufspannender Baum in G Dann hat G‘ genau n - 1 viele Kanten. ... falls G‘ weniger Kanten hat, kann G‘ nicht zusammenhängend sein ... falls G‘ mehr Kanten hat, kann G‘ nicht kreisfrei sein 4/6, Folie 6 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Aufgabenstellung Eingabe: ein ungerichteter zusammenhängender Graph G = (V,E) Ausgabe: ein aufspannender Baum G‘ = (V‘,E‘) in G ... später betrachten wir dieselbe Aufgabenstellung für kantenbewertete ungerichtete zusammenhängende Graphen und sind daran interessiert, einen aufspannenden Baum mit minimalem Gewicht zu bestimmen 4/6, Folie 7 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Motivation (Teil 2) gegeben: seien n Städte (/* hier A,B, ...,E */) und damit ein ungerichteter Graph G (/* ... und die Kanten haben die Entfernungen zwischen den Städten als Gewichte */) B 5 3 5 C A 5 5 5 D gesucht: 4/6, Folie 8 © 2014 Prof. Steffen Lange 3 5 5 5 E Teilgraph G‘ von G, in dem es eine Verbindung von jeder Stadt zu jeder anderen Stadt gibt und die Gesamtlänge der Verbindungen minimal sein soll - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Motivation (Teil 2, cont.) ... eine Lösung (/* Gesamtlänge der Verbindungen = 20 */) B 5 3 A 5 D 4/6, Folie 9 3 © 2014 Prof. Steffen Lange 5 - 5 HDa/FbI - Datenstrukturen 3 5 5 D E 5 A 5 5 5 3 5 C 5 5 B 5 5 C ... beste Lösung (/* Gesamtlänge der Verbindungen = 16 */) 5 E Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Datenstruktur • 4/6, Folie 10 eine Menge M von Kanten (/* dient zur Verwaltung der in G‘ potentiell aufzunehmenden Kanten */) © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u „erste“ algorithmische Idee (1) setze M = E und V‘ = ∅ und E‘ = ∅ (2) solange E‘ < | V | - 1 a) wähle eine Kante e = { x,y } aus M und streiche e aus M b) setze V* = V‘ ∪ { x,y } und E* = E‘ ∪ { e } c) teste, ob der Graph G* = (V*,E*) kreisfrei ist falls ja, so setze V‘ = E* und E‘ = E* falls nein, so ändere V‘ und E‘ nicht • • ... die Laufzeit hängt offenbar davon ab, wie effizient man in c) testen kann, ob G* = (V*,E*) kreisfrei ist ... Verfeinerung: diesen Test möglichst einfach realisieren 4/6, Folie 11 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Hintergrund für eine Verfeinerung der algorithmischen Idee • es sei G = (V,E) ein ungerichteter Graph • es seien die Graphen G1 = (V1,E1) und G2 = (V2,E2) kreisfreie zusammenhängende Teilgraphen von G mit V1 ∩ V2 = ∅ • es sei e = { x,y } ∈ E mit x ∈ V1 und y ∈ V2 Dann ist G* = (V*,E*) mit V* = V1 ∪ V2 und E* = E1 ∪ E2 ∪ { e } ein kreisfreier zusammenhängender Teilgraph von G. G ... es ist offenbar essentiell V1 und V2 zu kennen und die Menge E1 ∪ E2 4/6, Folie 12 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Illustration G1 = (V1,E1) B B A C D G2 = (V2,E2) A C D E E B A C G* = (V*,E*), wobei e = { B,E } ist D 4/6, Folie 13 © 2014 Prof. Steffen Lange - HDa/FbI E - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u Grundbegriff 4/6, Folie 14 • es sei O eine Menge von Objekten • es sei K = { M1,M2,...,Mk } (/* mit 1 ≤ k ≤ n */) eine Menge von nicht-leeren Teilmengen von O • K ist eine Klasseneinteilung der Menge O, falls gilt: • für alle alle i,j mit 1 ≤ i,j ≤ k gilt: Mi ∩ Mj = ∅ (/* die Mengen von K sind paarweise disjunkt */) • O = M1 ∪ M2 ∪ ... ∪ Mk (/* jedes Objekt aus O kommt in einer Menge von K vor */) © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen aufspannender Bäume u verfeinerte algorithmische Idee (1) setze M = E, E‘ = ∅ und bilde die Klasseneinteilung K = { { x } | x ∈ V } (2) solange E‘ < | V | - 1 a) wähle eine Kante e = { x,y } aus M und streiche e aus M b) bestimme V1,V2 ∈ K mit x ∈ V1 und y ∈ V2 c) teste, ob V1 ≠ V2 gilt • • falls ja, so setze E‘ = E‘ ∪ { e }, streiche V1 und V2 aus der Klasseneinteilung K und füge die Menge V‘ = V1 ∪ V2 zur Klasseneinteilung K hinzu (/* für alle V* ∈ K ist der durch V* induzierte Teilgraph G* = (V*,E(V*)) kreisfrei und zusammenhängend; V(E*) = { { x,y } ∈ E‘ | x,y ∈ V* } */) falls nein, so ändere E‘ nicht ... zur Verwaltung der Klasseneinteilung K verwendet man eine spezielle Datenstruktur (/* Union-Find-Struktur genannt */) 4/6, Folie 15 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen minimal aufspannender Bäume u Illustration M = { { A,B },{ A,C },{ B,C },{ A,D }, ... } E‘ = ∅ K = { { A },{ B },{ C },{ D },{ E } } B M = { { A,C },{ B,C },{ A,D }, ... } E‘ = { { A,B } } K = { { A,B },{ C },{ D },{ E } } D M = { { B,C },{ A,D }, ... } E‘ = { { A,B },{ A,C } } K = { { A,B,C },{ D },{ E } } 4/6, Folie 16 © 2014 Prof. Steffen Lange - HDa/FbI A C E M = { { A,D }, ... } E‘ = { { A,B },{ A,C } } K = { { A,B,C },{ D },{ E } } - Datenstrukturen Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Grundidee • es sei O = { o1,...,on } die Grundmenge der betrachteten Objekte (/* in unserem Fall sind das die Knoten von G */) • • wir interessieren uns für die Verwaltung von Klasseneinteilungen K von O (/* d.h. K = { M1,...,Mk } mit M1 ∪ ... ∪ Mk = O und die Mengen M1,...,Mk sind paarweise disjunkt */) die Anzahl der verwalteten Mengen ändert sich über die Zeit • zentrale Operation: Vereinigung disjunkter Mengen ... Zugriff auf die Mengen ??? 4/6, Folie 17 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Namensgebung von Mengen • • o1,...,on dienen als Namen für die Einermengen { o1 },...,{ on } allgemein dient ein ausgezeichnetes Element o ∈ M als Name für eine Teilmenge M ⊆ O u relevante Operation 4/6, Folie 18 • union(oi,ok) – Menge der verwalteten Mengen ändern, indem die Mengen mit den Namen oi bzw. ok vereinigt werden • find(o) – den Namen der Menge bestimmen, die aktuell das Objekt o enthält © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Realisierung von Union-Find-Strukturen (/* konzeptionell */) repräsentiere Mengen als Bäume beliebiger Ordnung • • • • 4/6, Folie 19 jeder Knoten hat ein Objekt als Label jeder Knoten hat einen Zeiger auf seinen Vater die Wurzel hat einen Zeiger auf sich selbst das Label der Wurzel dient als Name für diese Menge © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Illustration einelementige Mengen {2} 2 mehrelementige Mengen 1 3 { 1,3,5,7 } 5 7 4/6, Folie 20 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Realisierung von Union-Find-Strukturen (/* konzeptionell */) Find-Operation ... gib das Label der Wurzel des Baums zurück, in dem das Objekt o gespeichert ist 4 6 ... find(6) = find(2) = find(4) = 4 2 { 2,4,6 } Union-Operation ... mache die Wurzel das Baums für die Menge o2 zum Sohn der Wurzel des Baums für die Menge o1 4 6 1 2 4 3 6 { 2,4,6 } ∪ { 1,3 } = { 1,2,3,4,6 } 4/6, Folie 21 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen 1 2 3 Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Implementierung von Union-Find-Strukturen (/* Version 1 */) ... verwenden ein eindimensionales Array zur Repräsentation aller Bäume Väter 1 2 3 4 5 6 7 1 2 4 1 5 5 7 zugehörige Mengen: 4/6, Folie 22 © 2014 Prof. Steffen Lange - HDa/FbI { 1,3,4 } {2} { 5,6 } {7} - Datenstrukturen Objekte Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Implementierung von Union-Find-Strukturen (/* Version 1 */) 4/6, Folie 23 Initialisierung for ( int o = 1; o <= n; ++o ) v[o] = o; ... in Zeit O(n) Union-Operation void union ( int o1, int o2 ) { v[o2] = o1; } ... in Zeit O(1) Find-Operation int find ( int o ) { while ( v[o] != o ) { o = v[o]; } return(o); } © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen ... in Zeit O(n) Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Implementierung von Union-Find-Strukturen (/* Version 2 */) ... verwenden zwei eindimensionale Arrays zur Repräsentation aller Bäume 1 2 3 4 5 6 7 Väter 1 2 4 1 5 5 7 Mächtigkeit der Mengen 3 1 1 2 2 1 1 zugehörige Mengen: 4/6, Folie 24 © 2014 Prof. Steffen Lange - { 1,3,4 } {2} { 5,6 } {7} HDa/FbI - Datenstrukturen Objekte Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Implementierung von Union-Find-Strukturen (/* Version 2 */) for ( int o = 1; o <= n; ++o ) { v[o] = o; m[o] = 1; } Initialisierung void union ( int o1, int o2 ) { if ( m[o1] > m[o2] ) { v[o2] = o1; m[o1] = m[o1] + m[o2]; } else { v[o1] = o2; m[o2] = m[o2] + m[o1]; } } Union-Operation 4/6, Folie 25 © 2014 Prof. Steffen Lange - HDa/FbI - ... in Zeit O(1) ... aber, in Zeit O(log(n)) ... wie gehabt Find-Operation ... in Zeit O(n) Datenstrukturen Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Begründung – Laufzeit der Find-Operation (/* Version 2 */) • für einelementige Mengen gilt: tiefe(B) ≤ log(n) • es seien M1, M2 Mengen mit n1 bzw. n2 Elementen, wobei n1 ≥ n2 gilt (/* nach IV gilt für die zugehörigen Bäume B1 und B2: tiefe(B1) ≤ log(n1) und tiefe(B2) ≤ log(n2) */) Fall 1: tiefe(B) = tiefe(B1) à log(n) = log(n1 + n2) ≥ log(n1) ≥ tiefe(B1) B B1 B1 B 2 4/6, Folie 26 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen 2 Kapitel 4: Bäume / Graphen Union-Find-Strukturen u Begründung – Laufzeit der Find-Operation (/* Version 2 */) • für einelementige Mengen gilt: tiefe(B) ≤ log(n) • es seien M1, M2 Mengen mit n1 bzw. n2 Elementen, wobei n1 ≥ n2 gilt (/* nach IV gilt für die zugehörigen Bäume B1 und B2: tiefe(B1) ≤ log(n1) und tiefe(B2) ≤ log(n2) */) Fall 2: tiefe(B) = tiefe(B2) + 1 à log(n) = log(n1 + n2) ≥ log(2n2) ≥ log(2) + log(n2) ≥ 1 + tiefe(B2) B1 B1 4/6, Folie 27 © 2014 Prof. Steffen Lange - B B 2 2 HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen minimal aufspannender Bäume u Datenstruktur • • 4/6, Folie 28 eine Menge M von Kanten (/* dient zur Verwaltung der potentiell aufzunehmenden Kanten */) eine Union-Find-Struktur (/* Version 2 */) zur Verwaltung der Knotenmengen, der sukzessive erzeugten kreisfreien zusammenhängenden Teilgraphen © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen minimal aufspannender Bäume u verfeinerte algorithmische Idee (/* mit Union-Find-Struktur */) (1) setze M = E, setze E‘ = ∅ und initialisiere eine Union-Find-Struktur für die Knotenmenge V (2) solange E‘ < | V | - 1 a) wähle eine Kante e = { x,y } aus M und streiche e aus M b) bestimme a = find(x) und b = find(y) c) teste, ob a ≠ b gilt • • falls ja, so setze E‘ = E‘ ∪ { e } und führe die Operation union(a,b) aus falls nein, so ändere E‘ nicht ... geht in Zeit O(n) + m*O(1) + m*O(log(n)) (/* falls Variante 2 zur Implementierung von Union-Find-Strukturen verwendet wird */), wobei n die Anzahl der Knoten von G und m die Anzahl der Kanten von G ist 4/6, Folie 29 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen minimal aufspannender Bäume u Illustration B A B C D E A B C D E 1 1 1 1 1 A C M = { { A,B },{ A,C },{ B,C },{ A,D }, ... } E‘ = ∅ D A B C D E A A C D E 2 1 1 1 1 M = { { A,C },{ B,C },{ A,D }, ... } E‘ = { { A,B } } 4/6, Folie 30 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen E Kapitel 4: Bäume / Graphen Bestimmen minimal aufspannender Bäume u Illustration B A B C D E A A C D E 2 1 1 1 1 A C M = { { A,C },{ B,C },{ A,D }, ... } E‘ = { { A,B } } D A B C D E A A A D E 3 1 1 1 1 M = { { B,C },{ A,D }, ... } E‘ = { { A,B },{ A,C } } 4/6, Folie 31 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen E Kapitel 4: Bäume / Graphen Bestimmen minimal aufspannender Bäume u Illustration B A B C D E A A A D E 3 1 1 1 1 A C M = { { B,C },{ A,D }, ... } E‘ = { { A,B },{ A,C } } D A B C D E A A A D E 3 1 1 1 1 M = { { A,D }, ... } E‘ = { { A,B },{ A,C } } 4/6, Folie 32 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen E Kapitel 4: Bäume / Graphen Bestimmen minimal aufspannender Bäume u Grundbegriffe • • es sei G = (V,E) ein ungerichteter Graph es sei g(.) eine Funktion, die jeder Kante in V eine reelle Zahl zuordnet ... das Paar (G,g(.)) heißt ungerichteter kantengewichteter Graph • 4/6, Folie 33 das Gewicht g(G) von G ist die Summe der Gewichte der Kanten von G © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen minimal aufspannender Bäume u Aufgabenstellung 4/6, Folie 34 Eingabe: ein ungerichteter zusammenhängender Graph G = (V,E) und eine zugehörige Gewichtsfunktion g(.) Ausgabe: ein aufspannender Baum G‘ = (V‘,E‘) in G, der ein minimales Gewicht hat © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen minimal aufspannender Bäume u Datenstruktur • • 4/6, Folie 35 eine Menge M von Kanten (/* dient zur Verwaltung der in G‘ potentiell aufzunehmenden Kanten */) eine Union-Find-Struktur (/* Version 2 */) zur Verwaltung der Knotenmengen, der sukzessive erzeugten kreisfreien zusammenhängenden Teilgraphen © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmen minimal aufspannender Bäume u algorithmische Idee (1) setze M = E, setze E‘ = ∅ und initialisiere eine Union-Find-Struktur für die Knotenmenge V (2) solange E‘ < | V | - 1 a) wähle eine Kante e = { x,y } mit minimalem Gewicht aus M und streiche e aus M b) bestimme a = find(x) und b = find(y) c) teste, ob a ≠ b gilt • • falls ja, so setze E‘ = E‘ ∪ { e } und führe die Operation union(a,b) aus falls nein, so ändere E‘ nicht ... geht in Zeit O(n) + m*O(m)+ m*O(log(n)) (/* falls Variante 2 zur Implementierung von Union-Find-Strukturen verwendet wird */), wobei n die Anzahl der Knoten von G und m die Anzahl der Kanten von G ist 4/6, Folie 36 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen Kapitel 4: Bäume / Graphen Bestimmung minimal aufspannender Bäume u Anmerkung • falls man die Menge M, der aufzunehmenden Kanten, mit Hilfe einer Prioritätswarteschlange realisiert (/* Heap, wobei statt „≥“ ein „≤“ zur Sicherstellung der Heap-Eigenschaft verwendet wird */), kann 2a) jeweils in Zeit O(log(m)) realisiert werden, wobei m die Anzahl der Kanten von G ist (/* die Initialisierung der Prioritätswarteschlange kostet einmalig Zeit O(m) */) ... geht offenbar in Zeit O(n) + O(m) + m*O(log(m)) + m*O(log(n)), wobei n die Anzahl der Knoten von G und m die Anzahl der Kanten von G ist 4/6, Folie 37 © 2014 Prof. Steffen Lange - HDa/FbI - Datenstrukturen