Kapitel 5: Paradigmen des Algorithmenentwurfs Gliederung 1

Werbung
Kapitel 5: Paradigmen des Algorithmenentwurfs
Gliederung
1.  Grundlagen
2.  Analyse der Laufzeit von Algorithmen
3.  Untere Schranken für algorithmische Probleme
4.  Sortier- und Selektionsverfahren
5.  Paradigmen des Algorithmenentwurfs
6.  Ausgewählte Datenstrukturen
7.  Algorithmische Geometrie
8.  Umgang mit algorithmisch schwierigen Problemen
• 
• 
• 
5/2, Folie 1
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Divide and Conquer
Dynamisches Programmieren
Greedy-Algorithmen
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Gliederung
u  Fahrplan (/* Dynamisches Programmieren */)
• 
• 
• 
ein kleines Beispiel
Einordnung
komplexere Beispiele
... im Mittelpunkt steht die Frage, wie man rekursive
Lösungsalgorithmen möglichst effizient implementiert
5/2, Folie 2
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Bionomialkoeffizient
• 
• 
Anzahl der Möglichkeiten, einer Menge von n Elementen genau
k Elemente auszuwählen (/* Bez.: bk(n,k) */)
offenbar muss n ≥ k gelten
u  Beispiel
• 
es sei M = { A,B,C,D,E } und uns interessiert bk(5,3)
{ A,B,C }
{ A,B,D }
{ A,B,E }
{ A,C,D }
{ A,C,E }
{ A,D,E }
5/2, Folie 3
© 2014 Prof. Steffen Lange
{ B,C,D }
{ B,C,E }
{ B,D,E }
{ C,D,E }
... also gilt: bk(5,3) = 10
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Definition des Bionomialkoeffizienten (/* Idee */)
{ A,B,C }
{ A,B,D }
{ A,B,E }
{ A,C,D }
{ A,C,E }
{ A,D,E }
{ B,C,D }
{ B,C,E }
{ B,D,E }
{ C,D,E }
... alle Teilmengen der
Größe 3 von { A,B,C,D,E }
{ B,C,D }
{ B,C,E }
{ B,D,E }
{ B,C }
{ B,D }
{ B,E }
{ C,D }
{ C,E }
{ D,E }
5/2, Folie 4
... alle Teilmengen der
Größe 2 von { B,C,D,E }
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
{ C,D,E }
... alle Teilmengen der
Größe 3 von { B,C,D,E }
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Definition des Bionomialkoeffizienten
• 
• 
Anzahl der Möglichkeiten, k Elemente aus einer Menge von n Elementen
auszuwählen (/* Bez.: bk(n,k) */)
es seien n, k ∈ N mit n ≥ k
Fall 1: n = k oder k = 0
• 
dann ist bk(n,k) = 1
Fall 2 : n > k > 0
• 
5/2, Folie 5
© 2014 Prof. Steffen Lange
dann ist bk(n,k) = bk(n-1,k-1) + bk(n-1,k)
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  ... erste rekursive Implementierung
int bk ( int n, int k ) {
int result;
if ( n == k || k == 0 ) result = 1;
else result = bk(n-1,k-1) + bk(n-1,k);
return (result);
}
5/2, Folie 6
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Beispiel (/* Berechnung von bk(4,2) */)
bk(4,2)
bk(3,1)
bk(2,0)
bk(3,2)
bk(2,1)
bk(1,0)
• 
• 
bk(2,1)
bk(1,1)
bk(1,0)
bk(2,2)
bk(1,1)
Blätter haben gemäß der Basisfälle den Wert 1
Wert eines inneren Knotens ergibt sich als Summe der Werte seiner Söhne
•  Wert eines Knotens k ist gleich der Anzahl der Blätter im Teilbaum
mit Wurzel k
•  Anzahl der Additionen gleich der Anzahl der inneren Knoten
5/2, Folie 7
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Analyse (/* erste rekursive Implementierung */)
• 
• 
es seien n, k ∈ N mit n ≥ k
es bezeichne T(A,n,k) die Anzahl der Additionen, die benötigt werden,
um bk(n,k) rekursiv zu berechnen
• 
• 
Anzahl der Blätter: bk(n,k)
Anzahl der inneren Knoten: bk(n,k) - 1
T(A,n,k) = bk(n,k) - 1
... für k = n/2 gilt: bk(n,k) - 1 ≥ 2n/2
... Anzahl der Additionen ist im „worst case“ exponentiell in n
5/2, Folie 8
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Anmerkungen
• 
im zur Berechnung von bk(n,k) gehörenden Berechnungsbaum gibt es
exponentiell viele Knoten (/* jeder Knoten entspricht einem Aufruf der
Funktion bk(.,.) */)
• 
da es für gegebene n und k mit n ≥ k nur (n+1)*(k+1) viele Paare (n‘,k‘)
mit n‘ ≤ n und k‘ ≤ k gibt, muss die Funktion bk(.,.) mehrfach mit
denselben Parametern aufgerufen werden
... Ausweg: man merkt sich die Ergebnisse der bereits
ausgeführten Funktionsaufrufe
5/2, Folie 9
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Beispiel
1 bk(4,2)
2 bk(3,1)
3 bk(2,0)
7 bk(3,2)
4 bk(2,1)
5 bk(1,0)
8
bk(2,1)
9 bk(2,2)
bk(1,1) 6
... die Zahlen geben an, in welcher Reihenfolge die
Funktionsaufrufe stattfinden
5/2, Folie 10
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  ... bessere rekursive Implementierung
• 
erzeuge ein zweidimensionales Array a der Größe (n+1) × (k+1) und
initialisiere jede Zelle des Arrays mit dem Wert „-1“ (/* für „unbekannt“ */)
int bk ( int n, int k ) {
int result;
if ( a[n][k] != -1 ) result = a[n][k];
else { if ( n == k || k == 0 ) result = 1;
else result = bk(n-1,k-1) + bk(n-1,k);
a[n][k] = result;
}
return (result);
}
5/2, Folie 11
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Analyse (/* bessere rekursive Implementierung */)
• 
• 
es seien n, k ∈ N mit n ≥ k
es bezeichne T‘(A,n,k) die Anzahl der Additionen, die benötigt werden,
um bk(n,k) auf diese Art rekursiv zu berechnen
• 
offenbar wird nur dann eine Addition ausgeführt, wenn im Array a in
der Zelle a[n‘][k‘] noch der Wert „-1“ steht und n‘ ≠ k sowie k‘ ≠ 0 gilt
T‘(A,n,k) ≤ (n+1)*(k+1) - (n+1) - k = n*k
... Anzahl der Additionen ist polynomiell in n statt exponentiell in n
5/2, Folie 12
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Anmerkungen
• 
da Funktionsaufrufe bei der Berechnung einen nicht unerheblichen
„Overhead“ verursachen, ist es vorteilhaft anstelle des zuletzt
verwendeten „top-down“-Ansatzes einen „bottom-up“-Ansatz zu wählen
... das nennt man dann üblicherweise „dynamische Programmierung“
5/2, Folie 13
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Implementierung mit Hilfe der dynamischen Programmierung
• 
erzeuge ein zweidimensionales Array a der Größe (n+1) × (k+1), wobei für
die Indizierung der Zeilen die Zahlen 0 bis n und für die Indizierung der
Spalten die Zahlen 0 bis k verwendet werden (/* der gesuchte
Binomialkoeffizient bk(n,k) steht dann in der Zelle a[n][k] */)
• 
fülle dieses Array gemäß der folgenden Regeln zeilenweise von links nach
rechts, d.h. es wird mit der Zelle a[0][0] begonnen
•  wenn i < j gilt, so setze a[i][j] = 0
•  wenn i = j oder j = 0 gilt, so setze a[i][j] = 1
•  andernfalls, setze a[i][j] = a[i-1][j-1] + a[i-1][j]
... offenbar genügen so O(n*k) viele Elementaroperationen, um den
Binomialkoeffizienten bk(n,k) zu bestimmen
5/2, Folie 14
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Beispiel
i=0
j=0
j=1
j=2
1
0
0
i=1
i=2
i=3
i=4
5/2, Folie 15
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Beispiel (cont.)
j=0
j=1
j=2
i=0
1
0
0
i=1
1
1
0
i=2
i=3
i=4
5/2, Folie 16
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Beispiel (cont.)
j=0
j=1
j=2
i=0
1
0
0
i=1
1
1
0
i=2
1
2
1
i=3
i=4
5/2, Folie 17
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Ein erstes Beispiel
u  Beispiel (cont.)
5/2, Folie 18
j=0
j=1
j=2
i=0
1
0
0
i=1
1
1
0
i=2
1
2
1
i=3
1
3
3
i=4
1
4
6
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Einordnung
u  ... „Situationsbeschreibung“
• 
es sei ein rekursiver Lösungsalgorithmus A gegeben, also ein
Algorithmus, der ...
• 
• 
• 
• 
das Gesamtproblem in Teilprobleme zerlegt
diese Teilprobleme rekursiv löst
aus den Lösungen der Teilprobleme die Lösung des
Gesamtproblems konstruiert
während der Verarbeitung einer Eingabe werden bestimmte
Teilprobleme mehrfach gelöst
u  Anmerkung
• 
5/2, Folie 19
es geht also nicht um „Divide-and-Conquer“-Algorithmen (/* hier zerlegt
man das Gesamtproblem im allgemeinen in disjunkte Teilprobleme und
es werden immer unterschiedliche Teilprobleme gelöst */)
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Einordnung
u  Grundidee (/* „top-down“-Variante */)
• 
• 
man löst das Gesamtproblem rekursiv und merkt sich „parallel“ die
Lösungen aller bereits vollständig bearbeiteten Teilprobleme
sobald ein weiteres Teilproblem rekursive gelöst werden soll, wird
überprüft, ob die Lösung für dieses Teilproblem bereits bekannt ist
• 
5/2, Folie 20
ist die Lösung bereits bekannt, muss das Teilproblem nicht
rekursiv gelöst werden
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Einordnung
u  Grundidee (/* „bottom-up“-Variante */)
• 
• 
man bestimmt die Menge M aller Teilprobleme, die überhaupt bei der
Lösung des Gesamtproblems eine Rolle spielen können
man wählt eine Anordnung der Teilprobleme in der Menge M, so dass
für jedes Teilproblem TP gilt:
• 
• 
5/2, Folie 21
alle Teilprobleme TP‘, die bei der rekursiven Lösung des
Teilproblems TP eine Rolle spielen, stehen in der gewählten
Anordnung vor TP
man löst sukzessive alle Teilprobleme in der Menge M, wobei man die
gewählte Anordnung respektiert, d.h. mit dem ersten Teilproblem
beginnt
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Einordnung
u  Beispiel (/* Fibonacci-Zahlen */)
• 
rekursive Definition der Fibonacci-Zahlen
• 
• 
• 
• 
um fib(n) zu bestimmen, sind höchstens die folgende Teilprobleme zu
lösen:
• 
• 
bestimme fib(m) für alle m ≤ n
geeignete Anordnung der Teilprobleme:
• 
5/2, Folie 22
fib(n) = 0, falls n = 0
fib(n) = 1, falls n = 1
fib(n) = fib(n-1) + fib(n-2), sonst
fib(0), fib(1), ..., fib(n-2), fib(n-1), fib(n)
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Einordnung
u  Anmerkungen
• 
im allgemeinen ist es nicht schwierig, an Hand des gegebenen rekursiven
Lösungsalgorithmus
• 
• 
• 
die Menge M der überhaupt zu lösenden Teilprobleme zu bestimmen
eine geeignete Anordnung der Teilprobleme in der Menge M zu
bestimmen
um die Laufzeit des nicht-rekursiven Lösungsalgorithmus für Eingaben der
Größe n abschätzen, wählt man eine Funktion T(n) = f(n)*g(n), wobei gilt:
• 
• 
5/2, Folie 23
f(n) ist eine asymptotische obere Schranke für die Anzahl der
Teilprobleme in der Menge M
g(n) ist eine asymptotische obere Schranke für den Aufwand,
um die Lösungen von Teilprobleme direkt zu bestimmen bzw.
aus bereits gelösten Teilproblemen zu konstruieren
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Einordnung
u  Anwendungsgebiet
• 
Lösung von Optimierungsproblemen
u  Optimierungsprobleme
• 
• 
• 
• 
Beschreibung einer Menge X zulässiger Eingaben
Beschreibung einer Menge Y zulässiger Ausgaben
Beschreibung einer Funktion, die jeder zulässigen Eingabe die nicht
leere Menge der korrekten Ausgaben zuordnet
Beschreibung einer Funktion, die jeder korrekten Ausgabe ihren Wert
(/* Güte, Kosten */) zuordnet
... das Ziel besteht darin, einer zulässigen Eingabe x eine korrekte
Ausgabe y zuzuordnen, die unter allen korrekten Ausgaben die
beste Güte bzw. die minimalen Kosten hat
5/2, Folie 24
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Kapitel 5: Paradigmen des Algorithmenentwurfs
Weiterer Fahrplan
u  Gegenstand
• 
wir werden uns ein paar typische Optimierungsprobleme anschauen,
die man effizient mit Algorithmen lösen kann, die auf dem Paradigma
der dynamischen Programmierung basieren
• 
konkrete Optimierungsprobleme und die zugehörigen nicht-rekursiven
Lösungsalgorithmen
• 
der Entwurf der nicht-rekursiven Lösungsalgorithmen anhand gegebener
rekursiver Lösungsalgorithmen
• 
der Entwurf von rekursiven Lösungsalgorithmen
u  Fokus
5/2, Folie 25
© 2014 Prof. Steffen Lange
-
HDa/FbI
-
Algorithmik
Herunterladen