Modul: Algorithmik SS 2017 Volker Diekert1 31. August 2017 1 Übungen: Lukas Fleischer, Armin Weiß, Lukas Schulz 1 / 362 1. Vorlesung, 10.04.2017 Folien sind nur Orientierungshilfen zum Vorlesungsstoff Die Buchempfehlung lautet: Introduction to Algorithms“ Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, ” Clifford Stein 2 / 362 Landau-Symbole-Oh-oh Definition: ◮ O(f) Es gilt g ∈ O(f ), falls ∃c > 0 ∃n0 ∀n ≥ n0 : g (n) ≤ c · f (n). Also: g wächst nicht schneller als f . ◮ o(f) Es gilt g ∈ o(f ), falls ∀c > 0 ∃n0 ∀n ≥ n0 : g (n) ≤ c · f (n). Also: g wächst echt langsamer als f . 3 / 362 Landau-Symbole-Omega-Theta ◮ Ω(f) g ∈ Ω(f ) ⇔ f ∈ O(g ) Also: g wächst mindestens so schnell wie f . ◮ ω(f) g ∈ ω(f ) ⇔ f ∈ o(g ) Also: g wächst echt schneller als f . ◮ Θ(f) g ∈ Θ(f ) ⇔ (f ∈ O(g ) ∧ g ∈ O(f )) Dies heißt, g und f wachsen asymptotisch gleichschnell. 4 / 362 Reale Rechenzeiten Vergleich (1 Operation = 1 ms) vs. (1 Operation = 1 µs) Algorithmus n n log(n) n2 n3 2n 1 Minute Rechenzeit 1 OP=1 ms 1 OP=1 µs 6, 0 · 104 4.893 244 39 15 6, 0 · 107 2, 8 · 106 7.746 391 26 1 Stunde Rechenzeit 1 OP=1 ms 1 OP=1 µs 3, 6 · 106 2, 0 · 105 1.897 153 21 3, 6 · 109 1, 3 · 108 60.000 1.533 32 10-fache Beschl. ∗ 10 ∼√∗ 10 ∗√10 ∗ 3 10 + log2 (10) Es gilt: Je schneller der Rechner, desto mehr lohnen sich effiziente Algorithmen! 5 / 362 Komplexitätsmaße ◮ Komplexität im ungünstigsten Fall (worst case). ◮ Komplexität im Mittel (average case) benötigt eine Wahrscheinlichkeitsverteilung der Eingabe. Mittlerer Zeitbedarf: tA,Mittel (n) = E (tA (x), |x| = n) Dabei sei E [tA (x) | |x| = n] der bedingte Erwartungswert von tA (x) unter der Bedingung |x| = n 6 / 362 Durchschnittsanalyse Bei Quicksort ist die Anzahl der Vergleiche im ungünstigsten Fall tQ (n) ∈ Θ(n2 ). Mittlerer Zeitbedarf: tA,Mittel (n) ∈ O(n log n) Die Durchschnittsanalyse ist oft schwierig. Gleichverteilung der Eingaben gleicher Länge: tA,Mittel (n) = 1 X tA (x) |Xn | x∈Xn mit Xn := {x ∈ X | |x| = n} Eine Gleichverteilung der Eingaben ist nicht immer sinnvoll! 7 / 362 Beispiel binäre Suchbäume Beispiel 1.1 Gleichverteilung bei binären Suchbäumen: 1 2n Es gibt n+1 n (= (n + 1)-te Catalansche Zahl) verschiedene Binärbäume mit n Knoten. 2n n 4n ∼√ πn n n √ 2πn e √ Gleichverteilung: Mittlere Baumhöhe ist ungefähr n. n! ∼ 8 / 362 Beispiel binäre Suchbäume Beispiel 1.2 Gleichverteilung der Eingaben: Realistischer: Verteilung, die sich durch eine Gleichverteilung von Permutationen ergibt. Eingabe π = (3, 5, 1, 4, 6) ergibt einen Baum mit Wurzel 3 und dann wird von links nach rechts eingefügt“. ” Damit: Mittlere Baumhöhe Θ(log(n)). n! wächst wesentlich schneller als 1 n n+1 4 . Also ergeben sehr viele Permutationen dieselben Suchbäume. π = (3, 5, 1, 4, 6), π ′ = (3, 1, 5, 6, 4) und π ′′ = (3, 5, 6, 4, 1) ergeben identische Bäume. 9 / 362 Maschinenmodelle: Turingmaschine Die Turingmaschine (TM) ist ein mathematisch leicht exakt beschreibbares Berechnungsmodell. Allerdings ist der zeitraubende Speicherzugriff (Bandzugriff) in der Realität nicht gegeben. Arbeitet ein Algorithmus auf einer TM schnell, so ist er schnell! 10 / 362 Maschinenmodelle: Registermaschine x1 x2 x3 x4 x5 x6 x7 x8 x9 . . . Eingabe READ ONLY Speicher RAM 0 = Akku 1 = 1.Reg 2 = 2.Reg 3 = 3.Reg 4 = 4.Reg IC ✲ . Programm . . y1 y2 y3 y4 y5 y6 y7 y8 y9 . . . Ausgabe WRITE ONLY 11 / 362 Unter Schranken / Beispiel Sortieren Einer der schwierigen Aspekte der Algorithmentheorie ist die Suche nach unteren Schranken. Satz 1.3 (Sortieralgorithmen) Jeder Sortieralgorithmus, der ausschließlich auf Schlüsselvergleichen basiert, benötigt im Mittel und daher auch im schlechtesten Fall Ω(n log n) Vergleiche. Beweis: Wir fassen Sortieralgorithmen als Entscheidungsbäume auf, d.h. als Binärbäume, deren inneren Knoten mit Vergleichen der Art gilt x[i ] < x[j]?“ beschriftet sind. Es gibt ” n! Permutationen von n Elementen. Fasst man jede Permutation als einen Pfad durch einen Entscheidungsbaum auf, so muss dieser mindestens n! Blätter haben. Jeder binäre Baum mit n! Blättern hat eine Mindesthöhe von log(n!) ∈ Ω(n log(n)). Die Höhe des Entscheidungsbaums entspricht aber dem Zeitaufwand des Algorithmus. Eine ähnliche Argumentation führt auf die untere Schranke für die mittlere Anzahl der Vergleiche. Genaueres im Abschnitt über Entropie. 12 / 362 Sortieren ist schwieriger als den Median zu finden ◮ Um 5 Elemente zu sortieren benötigen wir im schlechtesten Fall ⌈log2 (5!)⌉ = ⌈log2 (120)⌉ = 7 Vergleiche. ◮ Den Median-aus-5 zu finden erfordert nur 6 Vergleiche. ◮ Siehe Tafelbeweis. 13 / 362 2. Vorlesung, 11.04.2017 Teil I: Mastertheorem II und Medianberechnung 14 / 362 Mastertheorem II Satz 2.1 (Mastertheorem II) Sei r ≥ 0 mit Pr i =1 αi < 1 und t(n) ≤ r X i =1 ! t(⌈αi n⌉) + O(n). Dann gilt t(n) ∈ O(n). Bemerkung. Ohne Einschränkung gibt es eine Konstante c mit ! r X t(⌈αi n⌉) + c · n. t(n) ≤ i =1 15 / 362 Beweis Mastertheorem II Wähle ein ε und ein n0 > 0 so, dass αi n0 ≤ n0 − 1 und P Pr dass r ⌈α n⌉ ≤ ( i i =1 i =1 αi ) · n + r + 1 ≤ (1 − ε)n für alle n ≥ n0 . Wähle ein γ so, dass c < γε und t(n) < γn für alle n < n0 . Für den Induktionsschritt (n ≥ n0 ) gilt: ! r X t(⌈αi n⌉) + cn t(n) ≤ ≤ i =1 r X i =1 ! γ⌈αi n⌉ + cn (mit Induktion) ≤ (γ(1 − ε) + c)n ≤ γn 16 / 362 Medianberechnung in linearer Zeit Gegeben sei ein Feld a[1 . . . n] von Zahlen. Gesucht ist das ⌊n/2⌋-kleinste Element in einer sortierten Reihenfolge der ai . Allgemeiner sei 1 ≤ k ≤ n. Berechne SELECT(k, a[1 . . . n]). Gesucht ist also das k-kleinste Element m, d.h., berechne m ∈ { a[i ] | 1 ≤ i ≤ n } mit: |{i | a[i ] < m}| < k und |{i | a[i ] > m}| ≤ n − k 17 / 362 Median der Mediane Bestimme ein Pivotelement als Median der Mediane aus 5: Wir teilen das Feld in Fünferblöcken auf. In jedem Block wird der Median bestimmt (mit 6 Vergleichen möglich). Wir bestimmen rekursiv den Median p dieses Feldes (mit dem gesamten Algorithmus). Der Wert p wird als Pivotelement im folgenden verwendet. Kosten: T ( n5 ). Genauer gilt: T ( n5 ). Dies beeinflusst (nur) die Kostante im O-Term. Zur besseren Lesbarkeit werden die Rundungen häufig ignoriert. 18 / 362 Quicksortschritt Mit dem Pivot p zerlege so, dass für gewisse m1 < m2 gilt: a[i ] < p a[i ] = p a[i ] > p für 1 ≤ i ≤ m1 für m1 < i ≤ m2 für m2 < i ≤ n Kosten: maximal n Schritte. Fallunterscheidung: 1. k ≤ m1 : Suche das k-te Element rekursiv in a[1], . . . , a[m1 ]. 2. m1 < k ≤ m2 : Das Ergebnis ist p. 3. k > m2 : Suche das (k − m2 )-te Element in a[m2 + 1], . . . , a[n]. 19 / 362 30 – 70 Aufteilung Die Wahl des Pivots als Median-aus-Fünf ergibt die folgende Ungleichungen für m1 , m2 : 3 n ≤ m2 10 und m1 ≤ 7 n 10 Damit ergeben sich die Kosten für den Rekursionsschritt als T ( 7n 10 ). Denn: Die Hälfte der 5-er Mediane ist ≤ p. Dies betrifft also (mindestens) n/10 der Blöcke. In jedem Block aus 5 Elementen sind mindestens 3 kleiner oder gleich dem Blockmedian. 20 / 362 Zeitanalyse Sei T (n) die Gesamtzahl der Vergleiche. Wir erhalten folgende Rekursionsgleichung für T (n): n 7n +T + O(n) T (n) ≤ T 5 10 Aus dem Mastertheorem II folgt damit T (n) ∈ O(n). 21 / 362 Zahl der notwendigen Schlüsselvergleiche T (n) ≤ T n 5 +T 7n 10 + 6n 2n + 5 5 2n Hierbei ist 6n 5 der Aufwand für die Bestimmung der Blockmediane und 5 der Aufwand für den Zerlegungsschritt ist. Denn wir können bei der richtigen Positionierung des Medians der Mediane jeweils in Fünferblöcken operieren und müssen daher aus einem Fünferblock jeweils nur noch zwei Elemente mit dem Pivotelement vergleichen. 7 = Es ergibt sich, dass damit T (n) ≤ 16n gilt: mit 15 + 10 9n 8n 8n T (n) ≤ T ( 10 ) + 5 und damit T (n) ≤ 10 · 5 = 16n. 9 10 erhalten wir Achtung: Wegender unterdrückten Rundungen ist 16 zu niedrig, aber: 7n n Der Term T 10 wird im Mittel näher bei T 2 liegen, d.h., der Medianalgorithmus verhält sich im Mittel besser. In Praxis ist jedoch Quickselect die bessere Methode. Später. 22 / 362 Weitere Themen: 1. Wiederholung: Elemente der diskreten Wahrscheinlichkeit. 2. Bucket-Sort. 3. Quicksort und Quickselect. 23 / 362 Wahrscheinlichkeitsraum Ein diskreter Wahrscheinlichkeitsraum ist eine endliche oder abzählbare Menge Ω zusammen mit einer Abbildung Pr : Ω → [0, 1] in das reelle 0-1-Intervall, welche die folgende Bedingung erfüllt: X Pr[ω] = 1 ω∈Ω Ein Ereignis ist eine Teilmenge A ⊆ Ω. Die Wahrscheinlichkeit von A: X Pr[A] = Pr[ω] ω∈A Eine Zufallsvariable X ist hier stets eine reellwertige Funktion X :Ω→R 24 / 362 Erwartungswert Der Erwartungswert von X wird wie folgt definiert: X E [X ] = X (ω)Pr[ω] ω∈Ω Bei einer Gleichverteilung ist der Erwartungswert der Mittelwert über die Funktionswerte der Zufallsvariablen. Es gilt dann: E [X ] = 1 X X (ω) |Ω| ω Pr[X = x] = { ω ∈ Ω | X (ω) = x } E [X ] = X ω X (ω)Pr[ω] = X x Pr[X = x] x 25 / 362 Markov-Ungleichung Satz 3.1 Sei X eine Zufallsvariable mit X (ω) ≥ 0 für alle ω und E [X ] > 0. Dann gilt für alle λ > 0: 1 Pr X ≥ λE [X ] ≤ λ Linearität des Erwartungswertes. Es gilt: E [aX + bY ] = aE [X ] + bE [Y ] 26 / 362 Dichte und Verteilung Ist X : Ω → R eine Zufallsvariable, so assoziiert man mit X ihre diskrete Dichte fX : R → [0, 1] und ihre Verteilung FX : R → [0, 1]. Diese sind wie folgt definiert: fX : R → [0, 1], fX (x) = Pr[X = x] FX : R → [0, 1], FX (x) = Pr[X ≤ x] Aus der Dichte lässt sich die Verteilung berechnen, und die Verteilung bestimmt die Dichte. Sehr verschiedene Zufallsvariablen können auf die gleiche Verteilung (Dichte) führen. Häufig spielt der konkrete Wahrscheinlichkeitsraum häufig gar keine Rolle. Insbesondere ist: X E [X ] = x fX (x) x∈R 27 / 362 Unabhängigkeit Zwei Zufallsvariablen X und Y heißen unabhängig, wenn für alle x, y ∈ R Pr[X = x ∧ Y = y ] = Pr[X = x] · Pr[Y = y] Falls X und Y unabhängig sind, so gilt: E [XY ] = E [X ] E [Y ] Betrachtet man die Zufallsvariable X − E [X ], so ist deren Erwartungswert 0. Interessanter ist das Quadrat dieser Zufallsvariablen (X − E [X ])2 . 28 / 362 Varianz Der Erwartungswert von (X − E [X ])2 heißt die Varianz Var[X ] von X und misst, wie stark X von E [X ] abweicht. Es gilt: Var[X ] = E (X − E [X ])2 i h = E X 2 − 2E [X ] X + E [X ]2 = E X 2 − 2E [X ] E [X ] + E [X ]2 = E X 2 − E [X ]2 Satz 3.2 Für unabhängige Zufallsvariablen X und Y gilt: Var[X + Y ] = Var[X ] + Var[Y ] 29 / 362 Tschebyschev-Ungleichung Mit σX wird die Standardabweichung von X bezeichnet, sie ist definiert durch p σX = Var[X ]. Der Name ergibt sich aus der folgenden Beziehung. Satz 3.3 Sei λ > 0. Dann gilt: 1 Pr |X − E [X ]| ≥ λ σX ≤ 2 λ 30 / 362 3. Vorlesung: 18. April 2017 Analyse von Bucket-Sort durch Bernoulli-Experimente 31 / 362 Erinnerung Varianz Satz 3.4 Var[X ] = E (X − E [X ])2 = E X 2 − E [X ]2 Für paarweise unabhängige Zufallsvariablen X1 , . . . , Xn gilt: Var[X1 + · · · + Xn ] = Var[X1 ] + · · · + Var[Xn ] 32 / 362 Bernoulli-Experimente Bei einem (Jacob Bernoulli, 1654–1705) misst man Erfolg oder Misserfolg durch ein 0-1-Ereignis. Typischerweise setzt man Pr[X = 1] = p und Pr[X = 0] = q = 1 − p. Damit ist E [X ] = p und Var[X ] = p − p 2 = pq. Seien X1 , . . . , Xn paarweise unabhängige Bernoulli-Experimente und X = X1 + · · · + Xn . Dann gelten E [X ] = np und Var[X ] = Var[X1 ] + · · · + Var[Xn ] = npq. 33 / 362 Anwendung: Bucket-Sort oder das Sortieren in Eimern Eingabe seien Zahlen a1 , . . . , an ∈ [0, 1). Wir wollen sie auf einer RAM in erwarteter Linearzeit sortieren. (Dies erfordert eine Annahme über die Verteilung der ai , die wir später formulieren. Definiere ein Feld B[0..(n − 1)]. Jede Eimer b[i ] ist eine initial leere Liste von Zahlen. In einem linearen Durchlauf hänge aj and die Liste im Bucket B[⌊n · aj ⌋] an. Sortiere die Liste B[i ] in einem listengeeigneten Verfahren: etwa Bubble-Sort. Füge die Listen B[i ] zu der sortierten Liste B[0], . . . , B[n − 1] zusammen. Sei Xi (π) = |B[i ]| (π) die Zufallsvariable, die die Länge des Buckets B[i ] misst (wenn π = (π(1), , . . . , π(n)) mit Pπ(j) = aj die Eingabepermutation ist). Dann ist die Laufzeit O( i Xi2 (π)) und damit die erwartete Laufzeit X O( E Xi2 ). i 34 / 362 Analyse von Bucket-Sort Worst-case: Quadratisch O(n2 ): Alles in einem Eimer. Angenommen, die aj sind paarweise unabhängig in [0, 1) gewählt und die Aufteilung in die Eimer sei gleichverteilt. Definiere weitere Zufallsvariablen Xij = “aj landet in B[i ]”. Formal Xij (π) = 1 falls π(j) ∈ B[i ] und Xij (π) = 0 sonst. Dann gilt aufgrund der Gleichverteilung Pr[aj landet in B[i ]] = Pr[Xij = 1] = E [Xij ] = 1/n. P P Also Xi = j Xij und damit E [Xi ] = j E [Xij ] = n · n1 = 1. Ferner gilt aufgrund der paarweisen Unabhängigkeit (siehe Bernoulli-Experimente): X X 1 1 1 Var[Xi ] = Var[Xij ] = (E Xij2 − E [Xij ]2 ) = n( − 2 ) = 1 − . n n n j Es folgt j X X E Xi2 = (Var[Xi ] + E [Xi ]2 ) = 2n − 1. i i Im Mittel erhalten wir eine lineare Laufzeit O(n). 35 / 362 Quicksort Quicksort-Algorithmus 1962 von Hoare: Wähle Pivotelement. Zerlege das Feld in zwei Teilfelder mit Pivot als Trennung. Nach linear vielen Vertauschungen sind die Elemente im linken Teilfeld kleiner oder gleich Pivot, im rechten größer oder gleich Pivot. Wende auf beide Teilfelder rekursiv den gleichen Algorithmus an. Wichtig: die Wahl des Pivots. Laufzeit ist optimal, falls das Pivotelement gleich dem mittleren Element des Feldes (Median) ist. In der Praxis bewährt: die Median-aus-Drei-Methode. 36 / 362 Quicksort mit Median-aus-3 procedure quicksort(A[ℓ . . . r ] : array of integer) begin if ℓ < r then p := Index des Median von A[ℓ], A[(ℓ + r ) div 2], A[r ]; (* Mathematische Analyse benutzt Median aus 3 zufällig gewählten Elementen*) m := partitioniere(A[ℓ . . . r ], p); (* Feld bzgl. A[p] partitionieren *) quicksort(A[ℓ . . . m]); (* linkes Teilfeld sortieren *) quicksort(A[m + 1 . . . r ]); (* rechtes Teilfeld sortieren *) endif endprocedure Bemerkung Tatsächlich kann es besser sein, das kleiner Feld zuerst zu sortieren. (Rekursionstiefe bleibt dann logarithmisch.) 37 / 362 Analyse von Quicksort und Quickselect. 38 / 362 Quicksort: Komplexität Worst-case Der Quicksort-Algorithmus ist quadratisch: In jedem Schritt enthält eines der beiden Teilfelder genau ein Element. Mögliches Szenario: Liste bereits (fast) sortiert, Pivot ist stets das erste oder letzte Element. Hier: Durchschnittsanalyse unter der Annahme einer zufälliger Auswahl des Pivotelements. Die alternative Annahme, dass das Feld zufällig angeordnet ist, ist möglich, aber sinnlos2 Satz 3.5 Q(n) := P die mittlere Anzahl der Schlüsselvergleiche. H(n) := nk=1 k1 = n-te harmonische Zahl. Dann gilt für Quicksort: Q(n) = 2(n + 1)H(n) − 4n. 2 Frei nach Loriot (1923-2011) 39 / 362 Quicksort: Interpretation der Durschnittsanalyse Es ist H(n) − ln n ≈ 0,57 . . . = Eulersche Konstante. Also: Q(n) ≈ 2(n + 1)(0,57 + ln n) − 4n ≈ 2n ln n − 2,8n ≈ 1,38n log2 n − 2,8n. Theoretische Grenze: log(n!) = n log n − 1,44n; Quicksort ist im Mittel um 38% schlechter. Eine Durchschnittsanalyse der Median-aus-Drei-Methode liefert 1,18n log n − 2,2n. Dies ist im Mittel nur noch um 18% schlechter. 40 / 362 Quickselect Algorithmus 3.1 function quickselect(A[ℓ . . . r ] : array of integer, k : integer) : integer begin if ℓ = r then return A[ℓ] else p := random(ℓ, r ); m := partitioniere(A[ℓ . . . r ], p); k ′ := (m − ℓ + 1); if k ≤ k ′ then return quickselect(A[ℓ . . . m], k) else return quickselect(A[m + 1 . . . r ], k − k ′ ) endif endif endfunction 41 / 362 Durchschnittsanalyse mit Zufallsvariablen ◮ Q(n) durchschnittliche Anzahl an Vergleichen bei Quicksort, um ein Feld der Größe n zu sortieren (bzw. bei Quickselect, um das k-te Element in einem Feld der Größe n zu finden). Das Feld ist fest gewählt. Bei Quicksort wird jedes Element genau einmal ein Pivot-Element. Mit π bezeichnen wir die zufällige Reihenfolge, in der Pivot-Elemente gezogen werden. Es sei 1 ≤ k ≤ n fest. Im Folgenden bezeichnen i , j Werte mit 1 ≤ i < j ≤ n. Im Laufe von Quickselect (oder auch Quicksort) werden i und j maximal einmal verglichen. Falls sie verglichen werden ist dann i oder j aktuelles Pivotelement. ◮ Xij (π) := i wird mit j verglichen“ ∈ {0, 1}. ” Es gilt in beiden Fällen X X Q(n) = E [ Xij ] = E [Xij ] = ◮ 1≤i <j<n 1≤i <j<n X Pr[Xij = 1] . 1≤i <j<n 42 / 362 Durchschnittsanalyse von Quicksort Pr[Xij ] ist die Wahrscheinlichkeit, dass in der Zufallsfolge π das erste Element in dem Intervall [i , . . . , j] entweder i oder j ist. (Ansonsten werden i und j getrennt und nie verglichen.) Also 2 . Pr[Xij ] = j −i +1 Also Q(n) = X Pr[Xij = 1] = 1≤i <j<n Wir berechnen q(n) = Q(n)/2 = X 1≤i <j≤n X 1≤i <j≤n 2 . j −i +1 1 . j −i +1 Behauptung q(n) = (n + 1)H(n) − 2n. 43 / 362 Beweis von q(n) = (n + 1)H(n) − 2n: q(n) = X n−1 n−d 1≤i <j≤n = XX 1 1 = j −i +1 d +1 n−1 X n−d d=1 d wie Differenz” ” d=1 i =1 d +1 = −n + n−1 X n−d d=0 d +1 n−1 X d +1−1 = −n + nH(n) − d +1 d=0 = −n + nH(n) − n − Also = −n + nH(n) − n + H(n) = (n + 1)H(n) − 2n n−1 X −1 d +1 d=0 Q(n) = 2q(n) = 2(n + 1)H(n) − 4n ≈ 2n ln n ≈ 1, 38n log2 (n). 44 / 362 Durchschnittsanalyse von Quickselect Unterscheide 3 Fälle: 1. Fall: i < j ≤ k. Xij (π) = i oder j wird als erstes ” im Intervall [i , . . . , k] gezogen“ = k−i2+1 X X 1≤i <k i <j≤k X k −i k −i +1 1≤i <k X 1 =2 1− k −i +1 Xij (π) = 2 1≤i <k = 2(k − 1 − H(k)) wobei H(k) ∈ Θ(ln k) die harmonische Funktion ist. 2 und 2. Fall: k ≤ i < j, analog folgt Xij (π) = j−k+1 X X Xij (π) = 2(n − k + 1 − H(n − k + 1)) k<j≤n k≤i <j 45 / 362 Durchschnittsanalyse: 1. und 2. Fall Die beiden ersten Fälle ergeben zusammen einen linearen Term: 2n − H(k) − H(n − k + 1) ∈ 2n − Θ(log n). 46 / 362 Durchschnittsanalyse von Quickselect 3. Fall: i < k < j Xij (π) = X X 2 j−i +1 Xij (π) = 2 1≤i <k k<j≤n X X 1≤i <k k<j≤n =2 X 1≤i <k <2 X 1≤i <k 1 j −i +1 1 1 + ··· + k −i +2 n−i +1 (ln(n − i + 1) − ln(k − i )) n = 2 ln k −1 47 / 362 Durchschnittsanalyse von Quickselect ◮ ◮ ◮ ◮ 1. Fall + 2. Fall zusammen ergeben < 2n n Mit kn ≤ 2n ergibt sich: Q(n) < 2 n + ln k−1 ≤ 2(1 + ln(2))n n (für n ≥ 2): Im Fall k = ⌈n/2⌉ folgt mit n1 2n ≤ ⌈n/2⌉ Q(n) > 2 (1 + ln(2)) n − c log(n) für ein geeignetes c Das heißt, Q(n) = 2(1 + ln(2))n − log -Terme für k ≈ n/2. Für die Median-Berechnung mit Quickselect werden im Mittel also 3,38n < 2 · 1,693147181n < 3,4n Vergleiche benötigt. 48 / 362 4. Vorlesung 24. April 2017 Hashing-Verfahren sind in der Praxis allgegenwärtig. Sie sind theoretisch und praktisch gut untersucht. Wir behandeln hier nur die Grundkonzepte. 49 / 362 Erinnering: Geburtstagsparadoxon Sind mehr als 23 Personen auf einer Party, so ist die Wahrscheinlichkeit größer als 1/2, dass zwei Gäste am gleichen Tag Geburtstag haben. Stellen wir die Gäste in eine Reihe und jeder nennt seinen Geburtstag (Tag und Monat), so erhalten wir eine Folge. Die Wahrscheinlichkeit, dass die ersten i + 1 Folgenglieder alle verschieden sind, ist dann: n−i 1 i n n−1 ··· =1· 1− ··· 1 − ≤ · n n n n n Die Wahrscheinlichkeit, dass alle m Geburtstage verschieden sind, ist daher: Pr[alle verschieden] ≤ m−1 Y i =0 i 1− n ≤ m−1 Y i e− n = e− Pm−1 i =0 i n = e− m(m−1) 2n i =0 Der Grenzwert 1/2 wird also spätestens im Bereich von m = n = 365 (oder 366) ist dies 23. √ 2n ln 2 unterschritten. Für 50 / 362 Folgerung für Hashing-Verfahren Hat eine Hashtabelle nicht mindestens quadratische Größe, so ist mit Kollisionen zu rechnen. Also, Kollisionsauflösung ist ein wichtiges Thema, wird aber aus Zeitgründen hier nur durch Verkettung gelöst. Dass Kollisionen auftreten, kann man auch beim Bildersammeln feststellen. 51 / 362 Coupon Collector Problem Coupon Collection: Angenommen, beim Kauf einer Schachtel findet man jedes Bild aus einer Sammlung von m Bildern mit der Wahrscheinlichkeit 1/m. Dann muss man durchschnittlich mH(m) ≈ m ln m Schachteln kaufen, bevor die Sammlung vollständig ist. Die Folge der Bilder wird als eine Folge zufälliger Hasheinträge in eine Tabelle der Größe m interpretiert. Wir teilen diese in m Abschnitte ein. Der i -te Abschnitt endet, wenn man einen bisher nicht verwendeten Hasheintrag besucht. Wir definieren Xi als die Länge der Abschnitte, also X1 = 1. Die Wahrscheinlichkeit, dass j das letzte Element in Abschnitt i ist, ist m−im+1 . Also gilt E [Xi ] = m−im+1 . Damit ist # " m m m X X X 1 m =m = mH(m). Xi = E m−i +1 m−i +1 i =1 i =1 i =1 52 / 362 Open Street Map Daten, die in OSM eingetragen werden, erhalten fortlaufende Nummern als Schlüssel. Früher dachte man irrtümlich, 32 Bit würden reichen, aber nach einem Überlauf ging man zu 64 Bit über. Die Daten werden in einer zeitlichen Reihenfolge in die OSM-Datenbank eingetragen. Direkte Adressierung array[0..264 − 1] ist unmöglich. Angenommen, wir interessieren uns nur für die OSM Daten aus Stuttgart. Dies sind ca. 220 Datensätze. Vorgehen: In der Preprocessing-Phase füttere die Stuttgarter Daten in ein Hashtabelle. Typischerweise nimmt man eine kleine Zahl von Kollisionen bewusst in Kauf. Nachdem man einmal die Daten gefiltert hat, kann man sie etwa sortieren, um dann auf direkte Adressierung zurückgreifen zu können. Dies ist ein nicht-fiktive Anwendung. Offensichtlich sind die Stuttgarter Einträge fern 64 jeder Zufallsverteilung in dem Raum 0.., . . . , 2 − 1 . 53 / 362 Steuernummern Präludium Jeder Bürger der BRD soll (seit 2007) eine Steueridentifikationsnummer erhalten. Die Steueridentifikationsnummer ist eine zufällige 10-stellige Dezimalzahl mit einer elften Ziffer als Prüfziffer. Die erste Ziffer ist keine 0. Es gibt also 9 · 109 mögliche Steueridentifikationsnummern in dem Universum von 100.000.000.000 elf-stelligen Zahlen. Bürger in der BRD gibt es wohl auf lange Zeit weniger als 100.000.000. Also wird nur jede 1000-te Nummer überhaupt benötigt. Sei jetzt S die Menge der steuerpflichtigen Bürger in Stuttgart. Setze n = |S|. Naive Schätzung: n ≤ 200.000. Wir wollen jetzt diese, sagen wir maximal 218 Schlüssel abspeichern. Wir verwenden eine Hash-Tabelle. Die Größe dieser Tabelle soll linear in n sein und möglichst einen Speicherzugriff in O(1) erlauben. 54 / 362 eTIN vs. Steueridenitifikationsnummer Seit 2003 haben Steuerpflichtige auch eine eTIN. Dies ist ein 14-stelliger Code. Meine beginnt mit den 8 Buchstaben DKRTVLKR und dann folgen 2 Ziffern, ein Buchstabe – bei mir F – zwei Ziffern sowie ein Buchstabe als Prüfziffer. Steueridenitifikationsnummern lassen sich sehr gut hashen. Es reicht, wie bei Bucketsort, für Stuttgarter, einfach die 18 ersten Bits der Steueridenitifikationsnummer als Hashwert zu verwenden. Die Tabellengröße entspricht ungefähr der Zahl der Einträge und die mittlere Zeit festzustellen, ob eine Nummer einem Stuttgarter gehört, ist O(1). Denn die Nummern wurden zufällig erzeugt. Für eTIN’s ist dies falsch! Die Verteilung der eTIN’s ist überhaupt nicht zufällig. 55 / 362 Problem und Lösung 1. Problem: Annahmen über Schlüsselmengen zu realen Daten können nicht von einer Gleichverteilung ausgehen. U 2. Ansatz. Die Menge S ⊆ U wurde nicht zufällig in |S| gewählt. 3. Lösung. Universelles Hashing: Wähle zufällige Hashfunktionen. 4. Perfektes Hashing. für statische Daten 5. Pragmatik. Bei vielen Anwendungen ist der Speicherplatz wichtiger als die Suchzeit. Man nimmt also häufig bewusst kleinere Hashtabellen, wenn die die Suchzeiten gering bleiben. 56 / 362 Universelles Hashing Im Folgenden sei: ◮ U ein Universum von möglichen Schlüsseln. ◮ S ⊆ U eine Teilmenge von n Elementen die in einer Hashtabelle T der Größe m abgespeichert werden soll. ◮ |S| = n, |T | = m mit dem Belegungsgrad β = n/m. ◮ ◮ ◮ h : U → T Hashfunktion. H eine Familie von Hashfunktionen. Gleichverteilung auf H. Wir behandeln nur Hashing mit Verkettung: Jeder Tabelleneintrag T [i ] ist eine Liste mit den Schlüsseln h−1 (i ) ⊆ S. Definition 4.1 H heißt universell, falls für alle x 6= y aus U gilt Pr[h(x) = h(y )] ≤ 1/m. 57 / 362 Existenz universeller Hashfamilien Satz 4.2 Sei p eine Primzahl mit p ≥ |U| und Fp = { 0, . . . , p − 1 } der Körper, in dem wir modp” rechnen. Für a ∈ F∗p = Fp \ { 0 } und b ∈ Fp setze ” hab (x) = (ax + b mod p) mod m. Dann ist hab (x) ∈ Z/mZ = { 0, . . . , m − 1 } = T und H = hab (a, b) ∈ F∗p × Fp eine universelle Familie von Hashfunktionen der Größe (p − 1)p. 58 / 362 Beweis von Satz 4.2 |H| = (p − 1)p ist trivial. Für x ∈ U definiere hab,p (x) = ax + b mod p ∈ Fp . Betrachte jetzt x, y ∈ U mit x 6= y . Dann gilt, da a 6= 0 ∈ Fp : hab,p (x) = ax + b mod p 6= ay + b mod p = hab,p (y ). Sei r = hab,p (x) und s = hab,p (y ). Dann kann man (a, b) aus (r , s) in Fp zurückrechnen. a = (r − s)(x − y )−1 mod p, b = r − ax mod p. Die Gleichverteilung auf H = F∗p × Fp überträgt sich auf eine Gleichverteilung in Hp = { (r , s) ∈ Fp × Fp | r 6= s } . Also Pr[{ h ∈ H | h(x) = h(y ) }] = Pr[{ r ≡ s mod m | (r , s) ∈ Hp }] 59 / 362 Beweis von Satz 4.2. Fortsetzung Es gilt für jedes r ∈ Fp : Pr[{ (r , s) ∈ Hp | r ≡ s mod m }] = Pr[{ s ∈ Fp \ { r } | r ≡ s mod m }] Ferner: |{ s ∈ Fp \ { r } | r ≡ s mod m }| ≤ ⌈p/m⌉ − 1 ≤ p+m−1 p−1 −1= m m Wir erhalten Pr[{ s ∈ Fp \ { r } | r ≡ s mod m }] ≤ 1/m. Also gilt die Behauptung, sogar genauer: 2 1 1 − ≤ Pr[{ h(x) = h(y ) | h ∈ H }] ≤ . m p m 60 / 362 Erwartungswerte beim universellen Hashing Satz 4.3 Sei H universell, u ∈ U und h : U → T ∈ H zufällig gewählt. Sei S ⊆ U mit n = |S| und m = |T |, β = n/m. Sei Nu die Zufallsvariable Nu = |{ v ∈ S | h(u) = h(v ) }|. Dann gilt: 1. Für u ∈ S gilt E [Nu ] ≤ 1 + β. 2. Für u ∈ / S gilt E [Nu ] ≤ β. Beweis: Setze Xuv (h) = [h(u) = h(v )] (Indikatorfunktion). Dann E [Xuv ] ≤ 1/m, da H universell. Setze X Yu = Xuv . v ∈S,u6=v Dann E [Yu ] ≤ n m = β. 1. Für u ∈ S gilt E [Nu ] = 1 + E [Yu ] ≤ 1 + β. 2. Für u ∈ / S gilt E [Nu ] = E [Yu ] ≤ β. 61 / 362 5. Vorlesung, 25.04.2017 Perfektes Hashing und Authentifizierung Entropie: untere Schranken 62 / 362 Zweistufiges Hashing Perfektes Hashing für statische Daten Im Folgenden sei S ⊆ U statisch und |S| = n. Gesucht ist eine Hashfunktion h : U → T , die sich schnell finden lässt und für die gilt. ◮ sie ist kollisionsfrei, also ist h : U → T , die injektiv auf S und damit n ≤ m = |T | ∈ Ω(n). ◮ Die Hashtabelle hat lineare Größe, also |T | ∈ Ω(n). Dies gelingt uns durch perfektes Hashing mit m = 4n in einem Monte-Carlo Verfahren: Starte mit einer beliebigen universellen Familie H. Definiere für jedes k ∈ T eine Zufallsvariable nk : H → N; Satz 4.4 Für m = n gilt: n ≤ E P k∈T h 7→ nk (h) = |{ u ∈ S | h(u) = k }| . nk2 ≤ 2n − 1. 63 / 362 Beweis von Satz 4.4 Für alle x gilt x 2 = x + 2 x2 . Also X X X nk nk 2 nk = (nk + 2 )=n+2 . 2 2 k∈T k∈T Zeige daher nur E k∈T " X nk k∈T 2 Sei wieder Xuv (h) = [h(u) = h(v )]; dann ist X nk = 2 k∈T # ≤ n−1 . 2 X { u,v }∈( Xuv . S 2 ) Da H universell ist, folgt E [Xuv ] ≤ 1/m ≤ 1/n. Also # " X nk n−1 n 1 . ≤ · = E n 2 2 2 k∈T 64 / 362 Wahl einer primären Hashfunktion und sekundäre Tabellen Aus der Markov-Ungleichung folgt, dass für mehr als die Hälfte aller h ∈ H gilt X nk2 (h) < 4n. k∈T Wir können also davon ausgehen, dass wir nach Pkonstant vielen Versuchen eine feste primäre Hashfunktion hS gefunden haben, die k∈T nk2 (hS ) < 4n erfüllt. Die Idee ist jetzt, die Werte in T [k] in Hashtabellen Tk zu speichern, wobei immer |Tk | = nk2 = nk2 (hS ) gelten soll. Dies geschieht mittels injektiver sekundärer Hashfunktionen, die jeweils aus universellen Familien Hn2 gewählt werden. k Die Summe der Größen aller sekundären Hashtabellen ist also durch 4n begrenzt. Die mögliche Wahl der sekundärer Hashfunktionen liefert der folgende Satz 4.5. 65 / 362 Injektive Hashfunktionen Satz 4.5 Für n2 ≤ m gilt: Pr[h ist kollisionsfrei ] > 1/2. Bemerkung: Die Aussage des Satzes ähnelt stark derjenigen im Geburtstagsparadoxon. Beweis: Sei X = P { u,v }∈(S2 ) Xuv . Dann ist n2 1 n 1 < ≤ . E [X ] ≤ 2m 2 2 m Für mehr als die Hälfte der h ∈ H einer universellen Familie H ist also X (h) < 1. Nun ist X (h) stets eine natürliche Zahl und es ist X (h) = 0 ⇐⇒ h ist injektiv. 66 / 362 Perfektes Hashing: Realisierung Sei S ⊆ U fest und |S| = n. Wir nehmen an, dass 4n < |U| gilt. 1. Wähle Primzahl p ≥ 4 |U| und verwende für m ≤ 4n die Hashfunktionen hab,m (x) = (ax + b mod p) mod m. Dies definiert universelle Familien Hm . P 2. Finde hS ∈ H4n mit k∈T nk2 (hS ) ≤ 4n. 3. Bilde die primäre Hashstruktur T . 4. Definiere Sk = T [k] ⊆ U mit |Sk | = nk (hS ). Setze mk = nk2 (hS ). 5. Für jedes k ∈ T definiere ein sekundäre Hashtabelle Tk der Größe mk . 6. Finde für jedes k eine eigene injektive Hashfunktion hk ∈ Hmk , die injektiv auf Sk ist. Für eine statische Menge S können wir durch perfektes Hashing eine Suchzeit von O(1) im schlechtesten Fall garantieren, wobei die Hashtabellen insgesamt nur linearen Speicherplatz verbrauchen. 67 / 362 Paarweise universelle Hashfamilien Eine Familie H von Hashfunktionen h : U → T heißt paarweise universell, falls für m = |T | und alle x, y ∈ U mit x 6= y und alle r , s ∈ T gilt: Pr[h(x) = r ∧ h(y ) = s] = 1/m2 . Satz 4.6 Seien d ≥ 1, p eine Primzahl und T = Fp = Z/pZ. Sie ferner U = Fdp , d.h., ein Schlüssel x wird blockweise durch d Werte in { 0, . . . , p − 1 } kodiert: x = (x1 , . . . , xd ). Für (a, b) = (a1 , . . . , ad , b) ∈ Fd+1 definiere p d X ai xi ) + b mod p). hab (x) = (( i =1 Dann ist hab (x) ∈ Fp = T und Hp,d = Familie von Hashfunktionen. hab (a, b) ∈ Fd+1 eine paarweise universelle p 68 / 362 Beweis von Satz 4.6 Seien r , s ∈ Fp und (x1 , . . . , xd ), (y1 , . . . , yd ) ∈ U mit xi 6= yi für ein i ∈ { 1, . . . , d }. Ohne Einschränkung ist i = 1. Fixiere (a2 , . . . , ad ) ∈ Fd−1 . Dann gibt es für jedes Paar p 2 2 (r , s) ∈ Fp genau ein Paar (a1 , b) ∈ Fp mit h(a1 ,...,ad ,b) (x) = r und h(a1 ,...,ad ,b) (y ) = s. Hieraus folgt Pr[h(x) = r ∧ h(y ) = s] = 1/p 2 . 69 / 362 Hashing und Authentifizierung: elektronische Unterschrift Alice und Bob einigen sich öffentlich auf das folgende Schema. 1.) Ein Dokument ist ein Element x ∈ U = Fdp für eine Primzahl p. 2.) Die Unterschrift t ist der Hashwert hab (x) ∈ Fp mit hab ∈ Hp,d . 3.) Bob wählt h ∈ Hp,d zufällig und übermittelt h geheim, etwa mittels RSA, an Alice. 4.) Nachdem Alice h kennt übermittelt sie ein Dokument x ∈ U in der Form (x, h(x)) an Bob, wobei h(x) ihre Unterschrift ist. Szenario Bob erhält ein unterschriebenes Dokument (y , s) und will sicher” sein, dass Alice y ∈ U ” mit s unterschrieben hat. 70 / 362 Sichere elektronische Unterschrift sind möglich Satz 4.7 Angenommen Alice beabsichtigt, an Bob über Oskar ein unterschriebenes Dokument (x, h(x)) zu senden, der jedoch (y , s) mit x 6= y weitergibt. Oskar wählt die Unterschrift” s ∈ Fp bzgl. irgendeiner selbstgewählten Strategie. Falls Oskar die geheime ” Hashfunktion h nicht kennt, gilt: Pr[Bob akzeptiert die Unterschrift] = 1/p. Proof. Übungsaufgabe. 71 / 362 Weiterführende Literatur Perfektes Hashing wurde von Fredman, M. L., Komlós, J., and Szemerédi, E. 1984. Storing a Sparse Table with O(1) Worst Case Access Time. J. ACM 31, 3 (Jun. 1984), 538-544 eingeführt Dynamisches perfektes Hashing wurde in der folgenden Arbeit untersucht. Dietzfelbinger, M., Karlin, A., Mehlhorn, K., Meyer auf der Heide, F., Rohnert, H., and Tarjan, R. E. 1994. Dynamic Perfect Hashing: Upper and Lower. SIAM J. Comput. 23, 4 (Aug. 1994), 738-761. Hashing und Authentifizierung: diverse Publikationen, spätestens seit: Bellare, M., Canetti, R., and Krawczyk, H.: Keying hash functions for message authentication. In: Advances in Cryptology – Crypto 96 Proceedings. LNCS 1109, Springer, 1996, S. 1–15 72 / 362 Entropie Entropie ist ein dem altgriechischen entlehntes Kunstwort und kann als ein Maß für Unbestimmtheit oder Unordnung gedeutet werden. ◮ In der Physik erhält die Entropie über die Boltzmann-Konstante eine Einheit: Joule/Kelvin. Fundamentale Bedeutung durch den zweiten Hauptsatz der Thermodynamik. ◮ Quantenmechanik: von-Neumann-Entropie (1932). ◮ Philosophie: Zeitempfinden folgt der Entropiezunahme? Zeitreisen? ◮ Informationstheorie: Shannon-Entropie (1948). ◮ Hier: Entropie von Zufallsvariablen mit endlichem Wertebereich. 73 / 362 Entropie in der Informationstheorie Sei X : Ω → W eine Zufallsvariable mit endlichem Wertebereich W . Im Folgenden Pn sei |W | = n und pi = Pr[X = wi ] für W = { w1 , . . . , wn }. Also gilt i =1 pi = 1 und pi ≥ 0. Definiere die Shannon-Entropie durch H(X ) = H(p1 , . . . , pn ) = − n X pi log(pi ). i =1 Hier und im Folgenden log(x) = log2 (x) und x log(x) = 0 für x = 0. H(X ) unterscheidet sich nur um den konstanten Faktor ln(2) von der natürlichen” ” von-Neumann-Entropie: He (X ) = He (p1 , . . . , pn ) = − n X pi ln(pi ). i =1 74 / 362 Lemma von Gibbs Lemma P 5.1 P Seien ni=1 pi = 1, ni=1 qi ≤ 1 und pi , qi ≥ 0 beliebig, dann gilt mit Gleichheit nur bei (p1 , . . . , pn ) = (q1 , . . . , qn ): n X i =1 pi ln(pi ) ≥ n X pi ln(qi ). i =1 Der Beweis benutzt für |x| < 1 die Reihendarstellung − ln(1 − x) = (oder nach einem Schaubild): x − 1 ≥ ln x. Folgerung für H(X ) = H(p1 , . . . , pn ) Für beliebige Verteilungen qi gilt H(X ) = H(p1 , . . . , pn ) ≤ − Gleichheit nur bei (p1 , . . . , pn ) = (q1 , . . . , qn ). Pn P i =1 pi xk k≥k k und daher log(qi ) mit 75 / 362 Beweis des Lemmas von Gibbs Ohne Einschränkung ist pi > 0 für alle i . Zu zeigen: 0≥ n X pi ln( i =1 qi ). pi Wegen x − 1 ≥ ln x reicht zu zeigen: 0≥ n X i =1 pi ( n n n X X X qi qi ) − 1. pi = ( qi − − 1) = pi Die letzte Zeile gilt, da nach Voraussetzung i =1 i =1 i =1 Pn i =1 qi ≤ 1. 76 / 362 Einige weitere Eigenschaften und Folgerungen ◮ ◮ ◮ H(p1 , . . . , pn ) ≤ − Pn i =1 pi log(1/n) = log2 (n). H(p1 , . . . , pn , 0) = H(p1 , . . . , pn ). Gruppierungseigenschaft: H(p1 , . . . , pn ) = H(p1 + p2 , p3 , . . . , pn ) + (p1 + p2 )H( p2 p1 , ). p1 + p2 p1 + p2 Bemerkung zum Beweis 1. Zeile: Lemma von Gibbs. 2. Zeile: trivial. 3. Zeile: sieht kompliziert aus, ist aber trivial. 77 / 362 Lemma von Kraft, Huffman-Kodierung und Entropie Später, zunächst die Entropie assimilieren 3 3 Assimilation (Biologie), die schrittweise erfolgende Stoffumwandlung körperfremder in körpereigene Stoffe, sowohl im Pflanzen- als auch Tierreich. 78 / 362 6. Vorlesung, 02.05.2017 Bottom-Up Heapsort Greedy Algorithmen Huffman Codes 79 / 362 Heapsort Konvention: a[1 . . . n] ist ein Feld mit Elementen einer linear geordneten Menge. Hier: Zahlen und außerdem a[i ] = −∞ für i < 0 und a[i ] = +∞ für n < i . Definition 6.1 Ein (Min-)Heap ist ein Feld a[1 . . . n] mit der Eigenschaft a[i ] ≤ min{a[2i ], a[2i + 1]}. Heapsort aus zwei Teilen: 1. Heapaufbau. Der Heap wird dabei von rechts nach links aufgebaut, wodurch viele kleine und nur wenige große Heaps betrachtet werden. Danach ist a[1] das kleinste Element. 2. Sortieren. Wir sortieren durch Vertauschung von a[1] und a[n]. Danach steht das kleinste Element hinten. Wir betrachten jetzt mit a[1 . . . n − 1] als neues Feld. Die Heapbedingung in a[1 . . . n − 1] ist jetzt, wenn überhaupt, nur bei a[1] verletzt und a[1] muss einsinken. 80 / 362 Heapsort x y 2 Vergleiche, um min{x, y , z} zu bestimmen z Ist y das Minimum, dann vertausche x und y . Analog für z. Ist x das Minimum, dann stoppt der Einsinkprozess. 81 / 362 Reheap Algorithmus 6.1 Reheap procedure reheap(i , n: integer) var m: integer; begin if i ≤ n/2 then m := min{a[i ], a[2i ], a[2i + 1]}; if (m 6= a[i ]) ∧ (m = a[2i ]) then swap(i , 2i ); reheap(2i , n) elsif (m 6= a[i ]) ∧ (m = a[2i + 1]) then swap(i , 2i + 1); reheap(2i + 1, n) endif endif endprocedure (∗ i ist die Wurzel ∗) (∗ 2 Vergleiche! ∗) (∗ vertausche x, y ∗) (∗ vertausche x, z ∗) 82 / 362 Heap-Aufbau for i := n 2 downto 1 do reheap(i , n) endfor Die Invariante hierfür ist: a[i . . . n] erfüllt die Heap-Bedingung bereits vor dem Aufruf reheap(i − 1, n). Für i = n2 + 1 ist dies richtig. Setze i um 1 herab, dann ist die Heapbedingung in a[i ] eventuell verletzt. Nach dem Einsinken ist die Invariante erneut erfüllt. 83 / 362 Zeitanalyse Das Einsinken kostet maximal 2 · (Höhe des Teilbaums unter a[i ]) Vergleiche. Wir führen die Analyse für n = 2k − 1 durch, d.h. die maximale Höhe des Heaps ist k − 1. Allgemein gibt es ◮ ◮ ◮ ◮ 20 Bäume der Höhe k − 1, 21 Bäume der Höhe k − 2, 2i Bäume der Höhe k − 1 − i , 2k−1 Bäume der Höhe 0. 84 / 362 Zeitanalyse Daher sind zum Heapaufbau für n = 2k − 1 maximal Q1 (n) = 2 · k−1 X i =0 2i (k − 1 − i ) Vergleiche nötig. Nach einer Indexvertauschung (j = k − 1 − i ) ergibt sich: Q1 (n) = 2 · 2k−1 · Wir zeigen auf der nächsten Folie Satz 6.2 P k−1 X j≥0 j j=0 j · 2−j ≤ 2k · X j≥0 j · 2−j · 2−j = 2 und erhalten damit: Heapaufbau ist in linearer Zeit mit weniger als 2(n + 1) Vergleichen möglich. 85 / 362 Beweis von P j≥0 j · 2−j = 2 Wir setzen für |z| < 1: f (z) = X j≥0 und leiten ab: f ′ (z) = X j≥0 Also: z · f ′ (z) = Also: X j≥0 j · (1/2)j = zj = 1 1−z j · z j−1 = X j≥0 j · zj = 1 (1 − z)2 z (1 − z)2 f ′ (1/2) 1 = =2 2 2 · (1 − (1/2))2 86 / 362 Standard Heapsort Algorithmus 6.2 Heapsort procedure heapsort(n: integer) begin for i := n2 downto 1 do reheap(i , n) endfor for i := n downto 2 do swap(1, i ); reheap(1, i − 1) endfor endprocedure Satz 6.3 Standard Heapsort erfordert 2n log n + O(n) Vergleiche. Beweis: Der Aufbau erfordert O(n) und der Abbau durch Einsinken 2n log n Vergleiche. 87 / 362 Bottom-Up-Heapsort Bemerkung 6.4 Eine Analyse der Durchschnittskomplexität von Heapsort ergibt einen mittlerer Aufwand von 2n log n Vergleichen. Damit ist Standard-Heapsort zu Quicksort nicht konkurrenzfähig. Bottom-Up-Heapsort benötigt wesentlich weniger Vergleiche. Nach dem Entfernen der Wurzel wird zuerst der potentielle Einsinkpfad des Elementes bestimmt. Es wird der Weg verfolgt, der immer zum kleineren der beiden Nachfolger führt (Kosten: nur log n statt 2 log n Vergleiche). Da erwartungsgemäß dieses Element tief einsinken wird, bietet sich anschließend eine bottom-up Bestimmung der tatsächlichen Position auf dem Einsinkpfad an. Hoffnung: Die bottom-up Bestimmung erfordert insgesamt nur O(n) Vergleiche. 88 / 362 Grundidee x0 Es gilt xi ≤ yi für 1 ≤ i ≤ Höhe. ✛ ✲ y1 x1 Vergleich Das Einsinken geschieht längs dieses Pfades, der mit log n Vergleichen bestimmt werden kann. y2 ✛ ✲ x 2 y3 ✛ ✲ x3 x4 ✛ ✲ y4 89 / 362 Die mittlere Höhe eines Knotens Die erwartete Höhe eines Knotens in einem Binärbaum mit zufälliger Knotenverteilung ist: ∞ 1 1 1 1X n 0 · + 1 · + 2 · + ··· = =1 2 4 8 2 2n n=0 Wir bestimmen jetzt vom Blatt aus (also bottom-up) die tatsächliche Position auf dem Einsinkpfad. Ist die Position i gefunden, so werden die Elemente x0 , . . . , xi zyklisch vertauscht (x0 geht an die Stelle von xi , und x1 , . . . , xi rutschen hoch). 90 / 362 Varianten Es kann gezeigt werden, dass im schlechtesten Fall höchstens 1,5n log n + o(n log n) Vergleiche benötigt werden. Wenn man nach Carlsson auf dem Pfad eine binäre Suche anwendet, so kommt man auf einen Aufwand von höchstens n log n + O(n log log n). Eine binäre Suche ist aber in der Praxis zu aufwendig und außerdem steigt man in den Pfad i.Allg. zu hoch ein. Durch eine leichte Abwandlung der reinen bottom-up Positionsbestimmung können wir die Zahl der wesentlichen Vergleiche auf n log n + o(n log n) bringen. 91 / 362 Anwendungen Verwalten wir eine Prioritätswarteschlange (= Datenstruktur, die die Operationen insert, delete-min, decrease-key unterstützt) in einem Heap, so benötigt jede dieser Operationen O(log n) Zeit, wenn die Schlange nicht mehr als n Elemente enthält. 92 / 362 Greedy Entwurfsstrategie Gierige Algorithmen – Greedy Algorithms Nehme das größte Stück zuerst!” ” 93 / 362 Optimalitätsprinzip Greedy ( gierig“) bezeichnet Lösungsstrategien, die auf der schrittweisen Berechnung von ” Teillösungen (lokalen Optima) basieren. Dieses Verfahren eignet sich für Probleme, bei denen jede Teilfolge einer optimalen Folge auch optimal ist (Optimalitätsprinzip). 94 / 362 Kürzeste Wege Klassisches Beispiel für die Greedy-Strategie ist die Bestimmung kürzester Wege (von einer Quelle aus) in einem Graphen mit positiven Kantengewichten. Graph: G = (V , E , γ) mit V die Knotenmenge, E ⊆ V × V die gewichteten Kanten, γ : E → N die Gewichtsfunktion. Das Gewicht eines Pfades ist gleich der Summe der Kantengewichte. Sei d(u, v ) für u, v ∈ V das Minimum der Gewichte aller Pfade von u nach v (mit der üblichen Konvention, dass d(u, v ) = ∞ gilt, falls kein Pfad von u nach v existiert). Die Aufgabe ist es, bei gegebenen Graphen G und Knoten u ∈P V für jedes v ∈ V einen Pfad u = u0 , u1 , u2 , . . . , un−1 , un = v mit minimalem Gewicht ni=1 γ(ui −1 , ui ) = d(u, v ) zu bestimmen. 95 / 362 Beispiel Dijkstra-Algorithmus Startknoten 0 1 1 6 3 ∞ 3 8 2 13 4 ∞ ∞ 3 6 ∞ 96 / 362 Beispiel Dijkstra-Algorithmus Startknoten 0 1 1 6 3 7 3 8 2 13 4 ∞ ∞ 3 6 14 97 / 362 Beispiel Dijkstra-Algorithmus Startknoten 0 1 1 6 3 7 3 8 2 13 4 11 7 3 6 14 98 / 362 Beispiel Dijkstra-Algorithmus Startknoten 0 1 1 6 3 7 3 8 2 13 4 11 7 3 6 13 99 / 362 Beispiel Dijkstra-Algorithmus Startknoten 0 1 1 6 3 7 3 8 2 13 4 9 7 3 6 13 100 / 362 Beispiel Dijkstra-Algorithmus Startknoten 0 1 1 6 3 7 3 8 2 13 4 9 7 3 6 12 101 / 362 Beispiel Dijkstra-Algorithmus Startknoten 0 1 1 6 3 7 3 8 2 13 4 9 7 3 6 12 102 / 362 Komplexität Dijkstra B := ∅; R := {u}; U := V \ {u}; v (u) := nil; D(u) := 0; while (R 6= ∅) do x := delete-min(R); B := B ∪ {x}; forall (x, y ) ∈ E do if y ∈ U then U := U \ {y }; v (y ) := x; D(y ) := D(x) + γ(x, y ); insert(R, y , D(y )); elsif D(x) + γ(x, y ) < D(y ) then v (y ) := x; D(y ) := D(x) + γ(x, y ); decrease-key(R, y , D(y )); endif endfor endwhile 103 / 362 Komplexität Der Dijkstra-Algorithmus verändert in jeweils den Rand. Es wird in dem Rand ◮ n mal ein insert, ◮ n mal ein delete-min, ◮ e mal ein decrease-key durchgeführt. Die Laufzeit hängt also wesentlich von der verwendeten Datenstruktur ab, die man für den Rand verwendet. 104 / 362 Bemerkungen zum Dijkstra-Algorithmus Ohne Einschränkung e ≥ n − 1 und n ≥ 2. Der Rand wird in dem abstrakten Datentyp einer Prioritätswarteschlange verwaltet. 1. Randverwaltung als Feld ergibt ein Aufwand von O(n2 ). 2. Für dünne Graphen (O(e) ⊆ o(n2 / log n)) ist es günstiger, den Rand R in einem Heap zu verwalten. Der Aufwand des Algorithmus wird damit nach der obigen Herleitung O(e log n + n log n) ⊆ O(e log n). 3. Bei Verwendung der Datenstruktur der Fibonacci-Heaps ergibt sich ein Aufwand von O(e + n log n). (Dies gilt als asymptotisch optimal: später) 4. Der Dijkstra-Algorithmus liefert nicht notwendigerweise ein korrektes Ergebnis, falls für die Kantengewichte auch negative Zahlen erlaubt sind. 105 / 362 Minimale aufspannende Bäume: Prim-Algorithmus Definition 7.1 Ein Graph G = (V , E ) heißt zusammenhängend, wenn je zwei Knoten durch einen Pfad verbunden sind. Definition 7.2 Ein Baum ist ein zusammenhängender, kreisfreier, ungerichteter Graph. Bemerkung 7.3 Jeder Baum mit n Knoten besitzt genau n − 1 Kanten. Definition 7.4 Ein minimaler aufspannender Baum (minimal spanning tree, MSB) zu einem gewichteten Graphen P G = (V , E , γ) ist ein Baum B = (V , F , γ|F ) mit F ⊆ E mit minimalem Gewicht γ(B) := e∈F γ(e). 106 / 362 Prim-Algorithmus wähle x0 ∈ V beliebig; B := {x0 }; R := ∅, U := V \ {x0 }; T := ∅; forall (x0 , y ) ∈ E do U := U \ {y }; v (y ) := x0 ; D(y ) := γ(x, y ); insert(R, y , D(y )) endfor while R 6= ∅ do x := delete-min(R); B := B ∪ {x}; T := T ∪ {v (x)x}; forall (x, y ) ∈ E , y 6∈ B do if y ∈ U then U := U \ {y }; v (y ) := x; D(y ) := γ(x, y ); insert(R, y , D(y )); elsif γ(x, y ) < D(y ) then v (y ) := x; D(y ) := γ(x, y ); decrease-key(R, y , D(y )); endif endfor endwhile return T 107 / 362 Beispiel Prim-Algorithmus Startknoten 1 3 6 8 2 4 13 3 6 108 / 362 Beispiel Prim-Algorithmus Startknoten 1 3 6 8 2 4 13 3 6 109 / 362 Beispiel Prim-Algorithmus Startknoten 1 3 6 8 2 4 13 3 6 110 / 362 Beispiel Prim-Algorithmus Startknoten 1 3 6 8 2 4 13 3 6 111 / 362 Beispiel Prim-Algorithmus Startknoten 1 3 6 8 2 4 13 3 6 112 / 362 Beispiel Prim-Algorithmus Startknoten 1 3 6 8 2 4 13 3 6 113 / 362 Beispiel Prim-Algorithmus Startknoten 1 3 6 8 2 4 13 3 6 114 / 362 Korrektheit des Prim-Algorithmus Idee: Austauschsatz. (Ausführlicher Beweis an der Tafel) Bi −1 y′ Ri −1 ∈T y v (x) 6∈ T x 115 / 362 Huffman-Codes Thema einer Seminararbeit am MIT von 1951: Finde einen optimalen Präfixcode”. ” Das Ergebnis wurde 1952 von David A. Huffman publiziert: “A Method for the Construction of Minimum-Redundancy Codes” Die Methode von Huffman ist gierig. Die Zeichen mit der niedrigsten Häufigkeit haben die längsten Codewörter. 116 / 362 8. Vorlesung 09.05.2017 P ⊆ Σ+ heißt Präfixcode, falls für alle u, v ∈ Σ∗ mit u, uv ∈ P gilt: u = uv . Kein Codewort ist also Präfix eines anderen Codeworts. Frage: Ist der Morsecode ein Präfixcode? Wenn ja, warum? Der SOS Ruf sollte so gesendet werden: ··· − − − ··· ··· − − − ··· ··· − − − ··· Ist jetzt w ∈ P ∗ eine Sequenz von Codewörtern, so lässt sich w eindeutig dekodieren: Es gibt genau eine Sequenz (u1 , . . . , uk ) mit ui ∈ P und w = u1 · · · uk . Im Folgenden betrachten wir Präfixcodes über Σ = { 0, 1 }. Es gibt jetzt eine Eins-zu-eins Beziehung zwischen endlichen Binärbäumen und endlichen Präfixcodes: Ein Codewort entspricht einem nicht leerem 0-1-Pfad zum einem Blatt und jeder solche Pfad ist ein Codewort. Siehe Tafelbild 117 / 362 Datenkompression Sei s = s1 · · · sm ein Text mit sj ∈ A über einem Alphabet A = { a1 , . . . , an } . Jedes ai komme mit der Wahrscheinlichkeit pi in s vor: pi = |s|ai / |s| . Aufgabenstellung: Finde einen einen Huffman-Code, also einen Präfixcode P = { u1 , . . . , un } ⊆ { 0, 1 }+ , der das folgende Gewicht” minimiert. ” γ(P) = n X i =1 pi |ui | . Mit einem Huffman-Code kann s mit |s| γ(P) Bit kodiert werden. 118 / 362 Lemma von Kraft Lemma 8.1 Sei k ≥ 1 und T ein saturierter k-Baum, also T 6= ∅ und es hat jeder innere Knoten genau k Kinder. Sei B die Menge der Blätter und für i ∈ B sei ti die Tiefe von Blatt i . Dann gilt X k −ti = 1. i ∈B Beweis. Besteht T nur aus einer Wurzel, so ist die Behauptung richtig. Ansonsten seien T1 , . . . , Tk die Kinder der Wurzel mit Blattmengen Bj . Die Behauptung folgt induktiv, denn: k X X k −(ti −1) = k. j=1 i ∈Bj Häufige Anwendung Für Binärbäume gilt P i ∈B 2−ti ≤ 1. 119 / 362 Entropie von (p1, . . . , pn ) als untere Schranke von γ(P) Jeder Präfixcode P = { u1 , . . . , un } ⊆ { 0, 1 }+ definiert als Binärbaum eine Folge (2−|u1 | , . . . , 2−|un | ). P Lemma von Kraft sagt ni=1 2−|ui | ≤ 1. Lemma von Gibbs sagt jetzt: H(p1 , . . . , pn ) = n X i =1 pi log( 1 ) ≤ γ(P). pi Für eine obere Schranke benötigen wir die Umkehrung des Lemmas von Kraft. 120 / 362 Umkehrung des Lemmas von Kraft Sei (b0 , . . . , bN ) eine Folge natürlicher Zahlen mit bN ≥ 1 und N X i =0 bi 2−i ≤ 1. Dann gibt es einen Binärbaum mit bi Blättern auf Tiefe i . Beweis. Für b0 = 1 gilt N = 0 und es ist nichts zu tun. Sei also N > 0. Für alle j ≤ N gilt j X i =0 −i bi 2 ≤ 1. Also: j X i =0 j−i bi 2 j−1 X bi 2j−i ) + bj ≤ 2j ≤ 2N . =( i =0 Wir fügen in einer Phase j die bj Blätter auf Tiefe j ein. Jedes auf Tiefe i für i < j eingefügte Blatt genau 2j−i Blätter auf Tiefe j. Also sind insgesamt vor der Pj−1”blockiert” j−i Phase j nur i =0 bi 2 Blätter der insgesamt 2j Blätter blockiert. Also ist genügend Platz für die Phase j. 121 / 362 Obere Schranke für Huffman-Codes l m P P Wähle ti = log( p1i ) , dann gilt ni=1 2−ti ≤ ni=1 pi = 1 Nach der Umkehrung des des Lemmas von Kraft gibt es einen Präfixcode P = { u1 , . . . , un } mit |ui | = ti . Also gilt für jeden Huffman-Code P die Aussage H(p1 , . . . , pn ) = n X i =1 pi log( 1 ) ≤ γ(P) ≤ H(p1 , . . . , pn ) + 1. pi 122 / 362 Greedy-Berechnung eines Huffman-Codes: Austausch Eigenschaften Wir starten mit An = { a1 , . . . , an }, n ≥ 2 und 0 < p1 ≤ · · · ≤ pn sowie einem zunächst beliebigen Huffman-Code P als Binärbaum. Einige Beobachtungen: ◮ P ist saturiert, da optimal. Also mindestens zwei tiefste Blätter. ◮ a1 und a2 sind tiefste Blätter, da optimal. ◮ Austauscheigenschaft: Ohne Einschränkung sind a1 und a2 Geschwister. ◮ Betrachte An−1 = { a, a3 , . . . , an } mit p(a) = p1 + p2 . Dann können wir induktiv annehmen, dass wir einen Huffman-Code Pn−1 für An−1 kennen. Wir erhalten Pn , indem wir dem Blatt a die Kinder a1 und a2 geben. ◮ Behauptung: Pn ist ein Huffman-Code. ◮ Komplexität: O(n log n) unter Verwendung der Datenstruktur Heap. (Übungsaufgabe) 123 / 362 Beweis von Pn ist ein Huffman-Code” ” Nenne einen Präfixcode P ⊆ Σ+ saturiert, wenn der entsprechende Binärbaum saturiert ist. Z.B. ist ∅ saturiert. Expandieren wir in einem saturierten P ′ ein Blatt a durch zwei neue Kinder a1 und a2 mit p(a) = p(a1 ) + p(a2 ), so erhalten wir einen saturierten Präfixcode P mit der Beziehung γ(P) = γ(P ′ ) + p1 + p2 . Umgekehrt, streichen wir in einem saturierten P zwei Blätter a1 und a2 mit einem gemeinsamen Elternknoten a und setzen p(a) = p(a1 ) + p(a2 ), so erhalten wir einen saturierten Präfixcode P ′ . Erneut gilt γ(P) = γ(P ′ ) + p1 + p2 . Der Huffman-Algorithmus ist korrekt, denn wir können ihn wie folgt interpretieren. 1. Starte mit einem beliebigen saturierten P und streiche zwei Blätter wie eben. 2. Erhalte P ′ . Das neue Blatt heiße a. 3. Optimiere P ′ zu einem Huffman-Code. b 4. Expandiere a und erhalte den Huffman-Code P. 124 / 362 Code Verbesserung bei Zufallstexten Für A mit einer Verteilung (p1 , . . . , pn ) setze H(A) = (p1 , . . . , pn ). Idee: Fasse Buchstabenpaare (ai , aj ) zu einem neuen Hyperbuchstaben aij mit p(aij ) = pi pj zusammen. Dann gilt: X X pi pj log(pi pj ) = 2 pi log(pi ). i ,j i Dann gilt H(A2 ) = 2H(p1 , . . . , pn ) = 2H(A) und allgemeiner H(Ad ) = dH(p1 , . . . , pn ) = dH(A). Damit reduziert sich unter Verwendung eines Huffman-Codes für An die mittlere Codewortlänge c(a) eines Zeichens a ∈ A mit auf 1 − log p(a) ≤ c(a) ≤ − log p(a) + . n Problem: Mehraufwand der Berechnung des Huffman-Codes; und die Verteilung der Buchstabenpaare ist in Texten s selten das Produkt aus den beteiligten Buchstaben. 125 / 362 Verschlechterung bei naiver Paarkodierung Betrachte das Wort s = ba ba aa Dann ist p(a) = 2/3 und p(b) = 1/3. Ein möglicher Huffman-Code liefert c(a) = 0 und c(b) = 1. Also c(s) = 101000 und 6 Bit, um s zu kodieren. Ferner gilt für Zufallsfolgen: p(aa) = 4/9, p(ab) = 2/9, p(ba) = 2/9, p(bb) = 1/9. Ein Huffman-Code ist: cb(aa) = 0, cb(ab) = 10, cb(ba) = 110, cb(bb) = 111. Würde man jetzt mittels cb das Wort s kodieren, so erhielte man Dies ist schlechter als vorher! cb(s) = 110 110 0. 126 / 362 Datenkompression Datenkompression ist ein wichtiges, spannendes und aktuelles Thema. In der Praxis sind für reale Daten (neben der Huffman-Codierung) viele andere Verfahren relevant(er). Einige Beispiele: ◮ Markov-Modelle: Nach einen weißen Pixel ist das nächste Pixel eher weiß als schwarz. ◮ Arithmetische Codierung: Ordne jedem Wort ein Intervall zu, zu Anfang dem leeren Wort das Intervall [0, 1] und verfeinere bei jedem neuen Buchstaben, der gelesen wird. ◮ Nehme Datenverlust in Kauf: jpeg. ◮ Lempel-Ziv Verfahren für Texte. ◮ Straight-line Programme: Kontext-freie Grammatiken, die genau ein Wort erzeugen. Entspricht Lempel-Ziv mit unbeschränkten Fenstergrößen. ◮ ... 127 / 362 Divide et impera Wikepedia sagt: Unter Teile und herrsche (Informatik) findet man ein wichtiges ” Grundprinzip der Algorithmik in der Informatik. Die lateinische Formulierung wird teilweise Machiavelli, der in seinem 1532 erschienenen Buch Der Fürst dem Fürsten Medici erklärt, wie er seine Herrschaft ausüben sollte, teilweise auch Ludwig XI. zugeschrieben. Abschließend konnte die Herkunft dieses Sprichwortes bisher nicht geklärt werden.” 128 / 362 Lösung einfacher Rekursionsgleichungen Satz 9.1 (Mastertheorem I) Seien a, b ∈ N und b > 1, g : N → N und es gelte die Rekursionsgleichung: t(1) = g (1) t(n) = a · t(n/b) + g (n) für n ≥ b. Dann gilt für n = b k (d.h. für k = logb (n)): t(n) = k X i =0 ai · g n bi . 129 / 362 Beweis des Satzes k = 0 : Es gilt n =b 0 = P1 undi t(1) =n g(1). k > 0 : Daher t nb = ik−1 =0 a · g bi +1 mit Induktion, also t(n) = a · t = a n b k−1 X i =0 = = k X i =1 k X i =0 + g (n) ! n ai · g + g (n) b i +1 ai · g ai · g n bi n bi + a0 g n b0 . 130 / 362 Mastertheorem I, Fortsetzung Korollar 9.2 (Anwendung vom Mastertheorem I) Seien a, b ∈ N, mit b > 1 und es gelte die Rekursionsgleichung: t(n) ∈ a · t(n/b) + Θ(nc ) Dann gilt: Bemerkung: log a log b c ; falls a < b c Θ(n ) c Θ(n log n) ; falls a = b c t(n) ∈ log a Θ(n log b) ; falls a > b c = logb a. Falls a > b c , so ist logb a > c. 131 / 362 Beweis Sei g (n) = nc . Damit ist t(n) = nc · Pk a i i =0 ( bc ) nach dem Satz. ∞ X a i 1 ∈ O(nc ). 1. Fall a < b : t(n) ≤ n · = nc · bc 1 − bac c c i =0 Außerdem gilt t(n) ∈ Ω(nc ). Hieraus folgt t(n) ∈ Θ(nc ). 2. Fall a = b c : t(n) = (k + 1) · nc ∈ Θ(nc log n). 132 / 362 Beweis, Fortsetzung 3. Fall a > b c : k a k+1 X −1 a i c ( bc ) = n · a bc bc − 1 i =0 a logb (n) Θ nc · c b ! nc · alogb (n) Θ b c logb (n) Θ alogb (n) = Θ b logb (a)·logb (n) Θ nlogb (a) t(n) = nc · ∈ = = = Beachte: logb (a) = log(a) log(b) . 133 / 362 Beispiel Mergesort Algorithmus 9.1 Mergesort procedure mergesort(l , r ) var m : integer; begin if (l < r ) then m := (r + l ) div 2; mergesort(l , m); mergesort(m + 1, r ); mische(l , m, r ); endif endprocedure 134 / 362 Mergesort 1. Laufzeit im schlechtesten, besten und mittleren Fall: Θ(n log n). 2. Es wird zusätzlicher Speicher benötigt, Mergesort ist im Gegensatz zu etwa Quicksort ein externes Sortierverfahren. 3. Geeignet für das Sortieren auf Sekundärspeichern. 4. Eine iterative Implementierung ist möglich und effizienter, da rekursive Aufrufe auch Speicher belegen. 135 / 362 Beispiele für Divide and Conquer Mergesort, Quicksort, Quickselect, . . . Weitere prominente Beispiele sind: 1. Multiplikation ganzer Zahlen 2. Matrixmultiplikation nach Strassen 136 / 362 9. Vorlesung 15.05.2017 Divide et impera Teile-und-Beherrsche Divide and Conquer 137 / 362 Multiplikation ganzer Zahlen Schulmäßige Multiplikation von zwei Binärzahlen der Länge n erfordert O(n2 ) Operationen. Anderer Ansatz: r = A B s = C D Dabei sind A (C ) die ersten und B (D) die letzten k Bits von r (s). r = A 2k + B; s = C 2k + D r s = A C 22k + (A D + B C ) 2k + B D Mastertheorem I: tmult-ng (n) = 4 · tmult-ng (n/2) + O(n) ∈ O(n2 ) Nichts gewonnen! 138 / 362 Multiplikation ganzer Zahlen Berechne stattdessen besser rekursiv AC , (A − B)(D − C ) und BD. Aufwand: 3 · tmult (n/2) + O(n) Damit: rs = A C 22k + (A − B) (D − C ) 2k + (B D + A C ) 2k + B D Gesamtaufwand nach dem Mastertheorem I: log 3 tmult (n) = 3 · tmult (n/2) + O(n) ∈ O(n log 2 ) = O(n1.58496... ). Wir haben also durch den Teile-und-Beherrsche Ansatz den Exponenten des naiven Ansatzes von 2 auf 1.58496... heruntergesetzt. 139 / 362 Schnelle Multiplikation Nach einem Verfahren von Schönhage-Strassen von 1971 (diskrete FFT in geeigneten Restklassenringen) lassen sich zwei Binärzahlen der Länge n in der Zeit O(n log n log log n) multiplizieren. (Der log log n-Term lässt sich sogar noch weiter verkleinern.) Der “Weltrekord” wird seit 2007 von Martin Fürer gehalten: Fürer, M. (2007). “Faster Integer Multiplication” in Proceedings of the thirty-ninth annual ACM symposium on Theory of computing, June 11–13, 2007, San Diego, California, USA n log n · 2O(log ∗ n) . bzw. nach einer genaueren Analyse in 2014 ist die Zeitkomplexität: ∗ O(n log n24 log n ). 140 / 362 Matrixmultiplikation naiver Divide-and-Conquer P Die übliche Multiplikation zweier n × n Matrizen (ai ,j ) (bi ,j ) = ( nk=1 ai ,k bk,j ) erfordert O(n3 ) skalare Multiplikationen. Divide-and-Conquer: A, B werden in 4 etwa gleichgroßen Untermatrizen unterteilt, wobei sich das Produkt AB = C wie folgt darstellen lässt: A11 A12 B11 B12 C11 C12 = A21 A22 B21 C21 B22 C22 141 / 362 Matrixmultiplikation naiver Divide-and-Conquer A11 A21 A12 A22 B11 B21 B12 B22 = C11 C21 C12 C22 Dabei ergeben sich folgende Beziehungen: C11 = A11 B11 + A12 B21 C12 = A11 B12 + A12 B22 C21 = A21 B11 + A22 B21 C22 = A21 B12 + A22 B22 Also: t(n) ∈ 8 · t(n/2) + Θ(n2 ) ∈ Θ(n3 ) Erneut keine Verbesserung. 142 / 362 Matrixmultiplikation nach Volker Strassen Berechne das Produkt von 2 × 2 Matrizen mit 7 Multiplikationen: M1 := (A12 − A22 )(B21 + B22 ) C11 = M1 + M2 − M4 + M6 M2 := (A11 + A22 )(B11 + B22 ) C12 = M4 + M5 M3 := C21 = M6 + M7 M4 := (A11 − A21 )(B11 + B12 ) (A11 + A12 )B22 C22 = M5 := M2 − M3 + M5 − M7 M6 := A11 (B12 − B22 ) M7 := A22 (B21 − B11 ) (A21 + A22 )B11 Laufzeit: t(n) ∈ 7t(n/2) + Θ(n2 ). Mastertheorem I (a = 7, b = 2, c = 2): t(n) ∈ Θ(nlog2 7 ) = Θ(n2,81... ) Theoretischer Durchbruch 1968. Die Schranke wurde mehrfach verbessert (auf Kosten sehr großer Konstanten). Zur Zeit (April 2017) liefert eine Variante des Coppersmith–Winograd-Algorithmus die folgende Schranke für die Matrixmultiplikation O(n2,372... ). 143 / 362 Anwendung: Wortproblem für kontext-freie Sprachen Das Wortproblem für kontext-freie Sprachen lässt sich in der Zeit O(n3 ) lösen: Stichwort CYK. Eine Reduktion auf Multiplikation boolescher Matrizen liefert nach Strassen bzw. dessen Verbesserungen O(nlog2 7 ) bzw. O(n2,372... ). 144 / 362 Monte-Carlo-Algorithmus von Rusin Freivalds (1977) Eingabe A, B, C ∈ K n×n über einem Körper K . Aufgabe. Teste, ob A · B = C , also ob A · B − C die Nullmatrix ist. Monte-Carlo-Lösung. 1. Wähle n mal zufällig und unabhängig ri ∈ { 0, 1 } und setze r T = (r1 , . . . , rn ) ∈ { 0, 1 }n . T Also ist r ein Spaltenvektor, Pn da r Zeilenvektor. 2. Berechne s = (si ) = ( k=1 bik rk ). Also s = B · r . P 3. Berechne t = (ti ) = ( nk=1 aik sk ). Also t = A · s = A · B · r . P 4. Berechne p = (pi ) = (ti − nk=1 cik rk ). Also p = (A · B − C ) · r . 5. Falls p 6= 0, dann A · B 6= C . 6. Falls p = 0, dann Pr[A · B = C ] ≥ 1/2. Beweis der letzten Zeile: Sei A · B − C = (dij ) und (i , j) fest gewählt mit dij 6= 0. Es gilt dann X pi = dij rj + dik rk = dij rj + y . k6=j 145 / 362 Wahrscheinlichkeitsanalyse mit dem Ansatz P pi = dij rj + k6=j dik rk = dij rj + y und dij 6= 0 Es folgt Pr[pi = 0] = Pr[pi = 0 ∧ y = 0] + Pr[pi = 0 ∧ y 6= 0] = Pr[pi = 0 | y = 0] Pr[y = 0] + Pr[pi = 0 | y 6= 0] Pr[y 6= 0] = Pr[rj = 0] Pr[y = 0] + Pr[pi = 0 | y 6= 0] Pr[y 6= 0] ≤ Pr[rj = 0] Pr[y = 0] + Pr[rj = 1] Pr[y 6= 0] = Pr[y = 0] /2 + Pr[y 6= 0] /2 = Pr[y = 0] /2 + (1 − Pr[y = 0])/2 = 1/2 Beachte, ist dij der einzige Nicht-Null-Eintrag, so folgt Pr[pi = 0] = 1/2 wegen pi = dij rj . Durch k-fache Wiederholung kann die Fehlerwahrscheinlichtkeit unter 2−k gedrückt werden. Zeit: O(kn2 ). 146 / 362 10. Vorlesung 22.05.2017 Dynamisches Programmieren Beim Verfahren der dynamischen Programmierung werden tabellarisch alle Teillösungen eines Problems bestimmt, bis schließlich die Gesamtlösung erreicht ist. Die Teillösungen werden dabei mit Hilfe der bereits existierenden Einträge berechnet. 147 / 362 Dynamisches Programmieren versus Backtracking Dynamischen Programmieren ist eng verwandt mit der Problemlösung durch Backtracking. Die zusätzliche Idee ist, Rekursion durch Iteration zu ersetzen und durch tabellarisches Festhalten von Teillösungen Mehrfachberechnungen zu vermeiden. BEISPIEL: Erinnerung an die Theorie-Vorlesung: Satz von Kleene. Bestimmung reguläre Ausdrücke: NEA A = (Q, Σ, δ ⊆ Q × Σ × Q, I , F ), Lk [i , j] = Sprache von i nach j über erlaubte Zwischenzustände aus der Menge {1, . . . , k}. L0 [i , j] = Kantenbeschriftung, (bzw. ε). Gesucht Ln [i , j] für alle i ∈ I und j ∈ F . Lk [i , j] := Lk−1 [i , j] + Lk−1 [i , k] · Lk−1 [k, k]∗ · Lk−1 [k, j] 148 / 362 Bestimmung reguläre Ausdrücke Algorithmus 10.1 Reguläre Ausdrücke aus einem endlichen Automaten Eingabe : NEA A = (Q, Σ, δ ⊆ Q × Σ × Q, I , F ) procedure NEA2REGEXP (Initialisiere: L[i , j] := {a | (i , a, j) ∈ δ ∨ (a = ε ∧ i = j)}) begin for k := 1 to n do for i := 1 to n do for j := 1 to n do L[i , j] := L[i , j] + L[i , k] · L[k, k]∗ · L[k, j] endfor endfor endfor end 149 / 362 Komplexitätsbetrachtung ◮ Auch wenn er der Algorithmus NEA nach REG” nur n3 Schleifen durchläuft kann ” die Ausgabekomplexität exponentiell in n sein. ◮ In jeder Schleife über k könnte sich die Länge des regulären Ausdrucks für L[i , j] vervierfachen. Die Ausgabelänge des Ausdrucks könnte also etwa bei 4n liegen. ◮ NEAs repräsentieren reguläre Sprachen kompakter als reguläre Ausdrücke. 150 / 362 Transitive Hülle Algorithmus 10.2 Warshall-Algorithmus: Berechnung der transitiver Hülle Eingabe : Graph als Adjazenzmatrix (A[i , j]) ∈ Booln×n procedure Warshall (var A : Adjazenzmatrix) begin for k := 1 to n do for i := 1 to n do for j := 1 to n do if (A[i , k] = 1) and (A[k, j] = 1) then A[i , j] := 1 endif endfor endfor endfor end 151 / 362 Korrektheit: Warshall Die Korrektheit des Warshall-Algorithmus folgt aus der Invarianten: 1. Nach dem k-ten Durchlauf der ersten for-Schleife gilt A[i , j] = 1, falls ein Pfad von i nach j über Zwischenknoten mit Nummern ≤ k existiert. – Beachte, k steht ganz außen! 2. Gilt A[i , j] = 1, so existiert ein Pfad von i nach j. 152 / 362 Transitive Hülle? Algorithmus 10.3 Ist dies Verfahren korrekt? Eingabe : Graph als Adjazenzmatrix (A[i , j]) ∈ Booln×n procedure Warshall’ (var A : Adjazenzmatrix) begin for i := 1 to n do for j := 1 to n do for k := 1 to n do if (A[i , k] = 1) and (A[k, j] = 1) then A[i , j] := 1 endif endfor endfor endfor end 153 / 362 Antwort Nein! 154 / 362 Von Warshall zu Floyd Trägt man in die Adjazenz-Matrix vom Warshall-Algorithmus Kantengewichte statt Boolesche Werte ein, so entsteht der Floyd-Algorithmus zur Berechnung kürzester Wege. 155 / 362 Floyd-Algorithmus Algorithmus 10.4 Floyd: Alle kürzesten Wege in einem Graphen Eingabe : Gewichteter Graph als Adjazenzmatrix A[i , j] ∈ (N ∪ ∞)n×n , wobei A[i , j] = ∞ bedeutet, dass es keine Kante von i nach j gibt. procedure Floyd (var A : Adjazenzmatrix) begin for k := 1 to n do for i := 1 to n do for j := 1 to n do A[i , j] := min{A[i , j], A[i , k] + A[k, j]}; endfor endfor endfor endprocedure 156 / 362 Floyd-Algorithmus Der Floyd-Algorithmus liefert ein korrektes Ergebnis auch wenn die Gewichte negativ sind, unter der Bedingung, dass keine negative Schleifen vorhanden sind. Zeitaufwand von Warshall und Floyd ist Θ(n3 ). Verbesserung“ dadurch, dass vor der ” j-Schleife zuerst getestet wird, ob A[i , k] = 1 (bzw. ob A[i , k] < ∞) gilt. Damit erreicht man den Aufwand O(n3 ): 157 / 362 Floyd-Algorithmus Algorithmus 10.5 Floyd-Algorithmus in O(n3 ) Eingabe : Adjazenzmatrix A[i , j] ∈ (N ∪ ∞)n×n procedure Floyd (var A : Adjazenzmatrix) begin for k := 1 to n do for i := 1 to n do if A[i , k] < ∞ then for j := 1 to n do A[i , j] := min{A[i , j], A[i , k] + A[k, j]}; endfor endif endfor endfor endprocedure 158 / 362 Floyd-Algorithmus Algorithmus 10.6 Floyd-Algorithmus mit negativen Zyklen Eingabe : Adjazenzmatrix A[i , j] ∈ (Z ∪ ∞ ∪ −∞)n×n procedure Floyd (var A : Adjazenzmatrix) begin for k := 1 to n do for i := 1 to n do if A[i , k] < ∞ then for j := 1 to n do if A[k, j] < ∞ then if A[k, k] < 0 then A[i , j] := −∞ else A[i , j] := min{A[i , j], A[i , k] + A[k, j]} endif endif endfor endif endfor endfor endprocedure 159 / 362 Transitive Hülle und Matrixmultiplikation Sei A = (aij ) die Adjazenzmatrix eines gerichteten Graphen mit n Knoten. Der Warshall-Algorithmus berechnet den reflexiven transitiven Abschluss A∗ in O(n3 ) Schritten. Hierbei ist X A∗ = Ak mit A0 = In und ∨ als Addition boolescher Matrizen k≥0 Mit Induktion ergibt sich leicht, dass Ak (i , j) = 1P genau dann gilt, wenn es von i nach j k einen Weg der Länge k gibt. Klar ist auch A∗ = n−1 k=0 A . 160 / 362 Transitive Hülle ≤ Matrixmultiplikation bis auf einen log-Faktor Setze B = In + A. Dann gilt A∗ = B m für alle m ≥ n − 1. Also reicht es, eine Matrix ⌈log2 (n − 1)⌉-mal zu quadrieren, um A∗ zu berechnen. Sei M(n) der Aufwand, zwei boolesche n × n-Matrizen zu multiplizieren, und sei T (n) der Aufwand, die reflexive transitive Hülle zu berechnen. Dann gilt also: T (n) ∈ O(M(n) · log n). Hieraus folgt für alle ε > 0 nach Strassen T (n) ∈ O(nε+log2 7 ). Ziel ist jedoch: T (n) ∈ O(M(n)). 161 / 362 Matrixmultiplikation ∼ Transitive Hülle Die Beziehung M(n) ∈ O(T (n)) gilt unter der plausiblen Annahme M(3n) ∈ O(M(n)). Denn seien A und B beliebige Matrizen, dann gilt: ∗ 0 A 0 In A AB 0 0 B = 0 In B . 0 0 0 0 0 In Unter den (ebenfalls plausiblen) Annahmen M(n) ∈ Ω(n2 ) und M(2n) ≥ (2 + ε)M(n) zeigen wir T (n) ∈ O(M(n)). Dies bedeutet: die Berechnung der transitiven Hülle ist bis auf konstante Faktoren genauso aufwendig wie die Matrixmultiplikation. 162 / 362 Berechnung der Transitive Hülle Eingabe: E ∈ Bool(n × n) 1. Teile E in vier Teilmatrizen A, B, C , D so, dass A und D quadratisch sind und jede Matrix ungefähr die Größe n/2 × n/2 hat: A B E= . C D 2. Berechne rekursiv D ∗ : Aufwand T (n/2). 3. Berechne F = A + BD ∗ C : Aufwand O(M(n/2)), da M(n) ∈ Ω(n2 ). 4. Berechne rekursiv F ∗ : Aufwand T (n/2). 5. Setze ∗ E = F∗ F ∗ BD ∗ D ∗ CF ∗ D ∗ + D ∗ CF ∗ BD ∗ . 163 / 362 Berechnung der Transitive Hülle Damit erhalten wir die Rekursionsgleichung T (n) ≤ 2T (n/2) + c · M(n) für ein c > 0. Dies ergibt P i · M(n/2i ) 2 i ≥0 P 2 i ≤ c · i ≥0 2+ε · M(n) T (n) ≤ c · (nach Mastertheorem) (da M(n/2) ≤ 1 2+ε M(n)) ∈ O(M(n)). 164 / 362 11. und 12. Vorlesung 23. und 29.05.2017 Matrizenmultiplikation Sei R ein (Semi-)Ring, etwa R = N, Z, Z/nZ, . . . und seien A, B Matrizen: A = (aik ) ∈ R p×q Dann gilt: & B = (bkj ) ∈ R q×r . q X A·B = ( aik bkj ) ∈ R p×r . k=1 Aufwand: p · q · r Multiplikationen und p · (q − 1) · r Additionen. 165 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von links (10 × 1) (1 × 10) (10 × 1) (1 × 10) (10 × 1) 166 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von links (10 × 1) (1 × 10) (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) 100 Multiplikationen (10 × 10) 167 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von links (10 × 1) (1 × 10) (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) (1 × 10) (10 × 1) 100 Multiplikationen (10 × 10) 100 Multiplikationen (10 × 1) 168 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von links (10 × 1) (1 × 10) (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) (1 × 10) (10 × 1) 100 Multiplikationen (10 × 10) 100 Multiplikationen (10 × 1) 100 Multiplikationen (10 × 10) (10 × 1) 169 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von links (10 × 1) (1 × 10) (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) (1 × 10) (10 × 1) 100 Multiplikationen (10 × 10) 100 Multiplikationen (10 × 1) 100 Multiplikationen (10 × 10) 100 Multiplikationen (10 × 1) (10 × 1) 170 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von links Insgesamt: 400 Multiplikationen 171 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von rechts (10 × 1) (1 × 10) (10 × 1) (1 × 10) (10 × 1) 172 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von rechts (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) (1 × 10) 10 Multiplikationen (10 × 1) (1 × 1) 173 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von rechts (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (1 × 10) 10 Multiplikationen 10 Multiplikationen (10 × 1) (1 × 1) (10 × 1) 174 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von rechts (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) 10 Multiplikationen (10 × 1) (1 × 1) 10 Multiplikationen 10 Multiplikationen (10 × 1) (1 × 10) (10 × 1) (1 × 1) 175 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von rechts (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) 10 Multiplikationen (10 × 1) (1 × 1) 10 Multiplikationen (10 × 1) 10 Multiplikationen (10 × 1) (1 × 10) (1 × 1) 10 Multiplikationen (10 × 1) 176 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation von rechts Insgesamt: 40 Multiplikationen Also: 400 vs. 40 Multiplikationen bei Veränderung der Reihenfolge, aber die optimale Reihenfolge erfordert nur 31 Multiplikationen! 177 / 362 Beispiel: Multiplikation einer Matrizenfolge Multiplikation in optimaler Reihenfolge (10 × 1) (1 × 10) (10 × 1) (1 × 10) (10 × 1) 178 / 362 Beispiel: Multiplikation einer Matrizenfolge (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) (1 × 10) 10 Multiplikationen (10 × 1) (1 × 1) 179 / 362 Beispiel: Multiplikation einer Matrizenfolge (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) 10 Multiplikationen (10 × 1) (1 × 10) 10 Multiplikationen (1 × 1) (10 × 1) (1 × 1) (1 × 1) 180 / 362 Beispiel: Multiplikation einer Matrizenfolge (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) 10 Multiplikationen (10 × 1) (10 × 1) (1 × 10) 10 Multiplikationen (1 × 1) (10 × 1) (1 × 1) (1 × 1) 1 Multiplikation (1 × 1) 181 / 362 Beispiel: Multiplikation einer Matrizenfolge (10 × 1) (1 × 10) (10 × 1) (10 × 1) (1 × 10) (10 × 1) 10 Multiplikationen (10 × 1) (10 × 1) (1 × 10) 10 Multiplikationen (1 × 1) (10 × 1) (1 × 1) (1 × 1) 1 Multiplikation (1 × 1) 10 Multiplikationen (10 × 1) 182 / 362 Multiplikation einer Matrizenfolge A(n,m) bezeichne eine Matrix A mit n Zeilen und m Spalten. Annahme: Wir berechnen C(p,r ) := A(p,q) · B(q,r ) mit p · q · r skalaren Multiplikationen. 1 2 3 N Aufgabe: Bestimme für eine Matrizenfolge M(n , M(n , M(n , . . . , M(n die 0 ,n1 ) 1 ,n2 ) 2 ,n3 ) N−1 ,nN ) minimale Zahl der skalaren Multiplikationen, um M[1, N] = M 1 · · · M N zu berechnen. Für die algorithmische Lösung ist die Eingabe eine Folge der Dimensionen: (n0 , n1 , . . . , nN ) Wir erhalten: cost(M 1 , . . . , M N ) = cost(1, . . . , N) Dynamisches Programmierung liefert: cost(i , . . . , j) = mink {cost(i , . . . , k) + cost(k + 1, . . . , j) + ni −1 · nk · nj }. 183 / 362 Multiplikation einer Matrizenfolge for i := 1 to N do cost[i , i ] := 0; for j := i + 1 to N do cost[i , j] := ∞; endfor endfor for d := 1 to N − 1 do for i := 1 to N − d do j := i + d; for k := i to j − 1 do t := cost[i , k] + cost[k + 1, j] + n[i − 1] · n[k] · n[j]; if t < cost[i , j] then cost[i , j] := t; best[i , j] := k; endif endfor endfor endfor return cost[1, N] 184 / 362 Die Multiplikation nach der best-Tabelle cost[i , j], best[i , j] sind berechnet. Was nun? Um das Produkt M[1, N] zu berechnen, benötigen wir nur die best[i , j]-Werte. i Setze M[i , i ] = M(n und berechne M[1, N] rekursiv: i −1 ,ni ) M[i , j] = M[i , best[i , j]] · M[best[i , j] + 1, j]. 185 / 362 ◮ Fortsetzung: Dynamisches Programmieren 186 / 362 Erkennung kontext-freier Sprachen Kontext-freie Grammatik G = (V , Σ, P, S) heißt kontext-freie Grammatik, falls ◮ ◮ ◮ V = {A1 , A2 , . . . , Aq } eine Menge von Nichtterminalen, Σ = {a1 , a2 , . . . , ar } das Alphabet, P ⊆ V × (V ∪ Σ)∗ = { A → α | A → α ∈ P } eine Menge von Produktionen und ◮ S ∈ V das Startsymbol ist. Beispiel: Die Menge der Palindrome ist kontext-frei. Otto Tarne nie deinen Rat Tu erfreut A MAN A PLAN A CANAL PANAMA 187 / 362 Wiederholung Chomsky-Normalform (CNF) Jede kontext-freie Grammatik G kann in Chomsky-Normalform umgewandelt werden. In CNF hat jede Produktion entweder ◮ ◮ die Form A → BC (A, B, C ∈ V ) oder die Form A → a (A ∈ V , a ∈ Σ). Die neue Grammatik erzeugt L(G ) bis auf das leere Wort. CYK-Algorithmus Für eine Grammatik G in CNF kann mittels des CYK-Algorithmus in O(n3 ) Schritten entschieden werden, ob w ∈ L(G ) für ein gegebenes Wort w ∈ Σ∗ gilt. 188 / 362 CYK-Algorithmus for i := 1 to N do Var[i , i ] := {A ∈ V | (A → ai ) ∈ P}; for j := i + 1 to N do Var[i , j] := ∅; endfor Eingabe: w = a1 · · · aN ∗ endfor Var[i , j] := {A ∈ V | A =⇒ ai · · · aj } for d := 1 to N − 1 do (1 ≤ i ≤ j ≤ N) for i := 1 to N − d do j := i + d; for k := i to j − 1 do Var[i , j] := Var[i , j] ∪ {A ∈ V | (A → BC ) ∈ P, B ∈ Var[i , k], C ∈ Var[k + 1, j]} endfor endfor endfor return Var[1, N] Es gilt w ∈ L(G ) ⇐⇒ S ∈ Var[1, N]. 189 / 362 Graphische Interpretation des CYK G = (V , Σ, P, S) kontext-frei ohne ǫ-Produktionen. Eingabe: a a a 1 2 3 0 −→ 1 −→ 2 −→ an−2 an−1 a n −→ n − 2 −→ n − 1 −→ n ··· Flute den Graphen mit Kanten: Regel Ist A → α ∈ P und ist ein Pfad von i nach j mit dem Wort α ∈ (V ∪ Σ)∗ beschriftet, A so füge eine mit A beschriftete Kante i → j ein. ◮ S a1 · · · an ∈ L(G ) ⇐⇒ Kante 0 → n wird erzeugt. 190 / 362 Vielleicht später. . . ◮ Valiants Algorithmus 191 / 362 Wortproblem für kontext-freie Sprachen Das Wortproblem für kontext-freie Sprachen lässt sich in der Zeit O(n3 ) lösen: Stichwort CYK. Leslie Valiant zeigte4 , dass man das Wortproblem einer kontext-freien Sprache L effizient auf die Multiplikation boolescher Matrizen reduzieren kann. Diese Reduktion auf Multiplikation boolescher Matrizen liefert dann nach Strassen: WP(L) ∈ O(nlog2 7 ). 4 General context-free recognition in less than cubic time. J. Computer and System Sciences, 10, (1975), pp.308-315 192 / 362 Optimale Suchbäume Erzeugung von optimalen Suchbäumen: Die direkte Methode Θ(n3 ). Der Algorithmus von Donald E. Knuth hat einen Aufwand von Θ(n2 ). (Teleskopsumme) Interessant ist hier, wie man durch eine genaue Analyse des Problems den kubischen Algorithmus in einen quadratischen verwandeln kann. Der Algorithmus ist nicht komplizierter, sondern der Gewinn liegt im Auslassen überflüssiger Schritte. 193 / 362 Optimale Suchbäume Sei ein linear geordnetes Feld gegeben mit v1 < v2 < · · · < vn . Zugriffshäufigkeit auf Knoten v sei durch γ(v ) gegeben. Der Wert γ(v ) kann sowohl die relativen als auch die absoluten Häufigkeiten bezeichnen. 194 / 362 Optimale Suchbäume Binärer Suchbaum: knotenbeschrifteter Baum. Für jeden Knoten v mit linkem Unterbaum L und u ∈ L gilt: u < v (bzw. w ∈ R rechts und dann v < w ). Jeder Knoten v hat ein Level ℓ(v ): ℓ(v ) := 1 + Abstand des Knotens v zur Wurzel. Das Auffinden eines Knotens auf Level ℓ erfordert ℓ Vergleiche. Ziel: Finde einen binären Suchbaum, der die gewichtete innere Pfadlänge X P(B) := ℓ(v ) · γ(v ) v ∈V minimiert. 195 / 362 Optimale Suchbäume Optimaler Suchbaum für 1, 2, 22 , 23 , 24 , 25 mittels Greedy-Strategie. 25 24 23 22 2 1 Gewichtete innere Pfadlänge: 1 · 32 + 2 · 16 + 3 · 8 + 4 · 4 + 5 · 2 + 6 · 1 = 120 Mittlere Suchzeit: 120/63 < 2. 196 / 362 Optimale Suchbäume Optimaler Suchbaum für 1, 2, 3, 4, 5, 6, 7. 5 3 2 7 4 6 1 Gewichtete innere Pfadlänge: 1 · 5 + 2 · 10 + 3 · 12 + 4 · 1 = 65. Mittlere Suchzeit: 65/28 ≈ 2,3. 197 / 362 Optimale Suchbäume Suchbaum für 1, 2, 3, 4, 5, 6, 7 nach Greedy-Strategie: 7 6 5 4 3 2 1 Gewichtete innere Pfadlänge: 7 + 12 + 15 + 16 + 15 + 12 + 7 = 84. Mittlere Suchzeit: 84/28 = 3. 198 / 362 Optimale Suchbäume Die innere Pfadlänge bestimmt die durchschnittlichen Kosten einer Sequenz von Find-Operationen. Dynamische Programmierung möglich, da die Unterbäume eines optimalen Baums auch optimal sind. 199 / 362 Optimale Suchbäume Bezeichnungen: ◮ Knotenmenge = {1, . . . , n}, d.h. die Zahl i entspricht dem Knoten vi . Weiterhin wird ℓi (bzw. γi ) eine andere Schreibweise für ℓ(i ) (bzw. γ(i )) sein. ◮ Pi ,j : gewichtete innere Pfadlänge eines optimalen Suchbaumes der Knoten {i , . . . , j}. ◮ ◮ ◮ Ri ,j : Wurzel eines optimalen Suchbaumes für {i , . . . , j}. Später: ri ,j kleinstmögliche Wurzel, Ri ,j größtmögliche Wurzel. P Γi ,j := jk=i γ(k): Gewicht der Knotenmenge {i , . . . , j}. 200 / 362 Optimale Suchbäume Im dynamischen Ansatz sind nun Werte ri ,j oder Ri ,j gesucht, die einen optimalen Suchbaum B mit Kosten Pi ,j realisieren. Man geht nun direkt vor und berechnet P(B) rekursiv (dabei bezeichnet BL bzw. BR den linken, bzw. rechten Unterbaum der Wurzel von B): P(B) := P(BL ) + P(BR ) + Γ(B) Wir realisieren diesen Ansatz zunächst in einem kubischen Algorithmus. Algorithmus: Berechnung eines optimalen Suchbaums ◮ ◮ Pi ,j = Γi ,j + mink∈{i ,...,j} {Pi ,k−1 + Pk+1,j } ri ,j = k, für den minimalen Index Pi ,k−1 + Pk+1,j das Minimum annimmt. 201 / 362 Optimale Suchbäume Lemma (Monotonie der Funktion P(B)) Sei B ′ ein optimaler Suchbaum für {1, . . . , n} und v ∈ {1, . . . , n}. Sei B ein optimaler Suchbaum für {1, . . . , n} \ {v }. Dann gilt P(B) ≤ P(B ′ ). Beweis: Entferne v aus B ′ . Fülle die Lücke von unten durch Rotationen. 202 / 362 Optimale Suchbäume Die folgende Beobachtung (von Knuth) ist entscheidend. Satz 11.1 (Monotonie der Wurzel) Sei r [i , j] (bzw. R[i , j]) die kleinste (bzw. größte) Wurzel eines optimalen Suchbaumes für die Knoten {i , . . . , j}. Dann gilt für n ≥ 2: r [i , j − 1] ≤ r [i , j], R[i , j − 1] ≤ R[i , j]. Die Anschauung ist klar, aber der Beweis ist schwierig. Wir stellen ihn zurück. 203 / 362 Optimale Suchbäume cost[n + 1, n] := 0; for i := 1 to n do cost[i , i − 1] := 0; cost[i , i ] := γ(i ); Γ[i , i ] := γ(i ); r[i , i ] := i ; endfor for d := 1 to n − 1 do for i := 1 to n − d do j := i + d; t := ∞; for k := r [i , j − 1] to r [i + 1, j] do if cost[i , k − 1] + cost[k + 1, j] < t then t := cost[i , k − 1] + cost[k + 1, j]; r := k; endif endfor Γ[i , j] := Γ[i , j − 1] + γ(j); cost[i , j] := t + Γ[i , j]; r [i , j] := r ; endfor endfor 204 / 362 Optimale Suchbäume – Teleskopsumme Beachte: Im Algorithmus war j = i + d. Daher Laufzeit: n−1 n−d X X d=1 i =1 (1 + r [i + 1, i + d] − r [i , i + d − 1]) = n−1 X 3 (n − d + r [n − d + 1, n] − r [1, d]) ≤ n2 ∈ Θ(n2 ). 2 d=1 Bemerkung 11.2 ◮ Ein linear geordnetes Feld v1 , . . . , vn kann aus einem ungeordneten Feld in O(n log n) Schritten erzeugt werden. Dies fällt aber bei Θ(n2 ) nicht ins Gewicht. Damit gilt: aus einem beliebigen Feld mit n Elementen kann ein optimaler Suchbaum in Θ(n2 ) Schritten erzeugt werden. 205 / 362 Monotonie der Wurzel. Zu zeigen ist noch: R[1, n − 1] ≤ R[1, n] und r [1, n − 1] ≤ r [1, n]. Es reicht zu zeigen (wegen Symmetrie) R[1, n − 1] ≤ R[1, n]. Mit Induktion ist Monotoniesatz von Knuth für j − i ≤ n − 2 bereits bewiesen. r [i , j − 1] ≤ r [i , j], R[i , j − 1] ≤ R[i , j]. Wegen Links-Rechts-Symmetrie folgt aus der ersten Zeile dann auch. R[i , j] ≤ R[i + 1, j]. Lemma: Sei {1, . . . , n} die Knotenmenge. Sei Bj ein optimaler Suchbaum mit minimalem Level j von Knoten n (also n möglichst hoch). Sei j1 die Wurzel von Bj . Sei Bi ein optimaler Suchbaum mit maximaler Wurzel i1 , also i1 ≥ j1 . Dann existiert ein optimaler Suchbaum B ′ mit Wurzel i1 und Knoten n auf Level j. 206 / 362 Kleines Level – große Wurzel Diese Verbindung der Eigenschaften minimales Level für n und große Wurzel ist für den Beweis des Satzes von Nutzen. Beweis des Lemmas: Wir betrachten die rechten Äste, wobei die Knoten von Bi mit ik und die Knoten von Bj mit jk bezeichnet sind: Beachte i1 ≥ j1 . Bj : j1 Bi : j2 1 i1 i2 .. 2 .. . n . ij j n i 207 / 362 Kleines Level – große Wurzel Bei festem i1 maximieren wir i2 , dann maximieren wir i3 usw. Der neue Baum wird weiterhin mit Bi bezeichnet. Angenommen, in Bi und Bj liegt der Knoten n auf gleichem Level j. Dann sind wir fertig. Andernfalls können wir (zur Vereinheitlichung der Bezeichnung) annehmen, dass der Knoten n in Bi auf Level i liegt und i > j gilt, weil j minimal gewählt wurde. Sei k maximal mit ik > jk . Dann gilt 1 ≤ k < j. Setze m = k + 1. Es gilt {ik + 1, . . . , n} ( {jk + 1, . . . , n}, und mit Induktion und Links-Rechts-Symmetrie des Satzes gilt jm ≤ R[jk + 1, n] ≤ R[ik + 1, n] = im . Also folgt jm = im , da k maximal gewählt wurde. 208 / 362 Kleines Level – große Wurzel Sei nun Ri der rechte Unterbaum in Bi , der im als Wurzel hat, und Rj sei der rechte Unterbaum in Bj , der jm als Wurzel hat. Wegen im = jm haben Ri und Rj dieselbe Knotenmenge und sind optimale Suchbäume. Wir bilden einen Baum B ′ durch Ersetzen von Ri in Bi durch Rj . Da P(Ri ) = P(Rj ) gilt, ergibt sich auch P(B ′ ) = P(Bi ) = P(Bj ), d. h. B ′ ist optimal für {1, . . . , n}, hat i1 als Wurzel und den Knoten n auf Level j. 209 / 362 Kleines Level – große Wurzel Angenommen i2 = j2 , also m = 2. Wir erhalten das folgende Bild. Beachte i1 ≥ j1 . Bi : i1 1 B ′ : i1 i2 = j 2 j2 i2 .. .. . ij . n n 2 j i 210 / 362 Kleines Level – große Wurzel Symmetrie ergibt: Lemma: Sei Bi ein optimaler Suchbaum für {1, . . . , n} mit maximalem Level i von Knoten n. Sei i1 die Wurzel von Bi . Sei Bj ein optimaler Suchbaum für {1, . . . , n} mit Wurzel j1 ≤ i1 . Dann existiert ein optimaler Suchbaum B ′ für {1, . . . , n} mit Wurzel j1 und Knoten n auf Level i . 211 / 362 Variation entlang α = γ(n) Es sei α = γ(n). Der Wert α variiert zwischen 0 und ∞. Mit rα (bzw. Rα ) bezeichnen wir die kleinste (bzw. größte) Wurzel eines optimalen Suchbaums für die Knoten {1, . . . , n}. Sei zunächst α = 0 und seien B ′ bzw. B ′′ optimale Suchbäume für die Knoten {1, . . . , n − 1} mit Wurzel r [1, n − 1] bzw. R[1, n − 1]. Nimmt man jeweils den Knoten n als rechtesten hinzu, so erhält man Suchbäume für {1, . . . , n}, ohne die gewichtete innere Pfadlänge zu erhöhen. Nach der Monotonie von P(B) sind diese Suchbäume optimal. Es folgt: r [1, n − 1] = r0 [1, n] und R[1, n − 1] = R0 [1, n]. Daher reicht es zu zeigen, dass rα und Rα monoton mit α steigen. Wegen der Symmetrie reicht es, Rα zu betrachten. 212 / 362 Variation entlang α = γ(n) Ab jetzt betrachten wir nur noch die Knotenmenge {1, . . . , n}. Bi sei ein optimaler Suchbaum unter der Nebenbedingung, dass der Knoten n auf dem Level i liegt. Dann gilt für eine gewisse Konstante c(i ): Pα (Bi ) = α · i + c(i ). Der Graph Pα (Bi ) ist eine Gerade mit Steigung i . Aufgrund der Linearität erhalten wir das folgende (vertikal gestauchte) Bild, bei der jede Steigung i = 1, . . . , n höchstens einmal vorkommt. 213 / 362 Variation entlang α = γ(n) Pα ✻ Pα (Bn ) Pα (Bℓ ) Pα (Bi ) Pα (Bk ) Pα (Bj ) ✲ α0 α 214 / 362 Monotoniebeweis Die Monotonie von rα oder Rα kann nur an einem Knick verletzt werden, wo sich Geraden mit verschiedenen Steigungen treffen. Um die Monotonie von rα zu zeigen, repräsentieren wir eine Gerade mit Steigung i durch ein Bi mit minimaler Wurzel, für Rα durch ein Bi mit maximaler Wurzel. Wir betrachten das Bild also in zwei Versionen“. ” 215 / 362 Monotoniebeweis für Rα Ein Schnittpunkt von Geraden sei bei α0 . Wenn wir α vergrößern, sind wir am Punkt α0 gezwungen, das Level von n zu verkleinern. (n kommt näher an die Wurzel.) Erinnerung: Die Verbindung der Eigenschaften minimales Level für n und große Wurzel ist von Nutzen. Sei Rα0 die maximale Wurzel, die bei den verschiedenen Geraden im Schnittpunkt α0 realisierbar ist. Dann kann Rα0 als Wurzel für die Gerade gewählt werden, die bei α0 die kleinste Steigung hat, denn dies entspricht dem minimalen Level von n. Daher können wir von links nach rechts den Baum wechseln und die maximale Wurzel wird nicht kleiner. Folglich steigt Rα monoton. 216 / 362 Monotoniebeweis für rα Die Monotonie heißt jetzt, rα muss von rechts nach links fallen. Wenn wir α verkleinern, sind wir am Punkt α0 gezwungen, das Level des Knotens n auf einen größeren Wert zu ändern. Jetzt können wir von rechts nach links den Baum wechseln und die minimale Wurzel wird nicht größer. Dies zeigt die Behauptung. 217 / 362 13. Vorlesung, 30.05.2017 Mittlere Höhe binärer Suchbäume: Wir nehmen an, dass binärer Suchbäume durch zufällig gewählte Permutationen erzeugt werden. 218 / 362 Bezeichnungen ◮ ◮ π: Permutation von {1, . . . , n} Schreibe π als Folge (π(1), π(2), π(3), . . . , π(n)) ◮ BI (π), I ⊆ {1, . . . , n}: Suchbaum mit den Elementen i ∈ I , eingefügt in der Reihenfolge (links nach rechts) von π. ◮ Zufallsvariablen: Wurzel von B(π) ist i“ ∈ {0, 1} ” XI (π) = Höhe von BI (π)“ ” YI (π) = 2XI (π) Ri (π) = Dies ist der Trick! Denn nach der Jensen’schen Ungleichung gilt 2E [XI ] ≤ E [2XI ] = E [YI ]. 219 / 362 Erwartungswerte XI (π) = Höhe von BI (π)“ ”X (π) YI (π) = 2 I Ziel: E [Xn ] ∈ O(log n). Wir zeigen hierfür: E [Yn ] ≤ 1 n+3 4 3 ∈ O(n3 ). (bei Gleichverteilung der Permutationen.) 220 / 362 Berechnung von E [Yn ] n = 1: E [Y1 ] = 1. n ≥ 2: 1 E [Yn ] = 2 · n X i =1 E [Ri · max{Y{1,...,i −1} , Y{i +1,...,n} }] P Denn Yn (π) = 2 ni=1 (Ri (π) · max{Y{1,...,i −1} (π), Y{i +1,...,n} (π)}). Man beachte, dass Ri (π) = 1, falls π(1) = i ist, und Ri (π) = 0 andernfalls. 221 / 362 Berechnung von E [Yn ] Für i 6∈ I sind die Zufallsvariablen YI und Ri unabhängig. Also gilt: E [Yn ] = 2 n X i =1 Es gilt E [Ri ] = 1 n E [Ri ] · E [max{Y{1,...,i −1} , Y{i +1,...,n} }] und max{YI , YJ }(π) ≤ YI (π) + YJ (π). Also: n E [Yn ] ≤ 2X (E [Y{1,...,i −1} ] + E [Y{i +1,...,n} ]). n i =1 Aufgrund der Linearität der Erwartungswerte und der Eigenschaft E [YI ] = E [Y{1,...,|I |} ] = E [Y|I | ] gilt: E [Yn ] ≤ n n n−1 i =1 i =1 i =1 2X 4X 4X (E [Yi −1 ] + E [Yn−i ]) = E [Yi −1 ] = E [Yi ]. n n n 222 / 362 Berechnung von E [Yn ] Wir werden jetzt zeigen, dass E [Yn ] ≤ n = 1: E [Y1 ] = 1 = 1 4 n ≥ 2: 4 3 . n−1 4X E [Yi ] E [Yn ] ≤ n i =1 Obere Summation = 1 n n+3 4 1 4 Induktion ≤ 1 = 4 n+3 3 gilt. n−1 4X1 n 4 i =1 n+3 3 i +3 3 n−1 1X < n i =0 i +3 3 . 223 / 362 Nachtrag Zu zeigen verbleibt die Obere Summation n−1 X i +k n+k = . k k +1 i =0 ◮ ◮ ◮ Zähle die k + 1-elementigen Teilmengen mit größtem Element i + k + 1. i +k Deren Anzahl ist k . Der Index i läuft dabei von 0 bis n − 1. 224 / 362 Berechnung von E [Xn ] Jensen’sche Ungleichung für konvexe Funktionen: f (E [X ]) ≤ E [f (X )]. In unserem Fall ist die konvexe Funktion f (x) = 2x : 1 n+3 24n3 (n + 3)(n + 2)(n + 1) E [Xn ] Xn 2 ≤ E [2 ] = E [Yn ] ≤ ≤ . = 4 24 24 3 Ziel erreicht: E [Xn ] ≤ 3 log2 n ∈ O(log n). 225 / 362 Konvexe Funktionen f : R → R heißt konvex falls für alle x < y und 0 ≤ λ ≤ 1 gilt: f ((1 − λ)x + λy ) ≤ (1 − λ)f (x) + λf (y ) . Schaubild der konvexen Funktion f : (1 − λ)f (x) + λf (y ) x (1 − λ)x + λy y 226 / 362 Jensen’sche Ungleichung Sei f : R → R eine konvexe Funktion und λi ≥ 0 für 1 ≤ i ≤ k mit P k i =1 λi = 1. Dann gilt f k X i =1 λi x i ! ≤ k X λi f (xi ). i =1 Beweis: Durch Induktion nach k. k = 1: Dann ist λ1 = 1 und die Aussage trivial. 227 / 362 Jensen’sche Ungleichung Damit gilt jetzt (für k > 1 und damit ohne Einschränkung λ1 < 1): f k X i =1 λi xi ! = f konvex ≤ Induktion ≤ = f k X λ1 x1 + (1 − λ1 ) i =2 λ1 f (x1 ) + (1 − λ1 )f λ1 f (x1 ) + (1 − λ1 ) k X λi xi 1 − λ1 k X i =2 k X i =2 ! λi xi 1 − λ1 ! λi f (xi ) 1 − λ1 λi f (xi ). i =1 228 / 362 Erwartungswerte diskreter Zufallsvariable Sei X : Ω → R eine diskrete Zufallsvariable. Dann berechnet sich der Erwartungswert durch X X E [X ] = Prob(i ) · X (i ) = λi xi mit xi = X (i ), λi = Prob(i ). i i Für eine konvexe Funktion f folgt dann aus der Jensen’schen Ungleichung: f (E [X ]) ≤ P i λi f (xi ) = E [f (X )]. 229 / 362 14. und 15. Vorlesung, 12./13.06.2017 Von Rucksäcken und Handlungsreisenden. Pseudo-polynomielle Algorithmen. Approximationen: FPTAS. Verzeige und beschränke: Branch & and Bound. 230 / 362 Rucksackproblem Eingabe: Eine Liste von n Objekten, die jeweils ein Gewicht gi und einen Wert wi haben sowie eine globale Schranke g , die dem maximalen Gewicht im Rucksack entspricht. Formal ist die Eingabe also: ((g1 , w1 ), . . . , (gn , wn ); g ) ∈ N2n+1 . Ziel: Maximiere P i ∈I wi unter der Nebenbedingung P i ∈I gi ≤ g . Sind die Zahlen binär gegeben, so ist das Problem schon in der folgenden Entscheidungsvariante NP-vollständig: X Subset sum: ∃I ⊆ { 1, . . . , n } : gi = g ? i ∈I Die NP-schwierige Frage ist: Kann man für wi = gi den Rucksack optimal füllen?” ” 231 / 362 Rucksackproblem: Dynamische Lösung Sind die Werte wi (oder die Gewichte gi ) unär gegeben, so ist das Problem durch dynamisches Programmieren in polynomieller Zeit lösbar. Das Rucksackproblem ist also pseudo-polynomiell. Betrachte zunächst Pn den Fall, dass alle wi unär gegeben sind. Idee: Setze m = i =1 wi . Dies ist der maximale Wert. Fülle in n Runden ein Feld G der Länge m so, dass in der Runde k an Position j der Eintrag Gj steht mit der folgenden Bedingung: ( ) X X Gj = min gi I ⊆ { 1, . . . , k } ∧ wi = j . i ∈I i ∈I Beachte: In Gj ist der Wert konstant j, aber das Gewicht wird minimiert. Wir berechnen also jeweils das kleinste Gewicht, um den Wert j zu erhalten. 232 / 362 Rechnung der k-ten Runde Initial ist G0 = 0 und Gj = ∞ für alle Werte j = 1, . . . , m. In der Runde k kann der Wert wk hinzukommen. Sei Gj (k − 1) der Wert Gj nach der (k − 1)-ten Runde. Wir erhalten Gj (k) = Gj (k − 1) für alle j < wk und für j ≥ wk : Gj (k) = min { Gj (k − 1), gk + Gj−wk (k − 1) } . Die Lösung ist das maximale wopt = j mit Gj (n) ≤ g . Angenommen, wir haben eine Schätzung W0 mit wopt ≤ W0 . Dann gilt wopt ≤ W0 ≤ m und es reicht, die Gj (k) für j ≤ W0 zu berechnen. Dies setzen wir um. Die Idee ist relevant, wenn wir wopt approximieren wollen. 233 / 362 Pseudocode, wie eben wopt ≤ W0 ≤ m = Pn i=1 wi Konstruiere eine Tabelle G [j, k] für 0 ≤ j ≤ W0 und 0 ≤ k ≤ n so, dass am Ende: ( ) X X G [j, k] = min gi wi = j ∧ I ⊆ { 1, . . . , k } . i ∈I i ∈I 1. Initialisierung: G [0, k] = 0 für 0 ≤ k ≤ n. 2. Konvention: G [j, k] = ∞ falls j < 0 oder k = 0 und j > 0. for j := 1 to W0 do for k := 1 to n do G [j, k] := min { G [j, k − 1], G [j − wk , k − 1] + gk } endfor endfor Laufzeit ist in O(nW0 ) ⊆ O(nm). Eigentlich reicht es sich jeweils die letzte Spalte zu merken. Also benötigen wir nur ein Feld: G [j] für 0 ≤ j ≤ W0 . So wurde es auf der vorigen Folie beschrieben. Aber Vorsicht! 234 / 362 Bemerkungen Vereinbarung: Es gilt immer gi ≤ g für alle 1 ≤ i ≤ n, denn alle anderen Objekte können entfernt werden. Es ist nicht notwendig, ein W0 < m oder alle Werte Gj für j = 1, . . . , W0 zu kennen. Es reicht, in P der Runde k die GP j (k) zu speichern, für die eine Teilmenge I ⊆ { 1, . . . , k } existiert mit i ∈I gi ≤ g und i ∈I wi = j. Wir erhalten eine Laufzeit, die polynomiell in n und W ist, wenn W die Anzahl der möglichen Werte ist, die angenommen werden können. ( ) X X gi ≤ g . wi I ⊆ { 1, . . . , n } ∧ W= i ∈I i ∈I Diese Beobachtung führt zu einem Approximationsalgorithmus, indem wir durch Skalieren und Abrunden ein W ′ polynomieller Größe erzeugen. Siehe die nächsten Folien. 235 / 362 Fully Polynomial Time Approximation Scheme (FPTAS) Ist die Anzahl der Werte W zu groß, so werden wir uns mit einer Approximation begnügen. Definition Ein FPTAS (für das Rucksackproblem) ist ein Algorithmus, der für jedes ε > 0 eine P Ausgabe I liefert mit i ∈I gi ≤ g und (1 − ε)wopt ≤ X i ∈I wi ≤ wopt , wobei wopt den optimal erreichbaren Wert darstellt und dessen Laufzeit durch ein Polynom in nε begrenzt ist. 236 / 362 Gleichwertige Definitionen für ein FPTAS Man kann auch X i ∈I fordern, denn dies impliziert wi ≤ wopt ≤ (1 + ε) (1 − ε)wopt ≤ X i ∈I X wi i ∈I wi ≤ wopt . Umgekehrt: für ε ≤ 1/2 impliziert die letzte Zeile X X wi ≤ wopt ≤ (1 + 2ε) wi . i ∈I i ∈I 1 . Dies liefert eine konstante Approximation. Besser Typische Werte für ε sind ε ∈ 1+O(1) −k ist beispielsweise ε ∈ O(n ) für k > 0. 237 / 362 Berechnung einer O(1)-Approximation in quadratischer Zeit Angenommen, wir könnten jedes Objekt mit Gewicht gi in gi Bruchstücke mit Wert wgii und Gewicht 1 zerlegen. Dann liefert der naive Greedy-Algorithmus das Optimum. ◮ Sortiere die Bruchstücke absteigend nach wi und fülle den Rucksack mit den ersten g gi Bruchstücken. Da wir keine Bruchstücke erlauben, berechnen eine Approximation wie folgt. ◮ Sortiere die n Objekte absteigend nach wi , also nach dem relativen Wert. gi Pm ◮ Fülle den Rucksack mit den ersten m Objekten, wobei m = max { i | i =1 gi ≤ g }. ◮ Setze I1 = { 1, . . . , m } und I2 = { m + 1 }. ◮ Gebe I1 oder I2 zurück, je nachdem welche Indexmenge den höheren Wert hat. P Der Bruchstück-Ansatz zeigt: m+1 i =1 wi ≥ wopt . Also gilt: 1.) Ist wm+1 ≥ wopt /2, so ist I2 eine konstante Approximation. 2.) Ist wm+1 ≤ wopt /2, so ist I1 eine konstante Approximation. Da wir den besseren Wert nehmen, wird in der Zeit O(n2 ) eine konstante Approximation W0 berechnet und genauer gilt sogar 1/2wopt ≤ W0 ≤ wopt ≤ 2W0 . 238 / 362 Eine neue Währung, falls eine konstante Approximation bekannt ist Sei W0 ein Wert mit W0 ≤ wopt ≤ 2W0 . Für k ≥ 1 vereinbaren wir: W0 = nk e. Damit lassen sich jetzt auch alle wi in wi′ Euros ausdrücken. Die Euros dienen nur einer Anschauung, wir skalieren zur besseren Lesbarkeit 1e = 1 und lassen die Euros fort. Runden wir wie eben ab oder auf, so erhalten wir jetzt maximal 2nk mögliche Werte, die wir beachten müssen, denn es ist wopt ≤ 2W0 . 1 Wegen wopt ≥ W0 = nk erhalten wir nk−1 wopt ≥ n. Sei jetzt Ik die die für die PIndexmenge, ′ abgerundeten Werte P (bzgl. der Euro-Währung) den Wert Wk = i ∈I ′ ⌊wi ⌋ unter der Nebenbedingung i ∈I ′ ⌊gi ⌋ ≤ g maximiert. Die Laufzeit ist jetzt in O(nk+1 ). Ferner gilt: (1 − 1 nk−1 )wopt ≤ wopt − n ≤ Wk ≤ wopt ≤ (1 + 2 nk−1 )Wk . Spezialfall: Eine (1 − 1/n)-Approximation kann in kubischer Zeit gefunden werden. Dieser Ansatz führt direkt zu (1 − ε)-Approximationen. Siehe die nächsten Folien. 239 / 362 Währungsfreie Skalierung Startpunkt W0 ≤ wopt ≤ 2W0 . ◮ ◮ ◮ Wähle Skalierungsfaktor S ∈ N. Löse das Rucksackproblem mit Gewichten wi′ = wi S . Die Ausgabe des modifizierten Rucksackproblems ist eine Approximations des ursprünglichen Rucksacks mit einem Wert WS Satz Sei S = j ǫW0 n k . Dann liefert das Verfahren in der Zeit O(n2 /ε) einen Wert WS mit (1 − ε)wopt ≤ WS ≤ wopt . 240 / 362 Beweis des Satzes Die Laufzeit ist klar, da nur 2n/ε Werte berücksichtigt werden müssen. Sei I diePoptimale Lösung des ursprünglichen Rucksacks und wopt ihr Wert P (d. h. wopt = i ∈I wi ) und sei I ′ die approximierte Lösung mit Wert WS = i ∈I ′ wi . Dann gilt X X j wi k (für geeignete 0 ≤ ǫi < 1) + ǫi WS = wi = S S ′ ′ i ∈I i ∈I X j wi k ≥S (ersetze jetzt I ′ durch I :) S i ∈I ′ X j wi k (weil I ′ die optimale Lösung war) ≥S S i ∈I X X wi X S ·n − ǫi = )wopt . =S wi − S ǫi ≥ wopt − S · n = (1 − S wopt i ∈I Nun gilt S·n wopt = j ǫW0 n k i ∈I · n/wopt ≤ ǫW0 wopt i ∈I ≤ ǫwopt wopt = ε. 241 / 362 Exakte Lösungen NP-schwieriger Probleme Beispiel: Das Problem des Handlungsreisenden. Branch and Bound – Verzweigen und Beschränken 242 / 362 Das Problem des Handlungsreisenden: TSP Eingabe: Eine Menge V von Städten und für alle i , j ∈ V die Kosten“ oder ” Entfernungen“ d(i , j), um von i nach j zu reisen. ” In der asymmetrischen Varianten sind Einbahnstraßen erlaubt. Ziel: Finde eine Rundreise, die alle Städte genau einmal besucht und die Gesamtkosten minimiert. Das Problem ist schon in der Entscheidungsvarianten NP-vollständig (Hamiltonkreis): Existiert eine Rundreise, die alle Städte genau einmal besucht?“ ” 243 / 362 Rundreise = Permutation Gesucht ist für V = { 1, . . . , n } also eine Permutation π = (π(1), . . . , π(n)), die die folgende Summe minimiert: Dopt = X d(π(i ), π(i + 1)). i ∈Z/nZ Wir erlauben d(i , j) = ∞ und vereinbaren in diesem Abschnitt d(i , i ) = ∞ (da wir keine Schleifen durchlaufen). Es reicht“ Dopt zu berechnen. (Warum?) ” Ohne Einschränkung gilt π(1) = 1, da wir eine Rundreise bei 1 starten können. Ein naiver Algorithmus durchsucht alle (n − 1)! Permutationen mit π(1) = 1. Die Funktion n! wächst etwa so schnell wie (n/e)n also schneller als jede einfach exponentielle Funktion k n , wenn k fest ist. Es ist möglich, TSP in der Zeit O(n2 2n ) zu lösen. 244 / 362 Einfache exponentielle TSP Lösung Dynamisches Programmieren: Berechne für alle (i , S) mit i = 1, . . . , n und S ⊆ { 1, . . . , n } \ { 1, i } die minimalen Kosten D(i , S) für einen Weg, der in i startet, alle Städte in S genau einmal besucht und in 1 endet. Dopt = D(1, { 2, . . . , n }). Initial ist: D(i , ∅) = d(i , 1). Für S 6= ∅ gilt: D(i , S) = min { d(i , k) + D(k, S \ { k }) | k ∈ S } . Wir minimieren über die k ∈ S, da die erste Stadt nach i eine Stadt k in der Menge S sein muss. Laufzeit: O(n2 2n ), um die ca. n2n Werte zu berechnen. 245 / 362 Matrixdarstellung des TSP ∞ 10 ∞ 20 5 ∞ 9 10 6 13 ∞ 12 Keine Kante von 1 nach 3. 8 8 9 ∞ ∞ 10 15 20 5 ∞ 9 10 6 13 ∞ 12 Eine Kante von 1 nach 3 mit Kosten 15. 8 8 9 ∞ ∞ 10 15 20 10 ∞ 9 10 15 9 ∞ 12 Keine Einbahnstraßen – symmetrische Matrix 20 10 12 ∞ 246 / 362 Branch and Bound Im Folgenden betrachten wir die folgende Matrix Schöning). ∞ 10 15 5 ∞ 9 6 13 ∞ 8 8 9 (aus dem Algorithmenbuch von Uwe 20 10 12 ∞ Jeder Rundweg verlässt 1 mit den Mindestkosten 10, also können wir 10 zur Lösung des folgenden Problems addieren. ∞ 0 5 10 5 ∞ 9 10 6 13 ∞ 12 8 8 9 ∞ 247 / 362 Reduktion: Bound = untere Schranke ∞ 10 15 20 5 ∞ 9 10 6 13 ∞ 12 8 8 9 ∞ Zeilenreduktion liefert untere Schranke bound = 29. ∞ 0 5 10 0 ∞ 4 5 0 7 ∞ 6 0 0 1 ∞ Spaltenreduktion liefert untere Schranke ∞ 0 0 0 bound = 29 + 1 + 5 = 35. 0 4 5 ∞ 3 0 7 ∞ 1 0 0 ∞ 248 / 362 Verzweigung ∞ 0 4 5 0 ∞ 3 0 0 7 ∞ 1 0 0 0 ∞ bound = 35 (= Übertrag nach der Reduktion) ¬(2, 1) ∞ 0 4 5 ∞ ∞ 3 0 0 7 ∞ 1 0 0 0 ∞ bound = 35 (2, 1) ∧ ¬(1, 2) ∞ ∞ 4 5 0 ∞ ∞ ∞ ∞ 7 ∞ 1 ∞ 0 0 ∞ bound = 35 + 4 + 1 = 40 249 / 362 Verzweigung mit ¬(2, 1) mit besserem bound“ ” ∞ 0 4 5 ∞ ∞ 3 0 0 7 ∞ 1 0 0 0 ∞ bound = 35 ¬(3, 1) ∞ 0 4 5 ∞ ∞ 3 0 ∞ 7 ∞ 1 0 0 0 ∞ bound = 35 + 1 = 36 (3, 1) ∧ ¬(1, 3) ∞ 0 ∞ 5 ∞ ∞ 3 0 0 ∞ ∞ ∞ ∞ 0 0 ∞ bound = 35 250 / 362 Verzweigung mit (3, 1) mit besserem bound“ ” ∞ 0 ∞ 5 ∞ ∞ 3 0 0 ∞ ∞ ∞ ∞ 0 0 ∞ bound = 35 ¬(4, 2) ∞ 0 ∞ 5 ∞ ∞ 3 0 0 ∞ ∞ ∞ ∞ ∞ 0 ∞ bound = 35 (4, 2) ∧ ¬(2, 4) ∞ 0 ∞ 5 ∞ ∞ 3 ∞ 0 ∞ ∞ ∞ ∞ 0 ∞ ∞ bound = 38 251 / 362 Verzweigung mit ¬(4, 2) mit besserem bound“ ” ∞ 0 ∞ 5 ∞ ∞ 3 0 0 ∞ ∞ ∞ ∞ ∞ 0 ∞ bound = 35 ¬(2, 4) ∞ 0 ∞ 5 ∞ ∞ 3 ∞ 0 ∞ ∞ ∞ ∞ ∞ 0 ∞ bound = 35 + 3 = 38 (2, 4) ∞ 0 ∞ ∞ ∞ ∞ ∞ 0 0 ∞ ∞ ∞ ∞ ∞ 0 ∞ bound = 35 Lösung: 1-2-4-3-1 252 / 362 Lösung: 1-2-4-3-1 Ausgangsmatrix: ∞ 10 15 20 5 ∞ 9 10 6 13 ∞ 12 8 8 9 ∞ Lösung: ∞ ∞ 6 ∞ 10 ∞ ∞ ∞ ∞ 10 ∞ ∞ ∞ ∞ 9 ∞ 253 / 362 Metrisches TSP Eingabe ist ein vollständiger ungerichteter Graph mit Knotenmenge V = { 1, . . . , n }, Kantengwichten d(i , j) = d(j, i ) ≥ 0 und es gilt die Dreiecksungleichung: d(i , j) ≤ d(i , k) + d(k, j). Ziel: Berechne einen optimalen Rundweg. Problem: Schon das Entscheidungsproblem Gibt es einen Rundweg mit Kosten ≤ n?” ist ” NP-schwierig für metrische TSPs mit d(i , j) ∈ { 0, 1, 2 }. Folklore(?): 2-Approximation mit MST und Eulertour. Christofides 1976: 3/2-Approximation mit Matching zwischen ungeraden Knoten. Papadimitriou 1976: Euclidean TSP is NP complete. (In dieser Form liegen die Punkte in der Ebene R2 und der Abstand ist der übliche euklidische Abstand. Sanjeev Arora, Carsten Lund, Rajeev Motwani, Madhu Sudan, Mario Szegedy 1992: There is no PTAS for Metric TSP, unless P = NP Vermutung: bestmögliche polynomielle Approximation mit Faktor: 4/3 254 / 362 Eine 2-Approximation in quadratischer Zeit Für eine Kantenmenge E = { e1 , . . . em } mit ei = (xi , yi ) sei d(E ) = Gewicht. Sei d ∗ das Gewicht einer optimalen Rundreise. P i d(xi , yi ) ihr ◮ Streicht man in einer Rundreise eine Kante, so erhalten wir einen Spannbaum. ◮ Aufgrund der Dreiecksungleichung ist eine optimale Rundreise, die jeden Knoten genau einmal besucht, nie länger als ein Rundweg durch alle Knoten, bei dem Mehrfachbesuche erlaubt sind. Daher sind Mehrfachbesuche von Knoten in metrischen TSPs erlaubt! Wir erhalten eine 2-Approximation wie folgt. 1. Berechne einen minimalen Spannbaum T in der Zeit O(n2 ). 2. Verdopple jede Kante, dann hat jeder Knoten einen graden Grad. 3. Berechne eine Eulertour R in der Zeit O(n). Für d ∗ > 0 gilt jetzt: d ∗ ≤ d(R) ≤ 2d(T ) < 2d ∗ . 255 / 362 Christofides’ 3/2-Approximation in polynomieller Zeit Sei T der eben berechnete minimalen Spannbaum und sei U ⊆ V die Menge der Knoten in (U, T ) mit ungeradem Grad. Da die Summe der Grade gerade ist, folgt |U| = m, wobei m gerade ist. Wie eben sei 0 < d ∗ das Gewicht einer optimalen Rundreise. Betrachte das metrische TSP für die Knotenmenge U und sei (e1 , . . . , em ) ein optimaler Rundweg durch U. Dann erhalten wir zwei perfekte Matchings für U: M1 = { e1 , e3 , . . . , em−1 } mit Gewicht d1 M2 = { e2 , e4 , . . . , em } mit Gewicht d2 Berechne ein gewichtsoptimales perfektes Matching M für den Graphen (U, d) in in polynomieller Zeit. (Wird hier nicht behandelt.) ◮ Berechne eine Eulertour in dem Graphen (V , T ∪ M) mit Gewicht dT ,M . Es gilt: d1 + d2 d(T ) < d ∗ und d(M) ≤ min { d1 , d2 } ≤ ≤ d ∗ /2. 2 Hieraus folgt: d ∗ ≤ dT ,M < 32 d ∗ . ◮ 256 / 362 16. und 17. Vorlesung, 19./20.06.2017 Thema: Verwaltung von Mengen Union – Find 257 / 362 Verwaltung von Mengen Union-Find-Algorithmen Definition: Eine Partition P einer Menge M ist eine Zerlegung von M in disjunkte, nicht-leere Teilmengen: m M = [ ˙ Pi i =1 P = {Pi | Pi ∩ Pj = ∅, Pi 6= ∅, 1 ≤ i < j ≤ m} Beispiel: Sei M = {1, 2, . . . , 12}. Dann ist P = {Q, R, S} mit Q = {i ∈ M | i ungerade}, R = {i ∈ M | i ≡ 0 mod 4} und S = {i ∈ M | i ≡ 2 mod 4} eine Partition von M. 258 / 362 Union-Find ◮ ◮ ◮ Find ist eine Funktion, die jedem i ∈ M die Menge Pj zuordnet, für die i ∈ Pj gilt. Benutzt wird Find(x) = Find(y )?“ ” Nur nach einem Find-Aufruf erfolgt u.U. ein Union-Aufruf. ◮ Union verändert die Partition wie folgt: Union(A, B) bedeutet, dass die Partitionselemente A, B ∈ P zu einer neuen Menge mit dem Namen C vereinigt werden. Der neue Name kann explizit in Form eines Union(A, B, C ) oder implizit sein. ◮ Nach Union(A, B) ist die neue Partition (P \ {A, B}) ∪ {A ∪ B}. 259 / 362 Thema: Kruskal-Algorithmus zur Union-Find-Berechnung” eines minimalen Spannbaums ” Zeitanalyse von Union – Find 260 / 362 Minimale Aufspannende Bäume Definition 16.1 Ein Graph G = (V , E ) heißt zusammenhängend, wenn je zwei Knoten durch einen Pfad verbunden sind. Definition 16.2 Ein Baum ist ein zusammenhängender, kreisfreier, ungerichteter Graph. Bemerkung 16.3 Jeder Baum mit n Knoten besitzt genau n − 1 Kanten. Definition 16.4 Ein minimaler aufspannender Baum (minimal spanning tree, MSB) zu einem gewichteten Graphen P G = (V , E , γ) ist ein Baum B = (V , F , γ|F ) mit F ⊆ E mit minimalem Gewicht γ(B) := e∈F γ(e). 261 / 362 Algorithmus 16.1 Kruskal-Algorithmus zur Bestimmung des MSB function kruskal(G = (V , E , γ): kantengew. Graph): Kantenmenge; (∗ G sei zusammenhängend ∗) (∗ E = {e1 , e2 , . . . , em } sei nach Gewichten aufsteigend sortiert. ∗) var m, i : integer; x, y : Knoten; T : Kantenmenge; (∗ des MSB ∗) begin m := |E |; T := ∅; forall v ∈ V do [v ] := {v } endfor; (∗ Init. des Waldes ∗) for i := 1 to m do xy := ei ; if Find(x) 6= Find(y ) then Union(x, y ); T := T ∪ {xy } endif endfor return T endfunction 262 / 362 Mögliche Prüfungsfragen ◮ ◮ Wie groß können m = |E | und |T | werden? (Allgemeine Graphen, planare Graphen?) Müssen alle Kanten vorsortiert werden? ◮ Was sind geeignete Datenstrukturen, um die Kanten zu verwalten? ◮ Wenn man die for-schleife durch eine while Schleife ersetzt, was ist dann die geeignete Abbruchbedingung? ◮ Was sind geeignete Datenstrukturen für Union-Find-Realisierungen? 263 / 362 Feld von Paaren 1 Q 2 S 3 Q 4 R 5 Q 6 S 7 Q 8 R 9 Q 10 S 11 Q 12 R Hier gilt z.B. Find(5) = Q Union(Q, R, T ) ergibt (d.h. Q und R werden zu einer Klasse mit Namen T vereinigt): 1 T 2 S 3 T 4 T 5 T 6 S 7 T 8 T 9 T 10 S 11 T 12 T 264 / 362 Feld: Quadratische Kosten ◮ ◮ ◮ ◮ Kosten: Find-Operation O(1). Kosten: Union-Operation Θ(n). In den Anwendungen werden häufig m Union-Find-Operationen hintereinander durchgeführt, mit m ∈ Ω(n). Damit insgesamt: Ω(n2 ). Ziel: m Union-Find-Operationen in fast linearer“ Zeit. ” 265 / 362 Knotenbeschriftete Bäume Klasse = knotenbeschrifteter Baum, Wurzel = Name der Klasse. Elemente der Grundmenge: 1, . . . , n. Knoten = {v1 , . . . , vn } Zugriffsmöglichkeiten: element: {1, . . . , n} → Knoten pred: Knoten → Knoten count: Wurzelknoten → Zahl name: Wurzelknoten → Klasse root: Menge → Wurzelknoten zugehöriger Knoten im Baum Vorgänger im Baum Anzahl der Elemente Name der Klasse Wurzel des Baumes 266 / 362 Union Die Initialisierung ist dann: name(vi ) := i root(i ) := vi pred(vi ) := nil count(vi ) := 1 Die Union-Operation Union(i , j) wird dann so realisiert, dass der kleinere der beiden Bäume i , j an die Wurzel des größeren angehängt wird: 267 / 362 Union Realisierung Hänge den kleineren Baum unter die Wurzel des größeren Baumes. L Union R L R 268 / 362 Logarithmische Find-Kosten Lemma 16.5 Sei B ein Baum der durch Union-Find Operationen entsteht und n = |B|. Hat B die Höhe r , so gilt r ≤ log2 n und n ≥ 2r . Beweis: Für r = 0 ist die Behauptung klar. Seien L und R Bäume, die zu einem Baum B mittels Union zusammengefügt werden und |R| ≥ |L|. Hat B weiterhin die Höhe von R, so gilt n ≥ |R| ≥ 2r mit Induktion. Ist die Höhe von B größer geworden, so gilt r = ℓ + 1, wenn ℓ die Höhe von L ist. Damit gilt nach Induktion: n = |L| + |R| ≥ 2 |L| ≥ 2 · 2ℓ = 2ℓ+1 = 2r . 269 / 362 Union Satz 16.6 Sei m ∈ Ω(n). Dann lassen sich bei einer n-elementigen Grundmenge m Union-Find-Operationen (ohne Pfadverkürzung) in der Zeit O(m log n) realisieren. Eine weitere Idee zur Verkürzung der Suchpfade (= benötigte Find-Zeit) besteht darin, bei einem Aufruf von Find alle Knoten auf dem Pfad, den man zur Wurzel hin durchläuft, direkt unter die Wurzel anzuhängen. 270 / 362 Find mit Pfadverkürzung p p s q q r r s Baum nach Find(s) Baum vor Find(s) 271 / 362 Find-Implementierung mit Pfadverkürzung Algorithmus 16.2 function Find(i : Element): Element; var u, v , root: Knoten; begin u := element[i ]; while pred(u) 6= nil do u := pred(u); endwhile root := u; u := element[i ]; while pred(u) 6= nil do v := pred(u); pred(u) := root; u := v endwhile return name(root); endfunction 272 / 362 Zeitanalyse für Union-Find Dieser Abschnitt beschreibt die Analyse nach Robert E. Tarjan (1983) für m Union-Find-Operationen. Wir verwenden die folgende Ackermannfunktion: A0 (r ) = r + 1, Ak+1 (r ) = Ark (r ). (Hierbei bezeichnet Ark (r ) die r -fache Anwendung von Ak auf r .) Es ist Ak (1) = 2 für alle k ∈ N; daher ist sinnvoll: α(n) = min{k | Ak (2) ≥ n}. A1 (x) = 2x, A2 (x) = x2x , A3 (2) = 2048, also A4 (2) = A23 (2) = A3 (2048) = A2048 (2048): ein Turm von mehr als 2000 Potenzen der 2. 2 2 ·· Es ist α(n) ≤ 4 = α(2049) für alle denkbaren Werte von n (etwa n ≤ |22{z } ). Turm von 2000 2ern 273 / 362 Der Rang eines Knotens Definition 16.7 Der Rang eines Knotens x, Rang(x), ist die Höhe des Knotens in dem Wald, der ohne Pfadverkürzung erzeugt wurde. Lemma 16.8 Sei x ein Knoten mit Rang(x) = r . Dann hat der Teilbaum mit der Wurzel x mindestens 2r Elemente. Beweis: Lemma von eben. Korollar 16.9 Es gibt höchstens n/2r Knoten mit Rang r . Beweis: Zwei Knoten mit gleichem Rang sind nicht Vorgänger voneinander. 274 / 362 Analyse von m Union-Find-Operationen Wir betrachten n Knoten und die folgende zeitabhängige Funktion part (x): Definition 16.10 Sei x ein Knoten ungleich der Wurzel mit Rang r . Dann bezeichnet part (x) seinen Vorgänger (englisch: parent) zum Zeitpunkt t. Definition 16.11 Ein Knoten x mit Rang r ≥ 2 gehört zur Zeit t zur Klasse (oder Ranggruppe) k, falls k maximal ist mit r (part (x)) ≥ Ak (r (x)). Beachte: n ≥ 2r (part (x)) >r (part (x)) ≥ Ak (r (x)) ≥ Ak (2). Also ist Ak (2) nicht größer oder gleich n und daher gilt für existierende Ranggrupxpen k stets: 0 ≤ k < α(n). 275 / 362 Analyse von m Union-Find-Operationen ◮ Wurzeln oder Knoten vom Rang 0 oder 1 gehören in keine Klasse. Ein innerer Knoten mit Rang 2 gehört mindestens in die Klasse 0. ◮ Es gibt höchstens α(n) verschiedene Klassen. ◮ Realistisch: nur die Klassen 0, 1, 2 und 3. ◮ Eine Klasse kann als Maß für den Abstand eines Knotens zu seinem Vaterknoten angesehen werden. Damit ist auch klar: Die Klassennummern, die man auf dem Pfad zur Wurzel antrifft, müssen nicht wie die Ränge monoton steigen. 276 / 362 Die Lebensgeschichte eines Knotens Erinnerung: Es gibt höchstens α(n) Rangklassen. ◮ Ein Knoten x beginnt als Wurzel. ◮ Wenn er den Wurzelstatus verliert, erhält er seinen Rang r (x). ◮ Bei Rang 0 oder 1 bleibt x für immer klassenlos. ◮ Bei Rang 2 oder mehr betritt x eine Klasse k ≥ 0. ◮ ◮ Ab jetzt geht es in der Klassengesellschaft nur aufwärts. Realistischerweise sollte man nur auf Klasse 3 hoffen. 277 / 362 Analyse von m Union-Find-Operationen Erinnerung: Teuer sind nur die Find-Operationen. Bei einem Find(i ) verteilen wir auf dem Pfad Gold- und Eisenstücke auf die Knoten. Wir unterscheiden α(n) Klassen von Eisenstücken, so dass es insgesamt 1 + α(n) verschiedene Währungen gibt. Goldverteilung: Wenn x auf dem Pfad zur Wurzel besucht wird, gibt es ein Goldstück, falls x keiner Klasse angehört (d.h. x ist Wurzel oder vom Rang 0 oder 1) oder x letzter seiner Klasse ist. Korollar 16.12 Insgesamt werden nicht mehr als (3 + α(n))m Goldstücke verteilt. 278 / 362 Analyse von m Union-Find-Operationen Eisenverteilung: Wenn x zur Zeit t auf dem Pfad zur Wurzel besucht wird, erhält x ein Eisenstück der Klasse k, falls x zu dieser Zeit zur Klasse k gehört und nicht letzter seiner Klasse ist. Beobachtung: Erhält x zur Zeit t ein Eisenstück der Klasse k, so gibt es auf dem Pfad zur Wurzel Knoten x, part (x), y , part (y ) mit: Ak (r (x)) ≤ r (part (x)) ≤ r (y ), Ak (r (y )) ≤ r (part (y )). Satz 16.13 Sei i ≥ 1 mit r (part (x)) ≥ Aik (r (x)). Dann gilt zur Zeit t + 1 die Beziehung: r (part+1 (x)) ≥ Aik+1 (r (x)). r (x) Konsequenz. Nach r (x) − 1 Besuchen von x gilt r (par(x)) ≥ Ak (r (x)) = Ak+1 (r (x)). 279 / 362 Beweis Wähle auf dem Pfad x, part (x), y , part (y ) mit: Aik (r (x)) ≤ r (part (x)) ≤ r (y ), Ak (r (y )) ≤ r (part (y )). Dann folgt: r (part+1 (x)) ≥ ≥ ≥ ≥ = r (part (y )) Ak (r (y )) Ak (r (part (x))) Ak (Aik (r (x))) Aik+1 (r (x)). 280 / 362 Korollare Ein Knoten vom Rang r erhält maximal r − 1 Eisenstücke der Klasse k. (Erinnerung r ≥ 2.) Beweis: Nach r Find-Operationen in der Klasse k gilt: r (pars (x)) ≥ Ark (r ) = Ak+1 (r ) und der Knoten steigt in die Klasse k + 1 auf. Korollar 16.14 Es werden insgesamt maximal 3n 2 ≤ 2n Eisenstücke der Klasse k verteilt. r Beweis: Es gibt höchstens n/2 Knoten mit Rang r und jeder erhält höchstens r − 1 Eisenstücke der Klasse k. Damit: X (r − 1)n =n 2r r ≥2 Korollar 16.15 Es werden insgesamt maximal α(n)n Eisenstücke verteilt. Beweis: α(n) Klassen und pro Klasse n Eisenstücke. 281 / 362 Abschätzung für die Gesamtkosten Alle Finds zusammen kosten O ((3 + α(n))m + α(n)n) Zeit. Beweis: (3 + α(n))m Gold + α(n)n Eisen. Übung: Für α(n) < 4 dominiert die Konstante 6m im O-Term, da m > n. Wie erreicht man 5m? Lösung steht etwa bei Kozen oder Tarjan. 282 / 362 Gemessene Laufzeitkosten Die folgenden Diagramme zeigen experimentell gemessene Werte für die Laufzeitkosten, die die Union-Find-Implementierung mit Pfadverkürzung beim Kruskal-Algorithmus verursacht. Gemessen wurde jeweils, wie viele Knoten alle Find-Operationen zusammen besuchen mussten. Der zugrunde gelegte Graph wurde stets zufällig erstellt und hatte n Knoten sowie m Kanten, wie es in den Diagrammen jeweils zu sehen ist. Die Diagramme zeigen die Ergebnisse jeweils für drei verschiedene Strategien der Implementierung: Normal Die normale Strategie, bei einem Union stets den kleineren Baum unter den größeren zu hängen Invers Die umgekehrte Strategie, bei einem Union stets den größeren Baum unter den kleineren zu hängen Zufall Bei jedem Union wird gewürfelt, ob nun der kleinere Baum unter den größeren gehängt werden soll oder umgekehrt 283 / 362 Experimente 284 / 362 Experimente 285 / 362 18. Vorlesung, 03.07.2017 Themen: 1. Fibonacci-Heaps 2. Amortisierte Zeitanalyse Anwendungen: 1. Dijkstra/Prim 2. Berechnung minimaler Schnitte nach Stoer/Wagner. (Siehe den nächsten Abschnitt.) 286 / 362 Fibonacci-Heaps Fibonacci-Heap H = Liste von Bäumen (also ein Wald): Die Bäume sind knotenbeschriftet. Alle Knoten, bis auf die Wurzel, können zusätzlich eine Marke tragen. V = Knotenmenge. key : V → N Beschriftung. root bezeichnet stets eine der Wurzeln. Heap-Bedingung: ∀x ∈ V : ist y ein Kind von x, so gilt: key (x) ≤ key (y ) 287 / 362 Fibonacci-Heaps ◮ Die Eltern-Kind-Beziehung wird durch Zeiger realisiert, da die Bäume unbalanciert sein werden. ◮ Im Gegensatz zu einem Standard-Heap müssen Indexrechnungen also durch aufwendige Zeigeroperationen ersetzt werden. ◮ Operationen: ◮ 1. merge, ◮ 2. insert, ◮ 3. delete min, ◮ 4. decrease key. 288 / 362 Fibonacci-Heaps ◮ merge: Konkatenation zweier Listen — konstante Zeit. ◮ insert: Spezialfall von merge — konstante Zeit. ◮ merge und insert können (eventuell sehr lange) Listen einelementiger Bäume erzeugen. ◮ Jede solche Liste ist ein Fibonacci-Heap. 289 / 362 delete min ◮ Sei H ein Fibonacci-Heap aus T Bäumen und n Elementen. ◮ Für einen Knoten x sei der Rang(x) = rg (x) = die Anzahl der Kinder von x. ◮ Für einen Baum B sei rg (B) = Rang der Wurzel von B. ◮ Sei rmax (n) der maximale Rang, der in einem Fibonacci-Heap mit n Elementen auftreten kann. ◮ rmax (n) < n. ◮ Später zeigen wir rmax (n) ∈ O(log n), aber wenn man es implementieren will, müssen wir es genauer wissen! Wir zeigen n ≥ Fk+2 , falls rmax (n) ≤ k. ◮ Für n = 106 = 1000000 bedeutet dies rmax (n) < 30. 290 / 362 procedure delete min 1. Suche minimalen Schlüssel als Wurzel in einem Baum. Sei r der Rang dieses Baumes. Zeit: O(T ). Alternativ gibt es einen Zeiger auf das kleinste Element. 2. Trenne die Wurzel ab und ersetze den Baum durch die r Teilbäume. Evtl. Marken entfernen. Zeit: O(T + r ). 3. Definiere Feld L[0, . . . , rmax (n)] mit L[i ] = die Liste der Bäume von Rang i . Zeit: O(T + rmax (n)). 4. for i := 0 to rmax (n) − 1 do while |L[i ]| ≥ 2 do Entnehme zwei Bäume aus L[i ]. Hänge den Baum mit dem größeren Schlüsselwert an der Wurzel direkt unter die Wurzel des anderen Baumes und füge diesen neuen Baum in L[i + 1] an. endwhile endfor delete min erfordert also die Zeit O(T + rmax (n)). 291 / 362 Bemerkung Am Ende der Prozedur delete min gibt es für jeden möglichen Rang höchstens einen Baum. Insbesondere ist die Zahl der Bäume durch rmax (n) beschränkt. Beachte, wir nehmen hier als Definition von rmax (n) mindestens den Wert an, der nie dazu führt, dass bei delete min die Liste L[rmax (n)] mehr als einen Baum erhalten kann. Wegen der naiven Abschätzung rmax (n) ≤ n − 1, existiert rmax (n). Später zeigen wir: n ≥ Frmax (n)+2 . 292 / 362 decrease key Kaskadenartige Schnitte: Sei x der Knoten, dessen Schlüssel verkleinert werden soll. 1. Ist x die Wurzel, so kann der Schlüsselwert verkleinert werden. Sei also x keine Wurzel und x = y0 , y1 , . . . , yk , . . . , root der Pfad von x zur Wurzel. Für ein k ≥ 1 sei yk der erste (von x verschiedene) Knoten, der keine Marke trägt. 2. Für 0 ≤ i < k trenne jetzt yi vom Elternknoten yi +1 ab und entferne dabei die Marke von yi . (Für y0 = x ist evtl. eine Marke vorhanden gewesen.) Damit wird yi für 0 ≤ i < k zu einer unmarkierten Wurzel eines eigenen Baumes. 3. Falls yk keine Wurzel ist, markiere yk . (Kind verloren!) 293 / 362 decrease key Es wird O(k + 1) Zeit benötigt. Beachte: Die Zahl der Marken hat sich mindestens um k − 2 verringert für k ≥ 2. Für k = 1 kann maximal eine Marke hinzugekommen sein. Dies passiert wenn, x und y1 vorher unmarkiert waren. Sei M die Zahl der Marken vor decrease key und M ′ danach. Dann gilt immer M ′ ≤ M + 2 − k. Die Anzahl der Bäume ist nach der Prozedur decrease key durch T + k begrenzt. 294 / 362 decrease key Definition 17.1 Ein Fibonacci-Heap ist eine Liste von Bäumen wie eingangs beschrieben, die aus der leeren Liste unter Anwendung der Operationen merge, insert, delete min und decrease key entstanden ist. Fibonacci-Heaps-Lemma 1. Sei x ein Knoten in einem Fibonacci-Heap, und ci das i -t älteste Kind von x (d.h., c1 ist der erste Knoten, der Kind von x geworden ist). Dann hat ci mindestens den Rang i − 2. 2. Hat x mindestens den Rang k, k ≥ 0, so enthält die Teilmenge der Wurzel x zusammen mit den Teilbäumen von k Kindern mindestens Fk+2 Knoten. Hierbei ist Fk+2 die (k + 2)-te Fibonacci-Zahl (F0 = 0, F1 = 1, Fk+2 = Fk + Fk+1 für k ≥ 0). 295 / 362 Beweis Lemma 1. Sei c1 , c2 , . . . , ck die dem Alter nach absteigend geordnete Folge der Kinder von x, und 1 ≤ i ≤ k. Dann ist c1 älter als c2 , c2 älter als c3 , u.s.w. Zu dem Zeitpunkt, als ci unter den Knoten x (der zu diesem Zeitpunkt eine Wurzel war) gehängt wurde, existierten also bereits die Kinder c1 , . . . , ci −1 . Der Rang von x war also mindestens i − 1. Da nur Bäume vom gleichen Rang zu einem Baum vereinigt werden, hatte ci zu diesem Zeitpunkt mindestens den Rang i − 1. Der Knoten ci kann inzwischen maximal ein Kind verloren haben. (In diesem Fall wäre ci markiert.) Der Verlust eines weiteren Kindes hätte die Abtrennung ci von x zur Folge gehabt. Es folgt die erste Behauptung rg (ci ) ≥ i − 2 . Die zweite Behauptung folgt dann mit Induktion und einem Bild. 296 / 362 Fibonacci-Zahlen √ x k+1 = x k + x k−1 ⇐⇒ x k−1 (x 2 − x − 1) = 0 √ Die Zahlen 1+2 5 , 1−2 5 sind die beiden Lösungen der quadratischen Gleichung x 2 − x − 1 = 0. Dies führt zu dem Ansatz: Fk = a √ !k 1+ 5 +b 2 √ !k 1− 5 2 Wegen F0 = 0 und F1 = 1 muss für a, b gelten: a Es folgt a = √1 , 5 b= −1 √ . 5 √ 1+ 5 + 2 b a + b = 0, √ 1− 5 2 = 1. 297 / 362 Fibonacci-Zahlen √ !k 1 1+ 5 Fk = √ − 2 5 Die Fibonacci-Zahlen wachsen exponentiell. Also rmax (n) ∈ O(log n). √ !k 1− 5 2 298 / 362 Zusammenfassung der Zeitabschätzungen 1,2. merge, insert: in konstanter Zeit 3. delete min: O(T + log n), wobei T die Zahl der Bäume ist. Der Summand log n ergibt sich aus rmax (n) ∈ O(log n). 4. decrease key: O(1) + O(k), wobei k ≥ 0 die Zahl der Marken sei, um die sich der Fibonacci-Heap verringert hat. 299 / 362 Amortisierte Zeiten Für die weitere Analyse einer Sequenz von Operationen betrachten wir die gegen eine Potentialfunktion amortisierte Zeit. Definition 17.2 Für einen Fibonacci-Heap H sei das Potential pot (H) gegeben durch pot (H) := T + 2M , wobei T die Zahl der Bäume und M die Zahl der Marken seien. Für eine Operation op sei ∆pot (op ) die Differenz des Potentials vor und nach der Ausführung: ∆pot (op ) = pot (Heap nach op ) − pot (Heap vor op ) . Die amortisierte Zeit einer Operation op sei tamort (op ) = t(op ) + ∆pot (op ) = t(op ) + pot (Heap nach op ) − pot (Heap vor op ) . 300 / 362 Potentialfunktion Die Potentialfunktion erfüllt: ◮ pot (H) ≥ 0, ◮ pot (∅) = 0. Sei jetzt op 1 , op 2 , op 3 , . . . , op m eine Sequenz von m Operationen auf einem zunächst leeren Fibonacci-Heap. Dann gilt: m m X X tamort (op i ) . t(op i ) ≤ i =1 i =1 Bemerkung: Die Differenz ist gerade das Potential des erzeugten Heaps. Wegen pot (H) ∈ O(|H|) gilt m X i =1 tamort (op i ) ∈ m X t(op i ) + θ(|H|). i =1 Es genügt also eine Schranke für tamort (op ) zu bestimmen. 301 / 362 Bequemlichkeit Für die weitere Rechnung ist es bequemer, sich bei der tatsächlich verbrauchten Zeit zunächst von der O-Notation zu befreien. Durch die Multiplikation mit einer geeigneten Konstanten können wir annehmen, dass sich merge und insert in einem Schritt realisieren lassen. Die Operation delete min benötigt höchstens T + log n und die Operation decrease key höchstens k + 1 Zeitschritte. Die Wahl der Basis für den Logarithmus ist in der Zeitanalyse unerheblich. 302 / 362 delete min ◮ tamort (merge) = t(merge) = 1. Denn das Potential der konkatenierten Liste ist die Summe der Potentiale der Einzellisten. ◮ tamort (insert) = t(insert)+∆pot (op ) = 1 + 1 = 2. ◮ Für delete min gilt t(delete min) ≤ T + log n, wobei T die Zahl der Bäume zuvor und rmax (n) bis auf einen konstanten Faktor die maximale Zahl der Bäume danach ist. Die Zahl der Marken kann nur kleiner werden. Aus ∆pot (op ) ≤ −T + rmax (n) folgt daher tamort (delete min) ≤ T + log n − T + rmax (n) ∈ O(log n) . 303 / 362 delete min ◮ Für decrease key gilt nach der obigen Bemerkung t(decrease key) ≤ k + 1. Dabei verliert der Heap mindestens k − 2 Marken, k ≥ 1, und erhält höchstens k neue Bäume. ∆pot (op ) = ∆(T ) + 2∆(M) ≤ k + 2 · (2 − k) = 4−k Also gilt tamort (decrease key) ≤ k + 1 + 4 − k = 5 ∈ O(1). 304 / 362 19. Vorlesung, 10.07.2017 Satz 17.3 Für einen Fibonacci-Heap gelten die folgenden amortisierten Zeiten: tamort (merge) ∈ O(1) tamort (insert) ∈ O(1) tamort (delete min) ∈ O(log n) tamort (decrease key) ∈ O(1) 305 / 362 Anwendungen Anwendung auf den Dijkstra- oder Prim-Algorithmus: Für den Dijkstra-Algorithmus sei V die Randmenge und key die ermittelte Distanz der Randknoten zum Quellknoten u (entsprechend für Prim). Sei n die Zahl der Knoten und e die Zahl der Kanten. Maximal werden n insert-, e decrease key- und n delete min-Operationen durchgeführt. 306 / 362 Anwendungen tDijkstra ≤ n · tamort (insert) + e · tamort (decrease key) + n · tamort (delete min) ∈ O(n + e + n log n) = O(e + n log n) Man beachte, dass sich für die Analyse des schlechtesten Falles keine Verbesserung ergibt. Asymptotisch ist O(e + n log n) jedoch mindestens genauso gut wie min(e · log n, n2 ). In n2 vielen Fällen (n log n ≤ e ≤ log n ) ist O(e + n log n) um den Faktor log n besser. 307 / 362 Berechnung eines minimalen Schnittes nach M. Stoer und F. Wagner (Konferenz 1994, Zeitschrift 1997). Ausblick: 1. Las Vegas (Quicksort) vs Monte Carlo (Primzahlerkennung, Fermat-Test). 2. Monte Carlo für minimale Schnitte. Literatur zum Thema Minimale Schnitte: STOER, MECHTHILD und WAGNER, FRANK A simple Min-Cut Algorithm. Journal of the ACM (1997) 585-591. KARGER, DAVID und STEIN, CLIFFORD A New Approach to the Minimum Cut Problem. Journal of the ACM (1996) 601-640. 308 / 362 Minimale Schnitte Sei G = (V , E , γ) ein ungerichteter Graph γ : E → N das Kantengewicht, durch Null fortgesetzt. Ein Schnitt C = (C1 , C2 ) ist eine Partition der Knoten. Ein s-t-Schnitt ist ein Schnitt (C1 , C2 ) mit s ∈ C1 und t ∈ C2 . Das Gewicht g (C ) von C ist die Summe: g (C ) = X γ(vw ) v ∈C1 ,w ∈C2 P Für A ⊆ V , v ∈ V setze g (A, v ) = a∈A γ(av ). Oder einheitlich: X g (A, B) = γ(ab) a∈A,b∈B 309 / 362 Stoer-Wagner-Algorithmus Der Algorithmus arbeitet in Phasen. 1) Berechne analog zum Prim-Algorithmus für zwei Punkte s, t ∈ V , s 6= t einen minimalen s-t-Schnitt Cphase . Achtung: Die Punkte s und t werden erst durch den Algorithmus bestimmt. 2) Verschmelze s und t zu einem neuen Punkt {s, t}: Die Kanten zwischen s und t werden gelöscht und für x ∈ / {s, t} setzt man γ({s, t}x) = γ(sx) + γ(tx). Der neue Graph heiße G /(s = t). 3) Rekursion: Sei C ′ der rekursiv berechnete Schnitt in G /(s = t). Dann ist C ′ ein minimaler Schnitt von G unter der Nebenbedingung, dass C ′ die Knoten s und t nicht trennt. Der minimale Schnitt ist das Minimum von g (Cphase ) und g (C ′ ). 310 / 362 Minimale s-t-Schnitte Es kommt also im Wesentlichen darauf an, den minimalen s-t-Schnitt für gewisse Knoten s, t ∈ V , s 6= t zu berechnen. Diese Phase verläuft analog zum Prim-Algorithmus. Zu Beginn der Phase gelte B = {v1 } und R = V \ {v1 }. Die Knoten aus B werden Baumknoten und die Knoten aus R Randknoten P genannt. Für einen Randknoten v ∈ R sei stets g (v ) = x∈B γ(xv ). (Gibt es keine Kante zwischen B und v , so hat diese Summe den Wert Null. Damit ist der Wert g (v ) = γ(v1 v ) in der Zeit O(|R|) für den Rand initialisiert.) 311 / 362 while |R| > 1 do Zu Beginn jeder Schleife wird ein delete max ausgeführt. Dies bestimmt einen Knoten v ∈ R mit g (v ) ≥ g (w ) ∀w ∈ R und entfernt v aus R. Es wird B um v ergänzt (v wird also ein Baumknoten) und die Schlüsselwerte werden mit increase key vergrößert: Für w ∈ R \ {v } setzt man g (w ) := g (w ) + γ(vw ). Eine Invariante ist also ∀w ∈ R : g (w ) = g (B, w ) 312 / 362 Termination Die Schleife wird solange durchlaufen, bis der Rand nur noch einen Knoten t enthält. P Dann gilt g (t) = vt∈E γ(vt), d.h. g (t) ist die Summe der Gewichte aller von t ausgehenden Kanten. Sei s der Knoten, der unmittelbar vor t zum Baumknoten wurde. Dann definiert die Zerlegung (V \ {t}, {t}) einen s-t-Schnitt Cphase mit dem Gewicht g (t). 313 / 362 Korrektheitslemma Lemma 17.4 Der Schnitt Cphase ist ein minimaler s-t-Schnitt im Eingabegraphen der Phase. Beweis: Sei v1 , v2 , . . . , vn eine Anordnung der Knoten in der Reihenfolge, in der sie zu Baumknoten wurden. Es gilt vn−1 = s, vn = t. Sei C = (C1 , C2 ) ein minimaler s-t-Schnitt mit s ∈ C1 , t ∈ C2 . Wir zeigen: g (Cphase ) ≤ g (C ) 314 / 362 g (Cphase) ≤ g (C ) In der Folge v1 , . . . , vn−1 , vn wird ein Knoten vi aktiv genannt, falls C ein vi −1 -vi -Schnitt ist. Da C ein s-t-Schnitt ist, ist insbesondere vn = t aktiv. Sei vi aktiv; setze B(i ) = {v1 , . . . , vi −1 } und betrachte den durch B(i ) ∪ {vi } induzierten Untergraphen. Durch Einschränkung definiert C auf diesem Untergraphen einen Schnitt. Diesen bezeichnen wir mit C (i ) und das Gewicht mit g (C (i )). Da t = vn aktiv ist und g (Cphase ) = g (B(n), t) sowie C (n) = C gelten, genügt es, die Behauptung g (B(i ), vi ) ≤ g (C (i )) für alle aktiven Knoten vi zu zeigen. Für den bzgl. der obigen Folge ersten aktiven Knoten vi gilt g (B(i ), vi ) = g (C (i )), denn die durch C induzierte Partition ist ({v1 , . . . , vi −1 }, {vi }). Dies ist die Induktionsverankerung. 315 / 362 Fortsetzung: Beweis Sei jetzt vi ein aktiver Knoten für den die Behauptung richtig ist und vj der nächste auf vi folgende aktive Knoten. Dann gilt 1 < i < j ≤ n. Zu zeigen ist: g (B(j), vj ) ≤ g (C (j)). Es gilt zunächst: g (B(j), vj ) = g (B(i ), vj ) + g ({vi , . . . , vj−1 }, vj ) Da der Knoten vi vor vj gewählt wurde, gilt g (B(i ), vj ) ≤ g (B(i ), vi ) und nach Induktion gilt g (B(i ), vi ) ≤ g (C (i )). Alle Kanten zwischen {vi , . . . , vj−1 } und vj sind Schnittkanten und tragen somit zum Gewicht von C (j) bei. Daher g (C (i )) + g ({vi , . . . , vj−1 }, vj ) ≤ g (C (j)), und insgesamt g (B(j), vj ) ≤ g (C (j)). 316 / 362 Laufzeit Phase In jeder Phase wird also ein minimaler s-t-Schnitt berechnet. Die Laufzeitanalyse einer Phase ist identisch zum Prim-Algorithmus: Wird der Rand R als ein Feld oder als eine Liste verwaltet, so ergibt sich die Zeit n · O(n) + e · O(1) = O(n2 ). Bei Verwendung eines Heaps erhalten wir n · O(log n) + e · O(log n) = O(e log n). Mit Fibonacci-Heaps ergibt die beste Abschätzung: n · O(log n) + e · O(1) = O(e + n log n) 317 / 362 Gesamtlaufzeit Nach jeder Phase wird der Graph durch Verschmelzen der beiden Knoten s und t verkleinert. Dies ist eine O(e)-Operation. Das Gewicht des jeweils aktuellen minimalen Schnittes ergibt sich in O(1) durch einen direkten Gewichtsvergleich. Die Aktualisierung der Partition (C1 , C2 ) kostet dann O(n) Schritte. Der Algorithmus terminiert, wenn der Graph nur noch einen Punkt enthält, d. h., es werden (n − 1) Phasen durchlaufen. Dies ergibt die Gesamtzeit O(n3 ) für Felder oder Listen, O(ne log n) für Heaps und O(ne + n2 log n) für Fibonacci-Heaps. 318 / 362 Phase Algorithmus 17.1 function Phase (G = (V , E , γ) || |V | ≥ 2; v1 ∈ V ); Die Ausgabe besteht aus zwei Knoten s, t mit dem Gewicht gphase eines minimalen s-t-Schnittes. *) var B : Knotenmenge; R : Knotenmenge; s, t, v , w : V ; begin B := {v1 }; R := V \ {v1 }; forall v ∈ R do g (v ) := γ(v1 v ); endfor s := v1 ; (∗ Baumknoten ∗) (∗ Randknoten ∗) (∗ Initialisierungen ∗) 319 / 362 Berechnung eines minimalen Schnittes Algorithmus 17.2 Fortsetzung while |R| > 1 do s := Knoten v ∈ R mit g (v ) ≥ g (w )∀w ∈ R; R := R \ {s}; B := B ∪ {s}; forall sw ∈ E , w ∈ R do g (w ) := g (w ) + γ(sw ) endfor endwhile t := der letzte Knoten in R return (s, t, g (t)) endfunction (∗ begin delete max ∗) (∗ end delete max ∗) (∗ increase key ∗) 320 / 362 Berechnung eines minimalen Schnittes Algorithmus 17.3 function Min Cut( G = (V , E , γ), |V | ≥ 2) (Partition C1 , C2 mit minimalem Schnitt g ); var C1 , C2 : Knotenmenge; (∗ Partition von V ∗) s, t : V ; g , gphase : integer; begin wähle ein v1 ∈ V ; (s, t, gphase ) := Phase(G , v1 ); verschmelze s und t; der neue Graph sei G /(s = t); if |V | = 2 then C1 := {s}; C2 := {t}; g := gphase ; else (C1 , C2 , g ) := Min Cut (G /(s = t)); endif (∗ Die Partition (C1 , C2 ) von G /(s = t) ist auch ein Schnitt von G . ∗) 321 / 362 Berechnung eines minimalen Schnittes Algorithmus 17.4 Fortsetzung und Ende von Min Cut if gphase ≤ g then C1 := V \ {t}; C2 := {t}; g := gphase ; endif return (C1 , C2 , g ) endfunction 322 / 362 Beispiel: Berechnung eines minimalen Schnittes 2 1 3 2 5 3 2 2 3 6 2 1 4 3 4 2 7 2 3 8 Abbildung: Ein Graph G = (V , E ) mit Kantengewichten γ : E → N. Der Startknoten ist Knoten 2. 323 / 362 Beispiel: Berechnung eines minimalen Schnittes t 2 1 3 a 2 2 5 s 2 3 6 f b 3 3 2 1 4 c 4 2 7 d 2 3 8 e Abbildung: Der Graph nach der ersten Phase mit Startknoten 2. Die Knoten wurden in der Reihenfolge a, b, c, d, e, f , s, t besucht. Der gefundene Schnitt ist die Partition {1} , {2, 3, 4, 5, 6, 7, 8} mit Gewicht g = 5. 324 / 362 Beispiel: Berechnung eines minimalen Schnittes a 2 4 1,5 b 2 3 6 c d 3 3 2 1 4 e 4 2 7 s 2 3 8 t Abbildung: Der Graph nach der zweiten Phase. Die Knoten wurden in der Reihenfolge a, b, c, d, e, s, t besucht. Der gefundene Schnitt ist die Partition {8} , {1, 2, 3, 4, 5, 6, 7} mit Gewicht g = 5. 325 / 362 Beispiel: Berechnung eines minimalen Schnittes a 2 4 1,5 b 6 c 3 2 2 3 d 3 1 4 s 4 4 7,8 t Abbildung: Nach der dritten Phase. Der gefundene Schnitt ist die Partition {7, 8} , {1, 2, 3, 4, 5, 6} mit Gewicht g = 7. 326 / 362 Beispiel: Berechnung eines minimalen Schnittes a 3 2 4 1,5 b s 3 6 2 3 6 c 1 4,7,8 t Abbildung: Nach der vierten Phase. Der gefundene Schnitt ist die Partition {4, 7, 8} , {1, 2, 3, 5, 6} mit Gewicht g = 7. 327 / 362 Beispiel: Berechnung eines minimalen Schnittes t a 3 2 4 1,5 b 2 3 3,4,7,8 1 6 s Abbildung: Nach der fünften Phase. Der gefundene Schnitt ist die Partition {3, 4, 7, 8} , {1, 2, 5, 6} mit Gewicht g = 4. 328 / 362 Beispiel: Berechnung eines minimalen Schnittes a 2 5 4 1,5 t 3 3,4,6,7,8 s Abbildung: Nach der sechsten Phase. Der gefundene Schnitt ist die Partition {1, 5} , {2, 3, 4, 6, 7, 8} mit Gewicht g = 7. 329 / 362 Beispiel: Berechnung eines minimalen Schnittes s 2 9 V \2 t Abbildung: Nach der siebten Phase. Der gefundene Schnitt ist die Partition {2} , {1, 3, 4, 5, 6, 7, 8} mit Gewicht g = 9. 330 / 362 Übung: Wie verhält sich der Algorithmus bei negativen Kantengewichten, bleibt er korrekt? 331 / 362 Antwort: Bei negativen Kantengewichten arbeitet der Algorithmus im Allgemeinen nicht korrekt: 1 3 2 −2 2 4 1 5 3 Abbildung: Beispiel für einen Graphen, bei dem der Algorithmus mit Startknoten 1 kein korrektes Ergebnis erzielt: In der ersten Phase werden die Knoten in der Reihenfolge 1, 2, 3, 4 besucht und es wird der Schnitt {4} , {1, 2, 3} gefunden (g = 3). Dann werden die Knoten 3 und 4 verschmolzen. Der minimale Schnitt (g = 2) ist jedoch {1, 4} , {2, 3}. 332 / 362 Monte Carlo für Minimale Schnitte 1. Las Vegas (Quicksort) vs Monte Carlo (Primzahlerkennung, Freivalds Matrixprodukt-Erkennung). 2. Monte Carlo für minimale Schnitte nach Karger und Stein: A New Approach to the Minimum Cut Problem Journal of the ACM (1996) 601-640. 333 / 362 20. Vorlesung am 17.07.17 Monte-Carlo-Algorithmen sind randomisierte Algorithmen, die bei beschränkter Laufzeit mit einer kleinen Wahrscheinlichkeit ein falsches Ergebnis liefern dürfen: Mostly Correct Durch Wiederholen des Algorithmus kann die Fehlerwahrscheinlichkeit gesenkt werden. Im Gegensatz zu Monte-Carlo-Algorithmen dürfen Las-Vegas-Algorithmen nur korrekte Lösungen berechnen, aber mit einer gewissen Wahrscheinlichkeit ist die Laufzeit lang. Verified. Kann man die Richtigkeit eines Ergebnisses effizient überprüfen, so kann man Monte-Carlo-Algorithmen in Las-Vegas-Algorithmen überführen, indem man sie solange wiederholt, bis ein richtiges Ergebnis gefunden wird. Las Vegas nach Monte Carlo: Bricht man nach einer gewissen Laufzeit ab, so ist man automatisch in Monte Carlo. 334 / 362 Monte-Carlo Methode zur Berechnung minimaler Schnitte 1. Wähle eine Kante zufällig. 2. Kontrahiere. 3. Wiederhole. Analyse: Zur Vereinfachung der Rechnung sei das Gewicht einer Kante stets 1. (Wir erlauben Mehrfachkanten in der Rechnung, aber in der Implementierung speichern wir eine Kante mit Gewicht!) Sei k das Gewicht des minimalen Schnitts, dann gilt: k ≤ min { deg(v ) | v ∈ V } . Dies ist eine Invariante, sie gilt auch nach Kantenkontraktionen! Die Anzahl (das Gewicht) aller Kanten ist |E | ≥ kn/2. Wähle Kante e zufällig, dann wird nur mit W’keit ≤ 2k/(kn) = 2/n eine Schnittkante getroffen. Also ist die W’keit keine Schnittkante zu treffen ≥ 1 − 2/n = n−2 n . Es ist also im Prinzip eine gute Idee, die gewählte Kante e zu kontrahieren. 335 / 362 Kantenkontraktionen Bei der Berechnung gehen wir davon aus, dass wir nie Schnittkanten treffen. Gehört eine Kante e nicht zum minimalen Schnitt, so auch keine der Mehrfachkanten zu e, sofern vorhanden. Genauer, sei e = xy die Kante, die kontrahiert werden soll. Dann werden alle yz ∈ E zu neuen zusätzlichen Kanten von x. Lösche danach y und alle ausgehenden Kanten. Insbesondere bleibt der Graph schlingenfrei. Jede Kantenkontraktion verringert die Zahl der Knoten um 1. Sei C ein minimaler Schnitt und pn die W’keit keine Schnittkante für einen Graphen mit n Knoten, n ≥ 3. Es gilt p3 ≥ 1/3. Setzen wir p2 = 1 so erhalten wir für n ≥ 3 die Rekursion: 2 pn ≥ (1 − )pn−1 . n 336 / 362 Monte-Carlo-Ansatz Dies liefert: ≥ n−2 n−3 n−c n−c −1 (n − c)(n − c − 1) · ··· · = . n n−1 n−c +2 n−c +1 n(n − 1) Anders ausgedrückt. Wiederholen wir das Experiment c-mal, so haben wir aufgrund der Invarianten immer noch die W’keit keine Schnittkante zu treffen: Für c = n − 2 ist die W’keit allerdings ziemlich klein geworden, aber immerhin: ≥ 2 . n(n − 1) Seien C1 , . . . Cℓ die minimalen Schnitte und Ei das Ereignis, dass für c = n − 2 der Schnitt Ci gefunden wurde. Dann sind die Ereignisse disjunkt und Pr[Ei ] ≥ 1/ n2 . Daher gilt ℓ ≤ n2 . Wichtige (und überraschende?) Folgerung: Satz Es gibt höchstens n 2 minimale Schnitte. 337 / 362 Naiver Monte-Carlo Ansatz Wiederhole das Experiment mehr als n2 -mal und behalte das beste Ergebnis. Dann ist die W’keit groß, einen fest gewählten minimalen Schnitt zu finden. Problem: Zu langsam! 338 / 362 Karger-Stein-Monte-Carlo-Ansatz Nächste Idee: Die Chancen, einen minimalen Schnitt zu treffen, sind zu Anfang gering und nehmen dann zu. Erfolg ist ab jetzt keine Schnittkante zu treffen. Misserfolg ist, eine zu treffen (und daher nicht den gewünschten Schnitt zu finden). Für c = n/2 ist die Erfolgs-W’keit noch mindestens ≥ (2n − n)(2n − n − 1) = 1/4. 4n(n − 1) √ Für n − c = n/ 2 ist die Erfolgs-W’keit mindestens 1/2. Dies ist daher unser Cut-Off-Point. 339 / 362 Karger-Stein-Algorithmus √ Sei G der Eingabegraph mit n Knoten, n = ( 2)k . (Wir vernachlässigen bewusst Rundungsfehler und kleine n.) Sei C ein fester minimaler Schnitt. Berechnung von C : 1.) Wiederhole zweimal: √ ◮ Wähle n − n/ 2-mal eine Zufallskante und kontrahiere jeweils die entsprechende Kante. ◮ ◮ ◮ ◮ ◮ Zeit für alle Kantenkontraktionen O(n2 ). Wir behandeln nicht, wie man effizient zufällige Kanten wählt, die ein Gewicht haben. (Die ist durchaus nicht trivial!) W’keit, Schnitt C nicht √ getroffen zu haben, ist ≥ 1/2. Restgraph G ′ hat ( 2)k−1 Knoten. Starte rekursiv den ganzen Algorithmus für G ′ . 2.) Behalte das bessere Ergebnis, also den kleineren Schnitt. Laufzeit: Mastertheorem I : √ t(n) = 2t(n/ 2) + O(n2 ). t(n) ∈ O(n2 log n). 340 / 362 Erfolgswahrscheinlichkeit: Ω(1/log n) Es sei pk die (Mindest-)Erfolgswahrscheinlichkeit. Wir können pk = 1 für kleine Werte von √ k ansetzen. Betrachte n = ( 2)k+1 . 1. Schnitt C wird bei den initialen Kantenkontraktionen mit W’keit 1/2 nicht getroffen. 2. Erfolg beim rekursiven Aufruf auf G ′ ist ≥ pk . 3. Erfolg beim ersten Durchlauf insgesamt ≥ p2k , Misserfolg also ≤ 1 − p2k . 4. Misserfolg bei beiden Durchläufen auf G ist ≤ (1 − p2k )2 . 5. Erfolg insgesamt bei G ist pk 2 ) 2 p2 = 1 − 1 + pk − k 4 pk2 = pk − 4 pk+1 ≥ 1 − (1 − 341 / 362 Lösung der Rekursion pk+1 ≥ pk − pk2 /4 Ansatz, definiere eine reelle Zahl zk ≥ 3 durch: pk = 4 . zk + 1 Also: 1 1 − zk+1 + 1 zk + 1 (zk + 1)2 zk = (zk + 1)2 zk = 2 zk + 2zk + 1 1 ≥ Damit folgt für die Kehrbrüche: zk2 + 2zk + 1 1 = zk + 2 + zk zk 1 ≤ zk + 1 + zk zk+1 + 1 ≤ zk+1 342 / 362 Zack zack. Wegen zk > 1 folgt zk+1 ≤ zk + 1 + 1 < zk + 2 zk Also wegen z2 = 3 mit Induktion zk ≤ 2k − 1 für k ≥ 2: zk ≤ 2k − 1 ∈ O(k) 1 2 pk ≥ ∈ Ω( ) k k Wegen k = log√2 n = 2 log2 n folgt für die Erfolgswahrscheinlichkeit P(n) des Karger-Stein-Algorithmus: 1 1 ∈Ω P(n) ≥ . log2 n log n 343 / 362 Finde minimale Schnitte mit hoher W’keit Satz 18.1 Wiederholen wir den Karger-Stein-Algorithmus 3 · ln n · log2 n-mal, so finden wir alle minimalen Schnitte in der Zeit O(n2 log3 n) mit einer Fehlerwahrscheinlichkeit kleiner als 1 2n . Beweis. Sei C zunächst ein fester minimaler Schnitt: 1 3·ln n·log2 n ) Pr(C wird nicht gefunden) ≤ (1 − log2 n ≤e Es gibt höchstens n 2 −3·ln n·log2 n log2 n ≤ e −3 ln n = 1 n3 minimale Schnitte. Also 1 n 1 < Pr(Nicht alle gefunden) ≤ 3 2n 2 n 344 / 362 21. Vorlesung, 27. Juni 2017 Thema: Kuchenschneide-Algorithmen Folien stammen (teilweise) von Ulrich Hertrampf! Literatur: Cake-Cutting Algorithms Jack Robertson / William Webb (AK Peters Natick, Massachusetts 1998) Be Fair If You Can. 345 / 362 Turings Kuchen 346 / 362 Grundvoraussetzungen ◮ Alle Beteiligten haben eine Bewertungsfunktion, die jedem beliebigen Teilstück des Kuchens einen Wert zwischen 0 und 1 so zuordnet, dass bei jeder Aufteilung die Gesamtsumme 1 herauskommt. ◮ Jeder ist in der Lage, einen Schnitt so anzusetzen, dass eine beliebige gewünschte Aufteilung entsteht. ◮ Alle Beteiligten kennen ihre eigene Bewertungsfunktion, aber nicht unbedingt die der anderen. ◮ Alle Beteiligten handeln vernünftig in dem Sinn, dass sie ihren worst-case-Anteil maximieren. (Je mehr je besser — ohne Risiko-Spiele) ◮ Eigentlich ist es egal, aus der Sicht jeder Person handelt jede andere nach Belieben. 347 / 362 Erste Algorithmen – als die Kinder noch klein waren Es war einmal ein großes Stück Kuchen da, auf das nur Lukas (11 Jahre) und Isabel (9 Jahre) Anspruch erhoben (- armer Jonas). UH war als Aufsicht dabei. Es ergaben sich verschiedene mögliche Algorithmen: ◮ UH teilt den Kuchen in zwei Teile. Dann gibt er ein Teil Lukas, das andere Isabel. ◮ UH teilt den Kuchen in zwei Teile. Lukas und Isabel werfen eine Münze, um zu entscheiden, wer zuerst wählen darf. ◮ Lukas teilt den Kuchen und nimmt sich dann ein Teil. Isabel bekommt das andere. ◮ Lukas teilt den Kuchen. Dann wählt Isabel ein Teil, Lukas bekommt das andere. ◮ Du teilst, ich wähle“ ” 348 / 362 Eine Person teilt, die andere wählt ◮ Lukas schneidet den Kuchen in zwei Stücke. ◮ Isabel wählt eines der beiden Stücke. ◮ Lukas bekommt das übrige Stück. Faire Analyse: Jede der beiden Kinder erhält nach eigener Einschätzung mindestens die Hälfte des Wertes. Neidfreie Analyse: Jede der beiden Kinder erhält nach eigener Einschätzung mindestens soviel wie die andere! 349 / 362 Drei Personen - erster Versuch ◮ Jonas möchte auch Kuchen ◮ Lukas teilt den Kuchen X in zwei Stücke, X1 und X2 , wobei nach seiner Einschätzung X1 ein Drittel des gesamten Kuchens ist. ◮ Isabel teilt X2 in zwei Stücke, X21 und X22 , die nach seiner Einschätzung gleich groß sind. ◮ Jonas wählt das nach seiner Ansicht größte der drei Stücke, dann wählt Lukas sich das größere der verbleibenden Stücke. Isabel bekommt, was übrigbleibt. Analyse: ◮ Jonas wählt als erster: Glück gehabt. . . ◮ Lukas bekommt auch mindestens sein Drittel! ◮ Was is mit Isabel? ◮ Lassen wir UH eingreifen! 350 / 362 Neid - eine schwerwiegende Komplikation Eine neue Situation: Auf dem Tisch liegen 9 Euro, und zwar: ◮ Zwei 2-Euro-Stücke ◮ Drei 1-Euro-Stücke ◮ Zwei 50-Cent-Stücke ◮ Zehn 10-Cent-Stücke UH gibt Lukas drei 1-Euros und einen 50er. Lukas freut sich (noch)! UH gibt Jonas die zehn Zehner. Jonas strahlt! (Soviele Münzen!) UH gibt Isabel zwei 2-Euros und einen 50er. Sie freut sich! Und was sagt Lukas jetzt??? 351 / 362 Neid - Definition der Neidfreiheit Eine Kuchenverteilung heißt neidfrei, wenn jede der teilenden Personen nach ihrem eigenen Maßstab mindestens so viel Kuchen bekommen hat, wie jede andere. Ein Algorithmus heißt neidfrei, wenn er immer eine neidfreie Verteilung ergibt. Ist Du teilst, ich wähle“ ein neidfreier Algorithmus? ” Ist die n-Personen-Verallgemeinerung neidfrei? 352 / 362 Successive-Pairs-Algorithmus Du teilst, ich wähle“-Algorithmus für n Personen: ” Wir entwerfen den Algorithmus sukzessive für steigende n. Bei n = 2 nehmen wir Du teilst, ich wähle“. ” ◮ Benutze (n − 1)-Version zwischen P1 und Pn−1 . ◮ ◮ Jeder Pi (1 ≤ i ≤ n − 1) teilt seinen Haufen durch weitere Schnitte in n gleiche Teile. Pn darf von jedem anderen Pi ein Teil wählen. Analyse: Korrektheit (für was?) ist klar. Aber was für ein Gekrümel? Ist das Gekrümel fair? Ist es neidfrei? 353 / 362 Aber was für ein Gekrümel? ◮ ◮ Habe ich bereits ein Gekrümel von x Stücken und will ich n gleichgroße Haufen erhalten, so benötige ich bis zu n − 1 weitere Schnitte. Rekursionsgleichung für die Anzahl der Schnitte: ◮ S(1) = 0, ◮ S(n) = (n − 1)2 + S(n − 1). Pn−1 2 (n−1)n(2n−1) ∈ Θ(n3 ) Schnitte und 1 Krümel mehr. i =1 i = 6 ◮ Maximale Schnittzahl ist also kubisch. Beispiel: S(8) = 140 354 / 362 Trimming ◮ P1 meldet Interesse und teilt möglicherweise ein Stück X des Kuchens ab. ◮ Nacheinander dürfen P2 bis Pn Interesse anmelden und bei Interesse das Stück X möglicherweise noch verkleinern. ◮ Der letzte, der Interesse angemeldet hat, bekommt das Stück. ◮ Die übrigen n − 1 Personen teilen den Rest rekursiv unter sich auf. Analyse: Einer bekommt ein n-tel des Kuchens. Die übrigen meinen, er hätte höchstens ein n-tel. Ergo: Es klappt! Die maximale Schnittanzahl quadratisch! S(n) = n(n − 1) 2 Beispiel: S(8) = 28 355 / 362 Moving Knife – Algorithmus n Personen wollen einen Kuchen teilen. ◮ Ein Messer fährt kontinuierlich von links nach rechts. ◮ Irgendwann ruft eine Person STOPP. ◮ Nun wird geschnitten, die Person bekommt den Teil links des Schnitts. ◮ Die übrigen n − 1 Personen teilen den Rest rekursiv unter sich auf. Wie realisiert man kontinuierliche Algorithmen? Analyse: Einer bekommt ein n-tel des Kuchens. Die übrigen meinen, er hätte höchstens ein n-tel. Ergo: Es klappt! Ist der Algorithmus neidfrei? 356 / 362 Untere Schranken Übung: 3 Personen, zwei Schnitte kann nicht fair sein. Denn: ? Trimming ist quadratisch, Das Gekrümel ist kubisch. Geht es besser? 357 / 362 Divide and Conquer Ziel: Θ(n log n) Algorithmus. Sei n > 1: P1 bis Pn−1 machen n − 1 vertikale Schnitte und jeder ist bereit, sein Stück links mit ⌊n/2⌋ Personen oder rechts vom Schnitt mit ⌈n/2⌉ Personen zu teilen. Beispiel: n = 5, dann mache sinnvollerweise einen 2 : 3-Schnitt Der wirkliche Schnitt ist der ⌊n/2⌋-te Schnitt von links. Wir haben also wieder zwei Stücke und Pn sucht sich einen Teil aus, von dem er ein Stück erhalten will. Die anderen werden dem Teil zugeordnet, in dem sich ihr Schnitt befindet. Die Person, die den Schnitt ⌊n/2⌋ verursacht hat, wird der anderen Seite als Pn zugeordnet. ⌊n/2⌋ bzw. ⌈n/2⌉ Personen teilen sich jeweils ein Stück, das jeder als genügend groß ansieht. Abbruch bei n = 1. 358 / 362 Zeit/Schnitt-Analyse ◮ Rekursionsgleichung für die Zeit bzw. Anzahl der Schnitte: ◮ S(1) = 0, ◮ S(n) = n − 1 + S(⌊n/2⌋) + S(⌈n/2⌉). ◮ ◮ ◮ ◮ Mastertheorem: S(n) ∈ O(n log n). Genauer: S(n) = nk − 2k + 1 mit k = ⌈log2 n⌉. Beweis folgt aus ⌈log2 ⌈n/2⌉⌉ = ⌈log2 ⌊n/2⌋⌉ = k − 1. Beispiel: n = 7, 8, 9, 10, . . . , 15, 16. ◮ S(7) = 14, S(8) = 17, S(9) = 20, S(10) = 23, . . . ◮ S(15) = 38, S(16) = 49. 359 / 362 Variationen ◮ Eigene Vorschläge für Erbengemeinschaften? ◮ oder zum Geburtstagskuchen teilen? ◮ Divide-and-Conquer-Moving-Knife ◮ Praktische Anwendungen? 360 / 362 Neidfrei für drei Personen, die ersten drei Schnitte Runde 1: ◮ P1 schneidet X in drei Teile. X = X1 + X2 + X3 ◮ Für P2 sei X1 das größte dieser Teile, X2 das zweitgrößte. ◮ P2 schneidet ein Stück E von X1 ab, und zwar so, dass Y = X1 − E für ihn gerade so groß ist wie X2 . ◮ Aus X1 − E , X2 und X3 wählen nacheinander P3 , P2 und P1 je eines aus, wobei P2 auf jeden Fall X1 − E nehmen muss, wenn es noch da ist. P1 erhält also ein unversehrtes Stück X1 , X2 oder X3 . Sicht von P1 : X2 = X3 ≥ Y + E ≥ Y . Sicht von P2 : Y = X2 ≥ X3 . Die erste Runde endet neidfrei! 361 / 362 Neidfrei für drei Personen, die beiden letzten Schnitte Runde 2: ◮ Die Person, die Y genommen hat, heisse nun R (Reststück). Das heißt, R ist entweder P2 oder P3 . Die andere dieser beiden Personen heiße Q. ◮ Die Akteure sind also R, P1 und Q. ◮ Q teilt E in drei Teile, von denen in der Reihenfolge R, P1 , Q gewählt wird. ◮ Q bleibt neidfrei, da sie geteilt hat. ◮ R bleibt neidfrei, da sie als erste ausgesucht hat. ◮ P1 hat vor Q gewählt, kann also höchstens auf R neidisch sein. Aber der der maximale Kuchenanteil ist Y + E ≤ X1 und schon die erste Runde ergab den Anteil X2 oder X3 für P1 . 362 / 362