Créer une présentation
Télécharger la présentation

Télécharger la présentation
## Dynamic Programming

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -

**Dynamic Programming**• Not a specific algorithm, but a technique (like divide-and-conquer) • Developed back in the day when “programming” meant “tabular method” (like linear programming). Doesn’t really refer to computer programming. • Used for optimization problems: • Find a solution with the optimal value. • Minimization or maximization. (We’ll see both.) • Four-step method • Characterize the structure of an optimal solution. • Recursively define the value of an optimal solution. • Compute the value of an optimal solution in a bottom-up fashion. • Construct an optimal solution from computed information.**Assembly-line Scheduling**S1,1 S1,2 S1,3 S1,4 S1,5 7 9 3 4 8 Automobile factory with two assembly lines. • Each line has n stations: S1,1, …, S1,n and S2,1, …, S2,n. • Corresponding stations S1,j and S2,j perform the same function but can take different amount of time a1,jand a2, j. • Entry times e1 and e2. • Exit times x1 and x2. • After going through a station, can either • Stay on same line; no cost, or • Transfer to other line; cost after Si,j is ti,j. (j = 1, …, n – 1. No ti,n, because the assembly line is done after Si,n.) a1,1 a1,2 a1,3 a1,4 a1,5 2 2 3 1 3 3 e1 t1,1 t1,2 t1,3 t1,4 x1 enter exit e2 2 t2,1 1 t2,2 2 t2,3 t2,4 x2 2 4 6 a2,1 a2,2 a2,3 a2,4 a2,5 8 5 6 4 5 S2,1 S2,2 S2,3 S2,4 S2,5**Assembly-line Scheduling**S1,1 S1,2 S1,3 S1,4 S1,5 7 9 3 4 8 Problem: Given all these costs (time = cost), what stations should be chosen from line 1 and from line 2 for fastest way through factory? Try all possibilities? • Each candidate is fully specified by which stations from line 1 are included. Looking for a subset of line 1 stations. • Line 1 has n stations. • 2n subsets. • Infeasible when n is large. a1,1 a1,2 a1,3 a1,4 a1,5 2 2 3 1 3 3 e1 t1,1 t1,2 t1,3 t1,4 x1 enter exit e2 2 t2,1 1 t2,2 2 t2,3 t2,4 x2 2 4 6 a2,1 a2,2 a2,3 a2,4 a2,5 8 5 6 4 5 S2,1 S2,2 S2,3 S2,4 S2,5**Structure of an Optimal Solution**Think about fastest way from entry through S1,j. • If j = 1, easy: just determine how long it takes to get through S1,1. • If j 2, have two choices of how to get to S1,j: • Through S1,j–1, then directly to S1,j. • Through S2,j–1, then transfer over to S1,j. Suppose fastest way is through S1,j–1. • Key Observation: We must have taken a fastest way from entry through S1, j–1 in this solution. If there were a faster way through S1,j–1, we would use it instead to come up with a faster way through S1,j. Now suppose a fastest way is through S2,j–1. Again, we must have taken a fastest way through S2, j–1. Otherwise use some faster way through S2,j–1 to give a faster way through S1, j**Structure of an Optimal Solution**Generally: An optimal solution to a problem (fastest way through S1,j) contains within it an optimal solution to subproblems (fastest way through S1,j–1 or S2,j–1 ). This is optimal substructure. Use optimal substructure to construct optimal solution to problem from optimal solutions to subproblems. Fastest way through S1,j is either • fastest way through S1,j–1 then directly through S1,j, or • fastest way through S2,j–1,transfer from line 2 to line 1,then through S1, j. Fastest way through S2,j is symmetric. Therefore, to solve problems of finding a fastest way through S1,j and S2,j, solve subproblems of finding a fastest way through S1,j–1, S2,j–1.**Recursive Solution**Let fi[j] = fastest time to get through Si,j, i = 1, 2 and j = 1, …, n. Goal: fastest time to get all the way through = f*. f* = min (f1[n] + x1, f2[n] + x2) f1[1] = e1 + a1,1 f2[1] = e2 + a2,1 For j = 2, …, n: f1[j] = min(f1[j – 1] + a1,j, f2[j – 1] + t2,j – 1 + a1,j) f2[j] = min(f2[j – 1] + a2,j, f1[j – 1] + t1,j – 1 + a2,j)**Recursive Solution**fi[j] gives the value of an optimal solution. What if we want to construct an optimal solution? • li[j] = line # (1 or 2) whose station j – 1 is used in fastest way through Si,j. • In other words Sli[j],j – 1 precedes Si,j. • Defined for i = 1, 2 and j = 2, …, n. • l* = line # whose station n is used.**Recursive Solution**S1,1 S1,2 S1,3 S1,4 S1,5 For example: Go through optimal way given by l values. (Thick path in the figure.) 7 9 3 4 8 a1,1 a1,2 a1,3 a1,4 a1,5 2 2 3 1 3 3 e1 t1,1 t1,2 t1,3 t1,4 x1 enter e2 2 t2,1 1 t2,2 2 t2,3 t2,4 x2 2 4 6 a2,1 a2,2 a2,3 a2,4 a2,5 8 5 6 4 5 S2,1 S2,2 S2,3 S2,4 S2,5**Compute an Optimal Solution**Could just write a recursive algorithm based on the previous recurrences. • Let ri(j) = # of references made to fi[j]. • r1(n) = r2(n) = 1. • r1(j) = r2(j) = r1(j + 1) + r2(j + 1) for j = 1, …, n – 1. Claim ri(j) = 2n – j. Proof Induction on j, down from n. Basis:j = n. 2n – j = 20 = 1 = ri(n). Inductive step: Assume ri(j + 1) = 2n – (j + 1). Then ri(j) = r1(j + 1) + r2(j + 1) = 2n – (j + 1) + 2n – (j + 1) = 2n – (j + 1) + 1 = 2n – j. Therefore, f1[1] alone is referenced 2n – 1 times! So top down isn’t a good way to compute fi[j]. Observation:fi[j] depends only on f1[j – 1] and f2[j – 1] (for j 2). So compute in order of increasingj.**Computing the Fastest Times**FASTEST-WAY (a, t, e, x, n) f1[1] e1 + a1,1 f2[1] e2 + a2,1 forj 2 ton do iff1[j – 1] + a1,j f2[j – 1] + t2,j – 1 + a1,j thenf1[j] f1[j – 1] + a1,j l1[j] 1 elsef1[j] f2[j – 1] + t2,j – 1 + a1,j l1[j] 2 iff2[j – 1] + a2,j f1[j – 1] + t1,j – 1 + a2,j thenf2[j] f2[j – 1] + a2,j l2[j] 2 elsef2[j] f1[j – 1] + t1,j – 1 + a2,j l2[j] 1 iff1[n] + x1 f2[n] + x2 thenf* = f1[n] + x1 l* = 1 elsef* = f2[n] + x2 l* = 2**Constructing the Fastest Way Through the Factory**PRINT-STATIONS (l, n) i l* print “line ” i “, station ” n forj ndownto 2 doi li[j] print “line ” i “, station ” j – 1 Time = (n)**Longest Common Subsequence**Problem: Given 2 sequences, X = <x1, …, xm> and Y = <y1, …, yn>. Find a subsequence common to both whose length is longest. A subsequence doesn’t have to be consecutive, but it has to be in order. Examples: [The examples are of different types of trees.] s p r i n g t i m e h o r s e b a c k p i o n e e r s n o w f l a k e m a e l s t r o m h e r o i c a l l y b e c a l m s c h o l a r l y Brute-force algorithm: For every subsequence of X, check whether it’s a subsequence of Y. Time: (n2m) • 2m subsequences of X to check. • Each subsequences takes (n) time to check: scan Y for first letter, from there scan for second, and so on.**Optimal Substructure**Notation: Xi = prefix <x1, …, xi> Yi = prefix <y1, …, yi> Theorem Let Z = <z1, …, zk> any LCS (longest common subsequence) of X and Y. • If xm = yn, then zk = xm = yn and Zk – 1 is an LCS of Xm – 1 and Yn – 1. • If xm yn, then zk xm Z is an LCS of Xm – 1 and Y. • If xm yn, then zk yn Z is an LCS of X and Yn – 1.**Optimal Substructure**Proof • First Show that zk = xm = yn. Suppose not. Then make a subsequence Z’ = <z1, …, zk, xm>. It’s a common subsequence of X and Y and has length k + 1 Z’ is a longer common subsequence than Z contradicts Z being an LCS. Now show Zk – 1 is an LCS of Xm – 1 and Yn – 1. Clearly, it’s a common subsequence. Now suppose there exists a common subsequence W of Xm – 1 and Yn – 1 that’s longer than Zk – 1 length of W k. Make subsequence W’ by appending xm to W. W’ is common subsequence of X and Y, has length k + 1 contradicts Z being an LCS. • If zk xm, then Z is a common subsequence of Xm – 1 and Y. Suppose there exists a subsequence W of Xm – 1 and Y with length k. Then W is a common subsequence of X and Y contradicts Z being an LCS • Symmetric to 2. Therefore, an LCS of two sequences contains as a prefix an LCS of prefixes of the sequences.**Recursive Formulation**Define c[i, j] = length of LCS of Xi and Yj. We want c[m, n]. 0 if i = 0 or j = 0, c[i, j] = c[i – 1, j – 1] + 1 if i, j 0 and xi = yj, max (c[i – 1, j], c[i, j – 1]) if i, j > 0 and xi yj. Again, we could write a recursive algorithm based on this formulation. Try with “bozo”, “bat”. • Lots of repeated subproblems. • Instead of recomputing, store in a table. 4,3 3,3 4,2 2,3 3,2 3,2 4,1 1,3 2,2 2,2 3,1 2,2 3,1 3,1 4,0 0,3 1,2 1,2 2,1 1,2 2,1 2,1 3,0 1,2 2,1 2,1 3,0 2,1 3,0**Computing the Length of an LCS**LCS-LENGTH (X, Y, m, n) fori 1 to m doc[i, 0] 0 forj 1 to n doc[0, j] 0 fori 1 to m do forj 1 to n do ifxi = yj thenc[i, j] c[i – 1, j – 1] + 1 b[i, j] “ ” else ifc[i – 1, j] c[i, j – 1] thenc[i, j] c[i – 1, j] b[i, j] “” elsec[i, j] c[i, j – 1] b[i, j] “” returnc and b**Constructing an LCS**PRINT-LCS (b, X, i, j) ifi = 0 or j = 0 then return ifb[i, j] = “ ” then PRINT-LCS (b, X, i – 1, j – 1) print xi elseifb[i, j] = “” then PRINT-LCS (b, X, i – 1, j) else PRINT-LCS (b, X, i, j – 1) • Initial call is PRINT-LCS (b, X, m, n) • b[i, j] points to table entry whose subproblem we used in solving LCS of Xi and Yj. • When b[i, j] = , we have extended LCS by one character. So longest common subsequence = entries with in them.**Demonstration**Time: (mn)