ACM ICPC Praktikum Kapitel 11 Dynamische Programmierung bersicht
ACM ICPC Praktikum Kapitel 11: Dynamische Programmierung
Übersicht • • • Definition Fibonacci Zahlen Binomialkoeffizienten Edit Distanz Transitive Hülle Fahrstuhloptimierung
Dynamische Programmierung • Entwickelt von R. Bellman in 50 er Jahren • Methode zur Lösung von Problemen mit überlappenden Teilproblemen dasselbe Teilproblem: berechne nur einmal
Fibonacci Zahlen • F(0)=F(1)=1 • F(n) = F(n-1)+F(n-2) • Getrennte rekursive Aufrufe: Aufwand n = 1, 682…n • Berechnung von 1 bis n durch Merken der zwei letzten Fibonacci Zahlen: Aufwand O(n)
Binomialkoeffizient • C(n, 0) = C(n, n) = 1 • C(n, k) = C(n-1, k-1) + C(n-1, k) • Getrennte rekursive Aufrufe: Aufwand O(2 n) • Berechnung über Tabelle von C(n‘, k‘)Werten, angefangen bei n‘=k‘=0: Aufwand O(n ¢ k)
Edit Distanz • Gegeben: zwei Zeichenketten s, t • Gesucht: Edit Distanz zwischen s und t, d. h. minimale Anzahl an Substitutionen, Einfügungen und Löschungen von Zeichen, um s in t zu überführen • Durchlauf aller Möglichkeiten: zu teuer!
Edit Distanz Brute force: 1. #define MATCH 0 2. 3. 4. 5. 6. int string_compare(char *s, char *t, int i, int j) { int k; /* counter */ int opt[3]; /* cost of the three options */ int lowest_cost; /* lowest cost */ 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. } #define INSERT 1 #define DELETE 2 if (i == 0) return(j * indel(' ')); if (j == 0) return(i * indel(' ')); opt[MATCH] = string_compare(s, t, i-1, j-1) + match(s[i], t[j]); opt[INSERT] = string_compare(s, t, i, j-1) + indel(t[j]); opt[DELETE] = string_compare(s, t, i-1, j) + indel(s[i]); lowest_cost = opt[MATCH]; for (k=INSERT; k<=DELETE; k++) if (opt[k] < lowest_cost) lowest_cost = opt[k]; m[i][j]. cost = lowest_cost; /* REMOVE FROM PRINTED VERSION */ return( lowest_cost );
Edit Distanz Subroutinen: 1. int match(char c, char d) 2. { 3. if (c==d) return(0); 4. else return(1); 5. } 6. int indel(char c) 7. { 8. return(1); 9. }
Edit Distanz Besser: statt getrennter rekursiver Aufrufe, berechne Tabelle • T[i, j] = min{T[i-1, j-1]+match(s[i], t[j]), T[i, j-1]+indel(t[j]), T[i-1, j]+indel(s[i])} • Aufwand: O(|s| ¢ |t|)
Transitive Hülle • Gegeben: Graph G=(V, E) • Gesucht: Boolesche Matrix T=(tij), in der tij=1 , es ex. Pfad von i nach j in G • Brute force: Breitensuche für jedes (i, j) Aufwand: O(n 2 ¢ m), n=|V|, m=|E| • Besser: rekursiver Ansatz
Transitive Hülle Rechenregeln: • t(0)i, j=1 , {i, j} 2 E • t(k)i, j=t(k-1)i, j Ç (t(k-1)i, k Æ t(k-1)k, j) • ti, j = t(n)i, j Berechnung der Tabelle: Aufwand O(n 3)
Fahrstuhl Optimierung • Gegeben: Ein Fahrstuhl mit n Personen, jede Person hat Zielstockwerk, Anzahl Halte k • Gesucht: Stockwerke für k Halte, so dass Anzahl der Stockwerke, die Personen laufen müssen, minimiert wird. Gleiche Kosten: wähle kleinstmögliches Stockwerk.
Fahrstuhl Optimierung • m[i, j]: minimale Kosten für genau j Halte mit höchstem Halt in Stockwerk i • m[i, 1] = mincost(0, i) + mincost(i, 1) • m[i, j] = mink<i { m[k, j-1] – mincost(k, 1) + mincost(k, i) + mincost(i, 1)} • mincost(a, b): minimale Kosten für Personen mit Zielstockwerken zwischen a und b, falls Halte bei a und b-1.
Rucksack Problem • Gegeben: n Gegenstände mit Gewicht w 1, . . . , wn und Wert v 1, . . . , vn, Kapazität W • Gesucht: Menge M an Gegenständen mit maximalem Wert, so dass i 2 M wi <= W • Ansatz: V[i, j] = maximaler Wert für Gegenstände 1 bis i bei Kapazität j
Rucksack Problem Rechenregel: • V[0, j] = 0 • V[i, j] = max{ V[i-1, j], vi + V[i-1, j-wi]} falls j-wi >= 0 • V[i, j] = V[i-1, j] falls j-wi < 0 Laufzeit: O(n ¢ W)
- Slides: 15