Presentation is loading. Please wait.

Presentation is loading. Please wait.

242-535 ADA: 7. Dynamic Prog.1 Objective o introduce DP, its two hallmarks, and two major programming techniques o look at two examples: the fibonacci.

Similar presentations


Presentation on theme: "242-535 ADA: 7. Dynamic Prog.1 Objective o introduce DP, its two hallmarks, and two major programming techniques o look at two examples: the fibonacci."— Presentation transcript:

1 242-535 ADA: 7. Dynamic Prog.1 Objective o introduce DP, its two hallmarks, and two major programming techniques o look at two examples: the fibonacci series and LCS Algorithm Design and Analysis (ADA) 242-535, Semester 1 2014-2015 7. Dynamic Programming

2 Overview 7.Is the c[] Algorithm Optimal? 8.Repeated Subproblems? 9.LCS() as a DP Problem 10.Bottom-up Examples 11.Finding the LCS 12.Space and Bottom-up 1.Dynamic Programming (DP) 2.Fibonacci Series 3.Features of DP Code 4.Longest Common Subsequence (LCS) 5.Towards a Better LCS Algorithm 6.Recursive Definition of c[]

3 242-535 ADA: 7. Dynamic Prog.3 The "programming" in DP predates computing, and means "using tables to store information". DP is a recursive programming technique: o the problem is recursively described in terms of smilar but smaller subproblems 1. Dynamic Programming (DP)

4 242-535 ADA: 7. Dynamic Prog.4 Optimal solution from optimal parts o An optimal (best) solution to the problem is a composition of optimal (best) subproblem solutions Repeated (overlapping) sub-problems o the problem contains the same subproblems, repeated many times What makes DP Different? Hallmark #1 Hallmark #2

5 242-535 ADA: 7. Dynamic Prog.5 Unix diff for comparing two files Smith-Waterman for genetic sequence alignment o determines similar regions between two protein sequences (strings) Bellman-Ford for shortest path routing in networks Cocke-Kasami-Younger for parsing context free grammars Some Famous DP Examples

6 242-535 ADA: 7. Dynamic Prog.6 Series defined by a 0 = 1 a 1 = 1 a n = a n-1 + a n-2 Recursive algorithm: Running Time? O(2 n ) 2. Fibonacci Series 1, 1, 2, 3, 5, 8, 13, 21, 34, … fib(n) 1. if n == 0 or n == 1, then 2. return 1 3. else 4. a = fib(n-1) 5. b = fib(n-2) 6. return a+b fib(n) 1. if n == 0 or n == 1, then 2. return 1 3. else 4. a = fib(n-1) 5. b = fib(n-2) 6. return a+b

7 242-535 ADA: 7. Dynamic Prog.7 Fibonacci can be viewed as a DP problem: o the optimal solution (fib(n)) is a combination of optimal sub-solutions (fib(n-1) and fib(n-2)) o There are a lot of repeated subproblems look at the execution graph (next slide) 2 n subproblems, but only n are different Computing Fibonacci Faster 7

8 242-535 ADA: 7. Dynamic Prog.8 Execution of fib(5): lots of repeated work, that only gets worse for bigger n lots of repeated work, that only gets worse for bigger n

9 242-535 ADA: 7. Dynamic Prog.9 Memoization : values returned by recursive calls are stored in a table (array) so they do not need to be recalculated o this can save enormous amount of running time Bottom-up algorithms : simple solutions are computed first (e.g. fib(0), fib(1),...), leading to larger solutions (e.g. fib(23), fib(24),...) o this means that the solutions are added to the table in a fixed order which may allow them to be calculated quicker and the table to be less large 3. Features of DP Code

10 242-535 ADA: 7. Dynamic Prog.10 Running time is linear = O(n) Requires extra space for the m[] table = O(n) Memoization fib() Algorithm fib(n) 1.if (m[n] == 0) then 2. m[n] = fib(n − 1) + fib(n − 2) 3.return m[n] fib(n) 1.if (m[n] == 0) then 2. m[n] = fib(n − 1) + fib(n − 2) 3.return m[n] : m[] 0 1 2 3 n-1 1 1 0 0 0 :

11 Bottom-up fib() Algorithm int fib(int n) { if (n == 0) return 1; else { int prev = 1; int curr = 1; int temp; for (int i=1; i < n; i++) { temp = prev + curr; prev = curr; curr = temp; } return curr; } Running time = O(n) Space requirement is 3 variables = O(1) ! o this has nothing to do with changing from recursion to a loop, but with changing from top-down to bottom- up execution, which in this case is easier to write as a loop

12 4. Longest Common Subsequence (LCS) Given two sequences x[1.. m] and y[1.. n], find a longest subsequence common to them both. x:x:ABCBDAB y:y:BDCABA BCBA = LCS(x, y) and BDAB BCAB

13 242-535 ADA: 7. Dynamic Prog.13 Check every subsequence of x[1.. m] to see if it is also a subsequence of y[1.. n]. Analysis Checking time for each subsequence is O(n). 2 m subsequences of x[] (can use or not use each element in x). Worst-case running time = O(n*2 m ), exponential time. Brute-force LCS Algorithm SLOW == BAD

14 242-535 ADA: 7. Dynamic Prog.14 Simplify the problem: 1.Find the length of a LCS 2. We'll extend the algorithm later to find the LCS. 5. Towards a Better LCS Algorithm

15 242-535 ADA: 7. Dynamic Prog.15 If X = then A prefix is x[1.. 4] == o we abbreviate this as x 4 Also x 0 is the empty sequencePrefixes

16 242-535 ADA: 7. Dynamic Prog.16 c[] is a table (2D array) for storing LCS lengths: c[i, j] = | LCS(x[1.. i], y[1.. j]) | | s | is the length of a sequence s Since x is of length m, and y is of length n, then o c[m, n] = | LCS(x, y) | Creating a Table of Lengths

17 242-535 ADA: 7. Dynamic Prog.17 Since X 0 and Y 0 are empty strings, their LCS is always empty (i.e. c[0, 0] == 0) The LCS of an empty string and any other string is empty, so for every i and j: c[0, j] == c[i, 0] == 0 Calculating LCS Lengths

18 242-535 ADA: 7. Dynamic Prog.18 Initial c[] 0 1 2 3 4 5 0 1 2 3 4 0 0 00000 0 0 0

19 242-535 ADA: 7. Dynamic Prog.19 The first line of this definition fills the top row and first column of c[] with 0's, as in the non-recursive approach. 6. Recursive Definition of c[]

20 242-535 ADA: 7. Dynamic Prog.20 When we calculate c[i, j], there are 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 the length of LCS of smaller strings X i-1 and Y i-1, plus 1

21 242-535 ADA: 7. Dynamic Prog.21 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 the biggest from before (i.e. max of LCS(X i, Y j-1 ) and LCS(X i-1,Y j )

22 242-535 ADA: 7. Dynamic Prog.22 One advantage of a recursive definition for c[] is that it makes it easy to show that c is optimal by induction o c[i, j] increases the size of a sub-solution (line 2) or uses the bigger of two sub-solutions (line 3) o assuming that a smaller c[] entry is optimal, then a larger c[] entry is optimal. o when combined with the base cases, which are optimal, then c[] is an optimal solution for all entries 7. Is c[] Algorithm Optimal?

23 242-535 ADA: 7. Dynamic Prog.23 c[] is an optimal way to calculate the length of a LCS using smaller optimal solutions ( Hallmark #1 ) The c[] algorithm can be used to return the LCS (see later), so LCS also has Hallmark #1 Is LCS() Optimal?

24 242-535 ADA: 7. Dynamic Prog.24 LCS(x, y, i, j) if i == 0 or j == 0 then c[i, j] ← 0 else if x[i] == y[ j] then c[i, j] ← LCS(x, y, i–1, j–1) + 1 else c[i, j] ← max( LCS(x, y, i–1, j), LCS(x, y, i, j–1) ) return c[i, j] The recursive definition of c[] has been changed into a LCS() function which returns c[] LCS Length as Recursive Code

25 242-535 ADA: 7. Dynamic Prog.25 Does the LCS() algorithm have many repeating (overlapping) subproblems? o i.e. does it have DP Hallmark #2 ? Consider the worst case execution o x [ i ] ≠ y [ j ], in which case the algorithm evaluates two subproblems, each with only one parameter decremented 8. Repeated Subproblems?

26 242-535 ADA: 7. Dynamic Prog.26 Height = m + n. The total work is exponential, but we’re repeating lots of subproblems. Recursion Tree (in worst cases)

27 242-535 ADA: 7. Dynamic Prog.27 The number of distinct LCS subproblems for two strings of lengths m and n is only m*n. o a lot less than 2 m+n total no. of problems Dynamic Programming Hallmark #2

28 242-535 ADA: 7. Dynamic Prog.28 LCS has both DP hallmarks, and so will benefit from the DP programming techniques: o recursion o memoization o bottom-up execution 9. LCS() as a DP Problem

29 242-535 ADA: 7. Dynamic Prog.29 LCS(x, y, i, j) if c[i, j] is empty then // calculate if not already in c[i, j] if i == 0 or j == 0 then c[i, j] ← 0 else if x[i] == y[ j] then c[i, j] ← LCS(x, y, i–1, j–1) + 1 else c[i, j] ← max( LCS(x, y, i–1, j), LCS(x, y, i, j–1) ) return c[i, j] 9.1. Memoization Time = Θ(m*n) == constant work per table entry Space = Θ(m*n)

30 242-535 ADA: 7. Dynamic Prog.30 This algorithm works top-down o start with large subsequences, and calculate the smaller subsequences Let's switch to bottom-up execution o calculate the small subsequences first, then move to larger ones 9.2. Bottom-up Execution

31 242-535 ADA: 7. Dynamic Prog.31 LCS-Length(X, Y) 1. m = length(X) // get the # of symbols in X 2. n = length(Y) // get the # of symbols in Y 3. for i = 1 to m c[i,0] = 0 // special case: Y 0 4. for j = 1 to n c[0,j] = 0 // special case: X 0 5. for i = 1 to m // for all X i 6. for j = 1 to n // for all Y j 7. if ( X i == Y j ) 8. c[i,j] = c[i-1,j-1] + 1 9. else c[i,j] = max( c[i-1,j], c[i,j-1] ) 10. return c LCS Length Bottom-up the same recursive definition of c[] as before

32 242-535 ADA: 7. Dynamic Prog.32 We’ll see how a bottom-up LCS works on: X = ABCB Y = BDCAB 10. Bottom-up Examples LCS(X, Y) = BCB X = A B C B Y = B D C A B LCS-length(X, Y) = 3

33 242-535 ADA: 7. Dynamic Prog.33 LCS Example 1 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD X = ABCB; m = |X| = 4 Y = BDCAB; n = |Y| = 5 Allocate array c[5,4] ABCB BDCAB

34 242-535 ADA: 7. Dynamic Prog.34 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 ABCB BDCAB for i = 1 to m c[i,0] = 0 for j = 1 to n c[0,j] = 0

35 242-535 ADA: 7. Dynamic Prog.35 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 0 ABCB BDCAB if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] )

36 242-535 ADA: 7. Dynamic Prog.36 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 000 ABCB BDCAB if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] )

37 242-535 ADA: 7. Dynamic Prog.37 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 0001 ABCB BDCAB if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] )

38 242-535 ADA: 7. Dynamic Prog.38 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 00011 ABCB BDCAB if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] )

39 242-535 ADA: 7. Dynamic Prog.39 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 00101 1 ABCB BDCAB if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] )

40 242-535 ADA: 7. Dynamic Prog.40 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] ) 10001 1111 ABCB BDCAB

41 242-535 ADA: 7. Dynamic Prog.41 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] ) 10001 11112 ABCB BDCAB

42 242-535 ADA: 7. Dynamic Prog.42 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] ) 10001 21111 11 ABCB BDCAB

43 242-535 ADA: 7. Dynamic Prog.43 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] ) 10001 12111 112 ABCB BDCAB

44 242-535 ADA: 7. Dynamic Prog.44 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] ) 10001 1211 112 1 22 ABCB BDCAB

45 242-535 ADA: 7. Dynamic Prog.45 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] ) 10001 1211 112 1 22 1 ABCB BDCAB

46 242-535 ADA: 7. Dynamic Prog.46 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] ) 10001 1211 112 1 22 1122 ABCB BDCAB

47 242-535 ADA: 7. Dynamic Prog.47 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C B YjBBACD 0 0 00000 0 0 0 if ( X i == Y j ) c[i,j] = c[i-1,j-1] + 1 else c[i,j] = max( c[i-1,j], c[i,j-1] ) 10001 1211 112 1 22 1122 3 ABCB BDCAB

48 242-535 ADA: 7. Dynamic Prog.48 The bottom-up LCS algorithm calculates the values of each entry of the array c[m, n] So what is the running time? O(m*n) Since each c[i, j] is calculated in constant time, and there are m*n elements in the array Running Time

49 242-535 ADA: 7. Dynamic Prog.49 Example 2 m elements in x[1..m] n elements in y[1..n] B == B, so max + 1

50 242-535 ADA: 7. Dynamic Prog.50 So far, we have found the length of LCS. We want to modify this algorithm to have it calculate LCS of X and Y Each c[i, j] depends on c[i-1, j] and c[i, j-1] or c[i-1, j-1] For each c[i, j] we can trace back how it was calculated: 11. Finding the LCS 2 23 2 For example, here c[i, j] = c[i-1, j-1] +1 = 2+1=3

51 242-535 ADA: 7. Dynamic Prog.51 So we can start from c[m,n] (bottom right of c[]) and move backwards Whenever c[i,j] = c[i-1, j-1]+1, record x[i] as part of the LCS When i=0 or j=0, we have reached the beginning, so can stop. Remember that:

52 242-535 ADA: 7. Dynamic Prog.52 Finding LCS Example 1 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C YjBBACD 0 0 00000 0 0 0 10001 1211 112 1 22 1122 3 B

53 242-535 ADA: 7. Dynamic Prog.53 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C YjBBACD 0 0 00000 0 0 0 10001 1211 112 1 22 1122 3 B

54 242-535 ADA: 7. Dynamic Prog.54 j 0 1 2 3 4 5 0 1 2 3 4 i Xi A B C YjBBACD 0 0 00000 0 0 0 10001 1211 112 1 22 1122 3 B BCB LCS:

55 242-535 ADA: 7. Dynamic Prog.55 Reconstruct LCS by tracing backwards (start at bottom-right, follow numbers and the lines back to top-left). LCS() = BCBA Finding LCS for Example 2

56 242-535 ADA: 7. Dynamic Prog.56 There may be several paths through the table, which represent different answers for LCS() LCS() = BDAB All of them have the LCS-length of 4 LCS() Offers Choices 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 2 2 2 2 D 2 2 0 0 0 0 1 1 2 2 2 2 2 2 2 2 C 2 2 0 0 1 1 1 1 2 2 2 2 2 2 3 3 A 3 3 0 0 1 1 2 2 2 2 3 3 3 3 3 3 B 4 4 0 0 1 1 2 2 2 2 3 3 3 3 AABCBDB B A 4 4 4 4 0 4 0 1 2 3 1234

57 242-535 ADA: 7. Dynamic Prog.57 With this bottom-up approach, the space requirements can be reduced to O(min(m, n)) from O(m*n). Why? The calculation of each element in the current row only depends on 3 elements (2 from the previous row). Alternatively, a column can be calculated using the previous column. So the calculation space only requires 1 row or 1 column, which ever is smaller. 12. Space and Bottom-up


Download ppt "242-535 ADA: 7. Dynamic Prog.1 Objective o introduce DP, its two hallmarks, and two major programming techniques o look at two examples: the fibonacci."

Similar presentations


Ads by Google