Dynamische Programmierung Manuel Grandeit Hallo Welt -Seminar 28.06.2011 Manuel Grandeit 1 / 40
Inhaltsübersicht Einführung Münzwechsel Was ist ein Zustand? Konstruktion einer DP-Lösung Top-Down-DP Bottom-Up-DP Anwendung von DP Das Rucksackproblem Die längste gemeinsame Unterfolge Die Editierdistanz Performancetuning Zusammenfassung Manuel Grandeit 2 / 40
Geschichte Wer hat s erfunden? Richard Bellman (auch durch den Bellman-Ford Algorithmus bekannt) Mathematisches Verfahren zum Lösen von Optimierungsproblemen Programmierung bedeutet hier: Speichern von Zwischenergebnissen in Tabellen Manuel Grandeit 3 / 40
Konzept Was wird gemacht? Konstruktion der Gesamtlösung aus den Lösungen der Teilprobleme Die Teilprobleme müssen dabei nicht, wie bei Divide & Conquer, unabhängig sein Zwischenergebnisse werden in Tabellen gespeichert Manuel Grandeit 4 / 40
Rezept für eine DP-Lösung Wie wird s gemacht? Struktur der optimalen Lösung analysieren Rekursive Definition der Lösung aufstellen Berechnung der Lösung (top-down oder bottom-up) Rekonstruktion der Lösung anhand der berechneten Werte Manuel Grandeit 5 / 40
Aufgabenstellung Münzwechsel Gegeben: Eine Anzahl an Münzen V 1, V 2,..., V n und eine Summe S Gesucht: Die minimale Anzahl an Münzen, die die gegebene Summe S ergeben Es dürfen beliebig viele Münzen einer Art ausgewählt werden Beispiel Münzen: 1, 3, 5 Summe: 10 Lösung:? Manuel Grandeit 6 / 40
Aufgabenstellung Münzwechsel Gegeben: Eine Anzahl an Münzen V 1, V 2,..., V n und eine Summe S Gesucht: Die minimale Anzahl an Münzen, die die gegebene Summe S ergeben Es dürfen beliebig viele Münzen einer Art ausgewählt werden Beispiel Münzen: 1, 3, 5 Summe: 10 Lösung:? Manuel Grandeit 6 / 40
Aufgabenstellung Münzwechsel Gegeben: Eine Anzahl an Münzen V 1, V 2,..., V n und eine Summe S Gesucht: Die minimale Anzahl an Münzen, die die gegebene Summe S ergeben Es dürfen beliebig viele Münzen einer Art ausgewählt werden Beispiel Münzen: 1, 3, 5 Summe: 10 Lösung: 2 Manuel Grandeit 6 / 40
Struktur der optimalen Lösung Zustand oder state Beschreibt eine Situation bzw. eine Teillösung des Problems Beispiel Der Zustand i ist die Lösung für eine Summe i (i < S) Ein kleinerer Zustand j ist die Lösung für eine Summe j (j < i) Manuel Grandeit 7 / 40
Struktur der optimalen Lösung Zustand oder state Beschreibt eine Situation bzw. eine Teillösung des Problems Beispiel Der Zustand i ist die Lösung für eine Summe i (i < S) Ein kleinerer Zustand j ist die Lösung für eine Summe j (j < i) Manuel Grandeit 7 / 40
Struktur der optimalen Lösung Überlegung Der Zustand i kann erst berechnet werden, wenn alle Zustände j (j < i) berechnet wurden Ist die minimale Anzahl an Münzen für den Zustand i bekannt, kann der Zustand i + 1 leicht berechnet werden Der Schritt zur Rekursion (wie berechnet sich der Zustand i?) Für jede Münze j, V j i betrachten wir die minimale Anzahl an Münzen m, der Summe i V j (schon berechnet) Ist m + 1 kleiner als die bisher, für die Summe i, gefundene Anzahl an Münzen, dann speichern wir m + 1 als neues Ergebnis Manuel Grandeit 8 / 40
Struktur der optimalen Lösung Überlegung Der Zustand i kann erst berechnet werden, wenn alle Zustände j (j < i) berechnet wurden Ist die minimale Anzahl an Münzen für den Zustand i bekannt, kann der Zustand i + 1 leicht berechnet werden Der Schritt zur Rekursion (wie berechnet sich der Zustand i?) Für jede Münze j, V j i betrachten wir die minimale Anzahl an Münzen m, der Summe i V j (schon berechnet) Ist m + 1 kleiner als die bisher, für die Summe i, gefundene Anzahl an Münzen, dann speichern wir m + 1 als neues Ergebnis Manuel Grandeit 8 / 40
Implementierung der Rekursion Naive rekursive Implementierung i n t v a l u e s [N ] ; i n t c o i n s ( i n t sum ) { i f ( sum == 0) r e t u r n 0 ; i n t min = INT MAX ; f o r ( i n t i = 0 ; i < N; i ++) { i f ( v a l u e s [ i ] <= sum ) { min = s t d : : min ( c o i n s ( sum v a l u e s [ i ])+1, min ) ; } } } r e t u r n min ; Manuel Grandeit 9 / 40
Vorteil dieser Lösung Einfach zu implementieren, da nur Rekursion Dementsprechend auch sehr übersichtlich Nachteil dieser Lösung Teilprobleme werden mehrfach berechnet hoher Rechenaufwand! O( N S ) Manuel Grandeit 10 / 40
Vorteil dieser Lösung Einfach zu implementieren, da nur Rekursion Dementsprechend auch sehr übersichtlich Nachteil dieser Lösung Teilprobleme werden mehrfach berechnet hoher Rechenaufwand! O( N S ) Manuel Grandeit 10 / 40
Vorteil dieser Lösung Einfach zu implementieren, da nur Rekursion Dementsprechend auch sehr übersichtlich Nachteil dieser Lösung Teilprobleme werden mehrfach berechnet hoher Rechenaufwand! O( N S ) Geht das nicht besser? (frei nach Prof. Philippsen) Manuel Grandeit 10 / 40
Memoization Verbesserte rekursive Implementierung i n t v a l u e s [N], memo[s] ; // memset w r i t e s b y t e s! be c a r e f u l! memset(memo, UNKNOWN, S*sizeof(int)); memo[0] = 0; i n t c o i n s ( i n t sum ) { if (memo[sum]!= UNKNOWN) return memo[sum]; i n t min = INT MAX ; f o r ( i n t i = 0 ; i < N; i ++) { i f ( v a l u e s [ i ] <= sum ) { min = s t d : : min ( c o i n s ( sum v a l u e s [ i ])+1, min ) ; } } } memo[sum] = min; r e t u r n min ; Manuel Grandeit 11 / 40
Memoization Definition Memoization bezeichnet das Speichern von Zwischenergebnissen bereits berechneter Teilprobleme Anwendung Tabelle mit UNKNOWN-Werten initialisieren Basisfälle in die Tabelle eintragen Es gibt zwei Möglichkeiten: Ergebnis bekannt: Es kann direkt aus der Tabelle gelesen werden Ergebnis unbekannt: Es muss berechnet und in der Tabelle gespeichert werden Manuel Grandeit 12 / 40
Memoization Definition Memoization bezeichnet das Speichern von Zwischenergebnissen bereits berechneter Teilprobleme Anwendung Tabelle mit UNKNOWN-Werten initialisieren Basisfälle in die Tabelle eintragen Es gibt zwei Möglichkeiten: Ergebnis bekannt: Es kann direkt aus der Tabelle gelesen werden Ergebnis unbekannt: Es muss berechnet und in der Tabelle gespeichert werden Manuel Grandeit 12 / 40
Top-Down-DP (Rekursion mit Memoization) Vor- und Nachteile (Zwischenstand) Positiv: Leicht umzusetzen, da nur eine Rekursionsformel implementiert werden muss Mehrfachberechnung von Zwischenergebnissen wird durch Memoization verhindert Negativ: Rekursionstiefe kann zu einem Problem werden Stackoverflow! Overhead durch Funktionsaufrufe Manuel Grandeit 13 / 40
Top-Down-DP (Rekursion mit Memoization) Vor- und Nachteile (Zwischenstand) Positiv: Leicht umzusetzen, da nur eine Rekursionsformel implementiert werden muss Mehrfachberechnung von Zwischenergebnissen wird durch Memoization verhindert Negativ: Rekursionstiefe kann zu einem Problem werden Stackoverflow! Overhead durch Funktionsaufrufe Manuel Grandeit 13 / 40
Bottom-Up-DP Idee Iteratives Füllen der Tabelle zu Beginn (keine Rekursion!) Ergebnisse können direkt aus der Tabelle gelesen werden Umwandlung der Rekursion in eine iterative Lösung Manuel Grandeit 14 / 40
Bottom-Up-DP Iterative (bottom-up) Implementierung i n t v a l u e s [N], min[s]; i n t c o i n s ( i n t sum ) { for (int i = 0; i < sum+1; i++) min[i] = INT MAX; min[0] = 0; f o r ( i n t i = 1 ; i <= sum ; i ++) { f o r ( i n t j = 0 ; j < N; j ++) { i f ( v a l u e s [ j ] <= i && min[i-values[j]] + 1 < min[i]) min[i] = min[i-values[j]] + 1; } } } return min[sum]; Manuel Grandeit 15 / 40
Top-Down vs Bottom-Up Top-Down Positiv: Relativ leicht zu implementieren (nur Rekursion) Gut geeignet, falls nicht alle Teilprobleme benötigt werden Negativ: Rekursionstiefe, Overhead durch Funktionsaufrufe Bottom-Up Positiv: Berechnung zu Beginn, schnelle Abfragen, keine Rekursion Negativ: Umwandlung der Rekursion nötig (nicht immer trivial) Effizienzverlust, falls nicht alle Werte benötigt werden Manuel Grandeit 16 / 40
Top-Down vs Bottom-Up Top-Down Positiv: Relativ leicht zu implementieren (nur Rekursion) Gut geeignet, falls nicht alle Teilprobleme benötigt werden Negativ: Rekursionstiefe, Overhead durch Funktionsaufrufe Bottom-Up Positiv: Berechnung zu Beginn, schnelle Abfragen, keine Rekursion Negativ: Umwandlung der Rekursion nötig (nicht immer trivial) Effizienzverlust, falls nicht alle Werte benötigt werden Manuel Grandeit 16 / 40
Top-Down vs Bottom-Up Top-Down Positiv: Relativ leicht zu implementieren (nur Rekursion) Gut geeignet, falls nicht alle Teilprobleme benötigt werden Negativ: Rekursionstiefe, Overhead durch Funktionsaufrufe Bottom-Up Positiv: Berechnung zu Beginn, schnelle Abfragen, keine Rekursion Negativ: Umwandlung der Rekursion nötig (nicht immer trivial) Effizienzverlust, falls nicht alle Werte benötigt werden Manuel Grandeit 16 / 40
Top-Down vs Bottom-Up Top-Down Positiv: Relativ leicht zu implementieren (nur Rekursion) Gut geeignet, falls nicht alle Teilprobleme benötigt werden Negativ: Rekursionstiefe, Overhead durch Funktionsaufrufe Bottom-Up Positiv: Berechnung zu Beginn, schnelle Abfragen, keine Rekursion Negativ: Umwandlung der Rekursion nötig (nicht immer trivial) Effizienzverlust, falls nicht alle Werte benötigt werden Manuel Grandeit 16 / 40
Verwendung von DP Pro Es handelt sich um ein Optimierungsproblem Das Problem lässt sich in optimale Teilprobleme zerlegen Es gibt sich überlappende Teilprobleme Contra Speicherplatzbedarf der Tabelle zu groß Reelle oder komplexe Zahlen als Parameter (Arrayindex!) Es existiert ein besserer Lösungsweg Manuel Grandeit 17 / 40
Verwendung von DP Pro Es handelt sich um ein Optimierungsproblem Das Problem lässt sich in optimale Teilprobleme zerlegen Es gibt sich überlappende Teilprobleme Contra Speicherplatzbedarf der Tabelle zu groß Reelle oder komplexe Zahlen als Parameter (Arrayindex!) Es existiert ein besserer Lösungsweg Manuel Grandeit 17 / 40
Das Rucksackproblem Typisches Alltagsproblem Manuel Grandeit 18 / 40
Das Rucksackproblem Typisches Alltagsproblem Wir rauben einen Juwelier aus! Manuel Grandeit 18 / 40
Das Rucksackproblem Typisches Alltagsproblem Wir rauben einen Juwelier aus! (Was packen wir bloß ein?) Manuel Grandeit 18 / 40
Das Rucksackproblem Kurzzusammenfassung Wir besitzen einen Rucksack der Größe K Jeder Gegenstand hat einen Wert v i und eine Größe s i Welche Gegenstände müssen wir einpacken, damit der Wert der Beute maximal wird? Wir haben wenig Zeit! Die Herren in Grün sind schon unterwegs... Manuel Grandeit 19 / 40
Struktur der optimalen Lösung Was ist zu tun? Die Gegenstände müssen so gewählt werden, dass die Summe n v i maximal wird i=1 Konstruktion einer rekursiven Lösung Nehmen wir an, der Rucksack wäre schon optimal gepackt Entfernen wir nun den Gegenstand i, dann erhalten wir eine optimale Lösung für die Kapazität K s i Manuel Grandeit 20 / 40
Struktur der optimalen Lösung Was ist zu tun? Die Gegenstände müssen so gewählt werden, dass die Summe n v i maximal wird i=1 Konstruktion einer rekursiven Lösung Nehmen wir an, der Rucksack wäre schon optimal gepackt Entfernen wir nun den Gegenstand i, dann erhalten wir eine optimale Lösung für die Kapazität K s i Manuel Grandeit 20 / 40
Das Rucksackproblem Rekursive Implementierung i n t s [N], v [N ] ; // s i z e and v a l u e i n t r u c k s a c k ( i n t c a p a c i t y ) { i n t maxvalue = 0, s p a c e ; f o r ( i n t i = 0 ; i < N; i ++) { i f ( ( s p a c e = c a p a c i t y s [ i ] ) >= 0) maxvalue = s t d : : max ( r u c k s a c k ( s p a c e ) + v [ i ], maxvalue ) ; } } r e t u r n maxvalue ; Manuel Grandeit 21 / 40
Das Rucksackproblem Top-Down-Implementierung mit Memoization i n t s [N], v [N], best[maxcap+1] ; // s i z e and v a l u e // memset w r i t e s b y t e s! be c a r e f u l! memset(best, UNKNOWN, (MAXCAP+1)*sizeof(int)); i n t r u c k s a c k ( i n t c a p a c i t y ) { i n t maxvalue = 0, s p a c e ; if(best[capacity]!= UNKNOWN) return best[capacity]; f o r ( i n t i = 0 ; i < N; i ++) { i f ( ( s p a c e = c a p a c i t y s [ i ] ) >= 0) maxvalue = s t d : : max ( r u c k s a c k ( s p a c e ) + v [ i ], maxvalue ) ; } best[capacity] = maxvalue; } r e t u r n maxvalue ; Manuel Grandeit 22 / 40
Rekonstruktion der Lösung Problem Bisher haben wir nur den maximalen Wert des Rucksacks berechnet Aber, welche Gegenstände haben wir eingepackt? Lösung Erstellen einer zweiten Tabelle items, die die mitgenommenen Gegenstände speichert Der erste eingepackte Gegestand steht in items[maxcap] Der Zweite steht in items[maxcap - s[items[maxcap]]] usw. Manuel Grandeit 23 / 40
Rekonstruktion der Lösung Problem Bisher haben wir nur den maximalen Wert des Rucksacks berechnet Aber, welche Gegenstände haben wir eingepackt? Lösung Erstellen einer zweiten Tabelle items, die die mitgenommenen Gegenstände speichert Der erste eingepackte Gegestand steht in items[maxcap] Der Zweite steht in items[maxcap - s[items[maxcap]]] usw. Manuel Grandeit 23 / 40
Das Rucksackproblem Top-Down-Implementierung mit Memoization i n t s [N], v [N], b e s t [MAXCAP+1], items[maxcap+1] ; // memset w r i t e s b y t e s! be c a r e f u l! memset ( best, UNKNOWN, (MAXCAP+1) s i z e o f ( i n t ) ) ; memset(items, UNKNOWN, (MAXCAP+1)*sizeof(int)); i n t r u c k s a c k ( i n t c a p a c i t y ) { i n t maxvalue = 0, space, maxitem ; } i f ( b e s t [ c a p a c i t y ]!= UNKNOWN) r e t u r n b e s t [ c a p a c i t y ] ; f o r ( i n t i = 0 ; i < N; i ++) { i f ( ( s p a c e = c a p a c i t y s [ i ] ) >= 0) { maxvalue = s t d : : max ( r u c k s a c k ( s p a c e ) + v [ i ], maxvalue ) ; maxitem = i; } } items[capacity] = maxitem; b e s t [ c a p a c i t y ] = maxvalue ; r e t u r n maxvalue ; Manuel Grandeit 24 / 40
Longest common subsequence Was ist eine LCS? Gegeben sind 2 Strings X = < x 1, x 2,..., x m > und Y = < y 1, y 2,..., y n > Die longest common subsequence ist ein String Z, der die Zeichen enthält, die sowohl in X als auch in Y vorkommen Allerdings müssen die Zeichen in der selben Reihenfolge vorkommen! Manuel Grandeit 25 / 40
Longest common subsequence Was ist eine LCS? Gegeben sind 2 Strings X = < x 1, x 2,..., x m > und Y = < y 1, y 2,..., y n > Die longest common subsequence ist ein String Z, der die Zeichen enthält, die sowohl in X als auch in Y vorkommen Allerdings müssen die Zeichen in der selben Reihenfolge vorkommen! Beispiele erlangen hacker hallo algen makaber welt Manuel Grandeit 25 / 40
Longest common subsequence Was ist eine LCS? Gegeben sind 2 Strings X = < x 1, x 2,..., x m > und Y = < y 1, y 2,..., y n > Die longest common subsequence ist ein String Z, der die Zeichen enthält, die sowohl in X als auch in Y vorkommen Allerdings müssen die Zeichen in der selben Reihenfolge vorkommen! Beispiele erlangen algen 4 lgen hacker makaber hallo welt Manuel Grandeit 25 / 40
Longest common subsequence Was ist eine LCS? Gegeben sind 2 Strings X = < x 1, x 2,..., x m > und Y = < y 1, y 2,..., y n > Die longest common subsequence ist ein String Z, der die Zeichen enthält, die sowohl in X als auch in Y vorkommen Allerdings müssen die Zeichen in der selben Reihenfolge vorkommen! Beispiele erlangen algen 4 lgen hacker makaber 4 aker hallo welt Manuel Grandeit 25 / 40
Longest common subsequence Was ist eine LCS? Gegeben sind 2 Strings X = < x 1, x 2,..., x m > und Y = < y 1, y 2,..., y n > Die longest common subsequence ist ein String Z, der die Zeichen enthält, die sowohl in X als auch in Y vorkommen Allerdings müssen die Zeichen in der selben Reihenfolge vorkommen! Beispiele erlangen algen 4 lgen hacker makaber 4 aker hallo welt 1 l Manuel Grandeit 25 / 40
Struktur der optimalen Lösung Überlegung Es existieren 2 X Teilsequenzen von X Bruteforce ist keine so gute Idee... Manuel Grandeit 26 / 40
Struktur der optimalen Lösung Überlegung Es existieren 2 X Teilsequenzen von X Bruteforce ist keine so gute Idee... Ist das letzte Zeichen der beiden Strings gleich, gehört es offensichtlich zur LCS Ist es nicht gleich, so entstehen zwei Teilprobleme, da jetzt in einem der beiden Strings ein Zeichen entfernt werden kann Manuel Grandeit 26 / 40
Struktur der optimalen Lösung Konstruktion der Rekursionsgleichung Ist x m = y n dann muss eine LCS von X m 1 und Y n 1 gesucht werden Ist x m y n dann müssen 2 Teilprobleme gelöst werden Es muss eine LCS von X m 1 und Y n, sowie eine LCS von X m und Y n 1 gefunden werden Die längere, der beiden gefundenen Unterfolgen, ist die LCS von X und Y Rekursionsgleichung 0 if i = 0 or j = 0 c[i, j] = c[i-1,j-1]+1 if i, j > 0 and x i = y j max(c[i,j-1], c[i-1,j]) if i, j > 0 and x i y j Manuel Grandeit 27 / 40
Struktur der optimalen Lösung Konstruktion der Rekursionsgleichung Ist x m = y n dann muss eine LCS von X m 1 und Y n 1 gesucht werden Ist x m y n dann müssen 2 Teilprobleme gelöst werden Es muss eine LCS von X m 1 und Y n, sowie eine LCS von X m und Y n 1 gefunden werden Die längere, der beiden gefundenen Unterfolgen, ist die LCS von X und Y Rekursionsgleichung 0 if i = 0 or j = 0 c[i, j] = c[i-1,j-1]+1 if i, j > 0 and x i = y j max(c[i,j-1], c[i-1,j]) if i, j > 0 and x i y j Manuel Grandeit 27 / 40
Longest common subsequence Bottom-Up-Implementierung i n t c [MAXLEN ] [ MAXLEN ] ; i n t l c s ( char x, i n t m, char y, i n t n ) { f o r ( i n t i = 0 ; i <= m; i ++) c [ i ] [ 0 ] = 0 ; f o r ( i n t j = 0 ; j <= n ; j ++) c [ 0 ] [ j ] = 0 ; f o r ( i n t i = 1 ; i <= m; i ++) { f o r ( i n t j = 1 ; j <= n ; j ++) { i f ( x [ i 1] == y [ j 1]) { c [ i ] [ j ] = c [ i 1][ j 1] + 1 ; } e l s e { c [ i ] [ j ] = s t d : : max ( c [ i 1][ j ], c [ i ] [ j 1 ] ) ; } } } } r e t u r n c [m] [ n ] ; Manuel Grandeit 28 / 40
Longest common subsequence Rekonstruktion der Lösung Wir erhalten die Länge der LCS, doch welche Zeichen sind enthalten? Rekonstruktion der Lösung mit Hilfe der Tabelle Implementierung v o i d p r i n t l c s ( char x, char y, i n t i, i n t j ) { i f ( i == 0 j == 0) r e t u r n ; i f ( x [ i 1] == y [ j 1]) { p r i n t l c s ( x, y, i 1, j 1); p u t c h a r ( x [ i 1 ] ) ; } e l s e i f ( c [ i 1][ j ] > c [ i ] [ j 1]) { p r i n t l c s ( x, y, i 1, j ) ; } e l s e { p r i n t l c s ( x, y, i, j 1); } } Manuel Grandeit 29 / 40
Longest common subsequence Beispieltabelle m e s n a 0 0 0 0 0 0 m 0 1 1 1 1 1 e 0 1 2 2 2 2 n 0 1 2 2 3 3 s 0 1 2 3 3 3 a 0 1 2 3 3 4 LCS: Manuel Grandeit 30 / 40
Longest common subsequence Beispieltabelle m e s n a 0 0 0 0 0 0 m 0 1 1 1 1 1 e 0 1 2 2 2 2 n 0 1 2 2 3 3 s 0 1 2 3 3 3 a 0 1 2 3 3 4 LCS: Manuel Grandeit 30 / 40
Longest common subsequence Beispieltabelle m e s n a 0 0 0 0 0 0 m 0 1 1 1 1 1 e 0 1 2 2 2 2 n 0 1 2 2 3 3 s 0 1 2 3 3 3 a 0 1 2 3 3 4 LCS: a Manuel Grandeit 30 / 40
Longest common subsequence Beispieltabelle m e s n a 0 0 0 0 0 0 m 0 1 1 1 1 1 e 0 1 2 2 2 2 n 0 1 2 2 3 3 s 0 1 2 3 3 3 a 0 1 2 3 3 4 LCS: a Manuel Grandeit 30 / 40
Longest common subsequence Beispieltabelle m e s n a 0 0 0 0 0 0 m 0 1 1 1 1 1 e 0 1 2 2 2 2 n 0 1 2 2 3 3 s 0 1 2 3 3 3 a 0 1 2 3 3 4 LCS: sa Manuel Grandeit 30 / 40
Longest common subsequence Beispieltabelle m e s n a 0 0 0 0 0 0 m 0 1 1 1 1 1 e 0 1 2 2 2 2 n 0 1 2 2 3 3 s 0 1 2 3 3 3 a 0 1 2 3 3 4 LCS: sa Manuel Grandeit 30 / 40
Longest common subsequence Beispieltabelle m e s n a 0 0 0 0 0 0 m 0 1 1 1 1 1 e 0 1 2 2 2 2 n 0 1 2 2 3 3 s 0 1 2 3 3 3 a 0 1 2 3 3 4 LCS: esa Manuel Grandeit 30 / 40
Longest common subsequence Beispieltabelle m e s n a 0 0 0 0 0 0 m 0 1 1 1 1 1 e 0 1 2 2 2 2 n 0 1 2 2 3 3 s 0 1 2 3 3 3 a 0 1 2 3 3 4 LCS: mesa Manuel Grandeit 30 / 40
Editierdistanz (oder auch Levenshtein-Distanz) Beschreibung Die Levenshtein-Distanz ist die minimale Anzahl an Einfüge-, Lösch- und Ersetzungsoperationen, die benötigt werden, um einen String X in einen String Y umzuwandeln. Beispiel Die Levenshtein-Distanz zwischen Hallo und Welt ist: 4 Hallo Manuel Grandeit 31 / 40
Editierdistanz (oder auch Levenshtein-Distanz) Beschreibung Die Levenshtein-Distanz ist die minimale Anzahl an Einfüge-, Lösch- und Ersetzungsoperationen, die benötigt werden, um einen String X in einen String Y umzuwandeln. Beispiel Die Levenshtein-Distanz zwischen Hallo und Welt ist: 4 Hallo Manuel Grandeit 31 / 40
Editierdistanz (oder auch Levenshtein-Distanz) Beschreibung Die Levenshtein-Distanz ist die minimale Anzahl an Einfüge-, Lösch- und Ersetzungsoperationen, die benötigt werden, um einen String X in einen String Y umzuwandeln. Beispiel Die Levenshtein-Distanz zwischen Hallo und Welt ist: 4 Hallo allo (H wurde gelöscht) Manuel Grandeit 31 / 40
Editierdistanz (oder auch Levenshtein-Distanz) Beschreibung Die Levenshtein-Distanz ist die minimale Anzahl an Einfüge-, Lösch- und Ersetzungsoperationen, die benötigt werden, um einen String X in einen String Y umzuwandeln. Beispiel Die Levenshtein-Distanz zwischen Hallo und Welt ist: 4 Hallo allo (H wurde gelöscht) Wllo (a wurde durch W ersetzt) Manuel Grandeit 31 / 40
Editierdistanz (oder auch Levenshtein-Distanz) Beschreibung Die Levenshtein-Distanz ist die minimale Anzahl an Einfüge-, Lösch- und Ersetzungsoperationen, die benötigt werden, um einen String X in einen String Y umzuwandeln. Beispiel Die Levenshtein-Distanz zwischen Hallo und Welt ist: 4 Hallo allo (H wurde gelöscht) Wllo (a wurde durch W ersetzt) Welo (l wurde durch e ersetzt) Manuel Grandeit 31 / 40
Editierdistanz (oder auch Levenshtein-Distanz) Beschreibung Die Levenshtein-Distanz ist die minimale Anzahl an Einfüge-, Lösch- und Ersetzungsoperationen, die benötigt werden, um einen String X in einen String Y umzuwandeln. Beispiel Die Levenshtein-Distanz zwischen Hallo und Welt ist: 4 Hallo allo (H wurde gelöscht) Wllo (a wurde durch W ersetzt) Welo (l wurde durch e ersetzt) Welt (o wurde durch t ersetzt) Manuel Grandeit 31 / 40
Struktur der optimalen Lösung Überlegung Um einen String X in einen leeren String umzuwandeln, müssen alle Zeichen gelöscht werden Außerdem entstehen auch hier, ähnlich der LCS, zwei Fälle: Zwei Zeichen sind gleich keine Operation nötig Zwei Zeichen sind nicht gleich Entweder eine Einfüge-, Lösch- oder Ersetzungsoperation nötig Rekursionsgleichung i if j = 0 j if i = 0 d[i, j] = d[i-1,j-1] if x i = y i 1 + min(d[i,j-1], d[i-1,j], d[i-1][j-1]) otherwise Manuel Grandeit 32 / 40
Struktur der optimalen Lösung Überlegung Um einen String X in einen leeren String umzuwandeln, müssen alle Zeichen gelöscht werden Außerdem entstehen auch hier, ähnlich der LCS, zwei Fälle: Zwei Zeichen sind gleich keine Operation nötig Zwei Zeichen sind nicht gleich Entweder eine Einfüge-, Lösch- oder Ersetzungsoperation nötig Rekursionsgleichung i if j = 0 j if i = 0 d[i, j] = d[i-1,j-1] if x i = y i 1 + min(d[i,j-1], d[i-1,j], d[i-1][j-1]) otherwise Manuel Grandeit 32 / 40
Editierdistanz Bottom-Up-Implementierung i n t d [MAXLEN ] [ MAXLEN ] ; i n t l e v e n s h t e i n ( char x, i n t m, char y, i n t n ) { f o r ( i n t i = 0 ; i <= m; i ++) d [ i ] [ 0 ] = i ; f o r ( i n t j = 0 ; j <= n ; j ++) d [ 0 ] [ j ] = j ; } f o r ( i n t i = 1 ; i <= m; i ++) { f o r ( i n t j = 1 ; j <= n ; j ++) { i f ( x [ i 1] == y [ j 1]) { d [ i ] [ j ] = d [ i 1][ j 1]; } e l s e { i n t min = s t d : : min ( d [ i ] [ j 1], d [ i 1][ j ] ) ; d [ i ] [ j ] = 1 + s t d : : min ( min, d [ i 1][ j 1 ] ) ; } } } r e t u r n d [m] [ n ] ; Manuel Grandeit 33 / 40
Editierdistanz Rekonstruktion der Lösung Wir erhalten die Levenshtein-Distanz, aber welche Operationen wurden verwendet? Rekonstruktion eines Lösungsweges mit Hilfe der Tabelle Manuel Grandeit 34 / 40
Editierdistanz Implementierung v o i d p r i n t o p s ( i n t i, i n t j ) { i f ( i == 0 j == 0) r e t u r n ; } i f ( d [ i 1][ j ] + 1 == d [ i ] [ j ] ) { p r i n t o p s ( i 1, j ) ; p r i n t f ( d e l ) ; } e l s e i f ( d [ i ] [ j 1] + 1 == d [ i ] [ j ] ) { p r i n t o p s ( i, j 1); p r i n t f ( i n s ) ; } e l s e i f ( d [ i 1][ j 1] + 1 == d [ i ] [ j ] ) { p r i n t o p s ( i 1, j 1); p r i n t f ( cha ) ; } e l s e i f ( d [ i 1][ j 1] == d [ i ] [ j ] ) { p r i n t o p s ( i 1, j 1); p r i n t f ( equ ) ; } Manuel Grandeit 35 / 40
Editierdistanz Beispieltabelle W e l t 0 1 2 3 4 H 1 1 2 3 4 a 2 2 2 3 4 l 3 3 3 2 3 l 4 4 4 3 3 o 5 5 5 4 4 Operationen: Manuel Grandeit 36 / 40
Editierdistanz Beispieltabelle W e l t 0 1 2 3 4 H 1 1 2 3 4 a 2 2 2 3 4 l 3 3 3 2 3 l 4 4 4 3 3 o 5 5 5 4 4 Operationen: Manuel Grandeit 36 / 40
Editierdistanz Beispieltabelle W e l t 0 1 2 3 4 H 1 1 2 3 4 a 2 2 2 3 4 l 3 3 3 2 3 l 4 4 4 3 3 o 5 5 5 4 4 Operationen: del Manuel Grandeit 36 / 40
Editierdistanz Beispieltabelle W e l t 0 1 2 3 4 H 1 1 2 3 4 a 2 2 2 3 4 l 3 3 3 2 3 l 4 4 4 3 3 o 5 5 5 4 4 Operationen: cha del Manuel Grandeit 36 / 40
Editierdistanz Beispieltabelle W e l t 0 1 2 3 4 H 1 1 2 3 4 a 2 2 2 3 4 l 3 3 3 2 3 l 4 4 4 3 3 o 5 5 5 4 4 Operationen: equ cha del Manuel Grandeit 36 / 40
Editierdistanz Beispieltabelle W e l t 0 1 2 3 4 H 1 1 2 3 4 a 2 2 2 3 4 l 3 3 3 2 3 l 4 4 4 3 3 o 5 5 5 4 4 Operationen: cha equ cha del Manuel Grandeit 36 / 40
Editierdistanz Beispieltabelle W e l t 0 1 2 3 4 H 1 1 2 3 4 a 2 2 2 3 4 l 3 3 3 2 3 l 4 4 4 3 3 o 5 5 5 4 4 Operationen: cha cha equ cha del Manuel Grandeit 36 / 40
Performancetuning Pruning (unmögliche Zustände verwerfen) Ein Zustand ist nutzlos, wenn sein Ergebnis immer 0 (Kombinatorik) oder unendlich (Optimierung) ist. Solche Zustände können gefahrlos gelöscht werden, da sie die Lösung des Problems nicht beeinflussen. Wie geht man dabei vor? Unmögliche Zustände verwerfen und gar nicht erst behandeln Parameter überprüfen: Gibt es Parameter, die für keinen Zustandswechsel relevant sind? Manuel Grandeit 37 / 40
Performancetuning Pruning (unmögliche Zustände verwerfen) Ein Zustand ist nutzlos, wenn sein Ergebnis immer 0 (Kombinatorik) oder unendlich (Optimierung) ist. Solche Zustände können gefahrlos gelöscht werden, da sie die Lösung des Problems nicht beeinflussen. Wie geht man dabei vor? Unmögliche Zustände verwerfen und gar nicht erst behandeln Parameter überprüfen: Gibt es Parameter, die für keinen Zustandswechsel relevant sind? Manuel Grandeit 37 / 40
Performancetuning Tabellengrösse reduzieren Oftmals wird nicht die gesamte Tabelle benötigt, sondern man kann die Größe extrem reduzieren Vorausberechnung (precalculate) Oft können DP-Lösungen von Vorausberechnungen profitieren Bei kombinatorischen Problemen kann man z.b. den Binomial-Koeffizient einiger Zahlen vorausberechnen Manchmal kann es hilfreich sein, z.b. die Partialsummen eines Arrays vorauszuberechnen Manuel Grandeit 38 / 40
Performancetuning Tabellengrösse reduzieren Oftmals wird nicht die gesamte Tabelle benötigt, sondern man kann die Größe extrem reduzieren Vorausberechnung (precalculate) Oft können DP-Lösungen von Vorausberechnungen profitieren Bei kombinatorischen Problemen kann man z.b. den Binomial-Koeffizient einiger Zahlen vorausberechnen Manchmal kann es hilfreich sein, z.b. die Partialsummen eines Arrays vorauszuberechnen Manuel Grandeit 38 / 40
Zusammenfassung Dynamische Programmierung DP löst Probleme durch Speichern von Zwischenergebnissen in Tabellen DP-Kandidaten: Optimierungs-, Maximierungs- oder Minimierungsprobleme Manuel Grandeit 39 / 40
Zusammenfassung Dynamische Programmierung DP löst Probleme durch Speichern von Zwischenergebnissen in Tabellen DP-Kandidaten: Optimierungs-, Maximierungs- oder Minimierungsprobleme Anwendung Manuel Grandeit 39 / 40
Zusammenfassung Dynamische Programmierung DP löst Probleme durch Speichern von Zwischenergebnissen in Tabellen DP-Kandidaten: Optimierungs-, Maximierungs- oder Minimierungsprobleme Anwendung 1. Rekursion erkennen und Gleichung aufstellen Manuel Grandeit 39 / 40
Zusammenfassung Dynamische Programmierung DP löst Probleme durch Speichern von Zwischenergebnissen in Tabellen DP-Kandidaten: Optimierungs-, Maximierungs- oder Minimierungsprobleme Anwendung 1. Rekursion erkennen und Gleichung aufstellen 2. Sinnvoll zwischen Top-Down- oder Bottom-Up-Variante wählen Manuel Grandeit 39 / 40
Zusammenfassung Dynamische Programmierung DP löst Probleme durch Speichern von Zwischenergebnissen in Tabellen DP-Kandidaten: Optimierungs-, Maximierungs- oder Minimierungsprobleme Anwendung 1. Rekursion erkennen und Gleichung aufstellen 2. Sinnvoll zwischen Top-Down- oder Bottom-Up-Variante wählen 3.??? Manuel Grandeit 39 / 40
Zusammenfassung Dynamische Programmierung DP löst Probleme durch Speichern von Zwischenergebnissen in Tabellen DP-Kandidaten: Optimierungs-, Maximierungs- oder Minimierungsprobleme Anwendung 1. Rekursion erkennen und Gleichung aufstellen 2. Sinnvoll zwischen Top-Down- oder Bottom-Up-Variante wählen 3.??? 4. PROFIT! (Effizienzgewinn!) Manuel Grandeit 39 / 40
Quellen Quellen T. Cormen, et al. Introduction to Algorithms (Third Edition) Rainer Müller, Hallo Welt Vortrag 2008 Tobias Werth, Hallo Welt Vortrag 2004 http: //www.topcoder.com/tc?module=static&d1=tutorials&d2=dynprog http://apps.topcoder.com/forums/?module=thread&threadid= 697925&start=0&mc=9 http://apps.topcoder.com/forums/?module=thread&threadid= 697369&start=0&mc=19 http://apps.topcoder.com/forums/?module=thread&threadid= 700080&start=0&mc=5 http://de.wikipedia.org/wiki/levenshtein-distanz Manuel Grandeit 40 / 40