Download presentation
Presentation is loading. Please wait.
Published byPaul Summers Modified over 9 years ago
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+
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.