1 / 30

Algorithms: Design and Analysis

Algorithms: Design and Analysis. 240-310 , Semester 2, 2018-2019. Objective introduce Dynamic Programming ( DP) look at several examples: Fibonacci, Knapsack compare DP to Greedy using Knapsack. 6. Dynamic Programming. 1. DP Features.

crobins
Télécharger la présentation

Algorithms: Design and Analysis

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Algorithms: Design and Analysis 240-310, Semester2, 2018-2019 • Objective • introduce Dynamic Programming (DP) • look at several examples: Fibonacci, Knapsack • compare DP to Greedy using Knapsack 6. Dynamic Programming

  2. 1. DP Features • 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.

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

  4. 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 • 2n subproblems, but only n are different

  5. Memoization + top-down fib() fibs[] 0 0 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]; } } • Running time is linear = O(n) • Requires extra space for the fibs[] table = O(n) 1 1 2 0 3 0 :: :: 0 MAX

  6. Speed-up 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

  7. Bottom-up Fib F(k-1) F(k-1) F(k-2) temp prev curr Running time = O(n) Space requirement is 5 variables = O(1) ! 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; } } + temp prev curr F(k) F(k-1) F(k)

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

  9. Maximize cost with at most 3 items: w = w = 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 22 18 6 1 c = c = 0 0 1 1 6 6 7 7 7 7 18 18 22 19 24 24 28 25 25 29 25 29 40 25 1 6 5 2 item 0 item 3 item 2 item 1 Try to add item 3:

  10. Mathematically • Items 0, 1, ... n have weights w0, w1, ...wnand costs c0, c1, ...cn. All values are positive integers. • W is the maximum capcity of the knapsack. • Definem[i,w] to be the maximum total cost with weight ≤w using items 0 to i.

  11. Define m[i,w] recursively • m[0,w] = c0 if w0 ≤ w • m[i,w] = m[i-1,w], if wi > w • the i item weighs more than the current weight limit • m[i,w] = max( m[i-1,w], m[i-1, w-wi]+ci), if wi≤ w • The solution is m[n,W]. To do this efficiently we must use a table to store previous computations. the maximum total cost with weight ≤ w using items 0 to i don't use wi use wi

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

  13. Code NOT EXAMINABLE see Knapsack0l.java 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 : m[][] has become totCosts[][]

  14. // compute maximum cost for first item for (int w = 0; w <= W; w++) { if (wi[0] <= w) { totCosts[0][w] = ci[0]; // first line of maths (slide 11) 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; third line of maths 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]; // second line of maths } } printTables(totCosts, used); itemsUsed(used, ci, wi); } // end of main()

  15. 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()

  16. Execution

  17. Using used[][] 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 W = 11 Item 3 used; weight == 6 W = 11 – 6 = 5 Item 2 used; weight == 5 W = 5 – 5 = 0 No item used; stop

  18. 4. 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.

  19. 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 algorithmsnever change choices made earlier in the calculation • makes "greedy" code easier to implement than DP

  20. Examples: • Minimum Spanning Tree Algorithms – Kruskal’s and Prim’s • last year • Dijkstra’s Algorithm • in part 10

  21. Fractional Knapsack Problem • Maximize the value of a knapsack that can hold at most W units worth of goods from a list of items I1, I2, ... In. • Each item i has two attributes: • Cost/unit == vi • Weight == wi

  22. Fractional Knapsack Algorithm • Sort the items into a list by cost/unit. • Take as much of the most expensive item as possible, then move down the list. • You may end up taking a fractional portion of the last item.

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

  24. 28 22 18 18 22 28 1 6 6 1 5 2 7 2 6 5 6 7 1 1 item 2 item 0 item 3 item 1 item 2 item 1 item 4 item 0 item 4 item 3 reorder by decreeasing cost/unit weight: cost/unit weight: 4 3.666 3.6 3 1

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

  26. Input Data Format • 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 see fkData.txt This is the example from the previous slides.

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

  28. 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()

  29. public class KItem implements Comparable<KItem> { 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

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

More Related