GIN2 – 2. Vorlesung, SS04 Prof. Dr. Wolfram Conen 1.4.2004 Rund um Dijkstra: - Bucket/Radix-Sort - Priority Queues - Heap 01.04.2004 (c) W. Conen, FH GE, GIN2 1 Schnelles Sortieren 6 12 5 9 10 11 1 2 4 8 3 7 1 2 3 4 5 6 7 8 9 10 11 12 Situation: n (Schlüssel-)Werte aus [1,n] Keine Duplikate. Kosten? O(n) 01.04.2004 (c) W. Conen, FH GE, GIN2 2 Schnelles Sortieren: BucketSort 6 12 5 9 6 10 11 1 Töpfe: Ergebnis: 1 6 5 6 9 10 11 12 1 5 6 6 9 10 11 12 Situation: m Töpfe, Schlüsselwerte aus [1,m], Duplikate 01.04.2004 (c) W. Conen, FH GE, GIN2 3 Schneller Sortieren: BucketSort in mehreren Phasen (Radixsort) Situation: n Werte aus [0,,nk-1], Duplikate möglich Kosten normaler Bucketsort: O(n+nk) Idee: Wir wenden ihn mehrfach an! Beispiel: n Werte aus [0,,n2-1], m = n 1. Phase: Werti einfügen in Bk mit k = Werti MOD m 2. Phase: Ergebnisliste durchlaufen, Werti nach Bk mit k = Werti DIV m, dort am ENDE anfügen 01.04.2004 (c) W. Conen, FH GE, GIN2 4 Schneller Sortieren: BucketSort in mehreren Phasen Beispiel: n = 10, Werte aus [0,,99], 1. Phase 3 18 24 6 47 7 56 34 98 60 3 MOD 10 = 3 18 MOD 10 = 8 Töpfe: 60 24 3 34 6 47 18 56 7 98 Ergebnis 1. Phase: 60 3 24 34 6 5 47 7 18 98 01.04.2004 (c) W. Conen, FH GE, GIN2 5 Schneller Sortieren: BucketSort in mehreren Phasen Beispiel: n = 10, Werte aus [0,,99], 2. Phase 60 3 24 34 6 56 47 7 18 98 60 DIV 10 = 6 18 DIV 10 = 1 Töpfe: Ergebnis: 01.04.2004 3 6 7 18 24 34 47 56 60 98 3 6 7 18 24 34 47 56 60 98 (c) W. Conen, FH GE, GIN2 6 Bucket/Radix Sort: Review • Wenn wir die Größe des Schlüsselbereichs als Konstante ansehen, dann sortieren wir zu Kosten von O(n) • Aus einer sortieren Folge können wir zu Kosten von O(1) das minimale Element finden und entnehmen • Aber Dijkstra verändert ja auch noch die Distanz-Werte der Knoten... 01.04.2004 (c) W. Conen, FH GE, GIN2 7 Priority Queues • INSERT: Warteschlangen, in die Elemente gemäß einer Priorität eingeordnet werden • DELETE MIN: Es wird jeweils das Element höchster Priorität entnommen (das soll das Element mit dem minimalen Wert sein) • Für uns noch wichtig: DECREASE KEY – der Wert eines Knotens verringert sich! • Das sind genau die Operationen, die wir im Dijkstra brauchen: Initialer Aufbau des Queues (INSERT), Updates der Knotenwerte (DECREASE KEY), Entnahme des „besten“ Knotens (DELETE MIN) 01.04.2004 (c) W. Conen, FH GE, GIN2 8 Priority Queues • Genauer: – INSERT(Q,v): Füge Knoten v mit Wert Wert(v) in Priority-Queue Q ein – (Q,v*) à DELETE MIN(Q): Liefere den Knoten mit dem minimalen Wert und lösche ihn aus dem PriorityQueue Q, liefere Q zurück – Q à DECREASE KEY(Q,v,Wert): Verringere den (Schlüssel-)Wert des Knotens v auf Wert. 01.04.2004 (c) W. Conen, FH GE, GIN2 9 Priority Queues: Implementierung • Wie kann man das effizient implementieren? • Z.B. mittels eines sogenannte Heaps! (wir betrachten zunächst nur die Operationen INSERT und DELETE MIN) • Was ist ein Heap (=Haufen)? Das ist ein partiellgeordneter Baum: Definition: Ein partiell-geordneter (binärer) Baum ist ein knotenmarkierter binärer Baum T, in dem für jeden Teilbaum T´ mit Wurzel w gilt: 8 y 2 T´: Wert(w) · Wert(y) 01.04.2004 (c) W. Conen, FH GE, GIN2 10 Partiell-geordneter Baum (Schlüssel-)Werte: 4 6 6 7 10 10 12 13 13 19 4 6 10 12 13 6 19 13 10 7 Alle Wurzeln erfüllen die Bedingung! Ist der Baum eindeutig? 01.04.2004 (c) W. Conen, FH GE, GIN2 11 Partiell-geordneter Baum (Schlüssel-)Werte: 4 6 6 7 10 10 12 13 13 19 4 6 10 12 13 6 19 7 10 13 Alle Wurzeln erfüllen die Bedingung! Aber der Baum ist nicht mehr „balanciert“! 01.04.2004 (c) W. Conen, FH GE, GIN2 12 Heap: INSERT • Wir betrachten linksvollständige partiell geordnete Bäume: – alle Ebenen bis auf die letzte sind voll besetzt – auf der letzten Ebene sitzen die Knoten soweit links wie möglich 01.04.2004 Algorithm INSERT(Q,v) Füge v auf der ersten freien Position der untersten Ebene ein (wenn voll, neue Ebene beginnen) p à Vater(v) Solange p existiert und Wert(v) < Wert(p) tue Vertausche die Werte von p und v; v à p; p à Vater(p) (c) W. Conen, FH GE, GIN2 13 Heap: INSERT Algorithm INSERT(Q,v) Füge v auf der ersten freien Position der untersten Ebene ein (wenn voll, neue Ebene beginnen) p à Vater(v) Solange p existiert und Wert(v) < Wert(p) tue Vertausche die Werte von p und v; v à p; p à Vater(p) Einfügen von 5 4 6 p! 12 13 10 19 6 7 13 5 10 Ãv Wert(v) < Wert(p)? Klar! Also: Vertauschen! 01.04.2004 (c) W. Conen, FH GE, GIN2 14 Heap: INSERT Algorithm INSERT(Q,v) Füge v auf der ersten freien Position der untersten Ebene ein (wenn voll, neue Ebene beginnen) p à Vater(v) Solange p existiert und Wert(v) < Wert(p) tue Vertausche die Werte von p und v; v à p; p à Vater(p) Einfügen von 5 4 6 Ãp v! 12 13 19 10 5 7 13 10 6 Wert(v) < Wert(p)? Klar! Also: Vertauschen! 01.04.2004 (c) W. Conen, FH GE, GIN2 15 Heap: INSERT Algorithm INSERT(Q,v) Füge v auf der ersten freien Position der untersten Ebene ein (wenn voll, neue Ebene beginnen) p à Vater(v) Solange p existiert und Wert(v) < Wert(p) tue Vertausche die Werte von p und v; v à p; p à Vater(p) Einfügen von 5 p! 4 5 Ãv 12 13 10 6 19 7 13 10 6 Wert(v) < Wert(p)? Nein! Also: Fertig! 01.04.2004 (c) W. Conen, FH GE, GIN2 16 Heap: INSERT Algorithm INSERT(Q,v) Füge v auf der ersten freien Position der untersten Ebene ein (wenn voll, neue Ebene beginnen) p à Vater(v) Solange p existiert und Wert(v) < Wert(p) tue Vertausche die Werte von p und v; v à p; p à Vater(p) 01.04.2004 Ist INSERT korrekt? Wir betrachten eine einzelne Vertauschung der Werte von v und p, es gilt also Wert(v) < Wert(p). Wert(p) ist minimal bzgl. aller Unterbäume von p (und damit aller Unterbäume von v – das gilt auch nach dem Positionswechsel!) Wg. Wert(v) < Wert(p) ist dann auchWert(v) nach Vertauschung minimal für alle Unterbäume, also ist der neue Baum partiell geordnet (unter der Annahme, dass der Ausgangsbaum partiell geordnet war). (c) W. Conen, FH GE, GIN2 17 Heap: DELETE MIN Algorithm DELETE MIN (Q): (Q, Min) Sei w die Wurzel des Heaps mit den Söhnen s1, s2; Min à Wert(w) Sei k der letzte Knoten (unten, rechts) Wert(w) à Wert(k); Lösche k; Solange s1 oder s2 existieren und (Wert(w) > Wert(s1) oder Wert(w) > Wert(s2)) tue Vertausche den Wert von w mit dem kleineren Wert der beiden Söhne, dieser Sohn sei s; w à s; s1 à Linker_Sohn(w); s2 à Rechter_Sohn(w) Gib Q und Min zurück. 01.04.2004 Entfernen des Minimums: w! 4 5 10 12 13 (c) W. Conen, FH GE, GIN2 6 19 7 13 10 6 Ãk 18 Heap: DELETE MIN Algorithm DELETE MIN (Q): (Q, Min) Entfernen des Minimums: Sei w die Wurzel des Heaps mit den Söhnen s1, s2; Min à Wert(w) w! 6 Sei k der letzte Knoten (unten, rechts) Wert(w) à Wert(k); Lösche k; Solange s1 oder s2 existieren und s = s1 ! s2 ! 10 5 (Wert(w) > Wert(s1) oder Wert(w) > Wert(s2)) tue Vertausche den Wert von w mit 12 6 13 10 dem kleineren Wert der beiden Söhne, dieser Sohn sei s; w à s; 13 19 7 s1 à Linker_Sohn(w); s2 à Rechter_Sohn(w) Gib Q und Min zurück. Bedingung für s = s1erfüllt! Also: Tauschen 01.04.2004 (c) W. Conen, FH GE, GIN2 19 Heap: DELETE MIN Algorithm DELETE MIN (Q): (Q, Min) Entfernen des Minimums: Sei w die Wurzel des Heaps mit den Söhnen s1, s2; Min à Wert(w) 5 Sei k der letzte Knoten (unten, rechts) Wert(w) à Wert(k); Lösche k; Solange s1 oder s2 existieren und w! 6 10 (Wert(w) > Wert(s1) oder Wert(w) > Wert(s2)) tue Vertausche den Wert von w mit s1 ! 12 s2 ! 6 13 10 dem kleineren Wert der beiden Söhne, dieser Sohn sei s; w à s; 13 19 7 s1 à Linker_Sohn(w); s2 à Rechter_Sohn(w) Gib Q und Min zurück. Bedingung nicht erfüllt! Also: Fertig! 01.04.2004 (c) W. Conen, FH GE, GIN2 20 Heap: DELETE MIN Algorithm DELETE MIN (Q): (Q, Min) Ist DELETE MIN korrekt? Sei w die Wurzel des Heaps mit den Wir betrachten eine einzelne Söhnen s1, s2; vertauschung der Werte von w und s, es gilt also Wert(s) < Wert(w). Min à Wert(w) Sei k der letzte Knoten (unten, rechts) Wert(s) ist minimal bzgl. aller Wert(w) à Wert(k); Lösche k; Unterbäume von s. Es wurde Solange s1 oder s2 existieren und ausgewählt, also ist es auch (Wert(w) > Wert(s1) oder Wert(w) > minimal im Vergleich zum anderen Wert(s2)) tue Kind-Baum – das gilt auch nach Vertausche den Wert von w mit dem Positionswechsel!) dem kleineren Wert der beiden Söhne, dieser Sohn sei s; w ist möglicherweise nicht minimal w à s; für seinen Unterbaum. Das wird s1 à Linker_Sohn(w); aber weiterbehandelt (w sinkt dann s2 à Rechter_Sohn(w) weiter!) bis schließlich Wert(w) · Gib Q und Min zurück. Wert(s1) und Wert(w) · Wert(s2). 01.04.2004 (c) W. Conen, FH GE, GIN2 21 Priority Queue • Mit dem Heap lassen sich INSERT und DELETE MIN mit Aufwand O(log n) realisieren! • Das gleiche gilt für Updates, also DECREASE KEYOperationen (analog zu INSERT plus schnelles Auffinden, kommt noch)! • Damit können wir (für sparsam besetzte Graphen) Dijkstra verbessern! • Wie es noch besser geht: s. Tarjan bzw. die nächste Veranstaltung 01.04.2004 (c) W. Conen, FH GE, GIN2 22