Download presentation
Presentation is loading. Please wait.
Published byHilary Kelly Modified over 9 years ago
1
CSS342: Recursion1 Professor: Munehiro Fukuda
2
CSS342: Recursion2 Topics Day 1: Lecture –Basic recursions 1.Sum 2.Fact 3.Print a number in any base 4.Binary search 5.Fibonacci sequence –Tracing recursions –Recursive applications Towers of Hanoi Divide & Conquer (Calculating the space of a given polynomial) Backtrack (8 queens) –Efficiency of recursion Day 2: Lab Work –Drawing Fractal Figures with Recursion Ruler Koch Curves Sierpinski Arrowhead Gosper or Hilbert Curves
3
CSS342: Recursion3 Basic Recursions Break a problem into smaller identical problems –Each recursive call solves an identical but smaller problem. a base caseStop 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
4
CSS342: Recursion4 Example 1: The Sum of the First N Positive 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
5
CSS342: Recursion5 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 environmentex. cout << sum(3); 1. Arguments 2. Local variables 3. Place holder for the value returned by a called function 4. A return value n = 3 A: sum(n-1) = ? return ? Basic Recursions
6
CSS342: Recursion6 Box trace of sum(3) n = 3 A: sum(n-1)=? return ? n = 2 A: sum(n-1)=? return ? n = 1 return 1 n = 3 A: sum(n-1)= ? return ? n = 2 A: sum(n-1)=? return ? n = 1 return 1 Each box corresponds to a function’s activation record or stack. cout << sum(3); 1 3 3 6 Basic Recursions
7
CSS342: Recursion7 Example 2: The Factorial of n Definition: factorial(n) = n * (n-1) * (n-2) * … * 1 for any integer n > 0 factorial(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
8
CSS342: Recursion8 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
9
CSS342: Recursion9 Box trace of fact(3) n = 3 A: fact(n-1)=? return ? n = 2 A: fact(n-1)=? return ? n = 1 return 1 n = 3 A: fact(n-1)= ? return ? n = 2 A: fact(n-1)=? return ? n = 1 return 1 cout << fact(3); 1 2 2 6 Basic Recursions
10
CSS342: Recursion10 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
11
CSS342: Recursion11 Example 3: Printing Numbers in Any Base How to convert a decimal to a hexadecimal Dividend Remainder 16) 1234567890 (10) ……..… 16) 7716049 (10) ………6 16) 482253 (10) ………1 16) 30140 (10) …13(D) 16) 1883 (10) …12(C) 16) 117 (10) …11(B) 16) 7 (10) ……....5 16) 0 (10) ……....7 1. Divide by a base(16) 2. Print each reminder from the bottom: 75BCD16(16) Basic Recursions
12
CSS342: Recursion12 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 < basebase 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 nothing Print: n % base = ? return nothing Basic Recursions
13
CSS342: Recursion13 Box trace of printNum(123456789, 16) Trace by yourself (This type of tracing problems will be given in your mid term.) Basic Recursions
14
CSS342: Recursion14 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 An entire sorted list First halfSecond half Can we call binarySearch( ) recursively? Basic Recursions
15
CSS342: Recursion15 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
16
CSS342: Recursion16 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; 3547 toptail ii+1 mid = (top + tail)/2 = (i + i+1)/2 = i top = mid + 1 = i + 1 Basic Recursions
17
CSS342: Recursion17 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 it else if ( top > tail ) return -1;// cannot find it else 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
18
CSS342: Recursion18 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
19
CSS342: Recursion19 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) = 1if n = 1 or 2 mice(n-1) + mice(n-2)if n > 2 Basic Recursions
20
CSS342: Recursion20 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) 11 m(2) Return 1 m(2) Return 1 21 112 35 111 23 8 Basic Recursions
21
CSS342: Recursion21 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
22
CSS342: Recursion22 Towers of Hanoi A BC Find how to move dishes from A to B using C. Restrictions: Recursive Applications
23
CSS342: Recursion23 Solution A BC A BC A BC A BC if we could move n-1 dishes from 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-1 Dishes 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 from A to B via C, Recursive Applications
24
CSS342: Recursion24 Example Code #include 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; }
25
CSS342: Recursion25 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 5 6 7 Recursive Applications
26
CSS342: Recursion26 Divide-and-Conquer Algorithms Computational 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 problem Trivial algorithm: O(n2) Divide & conquer: O(nlogn)
27
CSS342: Recursion27 Backtrack Trace 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
28
CSS342: Recursion28 Backtrack The 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--?
29
CSS342: Recursion29 Backtrack The 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]
30
CSS342: Recursion30 Backtrack The 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; }
31
CSS342: Recursion31 Fractal Curves Drawing a Ruler Recursive Applications // java code to draw a ruler void 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 1 Initial left Initial right
32
CSS342: Recursion32 Fractal Curves Drawing 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 ); }
33
CSS342: Recursion33 Fractal Curves Drawing 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
34
CSS342: Recursion34 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
35
CSS342: Recursion35 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(2 n ) Efficiency
36
CSS342: Recursion36 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
37
CSS342: Recursion37 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 ProblemsRecursionIteration Fibonacci sequenceO(2 n )O(n) Sum/Fact/printNumO(n) O(n) function call overhead Binary searchO(log n)O(log n) Tower of HanoiO(2 n ) Fractal figures (Koch)O(4 n ) Can you program it? N queensO(N n ) Efficiency
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.