VL-21: Greedy Algorithmen

Werbung
Organisatorisches
VL-21: Greedy Algorithmen
• Vorlesung: Gerhard Woeginger (Zimmer 4024 im E1)
Sprechstunde: Mittwoch 11:15–12:00
• Übungen: Tim Hartmann, David Korzeniewski, Björn Tauer
Email: [email protected]
(Datenstrukturen und Algorithmen, SS 2017)
Gerhard Woeginger
• Webseite: http://algo.rwth-aachen.de/Lehre/SS17/DSA.php
• Nächste Vorlesung:
Dienstag, Juli 18, Aula 1, zur gewohnten Zeit
SS 2017, RWTH
DSAL/SS 2017
VL-21: Greedy Algorithmen
1/39
DSAL/SS 2017
VL-21: Greedy Algorithmen
2/39
Greedy Algorithmen
Grundlegendes
• Grundlegendes
optimal versus gut versus schlecht
• Sequentielle Speicherung
• Stundenplanung
• Huffman Codes
DSAL/SS 2017
VL-21: Greedy Algorithmen
3/39
DSAL/SS 2017
VL-21: Greedy Algorithmen
4/39
Greedy Algorithmen
Greedy: kann optimal sein
Greedy Algorithmen (greedy = gierig)
I
Trifft in jedem Schritt eine Entscheidung, die bezüglich eines
“kurzsichtigen” Kriteriums optimal ist.
I
Dieses Kriterium ist einfach und schnell auszuwerten.
I
Wenn eine Wahl getroffen wurde, kann sie nicht mehr rückgängig
gemacht werden.
Wiederholung aus VL-16: Minimale Spannbäume
Eingabe: ein gewichteter zusammenhängender Graph G mit n Knoten
Ausgabe: ein minimaler Spannbaum von G
Kruskal’s Algorithmus
So lange weniger als n − 1 Kanten markiert sind:
1. Wähle eine billigste unmarkierte Kante
I
Greedy Algorithmen finden nicht immer die beste Lösung:
Wiederholte Wahl eines lokalen Optimums führt nicht automatisch
zum globalen Optimum
I
Greedy kann optimal sein (Beispiel folgt)
I
Greedy kann gut sein (Beispiel folgt)
I
Greedy kann beliebig schlecht sein (Beispiel folgt)
DSAL/SS 2017
VL-21: Greedy Algorithmen
2. Markiere sie, falls sie keinen Kreis mit anderen markierten Kanten
schliesst
• Bei Terminierung bilden die markierten Kanten einen MST
• n − 1 kurzsichtige, lokale Entscheidungen ergeben globales Optimum
5/39
Greedy: kann gut sein
DSAL/SS 2017
VL-21: Greedy Algorithmen
Greedy: kann beliebig schlecht sein (1)
Knotenfärbungsproblem für Graphen
Wiederholung aus VL-18: Matchings
Eingabe: ein ungerichteter Graph G = (V , E )
Ausgabe: ein Matching mit maximaler Kardinalität
Gegeben: ein ungerichteter Graph G = (V , E )
Ziel: Färbe die Knoten in V mit möglichst wenigen Farben, sodass
benachbarte Knoten immer verschiedene Farben erhalten
Greedy Algorithmus
Offizielle Definition
Wiederhole so lange es geht:
Markiere neue Kante, die mit keiner markierten Kante kollidiert
• Eine Färbung ist eine Funktion f : V → {1, . . . , k}
sodass f (x ) 6= f (y ) für alle {x , y } ∈ E gilt.
• Die chromatische Zahl χ(G) ist die kleinste Zahl k,
für die eine derartige Färbung der Knoten existiert.
• Bei Terminierung bilden die markierten Kanten ein Matching M
• Kardinalität von Greedy Matching M ist
mindestens 50% der Kardinalität des optimalen Matchings
(Beweis: Jede Greedy Kante blockiert ≤ 2 optimale Kanten)
DSAL/SS 2017
6/39
VL-21: Greedy Algorithmen
• χ(Kn ) = n
• Für jeden Baum T mit mindestens zwei Knoten gilt χ(T ) = 2
• Für n ≥ 1 gilt χ(C2n+1 ) = 3
7/39
DSAL/SS 2017
VL-21: Greedy Algorithmen
8/39
Greedy: kann beliebig schlecht sein (2)
Greedy Algorithmus für Knotenfärbung
So lange es einen ungefärbten Knoten gibt:
1. Wähle einen beliebigen Knoten v
2. Färbe Knoten v mit der kleinstmöglichen legalen Farbe
Sequentielle Speicherung
Beispiel
Wir betrachten bipartiten Graphen mit
• Knoten x1 , . . . xn und y1 , . . . yn
• Kanten {xi , yj } ∈ E genau dann wenn i 6= j
Falls Greedy die Reihenfolge x1 , y1 , x2 , y2 , x3 , y3 , . . . xn , yn verwendet,
so braucht Greedy n verschiedene Farben
Aber: χ(G) = 2 !!
DSAL/SS 2017
VL-21: Greedy Algorithmen
9/39
Sequentielle Speicherung
DSAL/SS 2017
VL-21: Greedy Algorithmen
10/39
Sequentielle Speicherung: Analyse
Problem: Dateien am Magnetband
Problem
Eingabe:
1. Dateien D1 , . . . , Dn mit Längen L[1], . . . , L[n]
2. Ein Magnetband
Ausgabe: Eine Anordnung der Dateien auf dem Magnetband, die die
durchschnittliche Lesezeit minimiert.
Eingabe: Zahlen L[1], . . . , L[n]
Ausgabe: Permutation π, die
n
1 X
(n − k + 1) L[π(k)] minimiert
n
k=1
Angenommen, die Dateien sind in Reihenfolge D1 , . . . , Dn abgespeichert
I
Bei jedem Lesezugriff wird das Band vom Anfang an gelesen, bis
korrekte Datei gefunden
Pk
Lesezeit für Dk ist dann i=1 L[i]
Angenommen,
an Stelle k liegt Datei mit Länge x und
an Stelle k + 1 liegt Datei mit Länge y < x
I
Durchschnittliche Lesezeit beträgt dann
• Beitrag zur Zielfunktion ist (n − k + 1)x + (n − k)y
• Vertauschen der Dateien liefert neuen Beitrag (n − k + 1)y + (n − k)x
• Neuer Beitrag ist besser/kleiner
I
n
k
1 XX
L[i] =
n
i=1
k=1
DSAL/SS 2017
n
1 X
(n − k + 1) L[k]
n
k=1
VL-21: Greedy Algorithmen
11/39
DSAL/SS 2017
VL-21: Greedy Algorithmen
12/39
Sequentielle Speicherung: Lösung
Variante mit Wahrscheinlichkeiten
Problem
Eingabe:
Satz / Folgerung / Zusammenfassung
Um die durchschnittliche Lesezeit zu minimieren,
müssen Dateien nach monoton steigender Länge abgespeichert werden.
1. Dateien D1 , . . . , Dn
2. Längen L[1], . . . , L[n] der Dateien
3. Zugriffswahrscheinlichkeiten p[1], . . . , p[n] der
Dateien (wobei Summe der p[i] gleich 1)
Ausgabe: Eine Anordnung der Dateien auf dem Magnetband, die die
erwartete Lesezeit minimiert.
Greedy Algorithmus für Sequentielle Speicherung
So lange noch (ungespeicherte) Dateien vorhanden sind:
Angenommen, die Dateien sind in Reihenfolge D1 , . . . , Dn abgespeichert
Pk
I Lesezeit für Dk ist dann
i=1 L[i]
1. Wähle eine kürzeste Datei
2. Speichere die Datei an der nächsten Stelle am Band ab
I
Durchschnittliche Lesezeit beträgt dann
Resultierende Laufzeit ist O(n log n)
n
X
k=1
DSAL/SS 2017
VL-21: Greedy Algorithmen
13/39
Variante mit Wahrscheinlichkeiten: Analyse
Beitrag = (p + q)
i=1
n
X
L[i] + (x + y )
k
X
i=1
L[i] =
n
X
i=1
L[i]
n
X
p[k]
k=i
VL-21: Greedy Algorithmen
14/39
Variante mit Wahrscheinlichkeiten: Lösung
Angenommen,
an Stelle k liegt Datei mit Länge x und Wahrscheinlichkeit p
an Stelle k + 1 liegt Datei mit Länge y und Wahrscheinlichkeit q
Angenommen,
an Stelle k liegt Datei mit Länge x und Wahrscheinlichkeit p
an Stelle k + 1 liegt Datei mit Länge y und Wahrscheinlichkeit q
k−1
X
DSAL/SS 2017
p[k]
• alter Beitrag < neuer Beitrag genau dann wenn qx < py
• alter Beitrag < neuer Beitrag genau dann wenn x /p < y /q
p[j] + px + qy + qx
j=k+2
Satz / Folgerung / Zusammenfassung
Beitrag nach Vertauschen der beiden Dateien
k−1
n
X
X
= (p + q)
L[i] + (x + y )
p[j] + px + qy + py
i=1
Um die erwartete Lesezeit zu minimieren,
müssen die Dateien nach monoton steigendem Quotienten L[i]/p[i]
abgespeichert werden.
j=k+2
• Wir erhalten einfachen Greedy Algorithmus
• Kurze und populäre Dateien am Anfang des Bandes
Lange und unpopuläre Dateien am Ende des Bandes
• Resultierende Laufzeit ist O(n log n)
Genaues Hingucken liefert:
alter Beitrag < neuer Beitrag genau dann wenn qx < py
DSAL/SS 2017
VL-21: Greedy Algorithmen
15/39
DSAL/SS 2017
VL-21: Greedy Algorithmen
16/39
Stundenplanung: Beispiel
Stundenplanung
DSAL/SS 2017
VL-21: Greedy Algorithmen
17/39
Stundenplanung: Beispiel
DSAL/SS 2017
VL-21: Greedy Algorithmen
18/39
Stundenplanung: Problemstellung
Problem: Stundenplanung
Eingabe:
1. Vorträge V1 , . . . , Vn
2. Startzeiten L[1], . . . , L[n] der Vorträge
3. Endzeiten R[1], . . . , R[n] der Vorträge
Ausgabe: Eine möglichst grosse Teilmenge von Vorträgen, die
zeitlich nicht überlappen
DSAL/SS 2017
VL-21: Greedy Algorithmen
19/39
DSAL/SS 2017
VL-21: Greedy Algorithmen
20/39
Stundenplanung: Beispiel, umgeordnet
Greedy Algorithmus
1
2
3
4
5
6
7
8
9
10
11
12
DSAL/SS 2017
VL-21: Greedy Algorithmen
21/39
Korrektheit (1)
Sortiere Vortraege nach ansteigendem Endpunkt R [ i ]
// R [1] <= R [2] <= ... <= R [ n ]
count = 1;
Loesung [ count ] = 1;
for ( i =2; i <= n ; i ++) {
if ( L [ i ] > R [ count ])
{ Loesung [++ count ] = i ; }
}
return Loesung [1.. count ];
DSAL/SS 2017
VL-21: Greedy Algorithmen
22/39
Korrektheit (2)
Wir nehmen R[1] ≤ R[2] ≤ R[3] ≤ · · · ≤ R[n] an
Satz
Wir nehmen R[1] ≤ R[2] ≤ R[3] ≤ · · · ≤ R[n] an
Es gibt eine optimale Lösung des Stundenplanung-Problems,
die Vortrag V1 (mit kleinstem rechten Endpunkt R[1]) verwendet.
Satz
Beweis:
• Betrachte beliebige optimale Lösung X ∗ , die V1 nicht verwendet
• Betrachte Vortrag Vk in X ∗ mit kleinstem rechten Endpunkt R[k]
• Dann gilt R[k] ≥ R[1]
• Wir können problemlos in X ∗ den Vortrag Vk durch V1 ersetzen
• Neue zulässige Lösung mit gleich vielen Vorträgen wie X ∗
• Ergo: neue Lösung ebenfalls optimal
Beweis:
• Wir betrachten optimale Lösung X ∗ , die V1 enthält
• Dann enthält X ∗ keinen Vortrag, der mit V1 überlappt
• Wir löschen V1 und alle überlappenden Vorträge
• Wir argumentieren induktiv für die weiteren Vorträge
DSAL/SS 2017
VL-21: Greedy Algorithmen
Der Greedy Algorithmus berechnet eine optimale Lösung.
23/39
DSAL/SS 2017
VL-21: Greedy Algorithmen
24/39
Anmerkung zu Greedy Algorithmen
Die Korrektheitsargumente
• für den Greedy Algorithmus zur sequentiellen Speicherung und
• für den Greedy Algorithmus zur Stundenplanung
sind ganz ähnlich strukturiert.
Intermezzo: Anmerkung zu Greedy
Algorithmen
I
Angenommen, es gibt eine optimale Lösung, die sich von der Greedy
Lösung unterscheidet
I
Finde den “ersten” Unterschied zwischen den beiden Lösungen
I
Argumentiere, dass man die optimale Entscheidung durch die Greedy
Entscheidung ersetzen kann, ohne die Qualität zu verschlechtern
• Sequentielle Speicherung: kleinster Index mit L[π(k)] > L[π(k + 1)]
• Stundenplanung: frühester Vortrag mit (lokal) nicht-kleinstem rechten
Endpunkt
DSAL/SS 2017
VL-21: Greedy Algorithmen
25/39
DSAL/SS 2017
VL-21: Greedy Algorithmen
26/39
Definitionen (1)
I
Ein Binär-Code kodiert jeden Buchstaben eines Alphabets Σ durch
einen String von 0en und 1en
I
Ein Binär-Code ist präfix-frei, wenn kein Codewort der Präfix eines
anderen Codeworts ist.
Huffman Codes
Beispiel
DSAL/SS 2017
VL-21: Greedy Algorithmen
27/39
I
7-Bit ASCII kodiert jeden Buchstaben durch einen String mit 7 Bits.
7-Bit ASCII ist ein präfix-freier Binär-Code.
I
Der Morse-Code ist ein Binär-Code.
Der Morse-Code ist nicht präfix-frei:
Codewort für A (· –) ist Präfix des Codeworts für J (· – – –)
DSAL/SS 2017
VL-21: Greedy Algorithmen
28/39
Definitionen (2)
Definitionen (3)
Jeder präfix-freie Binär-Code kann durch Binär-Baum dargestellt werden:
I
Die Buchstaben des Alphabets Σ sind in den Blättern
I
Das Codewort für Buchstaben entspricht Pfad von Wurzel zu Blatt
Optimierungsziel: Kodierte Botschaften sollen so kurz wie möglich sein
I
Entlang des Pfades gilt: Links=0 und Rechts=1
Problem: Optimaler präfix-freier Binär-Code
I
Länge des Codeworts = Tiefe des Blattes im Baum
Eingabe:
1. Ein Alphabet Σ mit n Buchstaben
2. Die Texthäufigkeiten h1 , h2 , . . . , hn der Buchstaben
Ausgabe: Ein präfix-freier Binär-Code, der die Gesamtlänge der
kodierten Botschaft minimiert:
k
X
Gesamtlänge =
hi · Tiefe[i]
i=1
DSAL/SS 2017
VL-21: Greedy Algorithmen
29/39
Beispiel (1)
DSAL/SS 2017
VL-21: Greedy Algorithmen
30/39
Beispiel (2)
170
59
A
3
O
9
C
3
R
6
D
2
S
27
E
26
T
22
F
5
U
2
G
3
V
5
H
8
W
8
I
13
X
4
L
2
Y
5
S
27
N
16
Z
1
111
32
60
N
16
16
H
8
W
8
39
O
9
8
VL-21: Greedy Algorithmen
31/39
DSAL/SS 2017
10
F
5
11
V
5
E
26
25
Y
5
U
2
I
13
12
R
6
6
A
3
4
L
2
DSAL/SS 2017
21
T
22
17
X
4
51
6
C
3
G
3
3
D
2
VL-21: Greedy Algorithmen
Z
1
32/39
Huffman Algorithmus
Huffman Algorithmus
Build-Huffman-Tree
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
David Albert Huffman (1925–1999):
Amerikanischer Computer Scientist; MIT; UC Santa Cruz
Greedy Algorithmus (Huffman, 1951)
So lange zwei oder mehr Buchstaben vorhanden sind:
1. Verschmilz die beiden Buchstaben mit kleinster Häufigkeit h und h0
2. Das verschmolzene Resultat erhält Häufigkeit h + h0
Implementierung: mit MinHeap (ExtractMin; Insert)
DSAL/SS 2017
VL-21: Greedy Algorithmen
33/39
Korrektheit (1)
void HuffmanTree ( int & frequency [2 n ] ,
& L [2 n ] , & R [2 n ] , & parent [2 n ]) {
for ( i =1; i <= n ; i ++) {
L [ i ]=0; R [ i ]=0;
insert (i , frequency [ i ])
}
for ( i = n +1; i <=2 n -1; i ++) {
x = ExtractMin () ;
y = ExtractMin () ;
frequency [ i ] = frequency [ x ]+ frequency [ y ]
L [ i ]= x ;
R [ i ]= y ;
parent [ x ]= i ; parent [ y ]= i ;
Insert (i , frequency [ i ])
}
parent [2 n -1]= 0;
}
DSAL/SS 2017
VL-21: Greedy Algorithmen
34/39
Korrektheit (2)
Unser Ziel:
Wir wollen nun zeigen, dass der Huffman Algorithmus für jede
Folge h1 , . . . , hn von Häufigkeiten einen optimalen präfix-freien
Binär-Code berechnet.
Beobachtung
Es seien a mit Häufigkeit ha und b mit Häufigkeit hb zwei Buchstaben
mit geringster Häufigkeit.
Dann existiert ein optimaler präfix-freier Binär-Code, in dessen Baum die
beiden Buchstaben a und b
Die Fälle n ≤ 2 sind trivial.
Wir nehmen von jetzt an n ≥ 3 an.
1. Geschwister sind, und
2. zwei Blätter mit maximaler Tiefe sind.
Beobachtung
Beweis:
• Andernfalls vertauschen wir Blatt a mit Blatt x mit maximaler Tiefe
• Tiefe[a] = alte Tiefe von a; Tiefe[x ] = alte Tiefe von x
• Man rechnet leicht nach:
ha · Tiefe[a] + hx · Tiefe[x ] ≥ ha · Tiefe[x ] + hx · Tiefe[a]
Wir betrachten einen optimalen präfix-freien Binär-Code.
Es sei b ein Blatt mit maximaler Tiefe im entsprechenden Binär-Baum.
Dann gibt es ein anderes Blatt b 0 ,
das die selbe Tiefe und den selben Vater wie b hat.
DSAL/SS 2017
VL-21: Greedy Algorithmen
35/39
DSAL/SS 2017
VL-21: Greedy Algorithmen
36/39
Korrektheit (3)
Korrektheit (4)
• Wir betrachten Häufigkeiten H = (h1 , . . . , hn ) mit h1 ≥ h2 ≥ · · · ≥ hn
• Es sei T der optimale Baum für H
• OBdA: Die beiden Buchstaben mit Häufigkeiten hn−1 und hn sind
Blätter in T , mit maximaler Tiefe und mit selbem Vater
I
cost(T )
cost(T )
=
=
cost(T 0 ) + (hn−1 + hn )
folgt, dass wir nur die Kosten von T 0 minimieren müssen, falls wir
die Kosten von T minimieren wollen
• Wir konstruieren neuen Baum T 0 : Wir verschmelzen diese beiden
Blätter mit Vater, und geben Vater v 0 die Häufigkeit h0 := hn−1 + hn
• Tiefe[v 0 ] = Tiefe[n] − 1
k
X
Aus der Gleichung
I
Restproblem: Finde einen optimalen präfix-freien Binär-Code für die
Häufigkeiten H 0 = (h1 , h2 , . . . , hn−2 , hn−1 + hn )
I
Induktives Argument: Huffman liefert optimalen Binär-Baum für H 0
Ergo: Huffman liefert optimalen Binär-Baum für H
hi · Tiefe[i]
i=1
Satz
= cost(T 0 ) + hn−1 · Tiefe[n] + hn · Tiefe[n] − h0 · Tiefe[v 0 ]
Der Huffman Algorithmus bestimmt für jede Häufigkeits-Verteilung
einen optimalen präfix-freien Binär-Code.
= cost(T 0 ) + (hn−1 + hn − h0 ) · Tiefe[n] + h0
= cost(T 0 ) + (hn−1 + hn )
DSAL/SS 2017
VL-21: Greedy Algorithmen
37/39
Organisatorisches
• Nächste Vorlesung:
Dienstag, Juli 18, Aula 1, zur gewohnten Zeit
• Webseite: http://algo.rwth-aachen.de/Lehre/SS17/DSA.php
DSAL/SS 2017
VL-21: Greedy Algorithmen
39/39
DSAL/SS 2017
VL-21: Greedy Algorithmen
38/39
Herunterladen