18. Dynamisches Programmieren Dynamische Programmierung wie gierige Algorithmen eine Algorithmenmethode, um Optimierungsprobleme zu lösen. Wie Divide&Conquer berechnet Dynamische Programmierung Lösung eines Problems aus Lösungen zu Teilproblemen. Lösungen zu Teilproblemen werden nicht rekursiv gelöst. Lösungen zu Teilproblemen werden iterativ beginnend mit den Lösungen der kleinsten Teilprobleme berechnet (bottom-up). SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 1 Dynamisches Programmieren (2) Wird häufig angewandt, wenn rekursiver Ansatz Lösungen zu immer wieder denselben Teilproblemen lösen wird. Lernen drei Beispiele kennen: Längste gemeinsame Teilfolge, optimale Suchbäume, Rucksackproblem. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 2 Längste gemeinsame Teilfolge (1) Seien X = (x1,K, x m ) und Y = (y1,K, y n ) zwei Teilfolgen, wobei x i , y j ∈ A für ein endliches Alphabet A. Dann heisst Y Teilfolge von X, wenn es aufsteigend sortierte Indizes i1,K, in gibt mit x i j = y j für j = 1,K, n. Beispiel: Y=(B,C,A,C) ist Teilfolge von X=(A,B,A,C,A,B,C). Wähle (i1, i2 , i3 , i4 ) = (2,4,5,7 ). Sind X,Y,Z Folgen über A, so heisst Z gemeinsame Teilfolge von X und Y, wenn Z Teilfolge sowohl von X als auch von Y ist. Beispiel: Z=(B,C,A,C) ist gemeinsame Teilfolge von X=(A,B,A,C,A,B,C) und Y=(B,A,C,C,A,B,B,C). SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 3 Längste gemeinsame Teilfolge (2) Z heisst längste gemeinsame Teilfolge von X und Y, wenn Z gemeinsame Teilfolge von X und Y ist und es keine andere gemeinsame Teilfolge von X und Y gibt, die größere Länge als Z besitzt. Beispiel: Z=(B,C,A,C) ist nicht längste gemeinsame Teilfolge von X=(A,B,A,C,A,B,C) und Y=(B,A,C,C,A,B,B,C). Denn (B,A,C,A,C) ist eine längere gemeinsame Teilfolge von X und Y. Beim Problem Längste-Gemeinsame-Teilfolge (LCS) sind als Eingabe zwei Teilfolgen X = (x1,K, x m ) und Y = (y1,K, y n ) gegeben. Gesucht ist dann eine längste gemeinsame Teilfolge von X und Y. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 4 Beispiel längste gemeinsame Teilfolge SS 2006 Folge X A B C B D A Folge Y B D C A B A Folge X A B C B D A Folge Y B D C A B A B B Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 5 Struktur von LCS Definition 18.1: Sei X = (x1,K, x m ) eine beliebige Folge. Für i = 0,1,K,m ist der i-te Präfix von X definiert als Xi = (x1,K, x i ). Der i-te Präfix von i besteht also aus den ersten i Symbolen von X. Der 0-te Präfix ist die leere Folge. Satz 18.2: Seien X = (x1,K, x m ) und Y = (y1,K, y n ) beliebige Folgen und sei Z = (z1,K, zk ) eine längste gemeinsame Teilfolge von X und Y. Dann gilt 1. Ist x m = y n , dann ist zk = x m = y n und Zk −1 ist eine längste gemeinsame Teilfolge von Xm−1 und Yn−1. 2. Ist x m ≠ y n und zk ≠ x m , dann ist Z eine längste gemeinsame Teilfolge von Xm−1 und Y . 3. Ist x m ≠ y n und zk ≠ y n , dann ist Z eine längste gemeinsame Teilfolge von X und Yn−1. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 6 Rekursion für Länge von LCS Lemma 18.3: Sei c[i, j] die Länge einer längsten gemeinsamen Teilfolge des i-ten Präfix Xi von X und des j-ten Präfix Yj von Y. Dann gilt: 0, falls i = 0 oder j = 0 c[i, j] = c[i − 1, j − 1] + 1, falls i, j > 0 und x i = y j . max{c[i − 1, j], c[i, j − 1]}, falls i, j > 0 und x ≠ y i j Beobachtung: Rekursive Berechnung der c[i, j] würde zu Berechnung immer wieder derselben Werte führen. Dieses ist ineffizient. Berechnen daher die Werte c[i, j] iterativ, nämlich zeilenweise. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 7 Berechnung der Werte c[i,j] ↑ LCS − Length(X, Y ) 1 m ← length(X ) b[i, j] speichert Informationen zur 2 n ← length(Y ) späteren Berechnung einer 3 for i ← 0 to m längsten gemeinsamen Teilfolge. do c[i,0] ← 0 4 5 for j ← 0 to n 6 do c[0, j] ← 0 7 for i ← 1 to m 8 do for j ← 1 to n do if x i = y j 9 10 then c[i, j] ← c[i − 1, j − 1] + 1 11 b[i, j] ← " " else if c[i - 1, j] ≥ c[i, j − 1] 12 13 then c[i, j] ← c[i − 1, j] 14 b[i, j] ←" ↑" 15 else c[i, j] ← c[i, j − 1] 16 b[i, j] ←" ←" 17 return b, c SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 8 Bespieltabellen c[i,j] und b[i,j] j i 0 SS 2006 xi 1 A 2 B 3 C 4 B 5 D 6 A 7 B 0 1 2 3 4 5 6 yj B D C A B A 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 2 2 0 1 1 2 2 2 2 0 1 1 2 2 3 3 0 1 2 2 2 3 3 0 1 2 2 3 3 4 0 1 2 2 3 4 4 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 9 Berechnung von LCS aus c und b ↑ Print - LCS(b, X,i, j) 1 if i = 0 ∨ j = 0 2 then return 3 if b[i, j] =" " 4 then Print - LCS(b, X,i - 1, j - 1) 5 print x i 6 else if b[i, j] =" ↑" 7 then Print - LCS(b, X,i - 1, j) 8 else Print - LCS(b, X,i, j - 1) SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 10 Laufzeit von LCS-Length und LCS-Print Lemma 18.4: Algorithmus LCS-Length hat Laufzeit O(nm), wenn die Folgen X,Y Länge n und m haben. Lemma 18.5: Algorithmus LCS-Print hat Laufzeit O(n+m), wenn die Folgen X,Y Länge n und m haben. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 11 Berechnung von LCS aus c,b - Illustration j i 0 SS 2006 xi 1 A 2 B 3 C 4 B 5 D 6 A 7 B 0 1 2 3 4 5 6 yj B D C A B A 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 2 2 0 1 1 2 2 2 2 0 1 1 2 2 3 3 0 1 2 2 2 3 3 0 1 2 2 3 3 4 0 1 2 2 3 4 4 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 12 Dynamisches Programmieren - Struktur 1. Bestimme rekursive Struktur einer optimalen Lösung. 2. Entwerfe rekursive Methode zur Bestimmung des Werts einer optimalen Lösung. 3. Transformiere rekursiv Methode in eine iterative (bottom-up) Methode zur Bestimmung des Werts einer optimalen Lösung. 4. Bestimmen aus dem Wert einer optimalen Lösung und in 3. ebenfalls berechneten Zusatzinformationen eine optimale Lösung. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 13 Optimale binäre Suchbäume (1) Gegeben ist Folge K = (k1,K, k n ) mit k1 < k1 < L < k n , sowie Werte p1,K, pn ; q0 , q1,K, qn ≥ 0 mit n n ∑p + ∑ q i=1 i j=0 j = 1. Bedeutung der pi , q j : Nach Schlüssel k i wird mit Wahrscheinlichkeit pi gesucht. Nach einem nicht existierenden Schlüssel im offenen Intervall (k i , k i+1 ) wird mit Wahrscheinlichkeit qi gesucht. Dabei sei k 0 = −∞ und k n+1 = ∞ . Repräsentieren nicht existierende Schlüssel im Intervall (k i , k i+1 ) durch dummy Schlüssel di , i = 0,1,K, n. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 14 Optimale binäre Suchbäume (2) Gesucht ist binärer Suchbaum Ti , der erwarteten Aufwand pro Suche minimiert. Hat k i oder di Tiefe t im Suchbaum T, so ist der Aufwand für eine Suche nach k i bzw. di genau t+1. Sei depth T (k i ),depth T (di ) Tiefe von Schlüssel k i bzw. di in einem Suchbaum T. Dann ist erwarteter Aufwand einer Suche in T gegeben durch n n i=1 i=0 E[Suchaufwan d] = ∑ (depth T (k i ) + 1) ⋅ pi + ∑ (depth T (di ) + 1) ⋅ qi n n i=1 i=0 = 1 + ∑ depth T (k i ) ⋅ pi + ∑ depth T (di ) ⋅ qi SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 15 Nützliche Verallgemeinerung Verlangen nicht mehr, dass die Werte p1,K, pn ; q0 , q1,K, qn ≥ 0 eine Wahrscheinlichkeitsvern teilung bilden. Erlauben also n ∑p + ∑ q i=1 i j=0 ≠ 1. j Wollen aber weiterhin Suchbaum für die Schlüssel k 1,K, k n , so dass die Summe n n ∑ (depth (k ) + 1) ⋅ p +∑ (depth (d ) + 1) ⋅ q i=1 T i i i=0 T i i minimiert wird. Nennen diese Summe trotzdem erwarteten Suchaufwand. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 16 Erwarteter Suchaufwand – Beispiele (1) i 0 1 2 3 4 5 0,15 0,10 0,05 0,10 0,20 pi qi 0,05 0,10 0,05 0,05 0,05 0,10 k2 k1 d0 k4 k3 d1 d2 SS 2006 k5 d3 d4 d5 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 17 Erwarteter Suchaufwand – Beispiele (2) Knoten Tiefe Wahrscheinlichkeit Beitrag k1 k2 k3 k4 k5 d0 d1 d2 d3 d4 d5 1 0,15 0,30 0 0,10 0,10 2 0,05 0,15 1 0,10 0,20 2 0,20 0,60 2 0,05 0,15 2 0,10 0,30 3 0,05 0,20 3 0,05 0,20 3 0,05 0,20 3 0,10 0,40 Erwarteter Suchaufwand: 2,80 SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 18 Erwarteter Suchaufwand – Beispiele (3) i 0 1 2 3 4 5 0,15 0,10 0,05 0,10 0,20 pi qi 0,05 0,10 0,05 0,05 0,05 0,10 k2 Erwarteter Suchaufwand: 2,75 k1 d0 k5 k4 d1 d4 k3 d2 SS 2006 d5 d3 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 19 Struktur optimaler Lösung Satz 18.5: Sei T ein optimaler Suchbaum für die Schlüsselfolge K = (k1,K,k n ) mit Wahrscheinlichkeiten p1,K, pn ; q0 , q1,K, qn . Enthält T den Teilbaum T’ mit den Schlüsseln k i , K , k j , dann ist T’ in optimaler Suchbaum für die Schlüssel k i , K , k j . SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 20 Rekursive optimale Lösung (1) Sei e[i, j] der erwartete Suchaufwand für einen optimalen Suchbaum mit Schlüsseln k i ,K, k j . Ist k r Wurzel eines optimalen Suchbaums für die Schlüssel k i ,K, k j , so gilt e[i, j] = pr + e[i, r − 1] + w[i, r − 1] + e[r + 1, j] + w[r + 1, j]. Dabei ist j w [i, j] := ∑ pk + k =i SS 2006 j ∑q k =i−1 k . Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 21 Rekursive optimale Lösung (2) Es gilt : w[i, j] = pr + w[i, r − 1] + w[r + 1, j] w[i, j] = p j + q j + w[i, j − 1] . Damit dann e[i, j] = e[i, r − 1] + e[r + 1, j] + w[i, j] . Schließlich folgt qi−1 , e[i, j] = { e[i, r − 1] + e[r + 1, j] + w[i, j]}, min i≤ r ≤ j SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren falls j = i - 1 falls i ≤ j . 22 Berechnung der Werte e[i,j] Optimal − BST (p, q, n) root [i, j] speichert Informationen zur 1 for i ← 1 to n + 1 späteren Berechnung eines opt2 do e[i, i - 1] ← qi−1 malen Suchbaums 3 w[i, i - 1] ← qi−1 4 for l ← 1 to n 5 do for i ← 1 to n - l + 1 6 do j ← i + l − 1 7 e[i, j] ← ∞ 8 w[i, j] ← w[i, j − 1] + p j + q j 9 for r ← i to j 10 do t ← e[i, r − 1] + e[r + 1, j] + w[i, j] 11 if t < e[i, j] 12 then e[i, j] ← t 13 root[i, j] ← r 14 return e, root SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 23 Laufzeit von Optimal-BST Satz 18.7: Optimal-BST hat bei einer Folge von n Schlüsseln Laufzeit O (n3 ). SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 24 Beispiel für Optimal-BST i 0 1 2 3 4 5 0,15 0,10 0,05 0,10 0,20 pi qi 0,05 0,10 0,05 0,05 0,05 0,10 w e 5 1,75 3 1,25 2 0,90 1 0,45 0 2,75 4 j 0,05 0,30 0,05 0,50 0,45 1 5 0,05 0,55 2 4 0,90 0,70 3 3 0,30 0 6 0,05 0,10 1 1,00 4 j i 1,30 0,60 0,25 0,05 2 2,00 1,20 0,70 0,40 0,10 5 1 0,25 0,10 3 0,60 0,30 0,15 0,05 i 0,80 0,50 0,35 2 0,50 0,20 0,05 4 5 0,35 0,05 6 0,10 root 5 2 3 2 2 1 1 1 SS 2006 2 4 j 1 4 2 2 2 2 3 5 4 3 i 4 5 4 5 5 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 25 Dynamisches Programmieren - Struktur 1. Bestimme rekursive Struktur einer optimalen Lösung. 2. Entwerfe rekursive Methode zur Bestimmung des Werts einer optimalen Lösung. 3. Transformiere rekursiv Methode in eine iterative (bottom-up) Methode zur Bestimmung des Werts einer optimalen Lösung. 4. Bestimmen aus dem Wert einer optimalen Lösung und in 3. ebenfalls berechneten Zusatzinformationen eine optimale Lösung. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 26 0/1-Rucksackproblem und dynamisches Programmieren Gegeben sind n Gegenstände g1,K, gn mit Werten v1,K, v n und Gewichten w 1,K, w n . Außerdem ist eine Gewichtsschranke G gegeben. Zulässige Lösungen sind Zahlen a1,K, an ∈ {0,1} mit n ∑a w i=1 i i ≤ G. D.h. jeder Gegenstand muss entweder vollständig oder überhaupt nicht genommen werden. Gesucht ist eine zulässige Lösung mit möglichst n ∑ ai v i . großem Gesamtwert i=1 SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 27 Struktur einer optimalen Lösung Definieren für i=1,…,n und x ∈ Z den Wert g [i , x ] als das minimale Gesamtgewicht einer Teilmenge der ersten i Gegenstände mit Gesamtwert mindestens x. Lemma 18.8: Der optimale Wert opt für eine Instanz des 0/1-Rucksackproblems ist gegeben durch max{x : g [n, x ] ≤ G} SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 28 Rekursive optimale Lösung Lemma 18.9: Für alle i=0,…,n und alle ganzzahligen x gilt: 0, g [i , x ] := ∞, min{g [i − 1, x ],w + g [i − 1, x − v ]}, i i SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren falls x ≤ 0 falls x > 0, i = 0 falls i , x > 0 29 Berechnung der Werte g[i,v] bis zum Optimum Optimal − Knapsack (w ,v ,G ) 1 x←0 2 for i ← 0 to n 3 do g[i, x ] ← 0 4 while g[n, x ] ≤ G 5 do x ← x + 1 6 g[0, x ] ← ∞ 7 for i ← 1 to n 8 9 10 do g[i, x ] ← g [i − 1, x ] if w i + g [i − 1, max{ x - v i ,0} ] < g[i, x ] then g[i, x ] ← w i + g [i − 1, max{ x - v i ,0} ] 11 return x - 1 SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 30 Beispiel für Optimal-Knapsack vi 1 2 1 3 i 1 2 3 4 x 0 1 2 3 4 5 6 0 0 ∞ ∞ ∞ ∞ ∞ ∞ 1 0 2 ∞ ∞ ∞ ∞ ∞ 2 0 2 3 5 ∞ ∞ ∞ 3 0 1 3 4 6 ∞ ∞ 4 0 1 1 1 2 4 5 i SS 2006 wi 2 3 1 1 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 31 Laufzeit von Optimal-Knapsack Lemma 18.9: Bei n Gegenständen hat Optimal-Knapsack Laufzeit O (n ⋅ opt ) , wobei opt der Wert einer optimalen Lösung ist. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 32 Dynamisches Programmieren - Struktur 1. Bestimme rekursive Struktur einer optimalen Lösung. 2. Entwerfe rekursive Methode zur Bestimmung des Werts einer optimalen Lösung. 3. Transformiere rekursiv Methode in eine iterative (bottom-up) Methode zur Bestimmung des Werts einer optimalen Lösung. 4. Bestimmen aus dem Wert einer optimalen Lösung und in 3. ebenfalls berechneten Zusatzinformationen eine optimale Lösung. SS 2006 Datenstrukturen und Algorithmen 18. Dynamisches Programmieren 33