Recursion and Dynamic Programming

Post on 23-Jan-2016

38 views 0 download

description

Recursion and Dynamic Programming. CSC 172 SPRING 2004 LECTURE 9. Grad TA help sessions?. What is a good time? Office hours are kind of early Would people like Thursdays @ 5ish? Induction Big-Oh Recurrence Code Style review. Project 1. General Observations - PowerPoint PPT Presentation

Transcript of Recursion and Dynamic Programming

Recursion and Dynamic Programming

CSC 172

SPRING 2004

LECTURE 9

Grad TA help sessions?

What is a good time? Office hours are kind of early Would people like Thursdays @ 5ish?

InductionBig-OhRecurrenceCode Style review

Project 1 General Observations Your “style” should travel with you Go to the writing place Some people paraphrased Bently, but got it wrong While big-Oh analysis was not required, some

notion of absraction and generalization is appropriate

Some people lost large amounts because of no disclaimer

Recursive definition

What is a list? A list can be “empty” A list can be an item, followed by a list.

Recursive definition

What is a Tree? A tree can be “empty” A tree can be a node with “children” that are trees.

Recursive definition

What is a number? (integer) A single digit is a number {0,1,2,3,4,5,6,7,8,9} A number is a digit followed by a number

Recursive Definition

What is a simple (4 func) arithmetic expression ? (7+5)* (3-2)

A number is an arithmetic expression If X is an ae, then (X) is an ae If X and Y are both aes, then X+Y , X-Y, X*Y, X/Y are all ae

Recursion We often think of recursion as a “programming

technique” Recursion is also a design pattern for data

structures Recursion is a way to think about problem

solving

A Theological AsideDisclaimer: you don’t have to believe

Can computer science inform theology? Christian notion of “Trinity”? "A three-fold personality existing in one divine

being or substance; the union in one God of Father, Son, and Holy Spirit as three infinite, co-equal, co-eternal persons; one God in three persons."

from about 400 AD to about 1800 AD, countless people were put to death for refusing to believe in the idea of "one God in three persons."

Serpinski TriangleThis design is called Sierpinski's

Triangle, after the Polish mathematician Waclaw Sierpinski who described it in 1916. Among these is its fractal or self-similar character. The large blue triangle consists of three smaller blue triangles, each of which itself consists of three smaller blue triangles, each of which ..., a process of subdivision which could, with adequate screen resolution, be seen to continue indefinitely.

Serpinski Triangle

What is a Serpinski Triangle?

A Serpinski Triangle is a triangle made up of 3 Serpinski triangles.

Weiss’s fundamental rules of recursion1. Base case: always have at least one case that can

be solved without recursion

2. Make progress: Any recursive call must progress toward the base case

3. “You gotta believe”: Always assume that the recursive call works. (In proofs “BTIH”).

4. Compound Interest rule: Never duplicate work by solving the same instance of a problem in separate recursive calls.

Example : Fibonacci Number

// Bad algorithm

public static long fib (int n) {

if (n <= 1)

return n;

else return fib (n-1) + fib(n-2);

}

Why is it bad?

Dynamic Programming If you can mathematically express a problem

recursively, then you can express it as a recursive algorithm.

However, sometimes, this can be inefficiently expressed by a compilerFibonacci numbers

To avoid this recursive “explosion” we can use dynamic programming

Example Problem: Making Change

For a currency with coins C1,C2,…Cn (cents) what is the minimum number of coins needed to make K cents of change?

US currency has 1,5,10, and 25 cent denominationsAnyone got a 50-cent piece?We can make 63 cents by using two quarters & 3

penniesWhat if we had a 21 cent piece?

63 cents

25,25,10,1,1,1

Suppose a 21 cent coin? 21,21,21 is optimal

Recursive Solution

1. If we can make change using exactly one coin, then that is a minimum

2. Otherwise for each possible value j compute the minimum number of coins needed to make j cents in change and K – j cents in change independently. Choose the j that minimizes the sum of the two computations.

public static int makeChange (int[] coins, int change){int minCoins = change;for (int k = 0;k<coins.length;k++)

if (coins[k] == change) return 1;for (int j = 1;j<= change/2;j++) {

int thisCoins = makeChange(coins,j)+makeChange(coins,change-j);

if (thisCoins < minCoins) minCoins = thisCoins;

}return minCoins;

}// How long will this take?

How many calls?63¢

62¢ 2¢1¢ 61¢ 31¢ 32¢. . .

How many calls?63¢

3¢1¢ 4¢ 61¢ 62¢. . .2¢

How many calls?63¢

3¢1¢ 4¢ 61¢ 62¢. . .2¢

How many calls?63¢

3¢1¢ 4¢ 61¢ 62¢. . .2¢

3¢1¢ 4¢ 61¢. . .2¢

How many times do you call for 2¢?63¢

3¢1¢ 4¢ 61¢ 62¢. . .2¢

3¢1¢ 4¢ 61¢. . .2¢

Some Solutions

1(1) & 62(21,21,10,10)

2(1,1) & 61(25,25,10,1)

. . . .

21(21) & 42(21,21)

….

31(21,10) & 32(21,10,1)

Improvements? Limit the inner loops to the coins

1 & 21,21,10,105 & 25,21,10,1,110 & 21,21,10,121 & 21,2125 & 25,10,1,1,1

Still, a recursive branching factor of 5How many times do we solve for 52 cents?

public static int makeChange (int[] coins, int change){

int minCoins = change;

for (int k = 0;k<coins.length;k++)

if (coins[k] == change) return 1;

for (int j = 1;j<= coins.length;j++) {

if (change < coins[j]) continue;

int thisCoins = 1+makeChange(coins,change-coins[j]);

if (thisCoins < minCoins) minCoins = thisCoins;

}

return minCoins;

}// How long will this take?

How many calls?63¢

58¢ 53¢62¢ 42¢ 38¢

48¢ 43¢52¢ 32¢ 13¢

57¢ 52¢61¢ 41¢ 37¢

Tabulation aka Dynamic Programming

Build a table of partial results. The trick is to save answers to the sub-problems in

an array. Use the stored sub-solutions to solve the larger

problems

DP for change making Find optimum solution for 1 cent Find optimum solution for 2 cents using previous Find optimum solution for 3 cents using previous …etc.

At any amount a, for each denomination d, check the minimum coins for the (previously calculated) amount a-d

We can always get from a-d to a with one more coin

public static int makeChange (int[] coins, int differentcoins, int maxChange, int[] coinsUsed, int [] lastCoin){coinsUsed[0] = 0; lastCoin[0]=1;for (int cents = 1; cents <= maxChange; cents++) {

int minCoins = cents; int newCoin = 1;for (int j = 0;j<differentCoins;j++) {

if (coins[j] > cents) continue;if (coinsUsed[cents – coins[j]]+1 < minCoins){

minCoins=coinsUsed[cents – coins[j]]+1;newCoin = coins[j];

}}coinsUsed[cents] = minCoins;lastCoin[cents] = newCoin;

}

Dynamic Programming solution

O(NK) N denominationsK amount of change

By backtracking through the lastCoin[] array, we can generate the sequence needed for the amount in question.