Lecture 8: Dynamic Programming Shang-Hua Teng
Longest Common Subsequence Biologists need to measure how similar strands of DNA are to determine how closely related an organism is to another. They do this by considering DNA as strings of letters A,C,G,T and then comparing similarities in the strings. Formally they look at common subsequences in the strings. Example X = AGTCAACGTT, Y=GTTCGACTGTG Both S = AGTG and S’=GTCACGT are subsequences How to do find these efficiently?
Brute Force if |X| = m, |Y| = n, then there are 2 m subsequences of x; we must compare each with Y (n comparisons) So the running time of the brute-force algorithm is O(n 2 m ) Notice that the LCS problem has optimal substructure: solutions of subproblems are parts of the final solution. Subproblems: “find LCS of pairs of prefixes of X and Y”
Some observations
Setup First we’ll find the length of LCS, along the way we will leave “clues” on finding subsequence. Define X i, Y j to be the prefixes of X and Y of length i and j respectively. Define c[i,j] to be the length of LCS of X i and Y j Then the length of LCS of X and Y will be c[m,n]
The recurrence The subproblems overlap, to find LCS we need to find LCS of c[i, j-1] and of c[i-1, j]
LCS Algorithm First we’ll find the length of LCS. Later we’ll modify the algorithm to find LCS itself. Recall we want to let X i, Y j to be the prefixes of X and Y of length i and j respectively And that Define c[i,j] to be the length of LCS of X i and Y j Then the length of LCS of X and Y will be c[m,n]
LCS recursive solution We start with i = j = 0 (empty substrings of x and y) Since X 0 and Y 0 are empty strings, their LCS is always empty (i.e. c[0,0] = 0) LCS of empty string and any other string is empty, so for every i and j: c[0, j] = c[i,0] = 0
LCS recursive solution When we calculate c[i,j], we consider two cases: First case: x[i]=y[j]: one more symbol in strings X and Y matches, so the length of LCS X i and Y j equals to the length of LCS of smaller strings X i-1 and Y i-1, plus 1
LCS recursive solution Second case: x[i] != y[j] As symbols don’t match, our solution is not improved, and the length of LCS(X i, Y j ) is the same as before (i.e. maximum of LCS(X i, Y j-1 ) and LCS(X i-1,Y j )
LCS Example We’ll see how LCS algorithm works on the following example: X = ABCB Y = BDCAB LCS(X, Y) = BCB X = A B C B Y = B D C A B What is the Longest Common Subsequence of X and Y?
LCS Example (0) j i Xi A B C B YjBBACD X = ABCB; m = |X| = 4 Y = BDCAB; n = |Y| = 5 Allocate array c[6,5]
LCS Example (1) j i Xi A B C B YjBBACD for i = 1 to m c[i,0] = 0
LCS Example (2) j i Xi A B C B YjBBACD for j = 0 to n c[0,j] = 0
LCS Example (3) j i Xi A B C B YjBBACD case i=1 and j=1 A != B but, c[0,1]>=c[1,0] so c[1,1] = c[0,1], and b[1,1] =
LCS Example (4) j i Xi A B C B YjBBACD case i=1 and j=2 A != D but, c[0,2]>=c[1,1] so c[1,2] = c[0,2], and b[1,2] = 0
LCS Example (5) j i Xi A B C B YjBBACD case i=1 and j=3 A != C but, c[0,3]>=c[1,2] so c[1,3] = c[0,3], and b[1,3] = 00
LCS Example (6) j i Xi A B C B YjBBACD case i=1 and j=4 A = A so c[1,4] = c[0,2]+1, and b[1,4] =
LCS Example (7) j i Xi A B C B YjBBACD case i=1 and j=5 A != B this time c[0,5]<c[1,4] so c[1,5] = c[1, 4], and b[1,5] =
LCS Example (8) j i Xi A B C B YjBBACD case i=2 and j=1 B = B so c[2, 1] = c[1, 0]+1, and b[2, 1] =
LCS Example (9) j i Xi A B C B YjBBACD case i=2 and j=2 B != D and c[1, 2] < c[2, 1] so c[2, 2] = c[2, 1] and b[2, 2] = 1
LCS Example (10) j i Xi A B C B YjBBACD case i=2 and j=3 B != D and c[1, 3] < c[2, 2] so c[2, 3] = c[2, 2] and b[2, 3] = 11
LCS Example (11) j i Xi A B C B YjBBACD case i=2 and j=4 B != A and c[1, 4] = c[2, 3] so c[2, 4] = c[1, 4] and b[2, 2] = 111
LCS Example (12) j i Xi A B C B YjBBACD case i=2 and j=5 B = B so c[2, 5] = c[1, 4]+1 and b[2, 5] = 1112
LCS Example (13) j i Xi A B C B YjBBACD case i=3 and j=1 C != B and c[2, 1] > c[3,0] so c[3, 1] = c[2, 1] and b[3, 1] =
LCS Example (14) j i Xi A B C B YjBBACD case i=3 and j= 2 C != D and c[2, 2] = c[3, 1] so c[3, 2] = c[2, 2] and b[3, 2] =
LCS Example (15) j i Xi A B C B YjBBACD case i=3 and j= 3 C = C so c[3, 3] = c[2, 2]+1 and b[3, 3] =
LCS Example (16) j i Xi A B C B YjBBACD case i=3 and j= 4 C != A c[2, 4] < c[3, 3] so c[3, 4] = c[3, 3] and b[3, 3] =
LCS Example (17) j i Xi A B C B YjBBACD case i=3 and j= 5 C != B c[2, 5] = c[3, 4] so c[3, 5] = c[2, 5] and b[3, 5] =
LCS Example (18) j i Xi A B C B YjBBACD case i=4 and j=1 B = B so c[4, 1] = c[3, 0]+1 and b[4, 1] =
LCS Example (19) j i Xi A B C B YjBBACD case i=4 and j=2 B != D c[3, 2] = c[4, 1] so c[4, 2] = c[3, 2] and b[4, 2] =
LCS Example (20) j i Xi A B C B YjBBACD case i=4 and j= 3 B != C c[3, 3] > c[4, 2] so c[4, 3] = c[3, 3] and b[4, 3] =
LCS Example (21) j i Xi A B C B YjBBACD case i=4 and j=4 B != A c[3, 4] = c[4, 3] so c[4, 4] = c[3, 4] and b[3, 5] =
LCS Example (22) j i Xi A B C B YjBBACD case i=4 and j=5 B= B so c[4, 5] = c[3, 4]+1 and b[4, 5] =
LCS Algorithm Running Time LCS algorithm calculates the values of each entry of the array c[m,n] So the running time is clearly O(mn) as each entry is done in 3 steps. Now how to get at the solution? We use the arrows we created to guide us. We simply follow arrows back to base case 0
Finding LCS j i Xi A B C YjBBACD B
Finding LCS (2) j i Xi A B C YjBBACD B BCB LCS (reversed order): LCS (straight order):B C B (this string turned out to be a palindrome)
LCS-Length(X, Y) m = length(X), n = length(Y) for i = 1 to m do c[i, 0] = 0 for j = 0 to n do c[0, j] = 0 for i = 1 to m do for j = 1 to n do if ( x i = = y j ) then c[i, j] = c[i - 1, j - 1] + 1 else if c[i - 1, j]>=c[i, j - 1] then c[i, j] = c[i - 1, j] else c[i, j] = c[i, j - 1] return c and b
Two Common Issues Optimal substructure Overlapping subproblems
Optimal Substructure A problem exhibits optimal substructure if an optimal solution contains optimal solutions to its sub-problems. Build an optimal solution from optimal solutions to sub- problems Example - Matrix-chain multiplication: An optimal parenthesization of A i A i+1 …A j that splits the product between A k and A k+1 contains within it optimal solutions to the problem of parenthesizing A i A i+1 …A k and A k+1 A k+2 …A j.
Illustration of Optimal Substructure A1A2A3A4A5A6A7A8A9 A1A2A3A4A5A6A7A8A9 Suppose ((A 7 A 8 )A 9 )is optimal((A 1 A 2 )(A 3 ((A 4 A 5 )A 6 ))) Minimal Cost_A Cost_A p 0 p 6 p 9 (A 3 ((A 4 A 5 )A 6 ))(A1A2)(A1A2)Thenmust be optimal for A 1 A 2 A 3 A 4 A 5 A 6 Otherwise, if((A 4 A 5 )A 6 )(A 1 (A 2 A 3 ))is optimal for A 1 A 2 A 3 A 4 A 5 A 6 Then((A 1 (A 2 A 3 )) ((A 4 A 5 )A 6 )) ((A 7 A 8 )A 9 ) will be better than ((A 7 A 8 )A 9 )((A 1 A 2 )(A 3 ((A 4 A 5 )A 6 )))
Recognizing subproblems Show a solution to the problem consists of making a choice. Making the choice leaves one or more sub-problems to be solved. Suppose that for a given problem, the choice that leads to an optimal solution is available. Notice something in common with a greedy solution, more on this later.
Dynamic vs. Greedy Dynamic programming uses optimal substructure in a bottom-up fashion –First find optimal solutions to subproblems and, having solved the subproblems, we find an optimal solution to the problem Greedy algorithms use optimal substructure in a top-down fashion –First make a choice – the choice that looks best at the time – and then solving a resulting subproblem
Overlapping Subproblems Divide-and-Conquer is suitable when generating brand- new problems at each step of the recursion. Dynamic-programming algorithms take advantage of overlapping subproblems by solving each subproblem once and then storing the solution in a table where it can be looked up when needed, using constant time per lookup
Assembly Line
Problem Definition e 1, e 2 : time to enter assembly lines 1 and 2 x 1, x 2 : time to exit assembly lines 1 and 2 t i,j : time to transfer from assembly line 1 2 or 2 1 a i,j : processing time in each station Time between adjacent stations are 0 2 n possible solutions
Optimal Substructure We want the fastest way through the factory (from the starting point) –What is the fastest possible way through S 1,1 (similar for S 2,1 ) Only one way take time e 1 –The fastest possible way through S 1,j for j=2, 3,..., n (similar for S 2,j ) S 1,j-1 S 1,j : T 1,j-1 + a 1,j –If the fastest way through S 1,j is through S 1,j-1 must have taken a fastest way through S 1,j-1 Similar for S 2, i-1 An optimal solution contains an optimal solution to sub-problems optimal substructure.
S1,1 = 9 S2,1 = 12
S1,2 = S1,1 + 9 = = 18 S2, = = 23 S2,2 = S1, = = 16 S2,1 + 5 = = 17
S1,2 18 S2,2 16 S1,3 = S1,2 + 3 = = 21 S2, = = 20 S2,3 = S1, = = 25 S2,2 + 6 = = 22
Formal Setup f i [j]: fastest possible time to go from starting point through station S i,j The fastest time to go all the way through the factory: f* = min(f 1 [n] + x 1, f 2 [n] + x 2 ) Boundary conditions, –f 1 [1] = e 1 + a 1,1 – f 2 [1] = e 2 + a 2,1
Setup Contd.. The fastest time to go through S i,j (for j=2,..., n) f 1 [j] = min(f 1 [j-1] + a 1,j, f 2 [j-1] + t 2,j-1 + a 2,j ) f 2 [j] = min(f 2 [j-1] + a 2,j, f 1 [j-1] + t 1,j-1 + a 2,j ) l i [j]: the line number whose station j-1 is used in a fastest way through S i,j (i=1, 2, and j=2, 3,..., n) –l* : the line whose station n is used in a fastest way through the entire factory