Algorithms: Design and Analysis

Slides:



Advertisements
Similar presentations
CS Section 600 CS Section 002 Dr. Angela Guercio Spring 2010.
Advertisements

Algorithm Design approaches Dr. Jey Veerasamy. Petrol cost minimization problem You need to go from S to T by car, spending the minimum for petrol. 2.
Greedy Algorithms.
Analysis of Algorithms
Greed is good. (Some of the time)
Dynamic Programming.
Recursion –a programming strategy for solving large problems –Think “divide and conquer” –Solve large problem by splitting into smaller problems of same.
Unit 181 Recursion Definition Recursive Methods Example 1 How does Recursion work? Example 2 Problems with Recursion Infinite Recursion Exercises.
KNAPSACK PROBLEM A dynamic approach. Knapsack Problem  Given a sack, able to hold K kg  Given a list of objects  Each has a weight and a value  Try.
Dynamic Programming 0-1 Knapsack These notes are taken from the notes by Dr. Steve Goddard at
Dynamic Programming Introduction to Algorithms Dynamic Programming CSE 680 Prof. Roger Crawfis.
Approaches to Problem Solving greedy algorithms dynamic programming backtracking divide-and-conquer.
RECURSION Lecture 7 CS2110 – Fall Overview references to sections in text 2  Note: We’ve covered everything in JavaSummary.pptx!  What is recursion?
Dynamic Programming. Well known algorithm design techniques:. –Divide-and-conquer algorithms Another strategy for designing algorithms is dynamic programming.
ADA: 7. Dynamic Prog.1 Objective o introduce DP, its two hallmarks, and two major programming techniques o look at two examples: the fibonacci.
1 0-1 Knapsack problem Dr. Ying Lu RAIK 283 Data Structures & Algorithms.
Algorithm Paradigms High Level Approach To solving a Class of Problems.
CSC 413/513: Intro to Algorithms Greedy Algorithms.
DP (not Daniel Park's dance party). Dynamic programming Can speed up many problems. Basically, it's like magic. :D Overlapping subproblems o Number of.
1 Programming for Engineers in Python Autumn Lecture 12: Dynamic Programming.
CSC 221: Recursion. Recursion: Definition Function that solves a problem by relying on itself to compute the correct solution for a smaller version of.
Recursion. Math Review Given the following sequence: a 1 = 1 a n = 2*a n-1 OR a n+1 = 2*a n What are the values of the following? a 2 = a 3 = a 4 =
Contest Algorithms January 2016 Introduce DP; Look at several examples; Compare DP to Greedy 11. Dynamic Programming (DP) 1Contest Algorithms: 11. DP.
1 Dynamic Programming Topic 07 Asst. Prof. Dr. Bunyarit Uyyanonvara IT Program, Image and Vision Computing Lab. School of Information and Computer Technology.
Dynamic Programming.  Decomposes a problem into a series of sub- problems  Builds up correct solutions to larger and larger sub- problems  Examples.
Lecture 151 Programming & Data Structures Dynamic Programming GRIFFITH COLLEGE DUBLIN.
Dynamic Programming (DP) By Denon. Outline Introduction Fibonacci Numbers (Review) Longest Common Subsequence (LCS) More formal view on DP Subset Sum.
Programming With Java ICS201 University Of Ha’il1 Chapter 11 Recursion.
7. Graph Traversal Describe and compare depth-first and breadth-first graph searching, and look at the creation of spanning trees Contest Algorithms: 7.
Contest Algorithms January 2016 Describe shortest path trees, SSSP, APSP, and three algorithms: Dijkstra, Bellman-Ford, Floyd-Warshall 9. Shortest Paths.
Fundamental Data Structures and Algorithms Ananda Guna March 18, 2003 Dynamic Programming Part 1.
Dynamic Programming. What is Dynamic Programming  A method for solving complex problems by breaking them down into simpler sub problems. It is applicable.
Contest Algorithms January 2016 Describe a MST and the Prim and Kruskal algorithms for generating one. 8. Minimal Spanning Trees (MSTs) 1Contest Algorithms:
Contest Algorithms January 2016 Describe the maxflow problem, explain the Ford-Fulkerson, Edmonds-Karp algorithms. Look at the mincut problem, bipartite.
Greedy Algorithms Many of the slides are from Prof. Plaisted’s resources at University of North Carolina at Chapel Hill.
Greedy Algorithms Many of the slides are from Prof. Plaisted’s resources at University of North Carolina at Chapel Hill.
All-pairs Shortest paths Transitive Closure
CS1020 – Data Structures And Algorithms 1 AY Semester 2
Dynamic Programming Sequence of decisions. Problem state.
Fundamental Structures of Computer Science
Algorithm Design and Analysis (ADA)
Towers of Hanoi Move n (4) disks from pole A to pole C
Greedy Algorithms (Chap. 16)
Seminar on Dynamic Programming.
Algorithm Design and Analysis (ADA)
Topic 25 Dynamic Programming
Algorithm Design Methods
Algorithm design and Analysis
Dynamic Programming.
Dynamic Programming.
Prepared by Chen & Po-Chuan 2016/03/29
Data Structures and Algorithms
CS Algorithms Dynamic programming 0-1 Knapsack problem 12/5/2018.
Dynamic Programming Dr. Yingwu Zhu Chapter 15.
MCA 301: Design and Analysis of Algorithms
Unit 3 Test: Friday.
Advanced Algorithms Analysis and Design
Java Programming: Chapter 9: Recursion Second Edition
Dynamic programming vs Greedy algo – con’t
Algorithms: Design and Analysis
CSC 413/513- Intro to Algorithms
Lecture 4 Dynamic Programming
Algorithm Design Techniques Greedy Approach vs Dynamic Programming
Dr. Sampath Jayarathna Cal Poly Pomona
Lecture 5 Dynamic Programming
This is not an advertisement for the profession
0-1 Knapsack problem.
Dynamic Programming Sequence of decisions. Problem state.
Knapsack Problem A dynamic approach.
Seminar on Dynamic Programming.
Presentation transcript:

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

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.

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); }

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

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)

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

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) !

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

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

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.

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

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

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[][]

// 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()

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

Execution

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

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.

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

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

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

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.

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

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

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 = 28 + 14.666 = 42.666

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.

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); :

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

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

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 == 42.666; w == 11 earlier selection current selection