css342: recursion1 professor: munehiro fukuda. css342: recursion2 topics day 1: lecture –basic...
Post on 23-Dec-2015
233 Views
Preview:
TRANSCRIPT
CSS342: Recursion 1
CSS342: Recursion
Professor: Munehiro Fukuda
CSS342: Recursion 2
TopicsDay 1: Lecture
– Basic recursions1. Sum2. Fact3. Print a number in any base4. Binary search5. Fibonacci sequence
– Tracing recursions– Recursive applications
• Towers of Hanoi• Divide & Conquer (Calculating the space of a given polynomial)• Backtrack (8 queens)
– Efficiency of recursionDay 2: Lab Work
– Drawing Fractal Figures with Recursion• Ruler• Koch Curves• Sierpinski Arrowhead• Gosper or Hilbert Curves
CSS342: Recursion 3
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 casea base case)
– Each recursive call tests the base case to eventually stop.
– Otherwise, we fall into an infinite recursion.
Basic Recursions
CSS342: Recursion 4
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
CSS342: Recursion 5
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
CSS342: Recursion 6
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
CSS342: Recursion 7
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
CSS342: Recursion 8
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
CSS342: Recursion 9
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
CSS342: Recursion 10
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
CSS342: Recursion 11
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
CSS342: Recursion 12
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
CSS342: Recursion 13
Box trace of printNum(123456789, 16)
Trace by yourself(This type of tracing problems will be given in your mid term.)
Basic Recursions
CSS342: Recursion 14
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
CSS342: Recursion 15
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
CSS342: Recursion 16
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
CSS342: Recursion 17
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
CSS342: Recursion 18
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
CSS342: Recursion 19
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
CSS342: Recursion 20
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
CSS342: Recursion 21
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
CSS342: Recursion 22
Towers of Hanoi
A B C
Find how to move dishes from A to B using C.Restrictions:
Recursive Applications
CSS342: Recursion 23
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
CSS342: Recursion 24
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;}
CSS342: Recursion 25
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
CSS342: Recursion 26
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)
CSS342: Recursion 27
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
CSS342: Recursion 28
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--?
CSS342: Recursion 29
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]
CSS342: Recursion 30
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;}
CSS342: Recursion 31
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
CSS342: Recursion 32
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 );}
CSS342: Recursion 33
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
CSS342: Recursion 34
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
CSS342: Recursion 35
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
CSS342: Recursion 36
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
CSS342: Recursion 37
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
top related