4. Übung – Algorithmen I Timo Bingmann, Christian Schulz I NSTITUT FÜR T HEORETISCHE I NFORMATIK , P ROF. S ANDERS Bingmann, Schulz 1 KITTimo – Universität des Landes Christian Baden-Württemberg und nationales Forschungszentrum in der Helmholtz-Gemeinschaft 4. Übung – Algorithmen I Fakultät für Informatik www.kit.edu Institut für Theoretische Informatik Übungsklausur Üben des Stoffes und Übungspunkte für den Schein Termin: Montag, 3. Juni 15:45 Uhr (statt Vorlesung), Dauer 90min Bitte seien Sie pünktlich!! Einlass: 15:35 Uhr, Beginn: 15:45 Uhr Nachzügler bekommen keinen Zugang!! D.h.: Ab 15:45 Uhr ist die Tür zu! Hilfsmittel: 1 DIN A4 einseitig handbeschriebener Zettel Unterschrift für selbständige Anfertigung Tutoriumsnummer auf die Klausur schreiben 2 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Unbounded Hashtables 3 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Unbounded Hashtables Amortisierung Problem: Daten Stück für Stück in Hashtabelle einfügen Anzahl unbekannt Was passiert wenn eine Hashtabelle zu voll wird? Hashing with linear Probing: Überlauf Hashing mit verk. Liste: find und remove werden langsamer Lösung: Hashtabelle dynamisch vergrößern und verkleinern 4 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Unbounded Hashtables mit verketteten Listen Modifizierte Operationen find: keine Veränderung insert: Größe verdoppeln, bei #Slots Elemente remove: Größe halbieren, bei 14 #Slots Elemente Erinnert an unbeschränkte Arrays 5 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Unbounded Hashtables verketteten Listen Problem: Hashfuntion muss zur Tabellengröße passen Grund: Soll möglichst gleichverteilt streuen Nach Größenänderung nicht mehr der Fall Lösung: Bei Größenänderung neue Hashfunktion wählen Dann: vollständiger „rehash“ D.h.: Elemente nicht nur kopieren, sondern neu „einhashen“ 6 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Unbounded Hashtable verketteten Listen – Laufzeit Laufzeit von insert, find, remove (exkl. rehash): Unverändert erwartet O(1) Laufzeit von rehash: Amortisiert O(1) Argumentation wie bei unbeschränkten Arrays D.h.: Bei insert und remove einzahlen aufs Konto 7 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Neue Hashfunktion wählen Beispiel Hashen von Zahlen h(x ) = x mod Tabellengröße Problem: Wenn Tabellengröße = 2k Entspricht: Extrahieren der k niedrigsten Bits D.h.: Nur k niedrigste Bits nehmen Einfluss Besser: Tabellengröße immer Primzahl Möglichst weit entfernt von Zweierpotenzen Implementierung: Primzahlentabelle, z.B. im Code Wähle bei Größenänderungen die nächstgrößere Primzahl aus Tabelle 8 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Rehash Beispiel insert: 22, 42, 9, 25, 18 und 96 h1 (x ) = x mod 5, h2 (x ) = x mod 11 0 1 2 3 4 −→ 25 −→ 42 −→ 22 −→ 18 −→ 9 9 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I 0 1 2 3 4 5 6 7 8 9 10 −→ 22 −→ 25 −→ 18 −→ 96 −→ 9 −→ 42 Fakultät für Informatik Institut für Theoretische Informatik Universalität von Hashfunktionen 10 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Analyse für zufällige Hash-Funktionen Wiederholung Satz ∀k : die erwartete Anzahl kollidierender Elemente ist O(1), falls |M | = O(m). M 0 := {e ∈ M : key(e) 6= k } für festes k definiere Kollisionslänge X := |t [h(k )]| die Anzahl der Element die auf den gleichen Slot gehasht werden 11 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Wahrscheinlichkeit für Kollision Wiederholung 0-1 ZV Xe : 1 für h(e) = h(k ), e ∈ M 0 , 0 sonst 12 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Wahrscheinlichkeit für Kollision Wiederholung 0-1 ZV Xe : 1 für h(e) = h(k ), e ∈ M 0 , 0 sonst E [X ] = E [ X Xe ] = e∈M 0 X E [Xe ] = e ∈M 0 X e ∈M 0 P [Xe = 1] = |M 0 | · P [Xe = 1] = Anzahl aller Hashfunktionen mit h(e)=h(k ) = |M 0 | · z }| { m|Key |−1 |Key | |m{z } = Anzahl aller Hashfunktionen 1 |M 0 | = |M | · = = O(1) m m 0 12 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Wahrscheinlichkeit für Kollision Wiederholung 0-1 ZV Xe : 1 für h(e) = h(k ), e ∈ M 0 , 0 sonst E [X ] = E [ X Xe ] = e∈M 0 X E [Xe ] = e ∈M 0 X e ∈M 0 P [Xe = 1] = |M 0 | · P [Xe = 1] = Anzahl aller Hashfunktionen mit h(e)=h(k ) = |M 0 | · z }| { m|Key |−1 |Key | |m{z } = Anzahl aller Hashfunktionen 1 |M 0 | = |M | · = = O(1) m m 0 springender Punkt in Rechnung: Hashfunktion zufällig aus Menge aller möglichen ausgewählt nicht: Hashfunktion würfelt Wert für jeden Schlüssel. 12 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Universelles Hashing Idee: nutze nur bestimmte “einfache” Hash-Funktionen Key H ⊆ {0..m − 1} ist universell falls für alle x, y in Key mit x 6= y und zufälligem h ∈ H, P [h(x ) = h(y )] = 1 . m Theorem gilt auch für universelle Familien von Hashfunktionen 13 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Universalität von Hashfunktionen Beispiele 14 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bit-Matrix-Multiplikation Universalität hM (x ) = Mx M ∈ {0, 1}w ×k , Arithmetik mod 2 (XOR and AND) Anzahl Slots m in Hashtabelle m = 2w Beachte: x ∈ {0, 1}k und Mx ∈ {0, 1}w 15 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bit-Matrix-Multiplikation Universalität hM (x ) = Mx M ∈ {0, 1}w ×k , Arithmetik mod 2 (XOR and AND) Anzahl Slots m in Hashtabelle m = 2w Beachte: x ∈ {0, 1}k und Mx ∈ {0, 1}w M= 1 0 1 1 0 1 1 1 und x = (1, 0, 0, 1)T ⇒ Mx mod 2 = (0, 1)T 15 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bit-Matrix-Multiplikation Universalität hM (x ) = Mx , M ∈ {0, 1}w ×k , m = 2w Zu zeigen, für alle x 6= y und hM gilt P[hM (x ) = hM (y )] = 1 m für ein M gewählt aus allen möglichen. h(x ) = h(y ) ⇔Mx = My ⇔∀i ∈ {1, . . . , w } : 16 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I k M j =1 Mij xj = k M Mij yj j =1 Fakultät für Informatik Institut für Theoretische Informatik Bit-Matrix-Multiplikation Universalität ∀i ∈ {1, . . . , w } : Lk j =1 Mij xj = Lk j =1 Mij yj Anzahl Matrizen, die obiges Gleichungssystem lösen? w Gleichungen und wk Variablen Mij ⇒ unterbestimmt, x 6= y wk − w Vektoren spannen Lösungsraum auf ⇒ 2wk −w Lösungen 17 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bit-Matrix-Multiplikation Universalität ∀i ∈ {1, . . . , w } : Lk j =1 Mij xj = Lk j =1 Mij yj Anzahl Matrizen, die obiges Gleichungssystem lösen? w Gleichungen und wk Variablen Mij ⇒ unterbestimmt, x 6= y wk − w Vektoren spannen Lösungsraum auf ⇒ 2wk −w Lösungen Anzahl möglicher Matrizen M: 17 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I 2wk Fakultät für Informatik Institut für Theoretische Informatik Bit-Matrix-Multiplikation Universalität ∀i ∈ {1, . . . , w } : Lk j =1 Mij xj = Lk j =1 Mij yj Anzahl Matrizen, die obiges Gleichungssystem lösen? w Gleichungen und wk Variablen Mij ⇒ unterbestimmt, x 6= y wk − w Vektoren spannen Lösungsraum auf ⇒ 2wk −w Lösungen Anzahl möglicher Matrizen M: 2wk P[hM (x ) = hM (y )] = 17 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I 2wk −w 2wk = 2−w = 1 2w = 1 m Fakultät für Informatik Institut für Theoretische Informatik Bloom Filter schnelle, ungenaue Suche 18 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bloom Filters Randomisierte Datenstruktur Problem: INSERT und CONTAINS(e) Operationen CONTAINS(e): "ja", wenn e enthalten, "nein” sonst erlaube false positive, d.h. Antwort ja, obwohl nicht enthalten Anwendungsbeispiele: Spellchecking Webcrawling 19 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bloom Filters Randomisierte Datenstruktur Problem: INSERT und CONTAINS(e) Operationen CONTAINS(e): "ja", wenn e enthalten, "nein” sonst erlaube false positive, d.h. Antwort ja, obwohl nicht enthalten Anwendungsbeispiele: Spellchecking Webcrawling Erste Idee: verwende Hashing (keine false positives) wir wollen weniger Speicher verwenden! 19 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bloom Filters Randomisierte Datenstruktur n Elemente k ≥ 1 Hashfunktionen hi array A[0 . . . , m − 1] von Bits Insert(x): 1 setze A[hi (x )] = 1∀i ∈ {1, . . . , k } Contains(x): 1 wenn A[hi (x )] = 1∀i ∈ {1, . . . , k } ⇒ ja 2 sonst ⇒ nein 20 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bloom Filters Insert Beispiel (k = 3) h1 (x) h2 (x) h3 (x) 0 0 1 0 0 0 1 0 1 0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 contains(x) liefert JA! 21 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bloom Filters Insert Beispiel (k = 3) h1 (z) h2 (z) h3 (z) 0 0 1 0 0 0 1 0 1 0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 contains(z) liefert NEIN! 22 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bloom Filters Insert Beispiel (k = 3) h1 (y) h2 (y) h3 (y) 0 0 1 0 0 0 1 0 1 0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 contains(y 6= x) liefert JA, obwohl y nicht einfügt wurde! 23 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bloom Filters Wie wahrscheinlich sind false positives? x n ex = limn→∞ 1 + n Annahme: Hashfunktionen haben uniform gleichverteiltes Bild p Wahrscheinlichkeit das Bit = 0 nach n Einfügungen p = 1− 1 kn m = 1− kn/m 1 m m ≈ e−kn/m Wahrscheinlichkeit für false positive also ≈ (1 − p)k = (1 − 24 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I 1 )k ekn/m Fakultät für Informatik Institut für Theoretische Informatik Bloom Filters Wie wahrscheinlich sind false positives? x n ex = limn→∞ 1 + n Annahme: Hashfunktionen haben uniform gleichverteiltes Bild p Wahrscheinlichkeit das Bit = 0 nach n Einfügungen p = 1− 1 kn m = 1− kn/m 1 m m ≈ e−kn/m Wahrscheinlichkeit für false positive also ≈ (1 − p)k = (1 − optimialer Wert für k := mn ln 2 24 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I 1 )k ekn/m Fakultät für Informatik Institut für Theoretische Informatik Bloom Filters Rechenbeispiel Wahrscheinlichkeit für false positive (1 − 1 )k ekn/m n = 100 000 Objekte m = 1 000 000 Bits wähle k = 7 Wahrscheinlichkeit für false positive < 1% Vorteile: viel kompaktere Repräsentation als Abspeichern von Objekten z.B. Strings, Webseiten, Hashwerte, . . . 25 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Bloom Filters Rechenbeispiel Wahrscheinlichkeit für false positive (1 − 1 )k ekn/m n = 100 000 Objekte m = 1 000 000 Bits wähle k = 7 Wahrscheinlichkeit für false positive < 1% genauere Analyse: ”on the false-positive rate of bloom filters”, Bose et. al Vorteile: viel kompaktere Repräsentation als Abspeichern von Objekten z.B. Strings, Webseiten, Hashwerte, . . . 25 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik De-amortisierung 26 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Deamortisierung Unbounded Arrays Wichtige Operationen: access(n) in O(1) push_back(n) amortisiert in O(1) pop_back(n) amortisiert in O(1) Worst-Case: Ω(n) für push_back, pop_back 27 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Deamortisierung Unbounded Arrays Wichtige Operationen: access(n) in O(1) push_back(n) amortisiert in O(1) pop_back(n) amortisiert in O(1) Worst-Case: Ω(n) für push_back, pop_back Problem für Echtzeitsysteme!? 27 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Deamortisierung Unbounded Arrays Wichtige Operationen: access(n) in O(1) push_back(n) amortisiert in O(1) pop_back(n) amortisiert in O(1) Ziel: richtiges O(1) Idee: Bankkontomethode anpassen statt Einzahlung Arbeit verrichten ⇒ Deamortisierung 27 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Deamortisierung Unbounded Arrays Arbeit statt Einzahlung: push_back starte direkt nach Verdoppelung 2n 4n Vorgehen: schreibe das eigentliche Element kopiere zwei weitere Elemente 28 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I n+1 Fakultät für Informatik Institut für Theoretische Informatik Deamortisierung Unbounded Arrays Arbeit statt Einzahlung: push_back starte direkt nach Verdoppelung Vorgehen: schreibe das eigentliche Element kopiere zwei weitere Elemente 28 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Deamortisierung Unbounded Arrays Arbeit statt Einzahlung: push_back starte direkt nach Verdoppelung Vorgehen: schreibe das eigentliche Element kopiere zwei weitere Elemente 28 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Deamortisierung Unbounded Arrays Arbeit statt Einzahlung: push_back starte direkt nach Verdoppelung Vorgehen: schreibe das eigentliche Element kopiere zwei weitere Elemente 28 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Deamortisierung Unbounded Arrays Arbeit statt Einzahlung: push_back starte direkt nach Verdoppelung Vorgehen: schreibe das eigentliche Element kopiere zwei weitere Elemente 28 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Deamortisierung Unbounded Arrays Arbeit statt Einzahlung: pop_back analog zu push_back Vorgehen: lösche das eigentliche Element kopiere ein weiteres Element 29 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Deamortisierung Unbounded Arrays Insgesamt: Worst-Case-Laufzeit auch in O(1) Nicht überall so leicht anwendbar. 30 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Sortieren – Rebooted Die meisten intuitiven Sortieralgorithmen basieren auf: 1 2 3 4 Selection: finde das kleinste (oder größte) Element, und trenne es von den übrigen. Wiederhole bis alle ausgewählt wurden. Insertion: betrachte Elemente einzeln und füge in sortierte Teilfolgen ein. Exchange: vertauscht ungeordnete Paare von Elemente, bis keine weitere Vertauschungen notwendig sind. Enumeration: vergleiche ein Element mit allen anderen. Dann platziere es endgültig an Hand der Anzahl kleiner Elemente. In der Regel erreichen diese nicht die untere Schranke Θ(n log n). 31 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Selection Sort Function selectionSort(A : Array of Element; n : N) for i := 0 to n − 1 do min := i for j := i + 1 to n − 1 do // Suche kleinstes Element if A[j ] < A[min] then min := j endfor swap(A[i ], A[min]) // Tausche Element an Anfang invariant A[0] ≤ · · · ≤ A[i ] endfor 32 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Selection Sort Function selectionSort(A : Array of Element; n : N) for i := 0 to n − 1 do min := i for j := i + 1 to n − 1 do // Suche kleinstes Element if A[j ] < A[min] then min := j endfor swap(A[i ], A[min]) // Tausche Element an Anfang invariant A[0] ≤ · · · ≤ A[i ] endfor Wieviele Vergleiche? 32 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Selection Sort Function selectionSort(A : Array of Element; n : N) for i := 0 to n − 1 do min := i for j := i + 1 to n − 1 do // Suche kleinstes Element if A[j ] < A[min] then min := j endfor swap(A[i ], A[min]) // Tausche Element an Anfang invariant A[0] ≤ · · · ≤ A[i ] endfor Wieviele Vergleiche? 32 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I immer n (n − 1) = Θ n2 ! 2 Fakultät für Informatik Institut für Theoretische Informatik Insertion Sort Function insertionSort(A : Array of Element; n : N) for i := 1 to n − 1 do // {A[0]} ist sortiert j := i x := A[j ] while (j > 0) & (A[j − 1] < x ) // Finde richtige Stelle j A[j ] := A[j − 1] // Schiebe größere Elemente j := j − 1 // nach hinten. endwhile A[j ] := x // Setze Element invariant A[0] ≤ · · · ≤ A[i ] endfor 33 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Insertion Sort Function insertionSort(A : Array of Element; n : N) for i := 1 to n − 1 do // {A[0]} ist sortiert j := i x := A[j ] while (j > 0) & (A[j − 1] < x ) // Finde richtige Stelle j A[j ] := A[j − 1] // Schiebe größere Elemente j := j − 1 // nach hinten. endwhile A[j ] := x // Setze Element invariant A[0] ≤ · · · ≤ A[i ] endfor Vermeide j > 0 mit einem Sentinel A[−1] := −∞. 33 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Insertion Sort Function insertionSort(A : Array of Element; n : N) for i := 1 to n − 1 do // {A[0]} ist sortiert j := i x := A[j ] while (j > 0) & (A[j − 1] < x ) // Finde richtige Stelle j A[j ] := A[j − 1] // Schiebe größere Elemente j := j − 1 // nach hinten. endwhile A[j ] := x // Setze Element invariant A[0] ≤ · · · ≤ A[i ] endfor Wieviele Vergleiche? worst-case? 33 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Insertion Sort Function insertionSort(A : Array of Element; n : N) for i := 1 to n − 1 do // {A[0]} ist sortiert j := i x := A[j ] while (j > 0) & (A[j − 1] < x ) // Finde richtige Stelle j A[j ] := A[j − 1] // Schiebe größere Elemente j := j − 1 // nach hinten. endwhile A[j ] := x // Setze Element invariant A[0] ≤ · · · ≤ A[i ] endfor Wieviele Vergleiche? worst-case: 33 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I n (n − 1) = Θ n2 , average? 2 Fakultät für Informatik Institut für Theoretische Informatik Insertion Sort Function insertionSort(A : Array of Element; n : N) for i := 1 to n − 1 do // {A[0]} ist sortiert j := i while (j > 0) & (A[j − 1] < A[j ]) // Finde richtige Stelle j swap(A[j − 1], A[j ]) // Schiebe größere Elemente j := j − 1 // nach hinten. endwhile invariant A[0] ≤ · · · ≤ A[i ] endfor Wieviele Swaps? worst-case: 33 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I n (n − 1) = Θ n2 , average? 2 Fakultät für Informatik Institut für Theoretische Informatik Insertion Sort – Average Case Annahme: Alle Elemente verschieden und die Eingabe ist eine zufällige Permutation davon. ⇒ Jede der n! Permutationen σ ∈ Sn ist gleich wahrscheinlich. σ= 34 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I ( 3 4 1 5 2 ) Fakultät für Informatik Institut für Theoretische Informatik Insertion Sort – Average Case Annahme: Alle Elemente verschieden und die Eingabe ist eine zufällige Permutation davon. ⇒ Jede der n! Permutationen σ ∈ Sn ist gleich wahrscheinlich. Eine Paar (i , j ) ∈ N1 mit i < j ist eine Inversion, wenn σ(i ) > σ(j ). σ= Ein σ ∈ Sn hat zwischen 0 und ( 3 4 1 5 2 ) n Inversionen. 2 Beispiele: (1, 2, 3, 4, 5) und (5, 4, 3, 2, 1). 34 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Insertion Sort – Average Case σ= ( 3 4 1 5 2 ) Jeder Austausch falsch sortierter, benachbarter Positionen (swap) reduziert die Anzahl der Inversionen um genau 1. ⇒ Die Anzahl von swaps in Insertion-Sort ist genau die Anzahl Inversionen in der Eingabe-Permutation. Nenne diese Anzahl X . Wir suchen den Erwartungswert: E(X ). 35 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Insertion Sort – Average Case Wir zählen die erwartete Anzahl von Inversionen: Für eine Permutation σ ∈ Sn sei ( 1 falls (i , j ) eine Inversion, Xi ,j := 0 sonst. Also ist X := P Xi ,j die Anzahl von Inversionen und i <j X X E(X ) = E Xi ,j = E(Xi ,j ) . i <j i <j n 1 1 · . Da E(Xi ,j ) = , ist so mit E(X ) = 2 2 2 n (n − 1) n n 1 ⇒ Worst case = und average case · . 2 2 2 2 36 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Merge Sort Function mergeSort(A : Array of Element; lo, hi : N) if hi − lo ≤ 1 then return // Basisfall mid := (lo + hi )/2 // mittleres Element mergeSort(lo, mid ), mergeSort(mid , hi ) // Sortiere Hälften T := allocate (Array of Element size hi − lo) i := lo, j := mid, k := 0 // Laufindizes while i < mid & j < hi if A[i ] < A[j ] T [k ++] := A[i++] // Mische! else T [k ++] := A[j++] endwhile while i < mid do T [k ++] := A[i++] // Kopiere Reste while j < hi do T [k ++] := A[j++] A[lo, . . . , hi − 1] := T [0, . . . , (hi − lo) − 1] // Kopiere zurück dispose (T ) Worst case: Θ(n log n), average case Θ(n log n). 37 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Sanders: Algorithmen I May 22, 2013 180 5.4 Quicksort – erster Versuch Idee: Teile-und-Herrsche aber verglichen mit mergesort „andersrum“. Leiste Arbeit vor rekursivem Aufruf Function quickSort(s : Sequence of Element) : Sequence of Element if |s| ≤ 1 then return s pick “some” p ∈ s a:= he ∈ s : e < pi b:= he ∈ s : e = pi c:= he ∈ s : e > pi return concatenation of quickSort(a), b, and quickSort(c) Sanders: Algorithmen I May 22, 2013 5.4.2 Quicksort: Effiziente Implementierung Array-Implementierung „inplace“ 2-Wegevergleiche 191 Sanders: Algorithmen I May 22, 2013 Procedure qSort(a : Array of Element; ℓ, r : N) if ℓ ≥ r then return k:= pickPivotPos(a, ℓ, r) m:= partition(a, ℓ, r, k) qSort(a, ℓ, m − 1) qSort(a, m + 1, r) 192 Sanders: Algorithmen I May 22, 2013 193 Function partition(a : Array of Element; ℓ, r, k : N) p:= a[k] swap(a[k], a[r]) i:= ℓ j r i ℓ p invariant ≤ p > p ? for j := ℓ to r − 1 do if a[ j] ≤ p then swap(a[i], a[ j]) i++ i ℓ >p assert ≤ p r p swap(a[i], a[r]) ℓ assert ≤ p return i i p >p r // pivot Sanders: Algorithmen I May 22, 2013 194 Beispiel: Partitionierung, k = 1 p, i, j 3 6 8 1 0 7 2 4 5 9 9 9 9 9 1 1 1 1 1 6 6 6 6 6 0 0 0 0 8 8 8 8 8 8 8 2 2 1 1 1 1 9 9 9 9 9 0 0 0 0 0 6 6 6 6 7 7 7 7 7 7 7 7 7 2 2 2 2 2 2 2 8 8 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 3 3 3 3 3 3 3 3 3 1 0 1 0 2 2 9 3 6 6 7 7 8 8 4 4 5 5 3 9 Sanders: Algorithmen I May 22, 2013 Beispiel: Rekursion 3 6 8 1 0 7 2 4 5 9 1 0 2|3|6 7 8 4 5 9 | | 0|1|2| |4 5|6|9 7 8 | | | | | |4|5| |8 7|9| | | | | |7|8| 195 Sanders: Algorithmen I May 22, 2013 Größerer Basisfall Procedure qSort(a : Array of Element; ℓ, r : N) if r − ℓ + 1 ≤ n0 then insertionSort(a[ℓ..r]) k:= pickPivotPos(a, ℓ, r) m:= partition(a, ℓ, r, k) qSort(a, ℓ, m − 1) qSort(a, m + 1, r) 196 Sanders: Algorithmen I May 22, 2013 197 h3,6,8,1,0,7,2,4,5,9i hi h0i Inplace? Wirklich? Im schlechtesten Fall: h3,6,8,1,7,2,4,5,9i hi h1i O(n) für Rekursionsstapel. h3,6,8,7,2,4,5,9i hi h2i h3,6,8,7,4,5,9i hi h3i h6,8,7,4,5,9i hi Im Mittel: h4i h6,8,7,5,9i hi O(log n) zusätzlicher Platz – kein Problem. Als Garantie für schlechtesten Fall: halbrekursive Implementierung Rekursion auf kleinere Hälfte h5i h6,8,7,9i hi h6i h8,7,9i hi h7i h8,9i hi h8i h9i Sanders: Algorithmen I May 22, 2013 Halbrekursive Implementierung Procedure qSort(a : Array of Element; ℓ, r : N) while r − ℓ + 1 > n0 do k:= pickPivotPos(a, ℓ, r) m:= partition(a, ℓ, r, k) if m < (ℓ + r)/2 then qSort(a, ℓ, m − 1); ℓ:= m + 1 else qSort(a, m + 1, r); r:= m − 1 insertionSort(a[ℓ..r]) 198 Sanders: Algorithmen I May 22, 2013 Halbrekursive Implementierung Procedure qSort(a : Array of Element; ℓ, r : N) while r − ℓ + 1 > n0 do k:= pickPivotPos(a, ℓ, r) m:= partition(a, ℓ, r, k) if m < (ℓ + r)/2 then qSort(a, ℓ, m − 1); ℓ:= m + 1 else qSort(a, m + 1, r); r:= m − 1 insertionSort(a[ℓ..r]) n Satz: Rekursionstiefe ≤ log n0 Beweisidee: Induktion. Teilproblemgröße halbiert sich (mindestens) mit jedem rekursiven Aufruf 199 Sanders: Algorithmen I May 22, 2013 Quadratische Komplexität bei gleichen Elementen? Variante aus dem Buch verwenden oder doch Drei-Wege-Partitionierung 200 Sanders: Algorithmen I May 22, 2013 Procedure qSortTernary(a : Array of Element; ℓ, r : N) if ℓ ≥ r then return p:= key(a[pickPivotPos(a, ℓ, r)]) (m, m′ ):= partitionTernary(a, ℓ, r, p) qSortTernary(a, ℓ, m − 1) qSortTernary(a, m′ + 1, r) 201 Sanders: Algorithmen I May 22, 2013 Function partitionTernary(a : Array of Element; ℓ, r : N; p : Key) i:= ℓ, j:= ℓ, k:= r j k r i ℓ invariant < p > p ? = p while ( j ≤ k) if a[ j] = p then swap(a[ j], a[k]), k−− ; else if a[ j] < p then swap(a[ j], a[i]), i++ , j++ ; else j++ ; i k r ℓ >p =p assert < p i′ := i + r − k + 1 swap(a[i..i′ ], a[k + 1..r]) r i i′ ℓ assert < p = p > p return (i, i′ ) 202 Sanders: Algorithmen I May 22, 2013 203 Vergleich Quicksort ↔ Mergesort Pro Mergesort O(n log n) Zeit (deterministisch) qsort: ∃ det. Varianten n log n + O(n) Elementvergleiche (≈ untere Schranke) qsort: möglich bei sorgfältiger Pivotwahl Stabil (gleiche Elemente behalten Reihenfolge bei) qsort: leicht bei Aufgabe der inplace-Eigenschaft Pro Quicksort inplace Etwas schneller? Vorgefertigte Sortieralgorithmen in aktuellen Programmiersprachen Verwenden Sie diese statt eigene zu implementieren! 38 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik Java Zahlen: Variante von Quick-Sort int[] numbers = {42, 7, 9, 18, 1, 123}; java.util.Arrays.sort(numbers) Allgemeine Elemente: Variante von Merge-Sort Comparator<Elem> comparator = new Comparator<Elem> { int compare(Elem a, Elem b) { /*...*/ } } Elem[] elements = { /*...*/ } java.util.Arrays.sort(elements, 3, 15, comparator) 39 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik C++ Zahlen: #include <algorithm> int numbers[] = {42, 7, 9, 18, 1, 123}; std::vector<int> vec(numbers, numbers + 6); std::sort(vec.begin(), vec.end()) Allgemeine Elemente: #include <algorithm> bool less_than(Elements& a, Elements& b) { /*...*/ } ... Elements* elements = createElements(n); std::sort(elements, elements + n, less_than) ...oder... std::stable_sort(elements, elements + n, less_than) 40 Timo Bingmann, Christian Schulz 4. Übung – Algorithmen I Fakultät für Informatik Institut für Theoretische Informatik time / (n log n) [ns] Sanders: Algorithmen I May 22, 2013 Benchmark 204 Sortieren einer zufaelligen Sequenz (int) 50 InsertionSort MergeSort QuickSort JDK−QuickSort 45 40 35 30 25 20 15 10 5 2 4 2 6 2 8 2 10 2 12 2 n 14 2 16 2 18 2 20 2 22 Sanders: Algorithmen I May 22, 2013 5.5 Auswahl (Selection) Definition: Rang der Elemente einer Folge s mit |s| = n: Abbildung r : 1..n → 1..n mit ∀i, j : s[i] < s[ j] ⇒ r(i) < r( j). Grob: a[i] ist das r(i)-te Element von a. Frage: warum ist r nicht notwendig eindeutig? // return an element of s with rank k Function select(s : Sequence of Element; k : N) : Element assert |s| ≥ k 205 Sanders: Algorithmen I May 22, 2013 Auswahl – Anwendungen Statistik Spezialfall Medianauswahl: k = ⌈|s|/2⌉ allgemeinere Quantile (10 % ,. . . ) Unterprogramm z. B. Eingabe eingrenzen auf vielversprechendste Elemente 206 Sanders: Algorithmen I May 22, 2013 Quickselect ≈ quicksort mit einseitiger Rekursion Function select(s : Sequence of Element; k : N) : Element assert |s| ≥ k pick p ∈ s uniformly at random // pivot key a := he ∈ s : e < pi k a if |a| ≥ k then return select(a, k)// b := he ∈ s : e = pi k a b = hp, . . . , pi if |a| + |b| ≥ k then return p // c := he ∈ s : e > pi k a c return select(c, k − |a| − |b|) // b 207 Sanders: Algorithmen I May 22, 2013 208 Beispiel s k p a h3, 1, 4, 5, 9, 2, 6, 5, 3, 5, 8i 6 2 h1i 4 6 4 5 h3, 4, 5, 9, 6, 5, 3, 5, 8i h3, 4, 5, 5, 3, 5i b h2i h3, 4, 5, 9, 6, 5, 3, 5, 8i h3, 4, 5, 5, 3, 5i h6i h3, 4, 3i c h5, 5, 5i h9, 8i hi Sanders: Algorithmen I May 22, 2013 Quickselect – Analyse Function select(s : Sequence of Element; k : N) : Element assert |s| ≥ k pick p ∈ s uniformly at random // pivot key a := he ∈ s : e < pi k a if |a| ≥ k then return select(a, k)// b := he ∈ s : e = pi k a if |a| + |b| ≥ k then return p // b = hp, . . . , pi c := he ∈ s : e > pi k a c return select(c, k − |a| − |b|) // b Satz: quickselect hat erwartete Ausführungszeit O(|s|) Beweis: hier nicht 209 Sanders: Algorithmen I May 22, 2013 210 Mehr zum Auswahlproblem Tuning (array, inplace, 2-Wege-Vergleiche, iterativ) analog quicksort Deterministische Auswahl: quickselect mit spezieller det. Pivotwahl partielles Sortieren (z. B. einfache Variante von quickselect) weiss wie es geht? Weitere Verallgemeinerungen: mehrere Ränge, teilweise sortierte Eingaben,. . . Beispiel: Optimale Range Median Berechnung [B. Gfeller, P. Sanders, ICALP 2009]. Vorberechnungszeit O(n log n), Zeit O(log n) füra select(hs[a], . . . , s[b]i, k) s k-th b wer