Presentation is loading. Please wait.

Presentation is loading. Please wait.

Contest Algorithms January 2016 Introduce DP; Look at several examples; Compare DP to Greedy 11. Dynamic Programming (DP) 1Contest Algorithms: 11. DP.

Similar presentations


Presentation on theme: "Contest Algorithms January 2016 Introduce DP; Look at several examples; Compare DP to Greedy 11. Dynamic Programming (DP) 1Contest Algorithms: 11. DP."— Presentation transcript:

1 Contest Algorithms January 2016 Introduce DP; Look at several examples; Compare DP to Greedy 11. Dynamic Programming (DP) 1Contest Algorithms: 11. DP

2  1. DP Features  2. The fibonacci series  3. Binomial coefs  4. 0-1 knapsack  5. Longest Common Subsequence  6. Edit distance  7. Compare DP to Greedy using fractional knapsack DP Topics Contest Algorithms: 11. DP2

3  An optimal (best) solution to the problem is a composition of optimal (best) subproblem solutions  makes the code recursive (perhaps)  The same subproblems appear many times while solving the problem  use tabling / memoziation to 'remember' answers  perhaps calculate subproblems first; called bottom-up evaluation  The current best solution choice may change solutions choices made earlier. 1. DP Features

4  Series defined by  fib 0 = 0  fib 1 = 1  fib n = fib n-1 + fib n-2  Recursive algorithm:  Running Time? O(2 n ) 2. Fibonacci Series 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, … public static int fib(int n) { if (n < 2) return n; else return fib(n-1) + fib(n-2); } see FibMemo.java

5  Fibonacci can be a DP problem:  the solution (fib(n)) is a combination of sub-solutions fib(n-1) and fib(n-2))  There are many repeated subproblems  2 n subproblems, but only n are different 5

6  Running time is linear = O(n)  Requires extra space for the fibs[] table = O(n) Memoization + top-down fib() private static long fibs = new long[MAX+1]; // in main() fibs[0] = 0; fibs[1] = 1; public static long fib(int n) { if (n < 2) return n; else { if (fibs[n] == 0) fibs[n] = fib(n−1) + fib(n−2) return fibs[n]; } } : fibs[] 0 1 2 3 MAX 0 1 0 0 0 :

7 10th Fib: 55 Number of fib() calls: 19 10th Fib: 55 Number of fib() calls: 1 11th Fib: 89 Number of fib() calls: 3 11th Fib: 89 Number of fib() calls: 1 Speed-up Contest Algorithms: 11. DP7

8 Bottom-up Fib int fib(int n) { if (n == 0) return 0; else { // deal with 1, 1, 2,... int prev = 0; 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 5 variables = O(1) ! tempprevcurr F(k-1) F(k-2)F(k-1) tempprevcurr F(k-1)F(k) +

9 9 2. Binomial Coefficients  How many ways are there to choose k things out of n?  Used to calculate the coefficients of of (a+b) n

10 10  It’s difficult to calculate the value of binomial coefficients using that equation:  arithmetic overflow will happen for n > 12!  Use Pascal’s triangle instead: 1 1 2 1 1 3 3 1 1 4 6 4 1 15 10 10 5 1 1 6 15 20 15 6 1 n == 0 n == 1 start counting k = 0 from left :::: a table of subproblems that are used repeatedly. A DP problem

11 11 Binomial Coefficients private static final int MAX = 100; // return n choose m static long binCoef(int n, int m) { long[][] bc = new long[MAX][MAX}; //table of binomial coefs for(int i = 0; i <= n; i++) bc[i][0] = 1; // init upper edges for(int j = 0; j <= n; j++) bc[j][j] = 1; for(int i = 1; i <= n; i++) // fill inside triangle for(int j = 1; j < i; j++) bc[i][j] = bc[i-1][j-1] + bc[i-1][j]; return bc[n][m]; } see Binomial.java

12 1 1 item 0 2 6 item 1 5 18 item 2 6 22 item 3 7 28 item 4 11 maximize cost, but total weight ≤ 11 3. 0-1 Knapsack Problem Crucial idea: total weight must be one of 12 values: 0-11 indivisible; use or not use a weight

13 1 1 item 0 2 6 item 1 5 18 item 2 Maximize cost with at most 3 items: 01234567891011w = c = 0167718192425 Try to add item 3: 6 22 item 3 01234567891011w = c = 016771822242829 40

14  Items 0, 1,... n have weights w 0, w 1,...w n and costs c 0, c 1,...c n. All values are positive integers.  W is the maximum capcity of the knapsack.  Define m[i,w] to be the maximum total cost with weight ≤ w using items 0 to i. Mathematically Contest Algorithms14

15  m[0,w] = c 0 if w 0 ≤ w  m[i,w] = m[i-1,w], if w i > w  the i item weighs more than the current weight limit  m[i,w] = max( m[i-1,w], m[i-1, w-w i ]+c i ), if w i ≤ w  The solution is m[n,W]. To do this efficiently we must use a table to store previous computations. Define m[i,w] recursively Contest Algorithms: 11. DP15 the maximum total cost with weight ≤ w using items 0 to i

16 Why use Dynamic Prog.?  The current selection may change an earlier selection: 1 1 item 0 2 6 item 1 5 18 item 2 c == 25; w == 8 earlier selection 5 18 item 2 6 22 item 3 c == 40; w == 11 current selection

17 public static void main(String[] args) { int W = 11; // knapsack capacity System.out.println("Knapsack capacity: " + W); // costs and weights for items int[] ci = { 1, 6, 18, 22, 28}; int[] wi = { 1, 2, 5, 6, 7}; int numItems = ci.length; for (int i=0; i < numItems; i++) System.out.println("Item " + i + ": weight = " + wi[i] + ", cost = " + ci[i]); System.out.println(); // totCosts[i, w] stores the maximum total cost // of some items in {0,1,...,i} of combined weight <= w int[][] totCosts = new int[numItems][W + 1]; // used[i, weight] is true when item i is part of the solution for weight boolean[][] used = new boolean[numItems][W + 1]; // all false by default : Code Contest Algorithms17 see Knapsack0l.java m[][] has become totCosts[][]

18 // compute maximum cost for first item for (int w = 0; w <= W; w++) { if (wi[0] <= w) { totCosts[0][w] = wi[0]; used[0][w] = true; // means that item 0 can be used when weight is w } else totCosts[0][w] = 0; } // compute maximum cost for rest of items for (int i = 1; i < numItems; i++) { for (int w = 0; w <= W; w++) { // w == current weight limit if (wi[i] <= w) { // item within current weight limit int costWith_i = ci[i] + totCosts[i-1][w-wi[i]]; if (costWith_i > totCosts[i-1][w]) { // higher cost is better totCosts[i][w] = costWith_i; used[i][w] = true; } else // leave cost unchanged totCosts[i][w] = totCosts[i-1][w]; } else // item exceeds current weight limit; don't use totCosts[i][w] = totCosts[i-1][w]; } printTables(totCosts, used); itemsUsed(used, ci, wi); } // end of main() Contest Algorithms: 11. DP18

19 private static void itemsUsed(boolean[][] used, int[] ci, int[] wi) { System.out.println("Items used:"); int wCapacity = used[0].length-1; // start at maximum weight (W) int usedWeight = 0; int usedCost = 0; // check if i is part of the set of items weighing wCapacity, // if yes, print i info, and reduce wCapacity by item i's weight // and find the next item for this new capacity for (int i = used.length-1; i >= 0; i--) { if (used[i][wCapacity]) { System.out.println("Item " + i + ": weight = " + wi[i] + ", cost = " + ci[i]); usedWeight += wi[i]; usedCost += ci[i]; wCapacity = wCapacity - wi[i]; } System.out.println("Total weight: " + usedWeight + "; Total cost: " + usedCost); } // end of itemsUsed() Contest Algorithms: 11. DP19

20 Execution Contest Algorithms20

21 Items used: Weight 0 1 2 3 4 5 6 7 8 9 10 11 Item 0: X X X X X X X X X X X Item 1: X X X X X X X X X X Item 2: X X X X X X X Item 3: X X X X X Item 4: X X X X Using used[][] Contest Algorithms21 W = 11 Item 3 used; weight == 6 W = 11 – 6 = 5 Item 2 used; weight == 5 W = 5 – 5 = 0 No item used; stop

22 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) or BDAB, BCAB

23 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

24 Simplify the problem: 1.Find the length of a LCS 2. We'll extend the algorithm later to find the LCS. Towards a Better LCS Algorithm

25  If X = then  A prefix is x[1.. 4] ==  we abbreviate this as x 4  Also x 0 is the empty sequence Prefixes

26  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  c[m, n] = | LCS(x, y) | Creating a Table of Lengths

27  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

28 Initial c[] 0 1 2 3 4 5 0 1 2 3 4 0 0 00000 0 0 0

29  The first line of this definition fills the top row and first column of c[] with 0's. Recursive Definition of c[]

30  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

31  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 )

32  Does the LCS() algorithm have many repeating (overlapping) subproblems?  Consider the worst case execution  x [ i ] ≠ y [ j ], in which case the algorithm evaluates two subproblems, each with only one parameter decremented Repeated Subproblems?

33 Height = m + n. The total work is exponential, but we’re repeating lots of subproblems. Recursion Tree (in worst cases)

34 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] Memoization Time = O(m*n) == constant work per table entry Space = O(m*n)

35  This algorithm works top-down  start with large subsequences, and calculate the smaller subsequences  Let's switch to bottom-up execution  calculate the small subsequences first, then move to larger ones Bottom-up Execution

36 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

37 We’ll see how a bottom-up LCS works on:  X = ABCB  Y = BDCAB Bottom-up Examples LCS(X, Y) = BCB X = A B C B Y = B D C A B LCS-length(X, Y) = 3

38 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

39 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 j 0 1 2 3 4 5

40 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] ) j 0 1 2 3 4 5

41 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] ) j 0 1 2 3 4 5

42 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] ) j 0 1 2 3 4 5

43 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] ) j 0 1 2 3 4 5

44 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] ) j 0 1 2 3 4 5

45 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 j 0 1 2 3 4 5

46 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 j 0 1 2 3 4 5

47 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 j 0 1 2 3 4 5

48 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 j 0 1 2 3 4 5

49 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 j 0 1 2 3 4 5

50 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 j 0 1 2 3 4 5

51 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 j 0 1 2 3 4 5

52 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 j 0 1 2 3 4 5

53  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

54 private static void lcs(String x, String y) { int[][] lengths = new int[x.length()+1][y.length()+1]; // filled with 0's by default for (int i = 1; i <= x.length(); i++) { for (int j = 1; j <= y.length(); j++) { if (x.charAt(i-1) == y.charAt(j-1)) // Java string index starts at 0, not 1 lengths[i][j] = lengths[i-1][j-1]+1; else lengths[i][j] = Math.max(lengths[i][j-1], lengths[i-1][j]); } System.out.println("LCS length: " + lengths[x.length()][y.length()]); System.out.println("LCS: " + getSubSeq(x, y, lengths)); } // end of lcs() Code Contest Algorithms: 11. DP54 see LCS.java c[][] has become lengths[][]

55  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: Finding the LCS 2 23 2 For example, here c[i, j] = c[i-1, j-1] +1 = 2+1=3

56  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:

57 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

58 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

59 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:

60  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

61 private static String getSubSeq(String x, String y, int[][] lengths) { StringBuffer sb = new StringBuffer(); int i = x.length(); // start at bottom right int j = y.length(); while ((i != 0) && (j != 0)) { if (x.charAt(i-1) == y.charAt(j-1)) { // Java string index starts at 0, not 1 sb.append(x.charAt(i-1)); i--; j--; } else if (lengths[i][j-1] >= lengths[i][j]) j--; else i--; } return sb.reverse().toString(); } // end of getSubSeq() Code Contest Algorithms: 11. DP61 see LCS.java c[][] has become lengths[][]

62 Execution Contest Algorithms: 11. DP62

63 5. Edit Distance (Levenshtein distance)  How to measure the difference between a pair of strings?  Three natural types of edits  Substitution : “shot” to “spot”  Insertion : “ago” to “agao”  Deletion : “hour” to “hor”  There's also " match ", which isn't an edit.  Edit distance : the minimum number of edits needed to transform one string into another  assign a score of 1 to each type of change (this could be different)  the edit distance is the minimum total score 63

64 Example  The edit distance from TGCATAT to ATCCGAT is 4  In short hand, the edit path is "S S M S S M M"  there are usually other possible edit paths of the same distance 64 TGCATAT substitute T -> A substitute G -> T substitute A -> C substitute T -> G match C's match A's match T's A GCATAT A T CATAT ATC C TAT ATCC G AT

65  Consider the last chars of strings S and T:  If the characters are the same (they match ):  recursively move onto finding the edit distance between the two strings left when this last char is deleted from both S and T  Otherwise, make one of three changes:  delete the last char of S  insert the last char of T  substitute the last char of S for the last char of T What is the edit distance from S (source) to T (target)? Contest Algorithms: 11. DP65

66 Prefixes and dist() function 66 The prefix substring of string S is s. The prefix substring of string T is t. The length of s is i, the length of t is j. The edit distance between s and t is dist(i, j) The edit distance for the complete strings is dist(S.size(), T.size()) Build a dist[][] table to store the dist(i, j) values

67 Calculating dist(i, j) 67 S T i j Consider character at location i in s (s i ) and location j in t (t j ). How is t j obtained? Three cases: 1.Match or substitution of s i sub-problem: dist (i-1, j-1) 2.Insertion sub-problem: dist (i, j-1) 3.Deletion sub-problem: dist (i-1, j) So, dist(i, j) = min { dist(i-1, j-1) + sub(i, j), dist(i, j-1) + 1, dist(i-1, j) +1 } int sub(char a, char b) { if (c == d) return 0; else return 1; }

68  The edit distance between an empty string and another string is the length of the second string.  This corresponds to having to insert each letter for the transformation. Empty String Case Contest Algorithms: 11. DP68

69 Example: "keep" --> "hello"  s="keep" and t="hello".  To deal with empty strings, an extra row and column have been added to the chart below:  An entry in this table simply holds the dist() value between the prefixes of the two strings.  For example, the highlighted square indicates that the edit distance between the strings "he" and "keep" is 3. hello 012345 k112345 e221234 e332234 p443334

70 Building the Table 1)Initialize values corresponding to the empty string base case. hello 012345 k1 e2 e3 p4

71 2)Loop through the table from the top left to the bottom right. In doing so, follow the recursive definition.  If the characters match (e.g. "e" and "e"): hello 012345 k112345 e22 e3 p4 Copy down the upper left value.

72  If the characters do not match  e.g. "l" and "e": Contest Algorithms: 11. DP72 hello 012345 k112345 e221 e3 p4 copy min ( 1+ above, 1+ left, 1+diag up)

73 public static int levDistance(String s, String t) // distance from s to t (source to target) { int m = s.length(); int n = t.length(); dist = new int[m+1][n+1]; // s is down row; t is across col for (int i = 0; i <= m; i++) dist[i][0] = i; for (int j = 0; j <= n; j++) dist[0][j] = j; // iterate though, and check last char for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { int sub = ((s.charAt(i-1) == t.charAt(j-1)) ? 0 : 1); // matching chars? dist[i][j] = min3( dist[i-1][j] + 1, // delete dist[i][j-1] + 1, // insert dist[i-1][j-1] + sub ); // match or sub } return dist[m][n]; } // end of levDistance() Code Contest Algorithms: 11. DP73

74 private static void printDists(String s, String t) { System.out.print("\n "); for (int j = 0; j < t.length(); j++) System.out.print(" " + t.charAt(j) + " "); System.out.println(); for (int i = 0; i < dist.length; i++) { if (i == 0) System.out.print(" : "); else System.out.printf(" " + s.charAt(i-1) + " : "); for (int j = 0; j < dist[0].length; j++) System.out.printf("%2d ", dist[i][j]); System.out.println(); } System.out.println(); } // end of printDists() Printing the dist[][] Table Contest Algorithms: 11. DP74

75 private static String buildPath(String s, String t) { // walk back through matrix to figure out path StringBuilder rPath = new StringBuilder(); int i = s.length(); int j = t.length(); while ((i != 0) && (j != 0)) { if (s.charAt(i-1) == t.charAt(j-1)) { // chars match rPath.append("M "); i--; j--; } else { // find previous position if (dist[i][j] == (dist[i-1][j-1] + 1)) { // substitute rPath.append("S "); i--; j--; } else if (dist[i][j] == (dist[i-1][j] + 1)) { // delete rPath.append("D "); i--; } else if (dist[i][j] == (dist[i][j-1] + 1)) { // insert rPath.append("I "); j--; } while (i != 0) { // j == 0, so must move up (i.e. delete) rPath.append("D "); i--; } while (j != 0) { // i == 0, so must move left (i.e. insert) rPath.append("I "); j--; } return rPath.reverse().toString(); } // end of buildPath() Building the Edit Path Contest Algorithms: 11. DP75

76 Execution Contest Algorithms: 11. DP76

77 Example 77 S: “thou shalt not” T: “you should not” D S M M M M M I S M S M M M M

78 More Examples Contest Algorithms: 11. DP78

79 DP Compared to Greedy DP features Again  Optimal sub-structure:  the best solution to the problem uses the best solutions to sub- problems  use recursive code  Overlapping (repeating) problems:  the same subproblems appear several times while solving the problem  use tabling / memoziation to 'remember' answer  The current best solution choice may change solutions choices made earlier.

80 Greedy Features  Optimal sub-structure: (same as DP)  the best solution to the problem uses the best solutions to sub-problems  use recursive code  The current best solution choice is made using only current ('local') information  greedy algorithms never change choices made earlier in the calculation  makes "greedy" code easier to implement than DP

81  Previous Examples:  Minimum Spanning Tree Algorithms – Kruskal’s and Prim’s  Dijkstra’s Algorithm

82 Fractional Knapsack Problem  Maximize the value of a knapsack that can hold at most W units worth of goods from a list of items I 1, I 2,... I n.  Each item i has two attributes: 1)Value/unit == v i 2)Weight == w i

83 1)Sort the items into a list by value/unit. 2)Take as much of the most expensive item as possible, then move down the list. 3)You may end up taking a fractional portion of the last item. Fractional Knapsack Algorithm Contest Algorithms83

84 1 1 item 0 2 6 item 1 5 18 item 2 6 22 item 3 7 28 item 4 11 maximize cost, but total weight ≤ 11 Fractional Knapsack Problem uses a greedy algorithm Crucial idea: order by cost per unit weight divisible; can use parts of a weight

85 1 1 item 0 2 6 item 1 5 18 item 2 6 22 item 3 7 28 item 4 1 1 item 0 2 6 item 1 5 18 item 2 6 22 item 3 7 28 item 4 cost/unit weight: 4 reorder by decreeasing cost/unit weight: 3.6663.631

86 Maximize cost by adding weights (or parts) in decreasing cost/ unit weight: Max weight == 11 : 6 22 item 3 7 28 item 4 Max cost ==7 * 44 * 3.666 7+4 + = 28 + 14.666 = 42.666

87  No. of items, knapsack W  Lines of item info; on each line:  ci, wi for an item e.g. 5 11 1 1 6 2 18 5 22 6 28 7 Input Data Format Contest Algorithms87 see fkData.txt This is the example from the previous slides.

88 public static void main(String[] args) throws Exception { if (args.length != 1) { System.out.println("Usage: java FracKnapsack "); return; } Scanner sc = new Scanner(new File(args[0])); int numItems = sc.nextInt(); int maxW = sc.nextInt(); LinkedList items = new LinkedList (); for (int i = 0; i < numItems; i++) items.add( new KItem(sc.nextInt(), sc.nextInt()) ); Collections.sort(items); : Code Contest Algorithms88

89 int currWeight = 0; double currCost = 0; while ((currWeight < maxW) && (!items.isEmpty())) { int remWeight = maxW - currWeight; KItem item = items.poll(); if (item.weight <= remWeight) { // add all of the item currWeight += item.weight; currCost += item.cost; } else { // item.weight > remWeight // add a fraction of the item currCost += remWeight * item.costWeightRatio; currWeight += remWeight; } System.out.printf("%.3f", currCost); } // end of main() Contest Algorithms: 11. DP89

90 public class KItem implements Comparable { public int cost, weight; public double costWeightRatio; public KItem(int cost, int weight) { this.cost = cost; this.weight = weight; costWeightRatio = ((double) cost) / weight; } public int compareTo(KItem i) { double diff = costWeightRatio - i.costWeightRatio; if (diff > 0) return -1; else if (diff == 0) return 0; else return 1; } // end of compareTo() public String toString() { return "(cost: " + cost + ", weight: " + weight + ")"; } } // end of KItem class Contest Algorithms: 11. DP90

91 Why is it Greedy?  The current selection does not affect the earlier selection: earlier selection c == 42.666; w == 11 current selection 7 28 item 4 7 * 4 c = 28; w == 7 6 22 item 3 7 28 item 4 7 * 44 * 3.666+


Download ppt "Contest Algorithms January 2016 Introduce DP; Look at several examples; Compare DP to Greedy 11. Dynamic Programming (DP) 1Contest Algorithms: 11. DP."

Similar presentations


Ads by Google