Dynamic Programming (DP)

Slides:



Advertisements
Similar presentations
Dynamic Programming Introduction Prof. Muhammad Saeed.
Advertisements

Recursion Chapter 14. Overview Base case and general case of recursion. A recursion is a method that calls itself. That simplifies the problem. The simpler.
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.
Tree Recursion Traditional Approach. Tree Recursion Consider the Fibonacci Number Sequence: Time: , 1, 1, 2, 3, 5, 8, 13, 21,... /
Dynamic Programming From An
§3 Dynamic Programming Use a table instead of recursion 1. Fibonacci Numbers: F(N) = F(N – 1) + F(N – 2) int Fib( int N ) { if ( N
Dynamic Programming An algorithm design paradigm like divide-and-conquer “Programming”: A tabular method (not writing computer code) Divide-and-Conquer.
Overview What is Dynamic Programming? A Sequence of 4 Steps
Problem Solving Dr. Andrew Wallace PhD BEng(hons) EurIng
Dynamic Programming.
Recursion. Recursion is a powerful technique for thinking about a process It can be used to simulate a loop, or for many other kinds of applications In.
Recursion –a programming strategy for solving large problems –Think “divide and conquer” –Solve large problem by splitting into smaller problems of same.
Recursion (define tell-story (lambda () (print ‘’Once upon a time there was a mountain. ‘’) (print ‘’On the mountain, there was a temple. ‘’) (print ‘’In.
Analysis of Algorithms Dynamic Programming. A dynamic programming algorithm solves every sub problem just once and then Saves its answer in a table (array),
Introduction to Algorithms
Joseph Lindo Recursion Sir Joseph Lindo University of the Cordilleras.
Dynamic Programming Technique. D.P.2 The term Dynamic Programming comes from Control Theory, not computer science. Programming refers to the use of tables.
Recursion Introduction to Computing Science and Programming I.
Recursion CS-240/CS341. What is recursion? a function calls itself –direct recursion a function calls its invoker –indirect recursion f f1 f2.
Recursive Algorithms Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Csci1300 Introduction to Programming Recursion Dan Feng.
Topic 7 – Recursion (A Very Quick Look). CISC 105 – Topic 7 What is Recursion? A recursive function is a function that calls itself. Recursive functions.
UNC Chapel Hill Lin/Manocha/Foskey Optimization Problems In which a set of choices must be made in order to arrive at an optimal (min/max) solution, subject.
Analysis of Algorithms
Dynamic Programming Introduction to Algorithms Dynamic Programming CSE 680 Prof. Roger Crawfis.
Dynamic Programming From An Excel Perspective. Dynamic Programming From An Excel Perspective Ranette Halverson, Richard Simpson, Catherine Stringfellow.
Recursion. Basic problem solving technique is to divide a problem into smaller subproblems These subproblems may also be divided into smaller subproblems.
Recursion. Basic problem solving technique is to divide a problem into smaller sub problems These sub problems may also be divided into smaller sub problems.
CS-2852 Data Structures LECTURE 12B Andrew J. Wozniewicz Image copyright © 2010 andyjphoto.com.
Glen Martin - School for the Talented and Gifted - DISD Recursion Recursion Recursion Recursion Recursion Recursion.
Comp 245 Data Structures Recursion. What is Recursion? A problem solving concept which can be used with languages that support the dynamic allocation.
CSE 12 – Basic Data Structures Cynthia Bailey Lee Some slides and figures adapted from Paul Kube’s CSE 12 CS2 in Java Peer Instruction Materials by Cynthia.
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.
Recursion and Dynamic Programming. Recursive thinking… Recursion is a method where the solution to a problem depends on solutions to smaller instances.
Introduction to algorithm design and recursion CS125 Spring 2007 Arthur Kantor.
Dynamic Programming Nattee Niparnan. Dynamic Programming  Many problem can be solved by D&C (in fact, D&C is a very powerful approach if you generalized.
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.
Recursion, pt. 1 The Foundations. What is Recursion? Recursion is the idea of solving a problem in terms of itself. – For some problems, it may not possible.
Data Structures R e c u r s i o n. Recursive Thinking Recursion is a problem-solving approach that can be used to generate simple solutions to certain.
Topic 25 Dynamic Programming "Thus, I thought dynamic programming was a good name. It was something not even a Congressman could object to. So I used it.
Building Java Programs Chapter 12 Recursion Copyright (c) Pearson All rights reserved.
Dynamic Programming. Many problem can be solved by D&C – (in fact, D&C is a very powerful approach if you generalize it since MOST problems can be solved.
Optimization Problems In which a set of choices must be made in order to arrive at an optimal (min/max) solution, subject to some constraints. (There may.
PROBLEM-SOLVING TECHNIQUES Rocky K. C. Chang November 10, 2015.
Dynamic Programming (DP) By Denon. Outline Introduction Fibonacci Numbers (Review) Longest Common Subsequence (LCS) More formal view on DP Subset Sum.
1 Today’s Material Dynamic Programming – Chapter 15 –Introduction to Dynamic Programming –0-1 Knapsack Problem –Longest Common Subsequence –Chain Matrix.
Dynamic Programming academy.zariba.com 1. Lecture Content 1.Fibonacci Numbers Revisited 2.Dynamic Programming 3.Examples 4.Homework 2.
Questions 4) What type of algorithmic problem-solving technique (greedy, divide-and-conquer, dynamic programming)
Recursion. Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example: A list.
Int fact (int n) { If (n == 0) return 1; else return n * fact (n – 1); } 5 void main () { Int Sum; : Sum = fact (5); : } Factorial Program Using Recursion.
Dynamic Programming. What is Dynamic Programming  A method for solving complex problems by breaking them down into simpler sub problems. It is applicable.
Welcome to Recursion! Say what?!? Recursion is… the process of solving large problems by simplifying them into smaller ones. similar to processing using.
CS314 – Section 5 Recitation 10
Lecture 12.
Rod cutting Decide where to cut steel rods:
Fundamental Structures of Computer Science
Introduction to Computing Science and Programming I
Weighted Interval Scheduling
Java 4/4/2017 Recursion.
Dynamic Programming Copyright © 2007 Pearson Addison-Wesley. All rights reserved.
Introduction to the Design and Analysis of Algorithms
Topic 25 Dynamic Programming
Data Structures and Algorithms
Data Structures and Algorithms
Binding Times Binding is an association between two things Examples:
Module 1-10: Recursion.
DYNAMIC PROGRAMMING.
Lecture 4 Dynamic Programming
This is not an advertisement for the profession
Presentation transcript:

Dynamic Programming (DP) Simpler, Better, Faster Carl Hultquist

Rough definition Dynamic programming is: Dynamic programming is not: Breaking a problem up into smaller sub-problems By finding the optimal solution to these smaller sub-problems, being able to find the solution to the bigger problem Dynamic programming is not: A type of programming language (like declarative and imperative)

Learn by example: Fibonacci numbers We all know the Fibonacci numbers 1 1 2 3 5 8 13… and that we can write a neat definition for these as: f(0) = 1 f(1) = 1 f(n) = f(n – 2) + f(n – 1) for n>1

Fibonacci in code int f(int n) { if (n < 2) return 1; else return f(n – 2) + f(n – 1); }

Fibonacci and big-O So we have an algorithm for finding f(n), but is it any good? What’s the big-O for finding f(n)? Answer: O(f(n)) So… is this good? Is it bad?

Recursive Fibonacci: bad As an indication, f(1000)=1,318,412,525 Surely we can do better…

The trick: overlapping subproblems For some n, f(n)=f(n-2)+f(n-1) Now f(n-1)=f(n-3)+f(n-2) Note the common f(n-2) – so to calculate the value of f(n), we actually calculate f(n-2) twice. Doing this using our recursive program is wasteful – we should only need to work it out once!!!

A better Fibonacci #define MAX_N 10000 int f[MAX_N]; int fib(int n) { f[0] = f[1] = 1; for (int i = 2; i <= n; i++) f[i] = f[i – 2] + f[i – 1]; return f[n]; }

Coin counting  Yes, today’s problem was a DP. So we want to make change of value M, we have N coin denominations, and their values are Vi for i=1…N. Now we can write the solution like this: coins(M) = min{coins(M – V1), coins(M – V2), …, coins(M – VN)} + 1 Now, doesn’t that look just a little bit like the Fibonacci definition? ;-)

A better solution… int N, M; int V[N]; int coins[M + 1]; coins[0] = 0; for (int i = 1; i <= M; i++) { int best = M; for (int j = 0; j < N; j++) if (V[j] <= i && coins[i – V[j]] + 1 < best) best = coins[i – V[j]] + 1; coins[i] = best; }

Checking for valid states int N, M; int V[N]; int coins[M + 1]; set(coins[0], coins[M], -1); coins[0] = 0; for (int i = 1; i <= M; i++) { int best = M; for (int j = 0; j < N; j++) if (V[j] <= i && coins[i – V[j]] != -1 && coins[i – V[j]] + 1 < best) best = coins[i – V[j]] + 1; coins[i] = best; }

An alternative coin solution: memoization int N, M; int V[N]; int cache[M + 1]; set(cache[0], cache[M], -1); int coins(int amount) { if (cache[amount] == -1) int best = M; for (int i = 0; i < N; i++) if (V[i] <= amount && coins(amount) + 1 < best) best = coins(amount) + 1; cache[amount] = best; } return cache[amount];

Two approaches to DP Top-down: recursion + memoization. Easier to code, but may have greater memory requirements. Also has extra stack + function call overhead. Bottom-up: iterative, solves subproblems from the smallest one up. Sometimes harder to code and/or work out exactly what’s going on, but more efficient.

Backtracking Some DP problems just call for the value of the best answer (like today’s problem). Others make your life harder: they ask for the “path” to the solution. Today’s problem could have done this by asking you to output the actual coins used

Backtracking (2) This usually isn’t too hard: in the same way that you have an array to store your best solution, you also keep an array indicating how you got there. For the coins problem, this array can simply store the last coin used to reach each total You can then “backtrack” by subtracting the coin value from the total, and look at the next coin that was needed. Repeat until you hit 0 

Coins with backtrack int N, M; int V[N]; int coins[M + 1]; int coinUsed[M + 1]; coins[0] = 0; for (int i = 1; i <= M; i++) { int best = M; int coin = -1; for (int j = 0; j < N; j++) if (V[j] <= i && coins[i – V[j]] + 1 < best) best = coins[i – V[j]] + 1; coin = j; } coins[i] = best; coinUsed[i] = coin;

Higher dimensions So far, we’ve just seen 1D DP problems At the IOI, 2D (or higher!) problems crop up often Consider this one: given a NxN grid of numbers and M co-ordinate pairs (a,b);(c,d), find the sum of the values in the grid for each of the rectangles with top-left co-ordinate (a,b) and bottom-right co-ordinate (c,d).

The naïve approach For each of the M rectangles, loop over the rectangle and sum up the values. This has O(N2M). With DP, we can instead get O(N2+M) which will usually be better (unless M is huge)

Getting clever… Suppose we can compute and store the sum of all rectangles with top-left co-ordinate (1,1). Let’s stash these in a 2D array called sum[][]. Then, to work out the sum of a rectangle from (a,b) to (c,d), we can work it out using our sum array like this: sum(a,b,c,d) = sum[c][d] – sum[c][b-1] – sum[a-1][d] + sum[a-1][b-1]

Cool, now how do we create our sum array? Suppose the grid values are in an array called grid[][]. To work out sum[i][j], we just need to see that it can be calculated as: sum[i][i] = sum[i][j-1] + sum[i-1][j] – sum[i-1][j-1] + grid[i][j]

… which we can do with a quick 2D loop sum[0][0] = 0; sum[0][j] = 0; sum[i][0] = 0; for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + grid[i][j];

Common applications Longest common subsequence problem Floyd’s all-pairs shortest path Knapsack problem Duckworth-Lewis method! … amongst many others. See: http://en.wikipedia.org/wiki/Dynamic_Programming

Questions?