1 recursion. 2 basic recursions break a problem into smaller identical problems –each recursive...

35
1 Recursion

Upload: horatio-bishop

Post on 16-Jan-2016

221 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

1

Recursion

Page 2: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

2

Basic Recursions

• Break a problem into smaller identical problems– Each recursive call solves an identical but smaller

problem.• Stop the break-down process at a special case whose

solution is obvious, (termed a base case)– Each recursive call tests the base case to

eventually stop.

– Otherwise, we fall into an infinite recursion.

Basic Recursions

Page 3: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

3

Example 1: The Sum of the First NPositive Integers• Definition:

sum(n) = n + (n-1) + (n-2) + … + 1 for any integer n > 0• Recursive relation;

sum(n) = n + [(n-1) + (n-2) + … + 1]= n + sum(n-1)

Looks so nice, but how about n == 1?sum(1) = 1 + sum(0), but the argument to sum( ) must be positive

• Final recursive definition:sum(n) = 1 if n = 1 (Base case)

= n + sum(n-1) if n > 1 (Recursive call)

Basic Recursions

Page 4: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

4

Recursive Definition of sum(n)int sum(int n){ if (n == 1) // base case return 1; else return n + sum(n-1); // recursive call A}

How should I test this function’s correctness?

Use the box method:

A box has each function’s local environment ex. cout << sum(3);

1. Arguments2. Local variables3. Place holder for the value returned by a called function4. A return value

n = 3

A: sum(n-1) = ?

return ?

Basic Recursions

Page 5: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

5

Box trace of sum(3)

n = 3A: sum(n-1)=?return ?

n = 2A: sum(n-1)=?return ?

n = 1

return 1

n = 3A: sum(n-1)= ?return ?

n = 2A: sum(n-1)=?return ?

n = 1

return 1

Each box corresponds to a function’s activation record or stack.

cout << sum(3);

13

36

Basic Recursions

Page 6: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

6

Example 2: The Factorial of n• Definition:

factorial(n) = n * (n-1) * (n-2) * … * 1 for any integer n > 0factorial(0) = 1

• Recursive relation;factorial(n) = n * [(n-1) * (n-2) * … * 1]

= n * factorial(n-1)Looks so nice, but how about n = 1?factorial(1) = 1 * factorial(0) but the argument to factorial( ) must be positive

• Final recursive definition:factorial(n) = 1 if n = 1

= n *factorial(n-1) if n > 1

Basic Recursions

Page 7: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

7

Recursive Definition of facotrial(n)int fact(int n){ if (n == 1) // base case return 1; else return n * fact(n-1); // recursive call A}

Trace its execution using the box method:

ex. cout << fact(3);

n = 3

A: fact(n-1) = ?

return ?

Basic Recursions

Page 8: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

8

Box trace of fact(3)

n = 3A: fact(n-1)=?return ?

n = 2A: fact(n-1)=?return ?

n = 1

return 1

n = 3A: fact(n-1)= ?return ?

n = 2A: fact(n-1)=?return ?

n = 1

return 1

cout << fact(3);

12

26

Basic Recursions

Page 9: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

9

Precondition of fact(n)

• Precondition: n >= 1• If the precondition is violated, what happen?

– Fact(0) calls fact(-1), which calls fact(-2), ….• For robustness, given a negative number or 0, fact should stop a

recursive call.

Always correct to recursions

int fact(int n){ if (n <= 1) // base case for n = 1 or bad args. return 1; else return n * fact(n-1); // recursive call A}

Basic Recursions

Page 10: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

10

Example 3: Printing Numbers in Any Base

How to convert a decimal to a hexadecimal

Dividend Remainder16) 1234567890(10)……..…16) 7716049(10)………616) 482253(10)………116) 30140(10)…13(D)16) 1883(10)…12(C)16) 117(10)…11(B)16) 7(10)……....516) 0(10)……....7

1. Divide by a base(16)

2. Print each reminder from the bottom:

75BCD16(16)

Basic Recursions

Page 11: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

11

Recursive Definition of printNum(n,base)void printNum(int n, int base){ static string DIGIT_TABLE = “0123456789abcdef”;

if (n >= base) // recursive call A printNum( n / base, base ); // else n < base base case cout << DIGIT_TALBE[ n % base ];}

Trace its execution using the box method:

ex. cout << print(123456789, 16);

n = 123456789, base = 16

A: fact(n-1) returns nothingPrint: n % base = ?

return nothing

Basic Recursions

Page 12: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

12

Example 4: Binary Search

• The search divides a list into two small sub-lists till a sub-list is no more divisible.

• Each step needs the top/tail indexes and a target item.

First half

First half

An entire sorted list

First half Second half

Second half

Can we call binarySearch( ) recursively?

Basic Recursions

Page 13: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

13

Binary Search (Recursive Version)

int binarySearch( const int array[], int top, int tail, int target ) {

int mid = (top + tail)/2;if ( target == array[mid] )

return mid;else if ( target < array[mid] )

return binarySearch( array, top, mid-1, target );else if ( target > array[mid] )

return binarySearch( array, mid+1, tail, target );}

Question: if it does not find the target, how can we stop this program?

Basic Recursions

Page 14: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

14

Binary Search Revisited

In the next recursive call,top = i + 1;tail = i;thus top > tail!!

Base cases: (1) if (target == array[mid]) return mid;(2) if top > tail return –1;

35 47

top tail

i i+1

mid = (top + tail)/2 = (i + i+1)/2 = itop = mid + 1 = i + 1

Basic Recursions

Page 15: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

15

Binary Search (Correct Recursive Version)

int binarySearch( const int array[], int top, int tail, int target ) {

int mid = (top + tail)/2;if ( target == array[mid] )

return mid; // find itelse if ( top > tail )

return -1; // cannot find itelse if ( target < array[mid] )

return binarySearch( array, top, mid-1, target );else if ( target > array[mid] )

return binarySearch( array, mid+1, tail, target );}

Basic Recursions

Page 16: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

16

Babies

Example 5: Multiplying Mice

Quite difficult to keep track of the

population explosion.

Month 1

Month 2

Month 4

Month 5

Month 3

Month 6

Month 7

Recursive relation:#babies in Month 7= #mice in Month 5#adults in Month 7 = #mice in Month 6

Basic Recursions

Page 17: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

17

The Fibonacci Sequence• mice(n) = mice(n-1) + mice(n-2)• Then, what are base cases?

• Recursive definition:

mice(1) = mice(0) + mice(-1) can’t happen.Thus, mice(1) = 1;

mice(2) = mice(1) + mice(0) can’t happen, either.Thus, mice(2) = 1;

mice(n) = 1 if n = 1 or 2mice(n-1) + mice(n-2) if n > 2

Basic Recursions

Page 18: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

18

Tracing mice(n)

m(6)Return m(5)+m(4)

m(5)Return m(4)+m(3)

m(4)Return m(3)+m(2)

m(3)Return m(2)+m(1)

m(2)Return 1

m(1)Return 1

m(3)Return m(2)+m(1)

m(1)Return 1

m(2)Return 1

m(1)Return 1

m(3)Return m(2)+m(1)

m(2)Return 1

m(4)Return m(3)+m(2)

1 1m(2)Return 1

m(2)Return 1

2 1

1 12

35

11 1

23

8

Basic Recursions

Page 19: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

19

Recursive Applications

• Discrete Mathematics (Combinatorics, Puzzles, Coding Theory)– Tower of Hanoi and Gray Code

• Divide and Conquer– Mergesort, Convex Hall, and Fast Fourier Transform

• Backtrack– 8 Queens, Maze and Classic Chess Program

• Fractal Figures– Koch, Sierpinski Allowhead, Gosper, Hilbert, and

Dragon curves

Recursive Applications

Page 20: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

20

Towers of Hanoi

A B C

Find how to move dishes from A to B using C.Restrictions:

Recursive Applications

Page 21: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

21

Solution

A B C

A B C

A B C

A B C

if we could move n-1 dishesfrom A to C via B,

we could move a dish, (i.e.,the last one) from A to B (via C),

and thereafter, we would move n-1Dishes from C to B via A!

move(n, A, B, C)

move(n-1, A, C, B)

move(1, A, B, C)

move(n-1, C, B, A)

In order to move n dishes fromA to B via C,

Recursive Applications

Page 22: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

22

Example Code#include <iostream>#include <stdlib.h>using namespace std;

void move( int n, char orig, char dest, char temp ) { if ( n == 1 ) cout << "move disk 1 from " << orig << " to " << dest << endl; else { move( n - 1, orig, temp, dest ); cout << "move disk " << n << " from " << orig << " to " << dest << endl; move( n - 1, temp, dest, orig ); }}

int main( int argc, char* argv[] ) { int nDishes = atoi( argv[1] ); move( nDishes, 'A', 'B', 'C' );

cout << "completed" << endl; return 0;}

Page 23: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

23

Tracing move(n, A, B, C)move(3, A, B, C)

move(2, A, C, B) move(1, A, B, C) move(2, C, B, A)

move(1, A, B, C)

move(1, A, C, B)

move(1, B, C, A)

move(1, C, A, B)

move(1, C, B, A)

move(1, A, B, C)

Locally, A is A, C is B, B is C. Locally C is A, B is B, A is C.

1

2

3

4

56

7

Recursive Applications

Page 24: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

24

Divide-and-Conquer AlgorithmsComputational Geometry – Finding a Convex Hall

• Divide:– Divide a problem into two

sub-problems recursively so that the sub-problems are calculated by themselves.

• Conquer:– Form a new solution from

the solutions answered by the sub-problems

Recursive Applications

The convex hull problemTrivial algorithm: O(n2)

Divide & conquer: O(nlogn)

Page 25: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

25

BacktrackTrace every combination until encountering a solution

• The eight queens problem– Place 8 queens on a 8 * 8

chessboard so that no queen can attack any other queen.

– Place a queen from the column 0 to 7 as checking if the queens placed on the former columns can attack the current queen.

Recursive Applications

Q

Q

Q

Q

Q

Q

Q

Q

Page 26: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

26

BacktrackThe Eight Queen Problem

• A Naïve Solution

Recursive Applications

Q

Q

Q

Q ??

Q

Q

for ( int col = 0; col < 7; col++ ) { for ( int row = 0; row < 7; row++ ) { if ( safeLocation( table, row, col ) ) { table[row][col] = true; break; } } // oops! No safe row to place a new queen // I got to go back to the previous column!}

• Then, how can I go back to the previous column? Just col--?

Page 27: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

27

BacktrackThe Eight Queen Problem

• A Recursive Solution:

Recursive Applications

Q

Q

Q

Q ??

Q

Q

[0,0] -> [0,1] NO [1,1] NO [2,1] -> [0,2] NO [1,2] NO [2,2] NO [3,2] NO [4,2] -> [0,3] NO [1,3] -> [0,4] NO [1,4] NO [2,4] NO [3,4] -> [0,5] NO [1,5] NO [2,5] NO [3,5] NO [4,5] NO [5,5] NO [6,5] NO [7,5] NO [4,4] NO [5,4] NO [6,4] NO [7,4] -> [0,5]

Page 28: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

28

BacktrackThe Eight Queen Problem

Recursive Applications

bool addQueen( bool t[SIZE][SIZE], int col ) { if ( col >= SIZE ) return true; // all cols have been examined for ( int row = 0; row < SIZE; row++ ) { if ( safeLocation( t, row, col ) ) { // this row may be a candidate t[row][col] = true; // place a new queen; if ( addQueen( t, col + 1 ) )

return true; // all the following cols were filled else

t[row][col] = false; // A wrong position. Try the next row } } return false; // all rows examined, but no candidates}

int main( ) { bool table[SIZE][SIZE]; // there are no matrix templates in STL

init( table ); // all table[i][j] = false; if ( addQueen( table, 0 ) ) print( table ); else cout << "no solution" << endl;}

Page 29: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

29

Fractal CurvesDrawing a Ruler

Recursive Applications

// java code to draw a rulervoid drawRuler( Graphics g, int left, int right, int level ){ if ( level < 1 ) return;

int mid = ( left + right ) / 2;

g.drawLine( mid, 80, mid, 80 – level * 5 );

drawRuler( g, left, mid – 1, level – 1 ); drawRuler( g, mid + 1, right, level – 1 );}

mid at level 3

mid at level 2 mid at level 2

mid at level 1 mid at level 1 mid at level 1 mid at level 1

Initial left Initial right

Page 30: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

30

Fractal CurvesDrawing a Koch Curve using a Turtle

Recursive Applications

class Turtle {public: Turtle( float initX=0.0, float initY=0.0, float initAngle=0.0 ) { ~Turtle( ); void draw( float d ); // draw a line from the current position for distance d void move( float d ); // simply move from the current position for distance d void turn( float a ); // turn left by angle a

private: float angle; // presented in degree but not in radian oftream out;};

int main( ) { Turtle t;

t.draw( 10 ); t.turn( 45 ); t.move( 10 ); t.draw( 10 );}

Page 31: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

31

Fractal CurvesDrawing a Koch Curve using a Turtle

Recursive Applications

class Koch : Turtle {public: Koch( float initX=0.0, float initY=0.0, float initAngle=0.0) : Turtle( initX, initY, initAngle ) { ) ~Koch( ); curve( int level, float length ) { if ( level > 1 ) { curve( level – 1, length ); turn( 60 ); curve( level – 1, length ); turn( -120 ); curve( level – 1, length ); turn( 60 ); curve( level – 1, length ); } draw( length ); }};

int main( ) { Koch k(100, 100, 0); k.curve( 3, 10 );}

Draw the level-3 Koch curve here

Page 32: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

32

Recursion and Efficiency

• Programmability– Capable of breaking down a complex problem– Based on mathematical induction

• Efficiency– The overhead associated with function calls

(Bookkeeping the current stack and creating a new one)

– The inherent inefficiency of some algorithm(Repeating the same computation)

Efficiency

Page 33: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

33

Efficiency of mice(n)

m(6)Return m(5)+m(4)

m(5)Return m(4)+m(3)

m(4)Return m(3)+m(2)

m(3)Return m(2)+m(1)

m(2)Return 1

m(1)Return 1

m(3)Return m(2)+m(1)

m(1)Return 1

m(2)Return 1

m(1)Return 1

m(3)Return m(2)+m(1)

m(2)Return 1

m(4)Return m(3)+m(2)

m(2)Return 1

m(2)Return 1

O(2n)

Efficiency

Page 34: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

34

Iterative Solution of mice(n)int iterativeMice(int n){

int previous = 1;int current = 1;int next = 1;for (int i = 3; i <= n; ++i) {

next = current + previous;previous = current;current = next;

}return next;

}

Efficiency of mice(n):O(n-2)=O(n)

Efficiency

Page 35: 1 Recursion. 2 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop

35

Recursion versus Iteration

• Discover a recursive solution if it is easier.• Convert it to iteration if an iterative solution is more efficient.

– When a recursion incurs more iterations– When each iteration includes a few computation

Problems Recursion IterationFibonacci sequence O(2n) O(n)Sum/Fact/printNum O(n) O(n)

function call overhead

Binary search O(log n) O(log n)Tower of Hanoi O(2n)Fractal figures (Koch) O(4n) Can you program it?

N queens O(Nn)

Efficiency