Informatik I 8. Kapitel B-Bäume Rainer Schrader Zentrum für Angewandte Informatik Köln 22. Juli 2008 1/1 2/1 B-Bäume B-Bäume • bisherige Annahme für das Suchen: • alle Daten befinden sich im Hauptspeicher (Random Access Memory = RAM) • d.h. jeder Zugriff ist gleich schnell Gliederung • jetzt: die Daten befinden sich auf einer Platte • Definitionen und Eigenschaften magnetische Oberfläche • Einfügen und Löschen in B-Bäumen • Vereinigen und Spalten von B-Bäumen • Laufzeit der dynamischen Verwaltung • zwei Anwendungen Platte Lese−/Schreib−Kopf Spur (track) 3/1 4/1 B-Bäume B-Bäume Organisation eines Plattenspeichers • jede Spur ist in “Seiten” fester Größe aufgeteilt Szenario • (z.B. 2048 Bytes pro Seite) • auf der Platte befindet sich eine große Datenmenge • zu jeder Zeit passt nur eine konstante Anzahl von Seiten in den • Zugriffe erfolgen immer in ganzen Seiten Hauptspeicher • Technik: • Flaschenhals für die Laufzeit: • positioniere L/S-Kopf • Lesen einer benötigten Seite • und warte, bis die gesuchte Seite vorbeikommt • Schreiben einer geänderten Seite auf die Platte • dies ergibt eine mittlere Zugriffszeit von: • wir wollen die „Wörterbuch“-Funktionen füge_ein, lösche und suche unterstützen • z.Zt. 1–10 Millisekunden auf Festplatten • zum Vergleich: z.Zt. ca. 10 Nanosekunden auf RAM • d.h. der Faktor liegt in der Größenordnung von 105 – 106 6/1 5/1 B-Bäume B-Bäume Beispiel: Ein voller Baum der Höhe h = 3 mit b = 256 Kindern pro internem Knoten (d.h. 255 Schlüssel pro Knoten): Idee: Verringerung der Höhe des Suchbaums durch Erhöhung der Kinderzahl pro Knoten, wobei jeder Knoten auf eine Seite passen muss. Knoten x eines Anzahl Schlüssel binären Suchbaums B-Baums c1 c2 c k ≤c ? ? k ≥c 1 Schlüssel, 2 Kinder ? k ≤ c1 ? ... c1 ≤ k ≤ c2 255 255 cn[x ] ... ... ? k ≥ cn[x ] 255 255 n[x ] Schlüssel, n[x ] + 1 Kinder ... • alle Operationen besuchen O(h(T )) viele Knoten • ⇒ Die Anzahl der Plattenzugriffe ist O(h(T )) 255 7/1 255 ... 255 255 255 256 . 255 255 ... 255 255 255 255 256 2. 255 8/1 B-Bäume B-Bäume Die Schlüssel bestehen wieder aus untereinander verschiedenen natürlichen Zahlen. • Anzahl der Datensätze im vollen (256)-Baum der Höhe 3: B-Baum 2563 = 16.777.216 Ein Baum T mit Wurzel r heißt B-Baum der Ordnung t ≥ 2, wenn gilt: • bei einer mittleren Zugriffszeit von 5 Millisekunden kann jeder Datensatz in ∼ 20 Millisekunden gelesen werden (1) jeder innere Knoten außer r hat mindestens t Söhne • zum Vergleich: • ein binärer Baum mit 16.777.216 hat Höhe 24. • damit dauern die Zugriffe im Schnitt 125 Millisekunden (2) r hat mindestens 2 Söhne (3) jeder Knoten hat höchstens 2t Söhne (4) die Blätter haben die gleiche Tiefe h = Höhe(T ) (5) zusätzlich gilt: • jeder innere Knoten mit k Söhnen enthält k − 1 Schlüssel 9/1 10 / 1 B-Bäume B-Bäume Aufbau eines inneren Knotens x : • x enthält folgende Angaben k = k (x ), ci = ci (x ), pi = pi (x ) • k ist die Anzahl der Schlüssel in x • k Schlüssel: c1 ≤ c2 ≤ . . . ≤ ck als geordnete Liste Lemma Sei T ein B-Baum der Ordnung t mit m Blätter und Höhe h. Dann gilt: (i) 2t h−1 ≤ m ≤ (2t )h • k + 1 Zeiger: p1 , p2 , . . . , pk +1 auf die Kinder (ii) Ist si ein im Unterbaum mit Wurzel pi gespeicherter Schlüssel, so gilt s1 ≤ c1 ≤ s2 ≤ c2 ≤ . . . ≤ ck ≤ sk +1 . log m − 1 log m ≤h ≤1+ 1 + log t log t Beweis: (ii) folgt aus (i) durch Logarithmieren 3 7 10 (i) jeder Knoten hat höchstens 2t Söhne ; höchstens (2t )h Blätter 13 • die Wurzel hat mindestens zwei, jeder andere mindestens h Söhne 1 3 6 8 9 11 12 14 ; (i). 15 Blätter sind entsprechend aufgebaut, lediglich die Zeiger fehlen. 11 / 1 12 / 1 B-Bäume B-Bäume Suche(T , s) eines Schlüssels s im B-Baum T (1) sei x Wurzelknoten von T Lemma (2) lade x (i) Ein B-Baum der Ordnung 2 kann als rot-schwarz-Baum dargestellt werden. (3) bestimme den kleinsten Index i , so dass s ≤ ci (4) ist s = ci : „gefunden”, stop (ii) Ein rot-schwarz-Baum kann als B-Baum der Ordnung 2 dargestellt werden. (5) ist x ein Blatt: „nicht gefunden”, stop (6) andernfalls setze x := pi und gehe zu (2) Beweis: Übungsaufgabe Die Suche in (3) kann mit Hilfe von Suchverfahren durchgeführt werden (linear, binär, . . .) 14 / 1 13 / 1 B-Bäume B-Bäume Laufzeitanalyse des Suchens in B-Bäumen Gliederung • sei T ein B-Baum der Ordnung t • Definitionen und Eigenschaften • Anzahl der gelesenen Seiten: O(Höhe(T )) = O(log n) • Einfügen und Löschen in B-Bäumen • Zeit für das Suchen in einem Knoten: O(t ) (da k (x ) < 2t ) • Vereinigen und Spalten von B-Bäumen • ; Gesamtlaufzeit: O(t · log n) • Laufzeit der dynamischen Verwaltung • zwei Anwendungen • (für B-Bäume mit großer Ordnung: binäre Suche) 15 / 1 16 / 1 B-Bäume B-Bäume Vorgehen beim Einfügen • suche nach s • falls s gefunden, stop Vorüberlegungen zum Einfügen • sei T ein B-Baum • sei s ein Schlüssel, der in T eingefügt werden soll • wie üblich suchen wir zuerst nach s • falls s bereits vorhanden ist, ist nichts weiter zu tun • andernfalls endet die Suche in einem Blatt w • füge s in w ein • falls w dann nur 2t − 1 Schlüssel enthält, stop • • • • • • andernfalls ist es nur sinnvoll, s in einem Blatt zu speichern • denn, wenn wir s in einem inneren Knoten ablegen: • müssten wir per definition einen weiteren Sohn erzeugen • und einen daran hängenden Unterbaum geeigneter Höhe • daraus ergibt sich der folgende Ansatz: andernfalls ersetze w durch zwei Knoten (mit Hilfe von „Spalte”) damit steigt die Anzahl der Söhne des Vaters von w falls der Vater nicht voll ist, stop andernfalls ersetze den Vater durch zwei Knoten ... • wenn dabei rekursiv die Wurzel erreicht wird: • spalte die Wurzel • und füge eine neue Wurzel als Vater hinzu • dadurch wächst die Höhe um 1 und das Verfahren terminiert. 17 / 1 18 / 1 B-Bäume B-Bäume Beispiel: Prozedur Spalte(x , i , y ) B-Baum T mit t = 2 für S = {4, 7, 8, 9}, füge_ein (T , 6) • dabei soll gelten: • y ist i -tes Kind von x • y enthält 2t Schlüssel 4 4 v 789 2 • und hat 2t + 1 Söhne 1 • y wird aufgespalten in zwei Knoten y 0 und z • y 0 erhält die ersten t − 1 Schlüssel und t Söhne • z erhält die letzten t Schlüssel und t + 1 Söhne 3 7 8 6 789 2 9 1 10 3 6 7 8 9 10 6 Spalte v 4 7 • y 0 und z werden Söhne von x • y 0 übernimmt die Rolle von y • der Schlüssel an der Position t wird in x aufgenommen • er trennt dort an Position i + 1 die Zeiger auf y 0 und z 6 2 1 19 / 1 3 6 89 7 8 9 10 20 / 1 B-Bäume B-Bäume Vorgehen beim Löschen des Schlüssels s Lemma • die Suche nach s endet in einem Knoten x Das Einfügen in einen B-Baum hat Zeitkomplexität O(log n) (1) ist x ein Blatt, so lösche s aus x Beweis: (2) ist x interner Knoten: • die Suche nach s benötigt O(log n) Schritte. • danach führen wir maximal O(log n) Spaltoperationen aus, die jeweils • bestimme den Nachfolger s 0 (kleinstes s 0 mit s 0 ≥ s) • s 0 liegt in einem Blatt x 0 O(1) Schritte benötigen • ersetze in x s durch s 0 • bei einer Spaltung wird ein Knoten y mit 2t + 1 Söhnen in 2 Knoten • lösche s 0 und setze x = x 0 mit jeweils t + 1 und t Söhnen zerlegt • da t ≥ 2, ist t + 1 ≤ 2t . (3) enthält x noch mindestens t − 1 Schlüssel, stop 21 / 1 22 / 1 B-Bäume B-Bäume (3) enthält x noch mindestens t − 1 Schlüssel, stop (3) enthält x noch mindestens t − 1 Schlüssel, stop (4) ist x die Wurzel und hat keinen Schlüssel mehr, so streiche sie, stop. (4) ist x die Wurzel und hat keinen Schlüssel mehr, so streiche sie, stop. (5) Stehle: (6) Verschmelze • sei y ein Bruder von x mit t − 1 Schlüsseln • falls x einen linken oder rechten Bruder hat, der mindestens t Schlüssel enthält: • sei z der Vater von x und y • verschiebe benachbarten Zeiger nach x • verschiebe zugehörigen Schlüssel zum Vater • bewege alle Schlüssel von y nach x • bewege den Schlüssel in z , der zu y gehört, ebenfalls nach x • verschiebe Schlüssel vom Vater nach x , stop (7) setze x = z und gehe zu (3). .... .... .... c r p r+1 p i c i p .... i+1 p 1 c p .... 1 p 2 .... .... c r p r+1 c p i 1 i c 1 p i+1 p i c i p i+1 c i+1 p i+2 .... .... p i c i+1 p i+2 .... .... p 2 .... • danach ist der Baum repariert. .... c r p r+1 p 1 c 1 p 2 .... .... c r p r+1 c i p 1 c 1 p 2 .... • der Defekt ist zur Wurzel hin verschoben. 23 / 1 24 / 1 B-Bäume B-Bäume Gliederung Lemma lösche(T , s) benötigt O(log n) • Definitionen und Eigenschaften Beweis: • Einfügen und Löschen in B-Bäumen • wir benötigen höchstens O(log n) Verschmelzungs- und 1 Stehl-Operation, die jeweils • Vereinigen und Spalten von B-Bäumen O(1) Schritte benötigen. • Laufzeit der dynamischen Verwaltung • eine Verschmelzung vereint einen Knoten mit t und einen mit t − 1 Söhnen zu einem Knoten mit 2t − 1 Söhnen. • zwei Anwendungen 25 / 1 26 / 1 B-Bäume B-Bäume Vereinige(T1 , T2 , T3 ) Für spätere Zwecke betrachten wir zwei weitere Operationen auf B-Bäumen: • seien S1 und S2 zwei disjunkte Schlüsselmengen • es sei max S1 < min S2 • beide Mengen seien in B-Bäumen T1 , T2 der gleichen Ordnung • Schlüsselmengen sind jeweils in B-Bäumen dargestellt • vereinige zwei disjunkte Schlüsselmengen abgelegt • zerlege die Schlüssel in „kleine” und „große” • die Ergebnisse sollen jeweils wieder in B-Bäumen abgelegt werden • gesucht ist ein B-Baum T3 , der S1 ∪ S2 repräsentiert • T1 und T2 können dabei zerstört werden • die Vereinigung wird durch die Operation Konkateniere(S1 , S2 , S3 ) realisiert 27 / 1 28 / 1 B-Bäume B-Bäume Konkateniere(S1 , S2 , S3 ) • sei r2 die Wurzel von T2 • sei v ∈ T1 der rechteste Knoten in T1 der Tiefe h1 − h2 • berechne h1 = Höhe(T1 ) → O(h1 ) h2 = Höhe(T2 ) → O(h2 ) r1 t1 = max{s ∈ S1 } → O(h1 ) • sei o.B.d.A. h1 ≥ h2 • sei r2 die Wurzel von T2 • sei v ∈ T1 der rechteste Knoten in T1 der Tiefe h1 − h2 r1 r2 v • lösche t1 aus T1 → O(h1 ) • ist v die Wurzel von T1 , so füge zu T1 eine neue Wurzel x hinzu • andernfalls sei x der Vater von v r2 • erweitere x um den Schlüssel t und den Sohn r2 • hat x höchstens 2t Söhne, stop v • andernfalls repariere wie beim Einfügen. 29 / 1 30 / 1 B-Bäume B-Bäume • sei T ein B-Baum, der die Menge S speichert • und x ein Schlüsselwert Lemma (i) Konkateniere(S1 , S2 , S3 ) benötigt O(log(max{|S1 |, |S2 |})) Schritte, • Ziel: ersetze S durch (ii) der neue B-Baum hat Höhe ≤ max{h1 , h2 } + 1. • S1 = {y ∈ S : y ≤ x } und • S2 = {y ∈ S : y > x }. Beobachtung: Idee: • seien folgende Größen bekannt: • das Verfahren fährt das Verfahren wie ein „Blitz” durch den Baum • und spaltet ihn entlang der Bruchstelle in Teilbäume auf • die dabei entstehenden Teilbäume sind (evtl. mit Ausnahme ihrer • die Höhen von T1 und T2 • ein Schlüssel t ∈ / S1 ∪ S2 mit max S1 ≤ t < min S2 • dann können wir in höchstens O(|h1 − h2 | + 1) Schritten einen Wurzel) wieder B-Bäume B-Baum T3 für S1 ∪ S2 ∪ t erzeugen • sammle die linken Teilbäume durch Verschmelzen wie oben auf, um • danach ist auch die Höhe von T3 bekannt S1 zu erzeugen. (Entsprechend S2 ) 31 / 1 32 / 1 B-Bäume B-Bäume Spalte(T , x ) • sei r die Wurzel von T • sei ci −1 (r ) < x ≤ ci (r ), d.h. die Suche geht zum i -ten Sohn w über B B 1 3 4 5 6 1 2 1 2 B 3 4 5 8 7 • v 0 erhält die ersten i − 1 Söhne von r und die Schlüsselelemente c1 (r ) . . . ci −2 (r ), • v 00 erhält Schlüsselelemente ci +1 (r ), . . . , ck (r ) sowie die zugehörigen Söhne pi +1 (r ), . . . , pk +1 (r ) 17 2 B 3 8 9 10 6 • erzeuge drei neue Bäume mit neuen Wurzelknoten v 0 , v 00 und w 1 9 10 11 12 B 13 2 19 20 21 15 16 17 14 15 16 17 18 19 20 • rufe rekursiv Spalte(T (w ), x ) auf 21 c A 1 B ... c i-2 C c i-1 c i w ... c k E c F i-1 c c 1 ... c i A B c i-2 w C i+1 E ... c k F 33 / 1 34 / 1 B-Bäume c A 1 B ... c i-2 C c i-1 c i w ... c k E c F i-1 c c 1 ... c i A B c i-2 C w i+1 E B-Bäume ... c k • es entstehen 2 Mengen Fl , Fr von Bäumen die fast B-Bäume sind • mit der einzig möglichen Ausnahme, dass die Wurzel nur einen Sohn hat F • die Höhen der Bäume können während des Spaltens berechnet werden • sei Si die Menge der Schlüsel in Fi , i = 1, 2 • sei Fl = {B1 , . . . , Bm } die Menge der linken Bäume von links nach • zusätzlich speichere jeweils: ci −1 (v ) und ci (v ) rechts durchnumeriert • (entsprechend Fr , wir betrachten im folgenden nur Fl ) 35 / 1 36 / 1 B-Bäume B-Bäume Lemma • sei hi = h(Bi ) • da Fl auf dem Suchpfad erzeugt wird, gilt h1 > h2 > . . . > hm und Für 1 ≤ i ≤ m − 2 gilt hi +1 ≤ hi0+1 ≤ hi +1 + 1 ≤ hi . m ≤ Höhe(T ) Beweis: • da Bi +1 in Bi0+1 aufgeht, folgt hi +1 ≤ hi0+1 • weiter gilt hi +1 + 1 ≤ hi • es ist max{s ∈ Bj } ≤ t < min{s ∈ Bj +1 }, wobei t der in diesem Spaltschritt gespeicherte Wert ist • führe wie bei B-Bäumen aus: • Rest per Induktion über i = m − 2, . . . , 1 : 0 • für i = m − 2 ist hm−1 ≤ max{hm−1 , hm } + 1 ≤ hm−1 + 1 0 • für i < m − 2 ist hi +1 ≤ max{hi +1 , hi0+2 } + 1 ≤ hi +1 + 1, da 0 Konkateniere(Bm−1 , Bm , Bm−1 ) 0 0 Konkateniere(Bm−2 , Bm−1 , Bm−2 ) hi0+2 ≤ hi +1 . .. . Konkateniere(B1 , B20 , B10 ) Lemma • hat am Schluss die Wurzel nur einen Sohn, so lösche sie Sei T ein B-Baum mit n Knoten. Die Operation Spalte(T , x ) benötigt O(log n) Schritte. 38 / 1 37 / 1 B-Bäume B-Bäume Beweis: • die Aufspaltphase benötigt O(log n) Schritte • bei jedem Konkatenierungsschritt sind Schlüsselwerte t bekannt • mit dem vorigen Lemma und der früheren Beobachtung folgt für die Fazit: Laufzeit L(Spalte(T , x )) der Aufbauphase: L(Spalte(T , x )) = |hm−1 − hm | + m−2 X • suche • füge_ein |hi − hi0+1 | + m − 1 • lösche • konkateniere i =1 = hm−1 − hm + m−2 X (hi − hi0+1 ) + m − 1 • spalte i =1 0 ≤ hm−1 − hm + m−2 X sind auf B-Bäumen in (hi0 − hi0+1 ) + m O(log n) Zeit durchführbar. i =1 ≤ m + h10 ≤ m + h1 + 1 = O(log n) 39 / 1 40 / 1 B-Bäume B-Bäume • bisher worst-case-Abschätzungen für die Laufzeiten der Operationen • Rebalancierung benötigen höchstens O(log |S|) Schritte Gliederung • Definitionen und Eigenschaften • wir untersuchen jetzt die dynamische Verwaltung eines B-Baums: • Einfügen und Löschen in B-Bäumen • in einem am Anfang leeren Baum • führen wir eine Folge von • Vereinigen und Spalten von B-Bäumen • E Einfüge- und • Laufzeit der dynamischen Verwaltung • L Lösch-Operationen durch • zwei Anwendungen • mit n = E + L • Ziel: zeige, dass die benötigte Laufzeit lediglich O(n) beträgt 41 / 1 42 / 1 B-Bäume B-Bäume • sei Op eine Operation, die den Baum T1 in den Baum T2 überführt • wir ordnen Op amortisierte Kosten zu: Idee: amortisierte Kosten(Op) = Laufzeit(Op) + pot(T2 ) − pot(T1 ) • die Operationen werden mehrmals hintereinander ausgeführt • • • • • die Hoffnung ist: • wir investieren Arbeit bei einer Operation • diese kann sich bei späteren Ausführungen bezahlt machen • diesen Beitrag abzuschätzen, ist schwierig • ; Analyse mit „amortisierten Kosten” wir starten mit einem leeren Baum T0 mit pot(T0 ) = 0 wir führen eine Folge von Operationen Op1 , Op2 , . . . , Opm durch Opi führt den Baum Ti −1 in den Baum Ti über dann gilt: amortisierte Kosten = • wir ordnen dazu jedem B-Baum T eine nichtnegative Zahl pot(T ) zu m X Laufzeit(Opi ) + i =1 m X pot(Ti ) − i =1 n X pot(Ti −1 ) i =1 = Gesamtlaufzeit + pot(Tm ) − pot(T0 ) (wird etwas später geeignet spezifiziert) • da pot(T0 ) = 0 und pot(Tm ) ≥ 0, folgt Laufzeit ≤ amortisierte Kosten. 43 / 1 44 / 1 B-Bäume B-Bäume • für den Knoten v bezeichne grad(v) die Anzahl seiner Schlüssel +1 • bei einem inneren Knoten entspricht grad damit der Anzahl der Söhne Damit folgt: • die amortisierten Kosten bilden obere Schranke für die Laufzeit • es reicht, die amortisierten Kosten zu berechnen • amortisierte Kosten können oft besser abgeschätzt werden • für einen Knoten v sei die Balance wie folgt definiert: b(v ) = min{grad(v ) − t , 2t − grad(v )} b ∗ (v ) = min{grad(v ) − 2, 2t − grad(v )} • Wahl der Potentialfunktion entscheidend v nicht Wurzel v Wurzel 45 / 1 46 / 1 B-Bäume B-Bäume Lemma (i) ist grad(v ) = t + k , so ist b(v ) = k für 0 ≤ k ≤ t 2 • (T , v ) heißt teilweise rebalancierter B-Baum, falls gilt: t 2 (iii) ist grad(v ) = 2 + k , so ist b ∗ (v ) = k für 0 ≤ k ≤ t − 1 (ii) ist grad(v ) = 2t − k , so ist b(v ) = k für 0 ≤ k ≤ • T erfüllt in allen Knoten u 6= v die Schlüssel-Bedingung • in v wird die Bedingung um höchstens 1 unter- bzw. überschritten (iv) ist grad(v ) = 2t − k , so ist b ∗ (v ) = k für 0 ≤ k ≤ t − 1 (v) Ist grad(v ) = t − 1 ⇒ b(v ) = −1 • insbesondere sind die folgenden Bäume teilweise rebalanciert: (v) Ist grad(v ) = 2t + 1 ⇒ b(v ) = −1 • jeder B-Baum Beweis: Die Aussagen folgen unmittelbar aus der Definition der Balance: b(v ) = min{grad(v ) − t , 2t − grad(v )} v nicht Wurzel ∗ v Wurzel b (v ) = min{grad(v ) − 2, 2t − grad(v )} Insbesondere ist b(v ) ≤ • die während des Einfügens oder Löschens entstehenden Bäume t und b ∗ (v ) ≤ t − 1. 2 47 / 1 48 / 1 B-Bäume B-Bäume • das Potential von (T , v ) ist X pot(T ) = b ∗ (v ) + Lemma b(u) Sei T ein B-Baum und T 0 der teilweise rebalancierte Baum der nach Hinzufügen oder Löschen eines Schlüssels entsteht. Dann ist u∈T u nicht Wurzel pot(T 0 ) ≥ pot(T ) − 1. Beobachtung: • sei T ein B-Baum • dann ist pot(T ) ≥ 0 • ändert sich der Grad eines Knotens um ±1, • so fällt das Potential des Baums um höchstens 1. Beweis: Für den Knoten v gilt grad(v ) = grad(v ) ± 1 50 / 1 49 / 1 B-Bäume B-Bäume Lemma Lemma Sei (T , v ) ein teilweise rebalancierter Baum mit grad(v ) = 2t + 1. Spalten von v und Expandieren des Vaters von v erzeugt einen teilweise rebalancierten Baum T 0 mit Sei (T , v ) ein teilweise rebalancierter Baum mit grad(v ) = 2t + 1. Spalten von v und Expandieren des Vaters von v erzeugt einen teilweise rebalancierten Baum T 0 mit pot(T 0 ) ≥ pot(T ) + 1. pot(T 0 ) ≥ pot(T ) + 1. Beweis: (i) v ist nicht Wurzel: • • • • • • • Beweis: (ii) v ist die Wurzel: wegen grad(v ) = 2t + 1 ist b(v ) = −1 • da grad(v ) = 2t + 1, folgt b ∗ (v ) = −1 • die neue Wurzel x wird erzeugt, ihr Grad wird 2 • v wird in v 0 und v 00 vom Grad t bzw. t + 1 gespalten sei x der Vater von v v wird in v 0 und v 00 vom Grad t bzw. t + 1 gespalten der Grad von x erhöht sich um eins dabei sinkt die Balance von x um höchstens eins 0 0 pot(T 0 ) = pot(T ) + b(v 0 ) + b(v 00 ) − b ∗ (v ) + b ∗ (x ) 00 damit gilt: pot(T ) ≥ pot(T ) + b(v ) + b(v ) − b(v ) − 1 = pot(T ) + 0 + 1 + 1 + 0 da b(v ) = −1 und b(v 0 ) = 0, b(v 00 ) = 1 folgt ≥ pot(T ) + 1 pot(T 0 ) ≥ pot(T ) + 1. 51 / 1 52 / 1 B-Bäume B-Bäume Beweis: Sei w der neue Knoten mit grad(w ) = 2t − 1. Lemma (a) Sei x nicht Wurzel von T : Sei (T , v ) ein teilweise rebalancierter B–Baum mit grad(v ) = t − 1, wobei v nicht die Wurzel von T ist. Sei y ein benachbarter Bruder von v und x der Vater. • der Grad von x fällt um eins • somit fällt die Balance von x um höchstens eins • es ist b(w ) = 1, b(v ) = −1, b(y ) = 0 • somit: (i) Ist grad(y ) = t , so sei T 0 der Baum nach Verschmelzen von v und y und Schrumpfen von x . Ist x die Wurzel und hat x den Grad 1 nach Schrumpfen, so wird x gelöscht. Dann ist pot(T 0 ) ≥ pot(T ) + 1. (ii) Ist grad(y ) > t , dann sei T 0 der Baum nach Stehlen eines Sohnes von x . Dann gilt pot(T 0 ) ≥ pot(T ). pot(T 0 ) ≥ pot(T ) + b(w ) − b(v ) − b(y ) − 1 ≥ pot(T ) + 1 − (−1) − 0 − 1 = pot(T ) + 1 54 / 1 53 / 1 B-Bäume B-Bäume (b) Sei x die Wurzel von T : • ist grad(x ) ≥ 3, so wird x nach Verschmelzen nicht gelöscht und die (ii) grad(v ) = t − 1, y Bruder, x Vater, grad(y ) > t , T 0 der Baum nach Stehlen eines Sohnes von y =⇒ pot(T 0 ) ≥ pot(T ). Aussage folgt wie vorher. • Ist grad(x ) = 2 (d.h. b ∗ (x ) = 0) vor dem Verschmelzen, so wird x anschließend gelöscht, Beweis: • w wird Wurzel mit b ∗ (w ) = 1. • somit: • die Balance von y sinkt um höchstens 1. • der Grad von v steigt von t − 1 auf t • damit steigt b(v ) um 1 pot(T 0 ) = pot(T ) + b ∗ (w ) − b(v ) − b(y ) − b ∗ (x ) • somit ist pot(T 0 ) ≥ pot(T ). = pot(T ) + 1 − (−1) − 0 − 0 ≥ pot(T ) + 1 55 / 1 56 / 1 B-Bäume B-Bäume Lemma • damit folgt: Sei T ein B-Baum mit m Blättern. Dann ist X pot(T ) = b ∗ (v ) + 0 ≤ pot(T ) ≤ t − 1 + (t − 1) · m b(u) + u innerer Knoten u nicht Wurzel ≤t −1+ Beweis: k X X b(u) u Blatt j · mj + k · m j =0 t 2 • für 0 ≤ j < k sei mj die Anzahl der inneren Knoten vom Grad t + j (ohne Wurzel) • sei k = • m + kj=0 mj ist die Anzahl aller Knoten ohne Wurzel • in T ist die Anzahl der Kanten gleich der Anzahl der Knoten −1 P • 2 + kj=0 (t + j ) · mj ist eine untere Schranke für die Anzahl der Kanten, P • sei mk die Anzahl der inneren Knoten vom Grad ≥ t + k (ohne • d.h. 2 + • somit: Wurzel) • weiter gilt: Pk j =0 (t + j ) · mj ≤ m + Pk j =0 mj k X (t + j − 1) · mj ≤ m − 2 ∗ • b (Wurzel) ≤ t − 1, j =0 • b(Blatt) ≤ k , 57 / 1 58 / 1 B-Bäume • pot(T ) ≤ t − 1 + • Pk j =0 (t Pk j =0 B-Bäume j · mj + k · m Satz + j − 1) · mj ≤ m − 2 • aus 0 ≤ j ≤ k folgt: pot(T ) ≤ t − 1 + Wir betrachten eine Folge von E Einfüge- und L Lösch-Operationen (n = E + L) in einem anfänglich leeren B-Baum T0 . j k ≤ t +j −1 t +k −1 k X Sei KS, KV und KD die Anzahl der Knotenspaltungen, -verschmelzungen und -diebstähle. Dann gilt: j · mj + k · m (i) KD ≤ L ≤ n, j =0 =t −1+ k X j =0 (ii) KS + KV ≤ n + t − 1 + E , j (t + j − 1) · mj + k · m t +j −1 k (m − 2) + k · m t +k −1 t t =t −1+ (m − 2) + · m 3t − 2 2 ≤ t − 1 + (t − 1) · m (iii) die Rebalancierung benötigt ≤t −1+ O(n) Operationen. Beweis: t (da k = ) 2 (i) KD ≤ L ≤ n : • Diebstahl wird höchstens einmal pro Löschoperation durchgeführt. 59 / 1 √ 60 / 1 B-Bäume B-Bäume (ii) KS + KV ≤ n + t − 1 + E : • für den leeren Baum T0 gilt pot(T0 ) = 0 • der letzte Baum Tn hat höchstens (i) KD ≤ S ≤ n E Blätter t −1 (ii) KS + KV ≤ n + t − 1 + E • nach vorigem Lemma ist pot(Tn ) ≤ t − 1 + (t − 1) · (iii) die Rebalancierung benötigt E t −1 O(n) Operationen Beweis von (iii): • die Balance • sinkt beim Einfügen/Löschen eines Schlüssels um höchstens 1 • steigt bei einer Spaltung um mindestens 1 • jede einzelne Operation von KD, KV und KD benötigt konstante Zzeit • nach (i) ist KD ≤ n • nach (ii) ist KS + KV ≤ n + t − 1 + E • steigt bei einer Verschmelzung um mindestens 1 • damit folgt: • somit: pot(Tn ) ≥ pot(T0 ) + KS + KV − n • da pot(T0 ) = 0, folgt: KS + KV ≤ n + t − 1 + E . KD + KS + KV ≤ 2n + t − 1 + n = O(n). √ 61 / 1 62 / 1 B-Bäume B-Bäume Gliederung • Definitionen und Eigenschaften • die Aussagen über B-Bäume gelten auch etwas allgemeiner: • Einfügen und Löschen in B-Bäumen • seien a, b ∈ N mit a ≥ 2 und b ≥ 2a − 1 • in einem (a, b)-Baum haben alle Knoten (bis auf die Wurzel) • Vereinigen und Spalten von B-Bäumen • Laufzeit der dynamischen Verwaltung mindestens a und höchstens b Söhne • zwei Anwendungen • B-Bäume sind (t , 2t )-Bäume • Sortieren von vorsortierten Daten • kürzeste Wege in Graphen 63 / 1 64 / 1 B-Bäume B-Bäume Vorgehen des Algorithmus: • wir verwenden einen B-Baum, der als Blattsuchbaum organsiert ist, d.h. • wir haben gesehen, dass die bisher behandelten Sortierverfahren eine Vorsortierung der Daten nicht ausnützen • der B-Baum wird um Blätter erweitert • unter Umständen benötigen sie sogar maximale Laufzeit bei bereits • die inneren Knoten entsprechen damit einem B-Baum vollständig sortierten Eingabedaten • zur Erinnerung: • sei x1 , . . . , xn eine Eingabefolge, die aufsteigend sortiert werden soll • für jedes i sei fi := |{xj : j > i , xj < xi }| die Anzahl der Inversionen 4 10 16 13 von i • die Inversionszahl der Folge sei F := ni=1 fi • die Folge x1 < . . . < xn hat F = 0, die Folge x1 > . . . > xn hat P 1 6 9 3 11 14 12 15 Inversionszahl F = n(n − 1)/2. 1 3 4 5 7 10 11 12 13 14 15 16 65 / 1 66 / 1 B-Bäume 4 10 B-Bäume 16 13 Vorgehen des Algorithmus: 1 1 3 6 9 3 4 5 7 11 10 11 12 14 12 13 14 15 15 (1) füge xn in einen leeren B-Baum ein (2) füge xi in den Baum mit den Blättern xi +1 . . . xn ein: 16 • wenn die Folge fast sortiert ist, wird xi sehr weit links eingefügt werden • weitere Eigenschaften von Blattsuchbäumen müssen: (3) gehe die linke Schulter hinauf durch die inneren Knoten v1 , v2 , . . . • jedes Blatt nimmt genau einen Schlüssel auf • interne Knoten speichern lediglich Informationen für die Suche • bis zum ersten Mal xi ≤ c1 (vj ) oder die Wurzel erreicht ist • d.h. xi muss im linkesten Unterbaum von vj , nicht aber im linkesten • (z.B. den maximalen Schlüssel im linken Teilbaum) • jeder Knoten wird um einen Sohn-Vater-Zeiger erweitert Unterbaum von vj −1 abgespeichert werden (4) suche von vj aus abwärts nach xi • die Schlüssel in den Blättern seien von links nach rechts aufsteigend sortiert (5) füge xi ein und rebalanciere • die Aussagen über mittlere Laufzeiten lassen sich auf Blattsuchbäume übertragen 67 / 1 68 / 1 B-Bäume B-Bäume Laufzeit für das Einfügen von xi : Laufzeitanalyse: O(Höhe(vj ) + KSi ) Zur Abschätzung von Höhe(vj ): (i) entweder j = 1, 2 ⇒ Höhe(vj ) = 1, 2 O(Höhe(vj )) O(Höhe(vj )) O(1) O(KSi ) Hinauflaufen Suche Einfügen Rebalancieren (ii) oder j ≥ 3 : • die Inhalte der Blätter im ersten Unterbaum von vj −1 sind kleiner als xi • d.h. die Inhalte der Blätter im Unterbaum Tvj −2 sind kleiner als xi • dann folgt mit früherem Lemma hierbei sei: fi ≥ # Blätter in Tvj −2 ≥ 2t Höhe(vj −2 ) • Höhe(vj ) die (unbekannte) Höhe des Knotes vj • KSi die (unbekannte) Anzahl an Spaltungen nach Einfügen von xi • somit Höhe(vj ) = Höhe(vj −2 ) + 2 = O(log fi ) • damit ist in beiden Fällen Höhe(vj ) = O(log fi + 1). 70 / 1 69 / 1 B-Bäume B-Bäume Beweis: • nach den obigen Bemerkungen ist der Zeitbedarf für das Sortieren Für die folgende Aussage benötigen wir einen Hilfssatz: durch Einfügen: O(n + Lemma log(fi + 1) + i =1 fi ≥1 Seien xi ∈ R+ für 1 ≤ i ≤ n. Dann ist das geometrische Mittel kleiner gleich dem arithmetischen Mittel: n X KSi ) i =1 • nach früherem Satz ist ni=1 KSi = O(n). • weiter gilt mit vorigem Lemma: P n n ”1 “Y 1X n xi xi . ≤ n i =1 n X i =1 n X i =1 Satz log(fi + 1) = log n “Y ” (fi + 1) i =1 n ” “1 X ≤ n log (fi + 1) n Eine Folge von n Elementen mit Inversionszahl F kann in F O(n + n log(1 + )) Schritten sortiert werden. n i =1 = n log(1 + F ). n Beispielsweise erhalten wir für F = n log n eine Laufzeit von O(n log log n). 71 / 1 72 / 1 B-Bäume B-Bäume • sei G = (V , E ) ein gerichteter Graph mit Knotenmenge V und Kantenmenge E • Entfernungen ce ≥ 0 für e ∈ E • zusätzlich sei ein Knoten s ∈ V ausgezeichnet Gliederung • Definitionen und Eigenschaften v1 • Einfügen und Löschen in B-Bäumen 9 5 7 • Vereinigen und Spalten von B-Bäumen s 6 • zwei Anwendungen v3 2 v4 3 • Sortieren von vorsortierten Daten v2 • kürzeste Wege in Graphen • ein Weg von v ∈ V nach w ∈ V ist eine Folge v0 , v1 , . . . , vk von Knoten, so dass • v0 = v , vk = w , • (vi , vi +1 ) ∈ E für 0 ≤ i ≤ k − 1 Pk −1 • der Weg hat die Länge i =0 c(i ,i +1) . 73 / 1 74 / 1 B-Bäume B-Bäume Dijkstra-Algorithmus gesucht: kürzeste Wege von s zu allen anderen Knoten. (1) setze Idee des Verfahrens Dist(s) := 0, • wir vergrößern schrittweise eine Menge M von Knoten • für Knoten v ∈ M haben wir bereits einen kürzesten Weg von s nach Dist(v ) := c(s, v ) und Vor(v ) := s für (s, v ) ∈ E Dist(v ) := +∞ und Vor(v ) := ∅ für (s, v ) ∈ /E v gefunden M = {s} • allen anderen Knoten v ∈ / M ordnen wir die Länge des bisher (2) bestimme u ∈ / M mit Dist(u) = min{Dist(v ) : v ∈ / M} gefundenen kürzesten Weges zu (3) setze M = M ∪ {u} • sei (4) für alle v ∈ V mit (u, v ) ∈ E (5) falls Dist(v ) > Dist(u) + c(u, v ) Dist(v ) = Länge des (bisherigen) kürzesten Weges setze Dist(v ) = Dist(u) + c(u, v ) Vor(v ) = Vorgänger auf so einem Weg Vor(v ) = u (6) falls M 6= V , gehe zu (2) 75 / 1 76 / 1 B-Bäume B-Bäume Beweis: • angenommen, es existieren Knoten u und v , so dass u vor v aufgenommen wird, aber d (u) > d (v ) gilt • die Menge M scheint sich „kreisförmig“ um den Startknoten • unter allen diesen v ’s wähle das als erste in M aufgenommene • in dem Moment, in dem u aufgenommen wird, gilt s auszubreiten • sei d (u) der Wert von Dist(u) zu dem Zeitpunkt, zu dem u in die d (u) = Dist(u) ≤ Dist(v ) Menge M aufgenommen wird. • da per Definition d (u) nicht mehr verändert wird, muss später Dist(v ) verringert worden sein Lemma • dies kann nur passieren, wenn ein Knoten w in M aufgenommen und Wird u vor v in M aufgenommen, so gilt d (u) ≤ d (v ). Dist(v ) = Dist(w ) + c(w , v ) gesetzt wird • sei w der letzte solche Knoten, d.h. es gilt d (v ) = d (w ) + c(w , v ). • nach Wahl von v gilt aber d (u) ≤ d (w ) • da c(w , v ) ≥ 0, folgt d (v ) ≥ d (u). 77 / 1 78 / 1 B-Bäume B-Bäume Lemma • wenn das Verfahren korrekt ist, muss am Schluß für alle Kanten Nach Beendigung des Verfahrens gilt für alle Kanten (u, v ) ∈ E : (u, v ) gelten: Dist(v ) ≤ Dist(u) + c(u, v ) Dist(v ) ≤ Dist(u) + c(u, v ). • andernfalls wäre es kürzer über u und die Kante (u, v ) nach v zu gehen • das folgende Lemma zeigt, dass das Verfahren diese notwendige Beweis: Bedingung erfüllt: • die Aussage gilt direkt nach der Iteration, in der u aufgenommen wird • angenommen sie gilt später nicht mehr • da Dist(v ) nicht wächst, muss Dist(u) verringert worden sein • d.h. es gilt Dist(u) < d (u) Lemma Nach Beendigung des Verfahrens gilt für alle Kanten (u, v ) ∈ E : • dies kann nur passieren, wenn ein Knoten w in M aufgenommen und Dist(v ) ≤ Dist(u) + c(u, v ). Dist(u) = d (w ) + c(w , u) gesetzt wird • nach dem ersten Lemma ist d (w ) ≥ d (u) • da c(w , u) ≥ 0 folgt Dist(u) ≥ d (u). 79 / 1 80 / 1 B-Bäume B-Bäume aus dem zweiten Lemma folgt: • daraus folgt unmittelbar die Korrektheit des Verfahrens: • sobald u in M aufgenommen wird: Satz • ist ein kürzester Weg gefunden worden Der Dijkstra-Algorithmus berechnet kürzeste Wege von s zu allen anderen erreichbaren Knoten. • und der Wert Dist(u) ändert sich nicht mehr • es reicht daher, die eine kleinere Menge U zu verwalten Beweis: • diese Front U besteht aus allen Knoten: • wir zeigen per Induktion über die Anzahl der Knoten auf einem • für die bereits ein Weg gefunden wurde kürzesten Weg, dass die notwendige Bedingung auch hinreichend ist • der jedoch noch nicht der kürzeste sein muss • die Aussage ist sicherlich richtig für s • sei jetzt v ein Knoten und u ein Vorgänger auf einem kürzesten Weg • per Induktion können wir annehmen, dass Dist(u) die Länge eines kürzesten Wegs von s nach u ist M • da Dist(v ) ≤ Dist(u) + c(u, v ), ist dann Dist(v ) die Länge eines U s kürzesten Weges nach v . 81 / 1 82 / 1 B-Bäume B-Bäume Dijkstra-Algorithmus Dist(s) := 0, U = s for v ∈ Vrs do Dist (v) = + ∞, Vor(v)=Null endfor while U 6= ∅ wähle u ∈ U mit Dist(u) minimal U := Uru for all (u, v) in E do if Dist(u) + c(u, v) < Dist(v) then Dist(v) = Dist(u) + c(u,v), Vor (v) = u, U := U ∪ v endif endfor endwhile Wir benötigen Datenstrukturen zur effizienten Verwaltung: • des Graphen, • der Distanz Dist (v ) • des Vorgängers Vor (v ) eines Knotens • sowie der Front U 83 / 1 84 / 1 B-Bäume B-Bäume Datenstrukturen • Adjazenzliste Feld Tail(1, . . . , n) • Tail(i ) zeigt auf Beginn einer verketteten Liste, die die Endknoten und Datenstrukturen • Felder Dist[1, . . . , n], Vor[1, . . . , n] Kosten von Kanten (i , j ) ∈ E enthält. • ein ungeordneter B-Baum für die Menge {(Dist (u), u) : u ∈ U } mit: 2 4 1 - die Blätter enthalten die Elemente (Dist (u), u) in beliebiger 3 Reihenfolge, - jeder innere Knoten v enthält einen Zeiger auf das Blatt von Tv , 5 das minimalen Distanzwert hat • zusätzlich Zeigerfeld Pointer(1 . . . n) auf das Blatt, das Knoten 1 2 2 C12 3 C23 u enthält, bzw. Pointer(u) = Null, falls u ∈ /U 4 5 3 4 5 3 5 1 86 / 1 85 / 1 B-Bäume B-Bäume Dijkstra-Algorithmus Dist(s) := 0, U = s for v ∈ Vrs do Dist (v) = + ∞, Vor(v)=Null endfor while U 6= ∅ wähle u ∈ U mit Dist(u) minimal U := Uru for all (u, v) in E do if Dist(u) + c(u, v) < Dist(v) then Dist(v) = Dist(u) + c(u,v), Vor (v) = u, U := U ∪ v endif endfor endwhile Der Algorithmus führt folgende Operationen aus: • finde Min • lösche Min • füge ein • verringere Inhalt eines Blattes mit Zeiger 87 / 1 88 / 1 B-Bäume B-Bäume Laufzeiten • finde Min: in O(1) Laufzeiten • füge_ein mit Fortschreibung des Minimums: in O(Höhe(T )) • lösche Min: in O(t · Höhe(T )) • beim Zurückgehen zur Wurzel wird: • rebalanciert • lösche das Blatt, das das Minimum enthält • durchlaufe alle Brüder des Blattes, um das neue Minimum unter ihrem Vater zu bestimmen ; O(t ) • beim Zurückgehen zur Wurzel wird: • und das alte Minimum mit dem neuem Wert verglichen • verringern: analog in O(Höhe(T )) • rebalanciert • jeweils in O(t ) Schritten das Minimum fortgeschrieben 89 / 1 90 / 1 B-Bäume B-Bäume Zur Erinnerung: Für die Höhe in einem B-Baum der Ordnung t gilt: Höhe(T ) = O(log n/ log t ) Wie oft werden die Operationen durchgeführt? • finde Min: höchstens n mal Satz • lösche Min: höchstens n mal Der Dijkstra-Algorithmus mit ungeordneten B-Bäumen hat eine Laufzeit von • einfügen mit Fortschreibung des Minimums: höchstens n mal O(tn log n/ log t + m log n/ log t ) • verringern: höchstens m mal 91 / 1 92 / 1 B-Bäume B-Bäume alternative Implementierung mit Eimern Bemerkungen zur Wahl von t • sei C der größte Wert auf einer Kante • die Länge eines kürzesten Weg ist nicht länger als (n − 1)C • eröffne (n − 1)C + 2 Eimer • m =O(n 2 ): • wähle t = n. Dann hat der Dijkstra-Algorithmus eine Laufzeit von O(n 2 ) und der Baum wird zum Feld • der Eimer i enthält alle Knoten u mit Dist(u) = i , i = 0, . . . (n − 1)C • der Eimer (n − 1)C + 2 enthält alle Knoten u mit Dist(u) = ∞ • m = O(n): • wähle t = 2. Dann hat der Dijkstra-Algorithmus eine Laufzeit von O(n log n) • finde min: suche den ersten nichtleeren Eimer k • lösche min: dessen Elemente werden nach und nach in • allgemein: M aufgenommen • wähle t = max{2, mn }. Dann hat der Dijkstra-Algorithmus eine Laufzeit von O(m log n/ max{1, log mn }). • verringere: verringert sich der Distanzwert eines Knotens, so wird er in einen „kleineren” Eimer verlegt • ist der Eimer k geleert, beginnt die Suche beim Eimer k + 1 93 / 1 94 / 1 B-Bäume B-Bäume Beweis: per Induktion über die Schritte des Algorithmus: • die Anzahl der Eimer kann deutlich verringert werden, wenn wir √ lediglich die Front verwalten • am Anfang ist U = {s} • sei die Aussage richtig, bevor ein Knoten u aus U entfernt wird • da u entfernt wird, war Dist(u) minimal unter allen Knoten in U • sei U die Front und die „Dicke” der Front gegeben durch: d = max{Dist(u) − Dist(v ) : u, v ∈ U } • d.h. es galt Dist(v ) ≤ Dist(u) + C für alle v ∈ U • damit gilt die Behauptung für alle alten Knoten in U • für die neu aufgenommenen Knoten v gilt per Konstruktion: Lemma Dist(v ) ≤ Dist(u) + C Die Front U ist nie dicker als C. • somit gilt die Behauptung auch im nächsten Schritt. 95 / 1 96 / 1 B-Bäume B-Bäume • die Menge M wächst konzentrisch um den Startknoten s Flensburg Wir können somit die Eimer wie einen Ringpuffer verwalten. 58 26 Kiel 21 23 Heide Cuxhaven Wilhelmshaven Korollar 55 65 48 Hannover 146 Berlin 147 Magdeburg 85 188 155 168 130 Kassel 73 Köln 71 78 56 Bemerkung: Das Eimer-Verfahren ist in der Praxis (für kleine C) sehr 234 70 Dresden 249 148 Frankfurt 94 177 114 214 Leipzig 69 55 174 172 Frankfurt/Oder 108 162 Dortmund Aachen 114 165 63 Bremen 105 Osnabrück 87 Rostock 75 Hamburg 123 10 119 Lübeck 65 106 Oldenburg Das Eimer-Verfahren hat eine Laufzeit von O(m + nC). 80 108 219 23 Würzburg 65 effizient. 104 75 Mannheim 81 70 86 72 Nürnberg 70 Karlsruhe 53 50 Stuttgart 91 163 103 Augsburg 233 Ulm 147 60 53 Basel 47 Singen Lindau 120 40 Kempten 64 München 85 Garmisch 97 / 1 98 / 1 B-Bäume B-Bäume Idee des bidirektionalen Verfahrens • ist G dicht, so wächst M quadratisch mit der Entfernung zu s • sei r die Länge des kürzesten Weges von s nach t • dann ist verhält sich M ungefähr wie r 2 • die Menge M wächst konzentrisch um den Startknoten s • dabei werden viele Knoten besucht, die „offensichtlich” nicht auf einem kürzesten Weg liegen • wir berechnen abwechselnd kürzeste Wege von s und nach t und umgekehrt • zwei Verbesserungen: • dies erzeugt Mengen M und M 0 • wir zeigen gleich, dass das Verfahren abbrechen kann, sobald ein • bidirektionales Vorgehen • future-cost-Verfahren Knoten u ∈ M ∩ M 0 liegt • dabei werden zwei Kreise vom Radius ≈ 0 • |M ∪ M | ≈ 2 · 99 / 1 ` r ´2 2 = r 2 erzeugt r2 2 100 / 1 B-Bäume • sei u der erste Knoten in M ∩ M 0 • sei P ∗ ein kürzester (s, t )-Weg • sei d (v ) die Länge eines kürzesten (s, v )-Wegs • sei d 0 (v ) die Länge eines kürzesten (v , t )-Wegs • sei v der erste Knoten auf P ∗ B-Bäume v w t s u • es ist: mit der Eigenschaft: • alle Knoten bis einschließlich v liegen in M • l (P ∗ ) = d (v ) + c(v , w ) + d 0 (w ) • d (v ) = Dist(v ) ≤ Dist(u) = d (u) • der nächste Knoten w auf P liegt nicht in M (da v bereits in M ) • Dist(v ) + c(v , w ) ≥ Dist(w ) ≥ Dist(u) (da w ∈ / M) • angenommen: w ∈ / M 0 . Da die Distanzen monoton wachsen, ist: v w • d 0 (w ) ≥ d 0 (u) • somit: t s l (P ∗ ) = d (v ) + c(v , w ) + d 0 (w ) ≥ Dist(u) + d 0 (u) = d (u) + d 0 (u) u 102 / 1 101 / 1 B-Bäume B-Bäume Idee des Future-Cost-Verfahrens • daher kann das Verfahren abbrechen, sobald ein Knoten u in • der Graph bestehe aus dem Fernstraßennetz der Bundesrepublik • wir suchen den kürzesten Weg von Köln nach München • es genügt, den Dijkstra-Algorithmus zu stoppen, sobald der Knoten M ∩ M 0 aufgenommen wird • ein kürzester Weg ist dann: • der kürzeste Weg von s über u nach t „München” in M liegt oder • ein kürzester Weg von s nach v ∈ M , • eine Kante (v , w ) • allerdings ist dann bereits z.B. Hamburg in M aufgenommen, da es • und ein kürzester Weg von w ∈ M 0 nach t • obwohl allein die Luftlinien-Entfernung zwischen Hamburg und näher an Köln liegt als München München größer ist als der Weg von Köln nach München • d.h. nach O(m) weiteren Schritten ist ein kürzester Weg berechnet. • wir versuchen, solche leicht berechenbaren unteren Schranken (wie hier die Luftlinie) zur Vermeidung unnötiger Berechnungen zu nutzen 103 / 1 104 / 1 B-Bäume B-Bäume • sei c 0 (v , w ) := c(v , w ) + f (w , t ) − f (v , t ) für alle v , w ∈ V • es ist c 0 (v , w ) ≥ 0 für alle v , w ∈ V , denn: future costs • sei f : V × V → R+0 eine Funktion mit c 0 (v , w ) = c(v , w ) + f (w , t ) − f (v , t ) ≥ f (v , w ) + f (w , t ) − f (v , t ) • f (v , v ) = 0 für alle v ∈ V • f (v , w ) + f (w , x ) ≥ f (v , x ) für alle v , w , x ∈ V ≥0 • für alle v , w ∈ V ist f (v , w ) eine untere Schranke für die Länge des kürzesten Weges von v nach w • weiter gilt für alle Wege P von s nach t : c 0 (P ) = c(P ) − f (s, t ) • der kürzeste Weg von s nach t bzgl. c entspricht einem kürzesten Weg bzgl. c 0 • damit ist es äquivalent, den Algorithmus bzgl. der Kosten c 0 laufen zu lassen 105 / 1 106 / 1 B-Bäume B-Bäume • entsprechend gilt Dist0 (u) = Dist(u) − f (s, t ) + f (u, t ) für alle Knoten • der Dijkstra-Algorithmus setzt voraus, dass alle Kanten nichtnegative u∈V Gewichte tragen • d.h. die untere Schranke für die restliche Entfernung f (u, t ) wird auf • wir werden diese Einschränkung im folgenden aufheben die Kosten Dist(u) addiert • sei dazu dk (v ) die Länge eines kürzesten Weges von s nach v , der • Knoten mit großer Entfernung zu t werden vermieden maximal k Kanten benutzt • je schärfer die untere Schranke f ist, desto effektiver arbeitet das • wir setzen dk (v ) = ∞, wenn kein solcher Weg existiert Verfahren • dann ist dn−1 (t ) die Länge eines kürzesten (s, t )-Weges • im schlechtesten Fall (f = 0) reduziert sich das Verfahren auf den klassischen Dijkstra • wir lassen das Verfahren aus Gründen, die weiter unten klar werden, aber bis n laufen • im günstigsten Fall (f (v , w ) ist minimale Weglänge von v nach w ) werden nur Knoten auf kürzesten Wegen besucht 107 / 1 108 / 1 B-Bäume B-Bäume Bellman-Ford-Verfahren Satz (1) setze d0 (s) = 0 und d0 (v ) = ∞ für alle v ∈ V r s. Sei G = (V , E ) ein gerichteter Graph ohne negative Kreise. Dann berechnet der Algorithmus von Bellman-Ford kürzeste Wege in O(mn) Schritten. (2) for k = 1, . . . , n do for v ∈ V r s do (3) dk +1 (v ) := min{dk (v ), dk (u) + c(u, v ) : (u, v ) ∈ E } (4) (5) Der Bellman-Ford-Algorithmus kann auch verwandt werden, um einen end do negativen Kreis zu entdecken: (6) end do 109 / 1 B-Bäume Satz Sei G = (V , E ) ein gerichteter Graph mit einer allgemeinen Kantenbewertung. Dann kann in O(mn) Schritten ein von s aus erreichbarer negativer Kreis gefunden werden, wenn ein solcher existiert. Beweis: • ist dn−1 (u) = dn (u) für alle u ∈ V , so kann kein negativer Kreis existieren, der von s aus erreicht werden kann • sei jetzt dn−1 (u) 6= dn (u) für ein u ∈ V • dann ist dn (u) < dn−1 (u) • und es existiert ein (s, u)-Pfad P der n Kanten benutzt • daher muss P einen Kreis C enthalten • wenn wir C aus P entfernen, erhalten wir einen (s, u)-Pfad P 0 , der weniger als n Kanten benützt • dann folgt l (P 0 ) ≥ dn−1 (u) > dn (u) = l (P ) = l (P 0 ) + l (C) • somit l (C) < 0, d.h. G enthält einen negativen Kreis. 111 / 1 110 / 1