640 likes | 780 Views
Recursive Definitions: functions, structures, languages. Section 4.3. 1. Recursively Defined Functions. A recursive (or inductive) definition for a function from f : N S : Specify the initial value of the function at n=0.
E N D
Recursive Definitions: functions, structures, languages Section 4.3 MSU/CSE 260 fall 2009 1
Recursively Defined Functions • A recursive (or inductive) definitionfor a function from f:N S: • Specify the initial value of the function at n=0. • Give a rule for finding its value at an integer from its values at smaller integers. 2 MSU/CSE 260 fall 2009
Example • Let f be defined recursively by: • f (0) = 3, • f (n) = 2 f (n - 1) + 3 for n≥ 1. • Let’s find f (1), f (2), f (3), f (4). • f (1) = 2f (0) + 3 = 2 3 + 3 = 9 • f (2) = 2f (1) + 3 = 2 9 + 3 = 21 • f (3) = 2f (2) + 3 = 2 21 + 3 = 45 • f (4) = 2f (3) + 3 = 2 45 + 3 = 93 … 3 MSU/CSE 260 fall 2009
Example • A recursive definition of the factorial function F(n) = n! • F(0) = 1 • F(1) = 1 • F(n) = n F(n - 1) for n≥ 1. This function is well defined (unambiguously) for all non negative integers n. F(0) is well defined. If F(k) is well defined, then so is F(k+1). Thus, F(n) is well defined for all n; F(n) exists and can be computed for all n using the above formula. 4 MSU/CSE 260 fall 2009
Example • The Fibonacci numbers, f0, f1, f2, …, are defined recursively by: • f0 = 0, • f1 = 1, • fn = fn-1 + fn-2 n≥ 2. • Let’s find f2, f3, f4, f5, f6. • f2 = f1 + f0 = 1 + 0 = 1 • f3 = f2 + f1 = 1 + 1 = 2 • f4 = f3 + f2 = 2 + 1 = 3 • f5 = f4 + f3 = 3 + 2 = 5 • f6 = f5 + f4 = 5 + 3 = 8 • Note the alternative notation: fn instead of f(n) 5 MSU/CSE 260 fall 2009
Fibonacci is well defined • Here we need strong induction. • fib(k) is defined for k=0 and k=1. • P(k): fib(k) is defined for 0,1, … ,k-2, k-1, k • P(0) and P(1) are trivially true as base cases • P(k) P(k+1) since f(k+1) = f(k) + f(k-1) and P(k) f(k) and f(k-1) are well defined MSU/CSE 260 fall 2009
C++ fibonacci function • int fibonacci ( int n ) • { • if ( n < 2 ) return 1; • else return ( fibonacci(n-1) • + • fibonacci(n-2) ); • } MSU/CSE 260 fall 2009
The sequence grows fast, so does the execution time for recursive computation. Give n - 0 Value of 0th Fibonacci number is 1 Give n - 3 Value of 3th Fibonacci number is 3 Give n - 20 Value of 20th Fibonacci number is 10946 Give n - 21 Value of 21th Fibonacci number is 17711 Give n - 22 Value of 22th Fibonacci number is 28657 Give n - 30 Value of 30th Fibonacci number is 1346269 Give n - 40 Value of 40th Fibonacci number is 165580141 MSU/CSE 260 fall 2009
Can layout F(n) in an array1 1 2 3 5 8 13 21 … • const int Limit=101; • int fibonacci ( int n ) // O(n) space and time • { • int F[Limit]; // 1 • F[0] = 1; F[1] = 1; // 2 • for (int k=2; k<=n; k++) // n • F[k] = F[k-2] + F[k-1]; // n-1 • return F[n]; // 1 • } MSU/CSE 260 fall 2009
Can get rid of O(n) storage • int fibonacci ( int n ) // runtime is still O(n) • { • int back1, back2, Fn; // need only 3 ints; O(1) • if ( n < 2 ) return 1; // same base case • back2 = 1; back1 = 1; • for (int k=2; k<=n; k++) • { • Fn = back2 + back1; • back2 = back1; • back1 = Fn; • } • return Fn; • } MSU/CSE 260 fall 2009
Example: Inductive definition for F(n) = 2n • F(0) = 1 • F(n) = F(n-1) + F(n-1) for n > 0 11 MSU/CSE 260 fall 2009
Example • F(0) = 1 • F(n) = F(n-1) + F(n-1) for n > 0 12 MSU/CSE 260 fall 2009
Example • F(0) = 1 • F(n) = F(n-1) + F(n-1) for n > 0 13 MSU/CSE 260 fall 2009
Example • F(0) = 1 • F(n) = F(n-1) + F(n-1) for n > 0 14 MSU/CSE 260 fall 2009
Example • F(0) = 1 • F(n) = F(n-1) + F(n-1) for n > 0 15 MSU/CSE 260 fall 2009
Example • F(1) = 1 • F(n) = F(n/2) + F(n/2) for n > 1 16 MSU/CSE 260 fall 2009
Recursive factorial in C++ So, a function is said to be defined recursively if its definition consists of An anchor or base case in which the function’s value is defined for one or more values of the parameters An inductive or recursive step in which the function’s value (or action) for the current parameter values is defined in terms of previously defined function values (or actions) and/or parameter values. int Factorial(int n){ if (n == 0) // base case return 1; else // recursive return n * Factorial(n - 1);} MSU/CSE 260 fall 2009
Tower of Hanoi puzzle See previous slides and worksheet. P(n): The Tower of Hanoi puzzle can be done with n disks MSU/CSE 260 fall 2009
Recursive step for Tower of Hanoi puzzle: move k ignoring biggest disk Move top k disks to middle post. Can be done as if biggest weren’t there! K disks Disk k+1 Disk k+1 K disks Disk k+1 Disk k+1 Now move disk k+1 to right post. Then move pile of K disks to right post. Can ignore biggest again. MSU/CSE 260 fall 2009
Analyzing Tower of Hanoi • It can be done with N=1 disk, AND with effort of 1 move, or 1 second. 2^1-1 = 1 • Assume that it can be done with k>=1 disks, AND with effort 2^k-1 • Prove P(N): it can be done with N disks with effort 2^N-1 take k+1 disks; move pile of top k to post A (2^k-1 effort) move big disk to post B in effort 1 move pile of k from post A to post B (2^k-1) total effort: (2^k-1) + 1 + (2^k-1) = 2^(k+1) - 1 MSU/CSE 260 fall 2009
Comments on Recursion There are several common applications of recursion where a corresponding iterative solution may not be obvious or easy to develop. Classic examples of such include Towers of Hanoi, path generation, multidimensional searching and backtracking. However, many common textbook examples of recursion are tail-recursive, i.e. the last statement in the recursive function is a single recursive invocation. Tail-recursive functions can be written more efficiently using a loop. MSU/CSE 260 fall 2009
int fibonacci ( int n ) { if ( n < 2 ) return 1; else return ( fibonacci(n-2) + fibonacci(n-1) ) ; } Give n - 0 Value of 0th Fibonacci number is 1 Give n - 1 Value of 1th Fibonacci number is 1 Give n - 2 Value of 2th Fibonacci number is 2 Give n - 3 Value of 3th Fibonacci number is 3 Give n - 4 Value of 4th Fibonacci number is 5 Give n - -1 Recursive function: not tail recursive MSU/CSE 260 fall 2009
Instrumented versions • // second 2 parameters are for study of behavior only • int fibonacci ( int n, int depth, int& N_calls) • { • N_calls = N_calls + 1; • if ( Debug > 0 ) • { cout << endl; • for (int k = 0; k<depth; k++) cout << " "; // just to indent • cout << " FIB: &n= " << &n << " n= " << n • << " depth= " << depth << " N_calls= " << N_calls; • } • if ( n < 2 ) return 1; • else return ( fibonacci(n-1, depth+1, N_calls) • + • fibonacci(n-2, depth+1, N_calls) ); • } MSU/CSE 260 fall 2009
F(4) requires F(3) and F(2) • Give n and Debug: • 4 1 • FIB: &n= 0xffbef964 n= 4 depth= 0 N_calls= 1 • FIB: &n= 0xffbef8ec n= 3 depth= 1 N_calls= 2 • FIB: &n= 0xffbef874 n= 2 depth= 2 N_calls= 3 begin F(2) • FIB: &n= 0xffbef7fc n= 1 depth= 3 N_calls= 4 • FIB: &n= 0xffbef7fc n= 0 depth= 3 N_calls= 5 • FIB: &n= 0xffbef874 n= 1 depth= 2 N_calls= 6 • FIB: &n= 0xffbef8ec n= 2 depth= 1 N_calls= 7 another F(2) • FIB: &n= 0xffbef874 n= 1 depth= 2 N_calls= 8 • FIB: &n= 0xffbef874 n= 0 depth= 2 N_calls= 9 • Value of 4th Fibonacci number is 5 • Number of calls = 9 MSU/CSE 260 fall 2009
Can layout F(n) in an array1 1 2 3 5 8 13 21 … • const int Limit=101; • int fibonacci ( int n ) // O(n) • { • int F[Limit]; 1 • F[0] = 1; F[1] = 1; 2 • for (int k=2; k<=n; k++) n • F[k] = F[k-2] + F[k-1]; n-1 • return F[n]; 1 • } MSU/CSE 260 fall 2009
Get rid of O(n) storage int fibonacci ( int n ) // runtime is still O(n) { int back1, back2, Fn; // need only 3 ints; O(1) if ( n < 2 ) return 1; // same base case back2 = 1; back1 = 1; for (int k=2; k<=n; k++) { Fn = back2 + back1; back2 = back1; back1 = Fn; } return Fn; } Conclusion: we do not need an array of storage and we can compute f(n) using only O(n) additions, although the code is not as pretty. MSU/CSE 260 fall 2009
Recursively Defined Sets • Recursive definition of a set has two parts: • Basic Step: Specifying a few elements of the set • Recursive Step: Defining rules for forming new elements of the set from previously defined elements • Exclusion Rule: The only elements in a recursively defined set are those elements that have been defined based on the elements of the basis step or the elements defined by recursive formula. 27 MSU/CSE 260 fall 2009
Example • Consider the set defined as follows: • Basis Step: 3 εS • Recursive Step: If xS and yS then x + yS Here are a few elements of 3+3 = 6, 3+6 = 9, 6+6 = 12, 3+9 = 12, … 28 MSU/CSE 260 fall 2009
Recursive definition and Strings • A string over an alphabet Σis a finite sequence of symbols from Σ • Examples: abfed, 11001, 2353, XYZT, … • Consider a string over the alphabet Σ. A new set of strings S over the alphabet Σ can be defined recursively by: • Basis step: λεS(λ is the empty string) • Recursive step: If ωεS and x∈Σ then ωxεS Example: Σ = {0,1} 29 MSU/CSE 260 fall 2009
Thinking Recursively; • Tower of Hanoi • Binary Search • Gossiping Problem • Quick Sort 30 MSU/CSE 260 fall 2009
Tower of Hanoi • Let Tnbe the minimum number of moves that will transfer n disks from one peg to another, according to the game rules. We have: • T1=1 • T2=3 • … • Tn=2Tn-1+ 1 31 MSU/CSE 260 fall 2009
Binary Search • Given an ordered list of items, the objective is to determine if the list contains a given item: • List: 3, 7, 8, 10, 14, 18, 22, 34 • Given item: 25 • Algorithms: • Linear Search • Binary Search • Let C(n) be the number of two-item comparisons required to determine if the list contains the given item. If we do it via binary search, we have (worst case scenario) : • C(1) = 1 • C(n) = 1 + C(n/2) 32 MSU/CSE 260 fall 2009
Combinations of n objects k at a time • How many unique subsets of size 5 from a set of 15 objects. How many bball teams possible from a bench of 15 players? • Comb(15, 5) = 15! / (5! * (15-5)!) definition 1 • Comb(n,0) = 1 the null set Comb(n,n) = 1 the full set Comb(n, k) = Comb(n-1,k) + Comb(n-1, k-1) Comb(3,2)=Comb(2,2)+Comb(2,1)=1+Comb(1,1) + Comb(1,0)=1+1+1=3 Take all but one object from the original set and add the new object n to each of those sets Take all objects from the original set of n-1 objects. All disjoint MSU/CSE 260 fall 2009
Combination • Note that: • C(n,n) = 1 since there is just one way to select n objects out of n objects • C(n,1) = n since there are n ways to select one object out of n objects. • C(n,2) = n(n-1)/2, the set of all pairs 34 MSU/CSE 260 fall 2009
example • S = { A, B, C } • 3 subsets of size 1 are { {A}, {B}, {C} } • Comb(3,1) = 3 • 3 subsets of size 2 are { {A,B}, {A,C}, {B,C} } • Consider adding element D to set S. • 6 subsets of size 2 from S = { A, B, C, D } • Take the 3 subsets { {A,B}, {A,C}, {B,C} } and the 3 subsets { {A}, {B}, {C} } with D added to each. These are the Comb(4, 2) = 6 subsets of size 2 of S = { A, B, C, D }. • Thus: Comb(n, k) = Comb(n-1,k) + Comb(n-1, k-1) MSU/CSE 260 fall 2009
This is the structure of the Pascal Triangle 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 Notes: element k in row n is Comb(n, k). It is the sum of the 2 closest elements in the row. The elements in row n account for all the subsets of {1, 2, 3, … , n }. Thus, the sum of elements in row n is 2^n MSU/CSE 260 fall 2009
A recursive fill or coloring algorithm Common in computer graphics and image processing. We will prove that the algorithm is correct. MSU/CSE 260 fall 2009
paint/fill algorithm • Object region must be bounded by color C • Start at any pixel [r,c] inside boundary of C • Recursively color neighbors MSU/CSE 260 fall 2009
A recursive fill algorithm Fills a bounded region in a 2D image with a given color C; Must have starting pixel location P=[r,c]; Color P with color C, then color all neighbors MSU/CSE 260 fall 2009
Why a good example? • important image operation • recursive example • can prove correctness • very general base algorithm with extensions to determine connectedness, solve a maze, find objects, etc MSU/CSE 260 fall 2009
Paint/fill algorithm overview • if image pixel I[r, c] already colored, return • color pixel: I[r, c] = C; • recurse on each neighbor of I[r, c] Note: In C++, the image reference will be I[r][c] MSU/CSE 260 fall 2009
Pixel neighborhoods 4-neighbors of PP 8-neighbors of PP N4 N3 N2 N2 r N3 PP N1 N5 PP N1 N6 N7 N8 N4 c MSU/CSE 260 fall 2009
Pre and Post conditions • Pre: region boundary marked with C is closed (so N-neighbors cannot leak out) • Pre: rest of image has color not C • Pre: pixel [r, c] is inside boundary • Post: every pixel inside boundary has color C • We will prove that the algorithm does yield the post condition MSU/CSE 260 fall 2009
Fill algorithm: next level of detail void fill ( image& I, const int r, c, const color C ) { if I[r, c] == C then return; I[r, c] = C; // set the pixel to the fill color for all neighbors I[r + delta_row, c + delta_col] fill ( image& I, r+delta_row, c+delta_col, C ) } MSU/CSE 260 fall 2009
Visiting pixels using a stack: optional void paint ( Image& I, int r, int c, int color ) { push r, c onto STACK; // replaces call stack of recursive fill while ( STACK not empty ) // are there more region pixels to visit? { pop c, r off STACK; if ( I[r][c] != background 0 or the current color ) { I[r][c] = color; // paint the current pixel for all neighbors of this pixel, push r+deltar, c+deltac onto STACK } } // when STACK is empty, all connected pixels have been visited } MSU/CSE 260 fall 2009
Worksheet for practice • consider given examples • trace algorithm and label pixels with color C and order k = 1, 2, 3, 4, … • consider how to compute area and bounding box • consider how to compute centroid MSU/CSE 260 fall 2009
Example 0 1 2 3 4 5 c 0 Start at pixel [ 3, 2 ] Use neighbor order right, up, left, down as (1, 2, 3, 4) Number each pixel that will be colored C with the order number in which it is reached and colored using the above recursive fill algorithm 1 C C C 2 C C r 3 C C 4 C C C 5 C MSU/CSE 260 fall 2009
Correctness proof by contradiction • suppose the pre conditions hold • prove the post condition follows • by contradiction: show that negative of post condition leads to a contradiction P MSU/CSE 260 fall 2009
Proof by contradiction • Assume some pixel U inside the region is NOT colored C by fill • Since U is inside the region, there must be a 8-connected (or 4-connected) path from P to U • Let L be the last pixel on this path that was colored by calling fill with start P • N is a neighbor of L; if L was colored C, then so must have been N because of the code structure of fill (contradiction) • Thus U must be colored whenever P is; or, every pixel that is connected to P by some 8-neighbor path must be colored C when function fill returns. MSU/CSE 260 fall 2009
Argue that process does not violate boundaries. • PRE: starting pixel within boundary • PRE: boundary encloses region so that there is no 4-connected path that can leave it • So, no region pixel can have a neighbor outside the boundary: neighbors are inside or on the boundary • Finite # pixels => function guaranteed to return MSU/CSE 260 fall 2009