Presentation is loading. Please wait.

Presentation is loading. Please wait.

Algorithms: Design and Analysis

Similar presentations


Presentation on theme: "Algorithms: Design and Analysis"— Presentation transcript:

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

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 Recursive algorithm:
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[] 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]; } } 1 1 2 3 : : : : MAX Running time is linear = O(n) Requires extra space for the fibs[] table = O(n)

6 Speed-up 10th Fib: 55 Number of fib() calls: 19 Number of fib() calls: 1 11th Fib: 89 Number of fib() calls: 3

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

8 3. 0-1 Knapsack Problem 11 1 item 0 2 6 item 1 5 18 item 2 6 22 item 3
7 28 item 4 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 1 item 0 2 6 item 1 5 18 item 2 Maximize cost with at most 3 items: 1 2 3 4 5 6 7 8 9 10 11 w = c = 18 19 24 25 6 22 item 3 Try to add item 3: 1 2 3 4 5 6 7 8 9 10 11 w = c = 18 22 24 28 29 40

10 Mathematically Items 0, 1, ... n have weights w0, w1, ...wn and costs c0, c1, ...cn. 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.

11 Define m[i,w] recursively
the maximum total cost with weight ≤ w using items 0 to i 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. don't use wi use wi

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

13 Code NOT EXAMINABLE see Knapsack0l.java m[][] has become totCosts[][]
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 algorithms never 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
1 item 0 2 6 item 1 5 18 item 2 6 22 item 3 7 28 item 4 uses a greedy algorithm divisible; can use parts of a weight maximize cost, but total weight ≤ 11 11 Crucial idea: order by cost per unit weight

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

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

26 Input Data Format 5 11 1 1 6 2 18 5 22 6 see fkData.txt 28 7
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? The current selection does not affect the earlier selection: 7 28 item 4 7 28 item 4 6 22 item 3 7 * 4 7 * 4 + 4 * 3.666 c = 28; w == 7 c == ; w == 11 earlier selection current selection


Download ppt "Algorithms: Design and Analysis"

Similar presentations


Ads by Google