Folien - Institut für Formale Methoden der Informatik

Werbung
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
Herunterladen