Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Recursion Jeff Edmonds York University COSC 2011 Lecture 5 Ruler Example One Step at a Time Stack of Stack Frames Friends and Strong Induction Recurrence.

Similar presentations


Presentation on theme: "1 Recursion Jeff Edmonds York University COSC 2011 Lecture 5 Ruler Example One Step at a Time Stack of Stack Frames Friends and Strong Induction Recurrence."— Presentation transcript:

1 1 Recursion Jeff Edmonds York University COSC 2011 Lecture 5 Ruler Example One Step at a Time Stack of Stack Frames Friends and Strong Induction Recurrence Relations Towers of Hanoi Check List Merge & Quick Sort Simple Recursion on Trees Binary Search Tree Things not to do Heap Sort & Priority Queues Trees Representing Equations Iterate over all s-t Paths Recursive Images

2 2 Andranik Mirzaian Draw Ruler drawLine( location, length ) put curser at location loop j = 1..length print(“-”)  1/4 , 3

3 3 Andranik Mirzaian Draw Ruler drawLine( location, length ) put curser at location loop j = 1..length print(“-”) drawRuler() drawLine(0,4) print(0) loop i = 1..12 drawLine(i,4) print(i) drawInterval(  i-1,i ,length-1)

4 4 Andranik Mirzaian Draw Ruler drawLine( location, length ) put curser at location loop j = 1..length print(“-”) drawRuler() drawLine(0,4) print(0) loop i = 1..12 drawLine(i,4) print(i) drawInterval(  i-1,i ,length-1)  1,2 , 3  0,1 , 3

5 5 Andranik Mirzaian Draw Ruler drawRuler() drawLine(0,4) print(0) loop i = 1..12 drawLine(i,4) print(i) drawInterval(  i-1,i ,length-1) drawLine( location, length ) put curser at location loop j = 1..length print(“-”) drawInterval(  a,b , length ) if ( length > 0 ) then mid = (a+b)/2 drawInterval (  a,mid , length-1 ) drawLine( mid, length ) drawInterval (  mid,b , length-1 )  0,1 , 4  0,1  4

6 6 Andranik Mirzaian drawInterval(  a,b , length ) if ( length > 0 ) then mid = (a+b)/2 drawInterval (  a,mid , length-1 ) drawLine( mid, length ) drawInterval (  mid,b , length-1 ) Draw Ruler drawRuler() drawLine(0,4) print(0) loop i = 1..12 drawLine(i,4) print(i) drawInterval(  i-1,i ,length-1) drawLine( location, length ) put curser at location loop j = 1..length print(“-”)

7 7 Friends & Strong Induction Recursive Algorithm: Assume you have an algorithm that works. Use it to write an algorithm that works. If I could get in, I could get the key. Then I could unlock the door so that I can get in. Circular Argument!

8 8 Friends & Strong Induction Recursive Algorithm: Assume you have an algorithm that works. Use it to write an algorithm that works. To get into my house I must get the key from a smaller house

9 9 Friends & Strong Induction Recursive Algorithm: Assume you have an algorithm that works. Use it to write an algorithm that works. Use brute force to get into the smallest house.

10 10 Friends & Strong Induction Recursive Algorithm: Assume you have an algorithm that works. Use it to write an algorithm that works. Use brute force to get into the smallest house. Advice: Do not trace it out. Trust your friend. Do your job.

11 11 PreconditionPostcondition On Step At a Time next I implored you to not worry about the entire computation. next It can be difficult to understand where computation go. i-1 i i i 0 T+1  x/4   3y (x-3  x 1 )  y Strange(x,y): x 1 =  x/4  ; y1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x1; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 );

12 12 Fibonacci(n): If n≤1 then return(n); else return( Fibonacci(n-1) + Fibonacci(n-2) ); 0123456789101112… 01123581321345589144… On Step At a Time Golden Ratio

13 13 Fibonacci(n): If n≤1 then return(n); else return( Fibonacci(n-1) + Fibonacci(n-2) ); On Step At a Time Cool enough But its entire computation can be understood in its entirety. In fact, it can be computed sequentially or by a formula. We need something harder.

14 14 Representations of Recursive Algorithms Pros Views Code Tracing out stack of stack frames Tree of stack frames Friends (strong induction) I need a higher level of understanding I am not a computer Crazy making Too much Must trust. Cons How implement for a computer How runs on computer View entire computation Worry about one step at a time Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 );

15 15 Code Representation Pros Views Code I need a higher level of understanding Cons How implement for a computer Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); Precise and succinct Perception that being able to code is the only thing needed to get a job. (false) I am not a computer Prone to bugs Language dependent

16 16 x = 30; y = 5 x 1 = 7; y 1 = 15 f 1 = Tracing out Stack of Stack Frames Stack Frame: A particular execution of one routine on one particular input instance. x = 7; y = 15 x 1 = 1; y 1 = 45 f 1 = x = 1; y = 45 return 45 Strange(30,5) = Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 );

17 17 x = 30; y = 5 x 1 = 7; y 1 = 15 f 1 = Tracing out Stack of Stack Frames Stack Frame: A particular execution of one routine on one particular input instance. Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); x = 7; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 4; y 2 = 15 f 2 = 45 x = 1; y = 45 return 45 x = 4; y = 15 x 1 = 1; y 1 = 45 f 1 = Strange(30,5) =

18 18 x = 30; y = 5 x 1 = 7; y 1 = 15 f 1 = Tracing out Stack of Stack Frames Stack Frame: A particular execution of one routine on one particular input instance. Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); x = 7; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 4; y 2 = 15 f 2 = return 105 45 x = 1; y = 15 return 15 x = 4; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 1; y 2 = 15 f 2 = return 60 15 60 45 Strange(30,5) =

19 19 x = 30; y = 5 x 1 = 7; y 1 = 15 f 1 = x 2 = 9; y 2 = 5 f 2 = Tracing out Stack of Stack Frames Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); 105 Stack Frame: A particular execution of one routine on one particular input instance. x = 9; y = 5 x 1 = 2; y 1 = 15 f 1 = x = 2; y = 15 return 30 Strange(30,5) =

20 20 Stack Frame: A particular execution of one routine on one particular input instance. Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); x = 9; y = 5 x 1 = 2; y 1 = 15 f 1 = x 2 = 3; y 2 = 5 f 2 = return 45 30 x = 3; y = 5 return 15 x = 30; y = 5 x 1 = 7; y 1 = 15 f 1 = x 2 = 9; y 2 = 5 f 2 = return 150 105 15 45 Strange(30,5) = 150 I am not a computer! This is crazy making Tracing out Stack of Stack Frames

21 21 Trace what actually occurs in the computer Concrete. It is what students attempt to describe when told not to give code. Described in words it is impossible to follow who is doing what. Does not explain why it works. Demonstrates for only one of many inputs. Pros:Cons: Tracing out Stack of Stack Frames

22 22 Tree of Stack Frames x = 30; y = 5 x 1 = 7; y 1 = 15 f 1 = x 2 = 9; y 2 = 5 f 2 = return 150 105 45 Strange(30,5) = 150 x = 1; y = 15 return 15 x = 7; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 4; y 2 = 15 f 2 = return 105 45 60 x = 1; y = 45 return 45 x = 4; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 1; y 2 = 15 f 2 = return 60 15 45 x = 1; y = 45 return 45 x = 9; y = 5 x 1 = 2; y 1 = 15 f 1 = x 2 = 3; y 2 = 5 f 2 = return 45 30 x = 3; y = 5 return 15 15 x = 2; y = 15 return 30

23 23 View the entire computation. Good for computing the running time. Must describe entire tree. –For each stack frame input instance computation solution returned. –who calls who Structure of tree may be complex. Pros:Cons: Tree of Stack Frames

24 24 Representations of Recursive Algorithms Pros Views Code Tracing out stack of stack frames Tree of stack frames Friends (strong induction) Must trust. Cons Worry about one step at a time Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 );

25 25 x = 30; y = 5 x 1 = 7; y 1 = 15 f 1 = x 2 = 9; y 2 = 5 f 2 = return 150 105 45 x = 1; y = 15 return 15 x = 7; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 4; y 2 = 15 f 2 = return 105 45 60 x = 1; y = 45 return 45 x = 4; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 1; y 2 = 15 f 2 = return 60 15 45 x = 1; y = 45 return 45 x = 9; y = 5 x 1 = 2; y 1 = 15 f 1 = x 2 = 3; y 2 = 5 f 2 = return 45 30 x = 3; y = 5 return 15 15 x = 2; y = 15 return 30 One Friend for each stack frame. Each worries only about his job. Imagine that you are one. Friends & Strong Induction

26 26 Consider your input instance If it is small enough solve it on your own. Allocate work –Construct one or more sub-instances It must be smaller and meet the precondition –Assume by magic your friends give you the answer for these. Use this help to solve your own instance. Do not worry about anything else. –Micro-manage friends by tracing out what they and their friend’s friends do. –Who your boss is. X = 7 Y = 15 XY = 105 X = 9 Y = 5 XY = 45 Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); ? Know Precond: ints x,y Postcond: ??? Friends & Strong Induction x = 30; y = 5 x 1 = 7; y 1 = 15 f 1 = 105 x 2 = 9; y 2 = 5 f 2 = 45 return 150

27 27 Consider generic instances.  x/4   3y (x-3  x 1 )  y Strange(x,y): x 1 =  x/4  ; y1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x1; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); Strange(x,y): If x < 4 then return( xy ); Remember! Do not worry about Who your boss is. How your friends solve their instance. Friends & Strong Induction Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 );

28 28 x = 30; y = 5 x 1 = 7; y 1 = 15 f 1 = x 2 = 9; y 2 = 5 f 2 = return 150 105 45 x = 1; y = 15 return 15 x = 7; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 4; y 2 = 15 f 2 = return 105 45 60 x = 1; y = 45 return 45 x = 4; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 1; y 2 = 15 f 2 = return 60 15 45 x = 1; y = 45 return 45 x = 9; y = 5 x 1 = 2; y 1 = 15 f 1 = x 2 = 3; y 2 = 5 f 2 = return 45 30 x = 3; y = 5 return 15 15 x = 2; y = 15 return 30 Friends & Strong Induction This solves the problem for every possible instance.

29 29 Worry about one step at a time. An abstraction within which to develop, think about, and describe algorithms in such way that their correctness is transparent. Students resist it. Students expect too much from their friends. Each sub-instance must be a smaller instance to the same problem. Students expect too much from their boss. You only know your instance. You do not know your boss’s instance. Pros:Cons: Friends & Strong Induction

30 30 So that we know –what is expected of us. –what we can expect from our friend. To be sure that we solve the problem for every legal instance. So that we know –what we can give to a friend. Carefully write the specifications for the problem. Required output : Set of legal instances (inputs) : Friends & Strong Induction

31 31 If you want more from your friends, change the pre and/or postconditions Be sure to document it. Be sure you and all of your friends are using the same pre/postconditions. Be sure to handle these changes yourself. Friends & Strong Induction

32 32 x = 30; y = 5 x 1 = 7; y 1 = 15 f 1 = x 2 = 9; y 2 = 5 f 2 = return 150 105 45 Strange(30,5) = 150 x = 1; y = 15 return 15 x = 7; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 4; y 2 = 15 f 2 = return 105 45 60 x = 1; y = 45 return 45 x = 4; y = 15 x 1 = 1; y 1 = 45 f 1 = x 2 = 1; y 2 = 15 f 2 = return 60 15 45 x = 1; y = 45 return 45 x = 9; y = 5 x 1 = 2; y 1 = 15 f 1 = x 2 = 3; y 2 = 5 f 2 = return 45 30 x = 3; y = 5 return 15 15 x = 2; y = 15 return 30 Friends & Strong Induction product x  y Know Precond: ints x,y Postcond: ???

33 33 Induction Strong Induction Friends & Strong Induction

34 34 Induction Hypothesis: ``The recursive algorithm works for every instance of size n.'' ``The algorithm works for every instance of any size.'' Base case size i Friends & Strong Induction Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); If x < 4 then return( xy ); return = Strange( x 1, y 1 ) + Strange( x 2, y 2 ) = Strange( x 1, 3y ) + Strange( x - 3  x 1, y ) = x 1  (3y) + (x - 3  x 1 )  y = 3x 1 y + xy - 3x 1 y = xy

35 35 Give and solve the recurrence relation for the Running Time of this algorithm. T(n) = aT(n/b)+n c Friends & Strong Induction

36 36 Recurrence Relations  Time of Recursive Program With all this recursing and looping, how do we determine the running time of this recursive program? procedure Eg(I n ) n = |I n | if(n  1) then put “Hi” else loop i=1..n c put “Hi” loop i=1..a I n/b = I n cut in b pieces Eg(I n/b ) T(1) = 1 T(n) = a T(n/b) + n c Recurrence relations.

37 37 Recurrence Relations  Time of Recursive Program Let n be the “size” of our input. procedure Eg(I n ) n = |I n | if(n  1) then put “Hi” else loop i=1..n c put “Hi” loop i=1..a I n/b = I n cut in b pieces Eg(I n/b ) T(1) = 1 T(n) = a T(n/b) + n c

38 38 Recurrence Relations  Time of Recursive Program Let T(n) be the # of “Hi”s printed by me procedure Eg(I n ) n = |I n | if(n  1) then put “Hi” else loop i=1..n c put “Hi” loop i=1..a I n/b = I n cut in b pieces Eg(I n/b ) T(1) = 1 T(n) = a T(n/b) + n c

39 39 Recurrence Relations  Time of Recursive Program Let T(n) be the # of “Hi”s printed by me And by all of my friends. procedure Eg(I n ) n = |I n | if(n  1) then put “Hi” else loop i=1..n c put “Hi” loop i=1..a I n/b = I n cut in b pieces Eg(I n/b ) T(1) = 1 T(n) = a T(n/b) + n c

40 40 If my input is sufficiently small (according to my measure of size) then I print  (1) “Hi”s. Recurrence Relations  Time of Recursive Program procedure Eg(I n ) n = |I n | if(n  1) then put “Hi” else loop i=1..n c put “Hi” loop i=1..a I n/b = I n cut in b pieces Eg(I n/b ) T(1) = 1 T(n) = a T(n/b) + n c

41 41 I personally output n c “Hi”s, i.e. top level stack frame. Recurrence Relations  Time of Recursive Program procedure Eg(I n ) n = |I n | if(n  1) then put “Hi” else loop i=1..n c put “Hi” loop i=1..a I n/b = I n cut in b pieces Eg(I n/b ) T(1) = 1 T(n) = a T(n/b) + n c

42 42 I have a friends i.e. recurse a times. Recurrence Relations  Time of Recursive Program procedure Eg(I n ) n = |I n | if(n  1) then put “Hi” else loop i=1..n c put “Hi” loop i=1..a I n/b = I n cut in b pieces Eg(I n/b ) T(1) = 1 T(n) = a T(n/b) + n c

43 43 Let b be the factor by which I shrink the input before giving it to a friend. i.e. if my input has size n then my friends are of size n/b. Recurrence Relations  Time of Recursive Program procedure Eg(I n ) n = |I n | if(n  1) then put “Hi” else loop i=1..n c put “Hi” loop i=1..a I n/b = I n cut in b pieces Eg(I n/b ) T(1) = 1 T(n) = a T(n/b) + n c

44 44 By definition of T, the number of “Hi”s printed by one of my friends and all of his friends is T(n/b). Recurrence Relations  Time of Recursive Program procedure Eg(I n ) n = |I n | if(n  1) then put “Hi” else loop i=1..n c put “Hi” loop i=1..a I n/b = I n cut in b pieces Eg(I n/b ) T(1) = 1 T(n) = a T(n/b) + n c

45 45 Hence, the total number printed by me and my a friends is T(n) = a T(n/b) + n c Recurrence Relations  Time of Recursive Program procedure Eg(I n ) n = |I n | if(n  1) then put “Hi” else loop i=1..n c put “Hi” loop i=1..a I n/b = I n cut in b pieces Eg(I n/b ) T(1) = 1 T(n) = a T(n/b) + n c

46 46 Technique 1 Guess and Verify Recurrence Relation: T(1) = 1 & T(n) = 4T(n/2) + n Guess: G(n) = 2n 2 – n Verify: Left Hand SideRight Hand Side T(1) = 2(1) 2 – 1 T(n) = 2n 2 – n 1 4T(n/2) + n = 4 [2( n / 2 ) 2 – ( n / 2 )] + n = 2n 2 – n

47 47 Technique 2: Decorate The Tree n T(n/2) T(n) = T(n) = n + 4 T(n/2) n T(n/2) T(n)T(n) = T(1) T(1) = 1 1 =

48 48 n T(n/2) T(n)T(n) =

49 49 n T(n/2) T(n)T(n) = n/2 T(n/4)

50 50 n T(n)T(n) = n/2 T(n/4) n/2 T(n/4) n/2 T(n/4) n/2 T(n/4)

51 51 n T(n)T(n) = n/2 11111111111111111111111111111111.... …………………….... 111111111111111111111111111111111 n/4

52 52 Evaluating: T(n) = aT(n/b)+f(n) Level 0 1 2 i h

53 53 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size 0 1 2 i h

54 54 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size 0n 1 2 i h

55 55 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size 0n 1 n/bn/b 2 i h

56 56 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size 0n 1 n/bn/b 2 n/b2n/b2 i h

57 57 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size 0n 1 n/bn/b 2 n/b2n/b2 i n/bin/bi h n/bhn/bh

58 58 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size 0n 1 n/bn/b 2 n/b2n/b2 i n/bin/bi h n/bhn/bh

59 59 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size 0n 1 n/bn/b 2 n/b2n/b2 i n/bin/bi h n/b h = 1 base case

60 60 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size 0n 1 n/bn/b 2 n/b2n/b2 i n/bin/bi h n/b h = 1

61 61 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size 0n 1 n/bn/b 2 n/b2n/b2 i n/bin/bi h = log n / log b n/b h = 1 b h = n h log b = log n h = log n / log b

62 62 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame 0n 1 n/bn/b 2 n/b2n/b2 i n/bin/bi h = log n / log b 1

63 63 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame 0n f(n)f(n) 1 n/bn/bf(n/b)f(n/b) 2 n/b2n/b2 f(n/b2)f(n/b2) i n/bin/bi f(n/bi)f(n/bi) h = log n / log b 1T(1)

64 64 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame # stack frames 0n f(n)f(n) 1 n/bn/bf(n/b)f(n/b) 2 n/b2n/b2 f(n/b2)f(n/b2) i n/bin/bi f(n/bi)f(n/bi) h = log n / log b n/bhn/bh T(1)

65 65 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame # stack frames 0n f(n)f(n) 1 1 n/bn/bf(n/b)f(n/b) a 2 n/b2n/b2 f(n/b2)f(n/b2) a2a2 i n/bin/bi f(n/bi)f(n/bi) aiai h = log n / log b n/bhn/bh T(1) ahah

66 66 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame # stack frames 0n f(n)f(n) 1 1 n/bn/bf(n/b)f(n/b) a 2 n/b2n/b2 f(n/b2)f(n/b2) a2a2 i n/bin/bi f(n/bi)f(n/bi) aiai h = log n / log b n/bhn/bh T(1) ahah

67 67 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame # stack frames 0n f(n)f(n) 1 1 n/bn/bf(n/b)f(n/b) a 2 n/b2n/b2 f(n/b2)f(n/b2) a2a2 i n/bin/bi f(n/bi)f(n/bi) aiai h = log n / log b n/bhn/bh T(1) ahah a h = a = n log n / log b log a / log b

68 68 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame # stack frames Work in Level 0n f(n)f(n) 1 1 n/bn/bf(n/b)f(n/b) a 2 n/b2n/b2 f(n/b2)f(n/b2) a2a2 i n/bin/bi f(n/bi)f(n/bi) aiai h = log n / log b n/bhn/bh T(1) n log a / log b

69 69 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame # stack frames Work in Level 0n f(n)f(n) 1 1 · f(n) 1 n/bn/bf(n/b)f(n/b) a a · f(n/b)a · f(n/b) 2 n/b2n/b2 f(n/b2)f(n/b2) a2a2 a 2 · f(n/b 2 ) i n/bin/bi f(n/bi)f(n/bi) aiai a i · f(n/b i ) h = log n / log b n/bhn/bh T(1) n log a / log b n · T(1) log a / log b Total Work T(n) = ∑ i=0..h a i × f(n/b i )

70 70 = ∑ i=0..h a i × f(n/b i ) If a Geometric Sum ∑ i=0..n x i = θ(max(first term, last term)) Evaluating: T(n) = aT(n/b)+f(n)

71 71 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame # stack frames Work in Level 0n f(n)f(n) 1 1 · f(n) 1 n/bn/bf(n/b)f(n/b) a a · f(n/b)a · f(n/b) 2 n/b2n/b2 f(n/b2)f(n/b2) a2a2 a 2 · f(n/b 2 ) i n/bin/bi f(n/bi)f(n/bi) aiai a i · f(n/b i ) h = log n / log b n/bhn/bh T(1) n log a / log b n · T(1) log a / log b Dominated by Top Level or Base Cases

72 72 Evaluating: T(n) = aT(n/b)+f(n)

73 73 Time for top level: Time for base cases: Dominated?: c = 1 < 2 = log a / log b θ(n ) = log a / log b θ(n ) = θ(n 2 ) log 4 / log 2 Hence, T(n) = ? = θ(base cases) = θ(n ) = θ(n 2 ). log a / log b Evaluating: T(n) = aT(n/b) + n c = 4T(n/2) + n n c = = n 1 1 If we reduce the number of friends from 4 to 3 is the savings just 25%?

74 74 n T(n)T(n) = n/2 T(n/4) n/2 T(n/4) n/2 T(n/4) n/2 T(n/4)

75 75 Time for top level: Time for base cases: Dominated?: c = 1 < 1.58 = log a / log b θ(n ) = log a / log b θ(n ) = θ(n 1.58 ) log 3 / log 2 Hence, T(n) = ? = θ(base cases) = θ(n ) = θ(n 1.58 ). log a / log b Evaluating: T(n) = aT(n/b) + n c = 3T(n/2) + n n c = = n 1 1 Not just a 25% savings! θ(n 2 ) vs θ(n 1.58.. )

76 76 Time for top level: n 2, c=2 Time for base cases: Dominated?: c = 1.58 = log a / log b θ(n ) = log a / log b θ(n ) = θ(n 1.58 ) log 3 / log 2 Hence, T(n) = ? = θ(top level) = θ(n 2 ). Evaluating: T(n) = aT(n/b) + n c = 3T(n/2) + n 2 2 >

77 77 Time for top level: n 1.58, c=1.58 Time for base cases: Dominated?: c = 1.58 = log a / log b Hence, all θ(logn) layers require a total of θ(n 1.58 ) work. The sum of these layers is no longer geometric. Hence T(n) = θ(n 1.58 logn) θ(n ) = log a / log b θ(n ) = θ(n 1.58 ) log 3 / log 2 Evaluating: T(n) = aT(n/b) + n c = 3T(n/2) + n 1.58

78 78 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame # stack frames Work in Level 0n f(n)f(n) 1 1 · f(n) 1 n/bn/bf(n/b)f(n/b) a a · f(n/b)a · f(n/b) 2 n/b2n/b2 f(n/b2)f(n/b2) a2a2 a 2 · f(n/b 2 ) i n/bin/bi f(n/bi)f(n/bi) aiai a i · f(n/b i ) h = log n / log b n/bhn/bh T(1) n log a / log b n · T(1) log a / log b All levels the same: Top Level to Base Cases

79 79 Evaluating: T(n) = aT(n/b)+f(n)

80 80 Logs log 27 log 9 =

81 81 Logs log ? 27 log ? 9 = Which base?

82 82 Logs log 2 27 log 2 9 = It does not matter. log 2 c · log c 27 · log c 9 = log c 27 log c 9 Which is easiest?

83 83 Logs log 3 27 log 3 9 = log 3 3 3 log 3 3 2 = 3 2 Please no calculators in exams. And I wont ask log 25 log 9

84 84 Evaluating: T(n) = aT(n/b)+f(n)

85 85  x/4   3y (x-3  x 1 )  y Strange(x,y): x 1 =  x/4  ; y1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x1; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); Evaluating: T(n) = aT(n/b)+n c The number of friends is a = 2. T(n) = 2T(n/b)+n c

86 86 Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); Evaluating: T(n) = aT(n/b)+n c The subinstances need to be smaller, but y 1 =3y is bigger! But we get to decide what is the “size” of the instance as long as –It gets smaller for every friend x 1 ≤ x/4 x 2 = x - 3  x 1  x - 3  x/4 = x/4 Hence, we can let “size” be x. Each subinstance size is x/4, i.e. b=4. –If it is sufficiently small, then we must solve it on our own. If x < 4 then return( xy ); T(n) = 2T(n/b)+n c T(x) = 2T(x/4)+x c

87 87 Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); Evaluating: T(n) = aT(n/b)+n c The work I personally do is denoted f(x) = x c. –  x/4  requires removing 2 lower order bits. –We will charge  (1) for additions –Hence, f(x) =  (1) = x c for c=0. T(x) = 2T(x/4)+x c T(x) = 2T(x/4)+x 0

88 88 Evaluating: T(n) = aT(n/b)+n c Time for top level: Time for base cases: Dominated?: c = 0 = log a / log b θ(x ) = log a / log b θ(x ) = θ(x 1/2 ) log 2 / log 4 Hence, T(x) = ? = θ(base cases) = θ(x ) = θ(x 0.5 ). log a / log b x c = = x 0 0 T(x) = 2T(x/4)+x 0

89 89 Multiplication Algorithms Kindergarten x = n2 n Grade Schooln2n2 Fastest Knownn logn 3*4=3+3+3+3 Strange (2 friends) x 1/2

90 90 Evaluating: T(n) = aT(n/b)+n c Time for top level: Time for base cases: Dominated?: c = 0 < ½ = log a / log b θ(x ) = log a / log b θ(x ) = θ(x 1/2 ) log 2 / log 4 Hence, T(x) = ? = θ(base cases) = θ(x ) = θ(x 0.5 ). log a / log b x c = = x 0 0 If we reduce the number of friends from 2 to 1 is the savings just 50%? T(x) = 2T(x/4)+x 0

91 91 Evaluating: T(n) = aT(n/b)+n c T(x) = T(x/4)+x 0 Time for top level: Time for base cases: (Note if I have one friend and so does he, then there is only one base case.) Dominated?: c = 0 = log a / log b Hence, all θ(logx) layers require a total of θ(1) work. The sum of these layers is no longer geometric. Hence T(x) = θ(logx) = θ(logX). We should charge θ(logX) instead of θ(1) for additions. Then the total time is θ(log 2 X) = θ(n 2 ) where n = # of bits in input. θ(n ) = log a / log b θ(n ) = θ(n 0 ) = 1 log 1 / log 4 n c = = n 0 0 1

92 92 Strange(x,y): If x < 4 then return( xy ); x 1 =  x/4  ; y 1 = 3y; f 1 = Strange( x 1, y 1 ); x 2 = x - 3  x 1 ; y 2 = y; f 2 = Strange( x 2, y 2 ); return( f 1 +f 2 ); Evaluating: T(n) = aT(n/b)+n c x 1 and x 2 are both about x/4. T(x) = T(x/4)+x 0 1 y 1 =3y and y 2 = y but was just to make the program strange. If the two friends are “identical”, why have two? Strange(x,y): If x≤0 then return( 0 ); f = Strange(  x / 2 , y ); If x is even return( 2  f ); else return( 2  f+y ); y even x = x/2 x/2 y x/2 x/2 f f y odd x = x/2x/2 y x/2x/2 1 f f y

93 93 Multiplication Algorithms Kindergarten x = n2 n Grade Schooln2n2 Fastest Knownn logn 3*4=3+3+3+3 Strange (2 friends) x 1/2 Strange (1 friends) n2n2

94 94 The Overhead Costs of Recursion Many problems are naturally defined recursively. This can lead to simple, elegant code. However, recursive solutions entail a cost in time and memory: each recursive call requires that the current process state (variables, program counter) be pushed onto the system stack, and popped once the recursion unwinds. This typically affects the running time constants, but not the asymptotic time complexity (e.g., O(n), O(n 2 ) etc.) Thus recursive solutions may still be preferred unless there are very strict time/memory constraints.

95 95 Output Try explaining what this algorithm does by tracing it out. I dare you!!! It is much easier to TAKE ONE STEP AT A TIME

96 96 n=1 X n=2 Y Output

97 97 n=1 X n=2 n=3 Y A ? B ? C Output

98 98 n=1 X n=2 n=3 Y A Y B X C Output

99 99 n=1 X n=2 n=3 Y AYBXC Output

100 100 n=1 X n=2 n=3 n=4 Y AYBXC A ? B ? C Output

101 101 n=1 X n=2 n=3 n=4 Y AYBXC A AYBXC B Y C Output

102 102 n=1 X n=2 n=3 n=4 Y AYBXC AAYBXCBYC Output

103 103 n=1 X n=2 n=3 n=4 n=5 Y AYBXC AAYBXCBYC A ? B ? C Output

104 104 n=1 X n=2 n=3 n=4 n=5 Y AYBXC AAYBXCBYC AAAYBXCBYCBAYBXCC Output

105 105 n=1 X n=2 n=3 n=4 n=5 Y AYBXC AAYBXCBYC AAAYBXCBYCBAYBXCC Output

106 106 Time: T(1) =  2T(n-1) +3 T(n-1) + T(n-2) + 3 T(n) = 1 1 T(2) = = 2  (n) defined?

107 107 Towers of Hanoi This job of mine is a bit daunting. Where do I start? And I am lazy.

108 108 Towers of Hanoi At some point, the biggest disk moves. I will do that job.

109 109 Towers of Hanoi To do this, the other disks must be in the middle.

110 110 Towers of Hanoi How will these move? I will get a friend to do it. And another to move these. I only move the big disk.

111 111 Towers of Hanoi

112 112 Towers of Hanoi Get a job at the Towers of Hanoi company at level n=1,2,3,4,….. Or get transferred in as the president & you decide what your vice president does.

113 113 Towers of Hanoi Time: T(1) = 1, T(n) = ≈ 2(2T(n-2)) ≈ 4(2T(n-3)) ≈ 2T(n-1) ≈ 4T(n-2) ≈ 8T(n-3) ≈ 2 i T(n-i) ≈ 2 n 1 + 2T(n-1)

114 114 Evaluating: T(n) = aT(n-b)+f(n) h = ? n-hb n-ib n-2b n-b T(0) f(n-ib) f(n-2b) f(n-b) f(n) n Work in Level # stack frames Work in stack frame Instance size a aiai a2a2 a 1 n/bn/b a · T(0) a i · f(n-ib) a 2 · f(n-2b) a · f(n-b) 1 · f(n) n/bn/b |base case| = 0 = n-hb h = n / b i 2 1 0 Level Likely dominated by base cases Exponential

115 115 Evaluating: T(n) = 1T(n-b)+f(n) h = ? Work in Level # stack frames Work in stack frame Instance size 1 1 1 1 1 f(0) f(n-ib) f(n-2b) f(n-b) f(n) n-b n n-hb n-ib n-2b T(0) f(n-ib) f(n-2b) f(n-b) f(n) h = n / b i 2 1 0 Level Total Work T(n) = ∑ i=0..h f(b·i) = θ(f(n)) or θ(n · f(n))

116 116 Evaluating: T(n) = aT(n/b)+f(n)

117 117 Check Lists for Recursive Programs This is the format of “all” recursive programs. Don’t deviate from this. Or else!

118 118 Check Lists for Recursive Programs This is input instance is your mission. You must return this output. (An x, y, & z in every computation path.) Focus on your mission.

119 119 Check Lists for Recursive Programs The & must document these variables and what you must do.

120 120 Check Lists for Recursive Programs To get help, you construct an instance for each friend It must be valid and smaller. And pass them to them.

121 121 Check Lists for Recursive Programs Each friend returns a solution his sub-instance. Trust him to do this. But don’t expect him to do or know anything else.

122 122 Check Lists for Recursive Programs Combine their solutions to construct a solution to your instance. Return your solution.

123 123 Check Lists for Recursive Programs If your solution is too small to get solved by the general technique solve it yourself. Be sure you handle every legal instance.

124 124 Check Lists for Recursive Programs You rarely need to change the values of these variable beyond their initial setting (this is not an iterative algorithm.) Your rarely need additional input, output, or local variable. But it you do document them.

125 125 Check Lists for Recursive Programs Have NO global variables. If you change the value of a local variable n, neither your friends nor your boss get that value.

126 126 Sorting Problem Specification : The input is a list of n values with the same value possibly repeated. : The output is a list consisting of the same n values in non-decreasing order. 88 14 98 25 62 52 79 30 23 31 14,23,25,30,31,52,62,79,88,98

127 127 Recursive Sorts Given list of objects to be sorted Split the list into two sub-lists. Recursively have a friend sort the two sub-lists. Combine the two sorted sub-lists into one entirely sorted list.

128 128 Minimal effort splitting Lots of effort recombining Lots of effort splitting Minimal effort recombining Four Recursive Sorts Merge SortInsertion Sort Quick SortSelection Sort Size of Sub-lists n/2,n/2 n-1,1

129 129 Merge Sort 88 14 98 25 62 52 79 30 23 31 Divide and Conquer

130 130 Merge Sort 88 14 98 25 62 52 79 30 23 31 Split Set into Two (no real work) 25,31,52,88,98 Get one friend to sort the first half. 14,23,30,62,79 Get one friend to sort the second half.

131 131 Merge Sort Merge two sorted lists into one 25,31,52,88,9814,23,30,62,7914,23,25,30,31,52,62,79,88,98

132 132

133 133 Merge Sort Sort Time: T(n) = =  (n log(n)) 2T(n/2) +  (n) Total work at any level =  (n) # levels =  (log(n))

134 134 Evaluating: T(n) = aT(n/b)+f(n) Level Instance size Work in stack frame # stack frames Work in Level 0n f(n)f(n) 1 1 · f(n) 1 n/bn/bf(n/b)f(n/b) a a · f(n/b) 2 n/b2n/b2 f(n/b2)f(n/b2) a2a2 a 2 · f(n/b 2 ) i n/bin/bi f(n/bi)f(n/bi) aiai a i · f(n/b i ) h = log n / log b n/bhn/bh T(1) n log a / log b n · T(1) log a / log b Total Work T(n) = ∑ i=0..h a i  f(n/b i ) 2T(n/2) +  (n) 2 i ·  (n/2 i ) =  (n) =  (n) · log(n) All levels basically the same.

135 135 Java Implementation Andranik Mirzaian

136 136 Java Implementation Andranik Mirzaian

137 137 Quick Sort 88 14 98 25 62 52 79 30 23 31 Divide and Conquer

138 138 Quick Sort 88 14 98 25 62 52 79 30 23 31 Partition set into two using randomly chosen pivot 14 25 30 23 31 88 98 62 79 ≤ 52 ≤

139 139 Quick Sort 14 25 30 23 31 88 98 62 79 ≤ 52 ≤ 14,23,25,30,31 Get one friend to sort the first half. 62,79,98,88 Get one friend to sort the second half.

140 140 Quick Sort 14,23,25,30,31 62,79,98,8852 Glue pieces together. (No real work) 14,23,25,30,31,52,62,79,88,98 Faster Because all done “in place” ie in the input array

141 141

142 142 Quick Sort 88 14 98 25 62 52 79 30 23 31 Let pivot be the first element in the list? 14 25 30 23 88 98 62 79 ≤ 31 ≤ 52

143 143 Quick Sort ≤ 14 ≤ 14,23,25,30,31,52,62,79,88,98 23,25,30,31,52,62,79,88,98 If the list is already sorted, then the slit is worst case unbalanced.

144 144 Quick Sort Best Time: Worst Time: Expected Time: T(n) = 2T(n/2) +  (n) =  (n log(n))

145 145 Quick Sort T(n) = 2T(n/2) +  (n) =  (n log(n)) Best Time: Worst Time: Expected Time: =  (n 2 ) T(n) = T(0) + T(n-1) +  (n)

146 146 Quick Sort T(n) = 2T(n/2) +  (n) =  (n log(n)) Best Time: T(n) = T(0) + T(n-1) +  (n) Worst Time: Expected Time: =  (n 2 ) T(n) = T( 1 / 3 n) + T( 2 / 3 n) +  (n) =  (n log(n))

147 147 Quick Sort Expected Time: T(n) = T( 1 / 3 n) + T( 2 / 3 n) +  (n) =  (n log(n)) Top work  (n) 2 nd level 3 rd level # levels = (n)(n) (n)(n) 1/31/3 1/31/3 1/31/3 2/32/3 2/32/3 2/32/3 2/32/3  (log(n)) 3/23/2 log (n)

148 148 Java Implementation Andranik Mirzaian148

149 149 K th Element Problem Specification : The input is a list of n values and an integer k. : The k th smallest in the list. 88 14 98 25 62 52 79 30 23 31 14,23,25,30,31,52,62,79,88,98 k=3 Output: 25

150 150 88 14 98 25 62 52 79 30 23 31 Partition set into two using randomly chosen pivot 14 25 30 23 31 88 98 62 79 ≤ 52 ≤ K th Element Problem Specification

151 151 14 25 30 23 31 88 98 62 79 ≤ 52 ≤ K th Element Problem Specification k=3 r=5 elements on left 14,23,25,30,31 Get one friend to find k=3 rd element in first half. Output: 25

152 152 14 25 30 23 31 88 98 62 79 ≤ 52 ≤ K th Element Problem Specification k=8 r=5 elements on left Get one friend to find k=8-5=3 rd element in second half. Output: 79 52,62,79,98,88

153 153

154 154 T(n) = K th Element Problem Specification =  (n) 1 T(n/2) +  (n) Best Time: Expected Time: Worst Time: n log a / log b # of base cases = = n 0 = 1 n log 1 / log 2 = n + n / 2 + n / 4 + n / 8 … +1

155 155 T(n) = =  (n) 1 T(n/2) +  (n) Expected Time: K th Element Problem Specification T(n) = 1 T(n-1) +  (n) Worst Time: ≈ n+T(n-1) ≈ n+(n-1)+T(n-2) ≈ n+(n-1)+(n-2)+T(n-3) ≈ n+(n-1)+(n-2)+(n-3)+…+1 ≈  (n 2 ) Best Time:

156 156 T(n) = =  (n) 1 T(n/2) +  (n) T(n) = 1 T( 2 / 3 n) +  (n) Expected Time: =  (n) K th Element Problem Specification T(n) = 1 T(n-1) +  (n) Worst Time: =  (n 2 ) Best Time:

157 157 N=7 N=2 N=1 N=2 N=1 N=2 N=1 N=4N=3 b4b4 b3b3 b 7 = b 3 × b 4 T(N) = 2T(N/2) + 1 =  (N) Size = log(b) + log(N) = 2  (n) Power bNbN

158 158 N=7 N=1 N=3 b3b3 b 7 = (b 3 ) 2 × b T(N) = 1T(N/2) + 1 =  (log(N)) Size = log(b) + log(N) =  (n) Power

159 159 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 (define)

160 160 Recursion on Trees A binary tree is: - the empty tree - a node with a right and a left sub-tree. 3 8 1 32 2 7 6 5 9 4 1 tree because (define)

161 161 Recursion on Trees A binary tree is: - the empty tree - a node with a right and a left sub-tree. 3 8 1 32 2 7 6 5 9 4 1 tree node (define)

162 162 Recursion on Trees A binary tree is: - the empty tree - a node with a right and a left sub-tree. 3 8 1 32 2 7 6 5 9 4 1 tree because (define)

163 163 Recursion on Trees A binary tree is: - the empty tree - a node with a right and a left sub-tree. 3 8 1 32 2 7 6 5 9 4 1 tree node (define)

164 164 Recursion on Trees A binary tree is: - the empty tree - a node with a right and a left sub-tree. 3 8 1 32 2 7 6 5 9 4 1 tree because (define)

165 165 Recursion on Trees A binary tree is: - the empty tree - a node with a right and a left sub-tree. 3 8 1 32 2 7 6 5 9 4 1 tree node tree (define)

166 166 Recursion on Trees A binary tree is: - the empty tree - a node with a right and a left sub-tree. 3 8 1 32 2 7 6 5 9 4 1 tree because empty (define)

167 167 Recursion on Trees number of nodes = ? 3 8 1 32 2 7 6 5 9 4 1 6 5 Get help from friends (friends)

168 168 Recursion on Trees number of nodes 3 8 1 32 2 7 6 5 9 4 1 = number on left + number on right + 1 = 6 + 5 + 1 = 12 6 5 (friends)

169 169 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 (communication) Being lazy, I will only consider my root node and my communication with my friends. I will never look at my children subtrees but will trust them to my friends. 6

170 170 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 (communication) We will only communicate through these walls  (1) info via the pre & post-conditions. 6

171 171 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 (communication) I know only what you tell me via the pre-condition. I tell you only what the post-condition instructs me to.

172 172 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 (communication) I certainly will tell you the answer for my subtree to the computational problem at hand

173 173 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 (communication) I can also tell you anything else about this subtree. Simply ask by changing the post-condition.

174 174 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 (communication) But remember, I know nothing about the outside world (root, other subtree, whether I am left or right.) except what you tell me.

175 175 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 (communication) I tell you extra information by changing the pre-condition. (Info about left subtree, the root, things my boss told me, …) 6

176 176 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 (communication) Of course if the pre or post-conditions change then I must fill this contract with my boss too. 6

177 177 Recursion on Trees Base Case ? 3 8 1 32 2 7 6 5 9 4 1 number of nodes 1 Are we done? (base case)

178 178 Recursion on Trees Base Case ? 3 8 1 32 2 7 6 5 9 4 1 number of nodes ? (base case)

179 179 Recursion on Trees Base Case ? 3 8 1 32 2 7 6 5 9 4 1 number of nodes 0 Better base case! (base case)

180 180 Recursion on Trees Base Case ? 3 8 1 32 2 7 6 5 9 4 1 number of nodes 1 Does this still need to be a base case? (base case)

181 181 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 0 0 number of nodes = number on left + number on right + 1 = 0 + 0 + 1 = 1 No! (base case)

182 182 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 0 0 Most programmers don’t use the empty tree as a base case. This causes a lot more work. (base case)

183 183 Recursion on Trees (code)

184 184 Recursion on Trees 3 Designing Program/Test Cases generic 3 3 0 0 0+0+1=1 n1n1 n2n2 n 1 + n 2 + 1 0 n1n1 n 1 +0+1 Same code works! Try same code 0 Base Case (cases)

185 185 Time: T(n) = Recursion on Trees This only works for balanced tree. We don’t know how many nodes on left vs right. How do we solve this? aT(n/b) +  (n c ) = 2T(n/2) +  (1) =  (n) = T(left) + T(right) +  (1) = ?? (time)

186 186 Time: T(n) = Recursion on Trees ∑ stack frame Work done by stack frame X = 2133 Y = 2312 ac = 483 bd = 396 (a+b)(c+d) = 1890 XY = 4931496 X = 21 Y = 23 ac = 4 bd = 3 (a+b)(c+d) = 15 XY = 483 X = 33 Y = 12 ac = 3 bd = 6 (a+b)(c+d) = 18 XY = 396 X = 54 Y = 35 ac = 15 bd = 20 (a+b)(c+d) = 72 XY = 1890 X = 2 Y = 2 XY=4 X = 1 Y = 3 XY=3 X = 3 Y = 5 XY=15 X = 3 Y = 1 XY=3 X = 3 Y = 2 XY=6 X = 6 Y = 3 XY=18 X = 5 Y = 3 XY=15 X = 4 Y = 5 XY=20 X = 9 Y = 8 XY=72 (time)

187 187 Recursion on Trees One stack frame for each node in the tree and for empty trees hang off And constant work per stack frame. =  (n) × Time: T(n) = ∑ stack frame Work done by stack frame  (1) =  (n) (time)

188 188 Recursion on Trees number of nodes = One friend for each sub-tree. 3 8 1 32 2 7 6 5 9 4 1 4 4 2 2 4 Many Children 4 + 2 + 4 + 2 + 1 = 13 (friends) (mult-children)

189 189 Recursion on Trees (code) (mult-children)

190 190 Recursion on Trees 3 Designing Program/Test Cases generic 3 3 0 +1=1 n1n1 n 1 + 1 Same code works! Try same code generic n1n1 n3n3 n 1 + n 2 + n 3 + 1 n2n2 But is this needed (if not the input) (cases) (mult-children)

191 191 Recursion on Trees (code) (mult-children)

192 192 Recursion on Trees One stack frame for each node in the tree And constant work per stack frame. =  (n) × Time: T(n) = ∑ stack frame Work done by stack frame  (1) =  (n)  (n) =  (n 2 ) (time) (mult-children)

193 193 Recursion on Trees Time: T(n) = ∑ stack frame Work done by stack frame  (edge Tree ) (time) (mult-children) = ∑ stack frame  (# subroutine calls)  (node Tree )  (n) = ∑ node  (# edge in node)

194 194 We pass the recursive program a “binary tree”. But what type is it really? This confused Jeff at first. class LinkedBinaryTree { class Node { E element; Node parent; Node left; Node right; } Node root = null; Tree Recursion on Trees

195 195 One would think tree is of type LinkedBinaryTree. Then getting its left subtree, would be confusing. class LinkedBinaryTree { class Node { E element; Node parent; Node left; Node right; } Node root = null; Tree Recursion on Trees left_Tree (LinkedBinaryTree tree)

196 196 One would think tree is of type LinkedBinaryTree. Then getting its left subtree, would be confusing. class LinkedBinaryTree { class Node { E element; Node parent; Node left; Node right; } Node root = null; Tree Recursion on Trees left_Tree (LinkedBinaryTree tree)

197 197 It is easier to have tree be of type Node. But it is thought of as the subtree rooted at the node pointed at. The left child is then class LinkedBinaryTree { class Node { E element; Node parent; Node left; Node right; } Node root = null; Tree Recursion on Trees (Node tree) tree tree.left or tree.Getleft() or Tree.leftSub(tree) or leftSub(tree)

198 198 But the outside user does not know about pointers to nodes. class LinkedBinaryTree { class Node { E element; Node parent; Node left; Node right; } Node root = null; public int NumberNodes() { return NumberNodesRec( root ); } Tree Recursion on Trees tree private int NumberNodesRec (Node tree) NumberNodesRec

199 199 Recursion on Trees sum of nodes = ? 3 8 1 32 2 7 6 5 9 4 1 23 25 Get help from friends (sum)

200 200 Recursion on Trees sum of nodes 3 8 1 32 2 7 6 5 9 4 1 = sum on left + sum on right + value at root = 23 + 25 + 3 = 51 23 25 (sum)

201 201 Recursion on Trees Base Case ? 3 8 1 32 2 7 6 5 9 4 1 sum of nodes = ? 0 (sum)

202 202 Recursion on Trees (sum)

203 203 Recursion on Trees 3 generic 3 3 0 s1s1 s2s2 s 1 + s 2 + 3 0 s1s1 s 1 + 3 0 0 0+0+ 3 =3 Designing Program/Test Cases (sum)

204 204 Recursion on Trees max of nodes = ? 3 8 1 32 2 7 6 5 9 4 1 8 9 Get help from friends (max)

205 205 Recursion on Trees max of nodes 3 8 1 32 2 7 6 5 9 4 1 = max( max on left, max on right, value at root) = max( 8, 9, 3) = 9 8 9 (max)

206 206 Recursion on Trees Base Case ? 3 8 1 32 2 7 6 5 9 4 1 max of nodes = ? ? (max)

207 207 3+4+2+8+… Sum so far is 17 Sum so far is0 Recursion on Trees NewSum = OldSum + nextElement = 0 + 3 = 3 (max)

208 208 3*4*2*3*… Product so far is 72 Product so far is1 Recursion on Trees NewProd = OldProd × nextElement = 1 × 3 = 3 (max)

209 209 True and True and False and … Conclusion so far is True Conclusion so far isTrue Recursion on Trees NewProd = OldProd and nextElement = True and True = True (max)

210 210 Max(3,4,2,3,… Max so far is 4 Max so far is -- Recursion on Trees NewMax = max(OldMax, next Element) = max( - , 3 ) = 3 (max)

211 211 Recursion on Trees (max)

212 212 Recursion on Trees height of tree = ? 3 8 1 32 2 7 6 5 9 4 1 3 4 Get help from friends (height)

213 213 Recursion on Trees height of tree 3 8 1 32 2 7 6 5 9 4 1 = max(height of left,height on right) + 1 = max(3,4) + 1 = 5 3 4 (height)

214 214 Recursion on Trees Base Case ? 3 8 1 32 2 7 6 5 9 4 1 height of tree ? (height)

215 215 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 height of tree? 2 nodes or 1 edge 0 nodes ? edges Base Case ? (height)

216 216 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 Work it out backwards ? edges height = = max(height of left,height on right) + 1 = max(?,?) + 1 ? ? 0 edge (height)

217 217 Recursion on Trees 3 8 1 32 2 7 6 5 9 4 1 Work it out backwards -1 edges height = = max(height of left,height on right) + 1 = max(-1,-1) + 1 0 edge (height)

218 218 Recursion on Trees (height)

219 219 Recursion on Trees number of leaves = ? 3 8 1 32 2 7 6 5 9 4 1 3 2 Get help from friends (#leaves)

220 220 Recursion on Trees number of leaves 3 8 1 32 2 7 6 5 9 4 1 = number on left + number on right = 3 + 2 = 5 3 2 (#leaves)

221 221 Recursion on Trees Base Case ? 3 8 1 32 2 7 6 5 9 4 1 number of leaves 0 (#leaves)

222 222 Recursion on Trees 3 generic 3 3 0 L1L1 L2L2 L 1 + L 2 0 L1L1 L1L1 0 0 0+0 = 0 Needs to be another base case. 1 No! Designing Program/Test Cases (#leaves)

223 223 Recursion on Trees (#leaves)

224 224 Recursion on Trees (travers)

225 225 Recursion on Trees (copy)

226 226 Recursion on Trees ? Drops the tree. (deallocate)

227 227 38 25 17 421 31 2835 51 42 4049 63 5571 Define Problem: Binary Search Tree –Key 25 –A binary search tree. – –Find key in BST (if there). Recursion on Trees (BST)

228 228 38 25 17 421 31 2835 51 42 4049 63 5571 Binary Search Tree Its left children ≤ Any node ≤ Its right children ≤ ≤ (BST)

229 229 Define Loop Invariant Maintain a sub-tree. If the key is contained in the original tree, then the key is contained in the sub-tree. key 17 38 25 17 421 31 2835 51 42 4049 63 5571 (BST)

230 230 Define Step Cut sub-tree in half. Determine which half the key would be in. Keep that half. key 17 38 25 17 421 31 2835 51 42 4049 63 5571 If key < root, then key is in left half. If key > root, then key is in right half. If key = root, then key is found (BST)

231 231 Recursion on Trees (BST)

232 232 Things to Remember Things to Do and Things NOT TO DO

233 233 Trust your friends to solve sub-instances. The sub-instance given must be smaller and must be an instance to the same problem. Combine solution given by friend to construct your own solution for your instance. Focus on one step. Do not talk of their friends friends friends. Solve small instances on your own. I am obsessed with the Friends - Strong Induction View of Recursion. Do it!

234 234 Define pre & post conditions Don't have inputs or outputs that are not explained! Typical Test Answer

235 235 Typical Test Answer Call recursively on the correct types of input k,num,v

236 236 Typical Test Answer Call recursively Save the results (or don't bother calling) returning the correct types of output

237 237 Typical Test Answer Combine solutions given by friends to construct your own solution.

238 238 Typical Test Answer Return things of the correct types. Not an element In every path through code the root?

239 239 Typical Test Answer Sub-instances need to be smaller. “Size” is size of the tree Wrong base case

240 240 Typical Test Answer Still zero. The friend has his own variable n. What is the value of n here? No Global Variables.

241 241 Typical Test Answer No Global Variables. Maybe they mean to pass the new n in and out. Please don’t use these to pass out values when I am marking.

242 242 Typical Test Answer Looks like an iterative algorithm Which is it? Looks like an recursive algorithm

243 243 Recursion on Trees Evaluate Equation Tree = ?  + 12 7 Get help from friends 3+4  7 (3+4)  7

244 244 Recursion on Trees Evaluate Equation Tree 7 7 = root op ( value on left, value on right ) = root op (7,7) = 7  7 = 49  + (3+4)  7

245 245 Recursion on Trees Evaluate Equation Tree 7 Base Case ?  + (3+4)  7

246 246

247 247 Derivatives Input: a function f. Output: Its derivative df / dx.

248 248 Derivatives

249 249 Derivatives Input: a function f. Output: Its derivative df / dx.

250 250 Derivatives Input: a function f. Output: Its derivative df / dx.

251 251 Derivatives Input: a function f. Output: Its derivative df / dx.

252 252 Derivatives Input: a function f. Output: Its derivative df / dx.

253 253 Derivatives Input: a function f. Output: Its derivative df / dx.

254 254 Derivatives Input: a function f. Output: Its derivative df / dx. g

255 255 Simplify Input: a function f. Output: f simplified.

256 256 Simplify

257 257 Iterate over all s-t Paths Precondition: Directed Acyclic Graph Postcondition: Iterate over all s-t paths.

258 258 Iterate(G,s,t) loop over all edges Iterate(G,v,t) Iterate over all s-t Paths Precondition: Directed Acyclic Graph Postcondition: Iterate over all s-t paths. For each edge, I get a friend to iterate over all v-t paths.

259 259 Iterate(G,s,t) loop over all edges Iterate(G,v,t) Iterate over all s-t Paths Precondition: Directed Acyclic Graph Postcondition: Iterate over all s-t paths. For each edge, I get a friend to iterate over all v-t paths.

260 260 Iterate(G,s,t) loop over all edges Iterate(G,v,t) Iterate over all s-t Paths Precondition: Directed Acyclic Graph Postcondition: Iterate over all s-t paths. For each edge, I get a friend to iterate over all v-t paths.

261 261 Iterate(G,s,t) loop over all edges Iterate(G,v,t) Iterate over all s-t Paths Precondition: Directed Acyclic Graph Postcondition: Iterate over all s-t paths. For each edge, I get a friend to iterate over all v-t paths. The number of such paths likely is 2  (n)

262 262 Recursive Images if n=0, draw else draw And recursively Draw here with n-1 if n=1 n=0

263 263 Recursive Images if n=0, draw else draw And recursively Draw here with n-1 if n=2 n=1

264 264 Recursive Images if n=0, draw else draw And recursively Draw here with n-1 if n=3 n=2

265 265 Recursive Images if n=0, draw else draw And recursively Draw here with n-1 if n=30

266 266 Recursive Images if n=1if n=2if n=3 if n=4 if n=5 if n=0

267 267 Recursive Images if n=1 if n=0 if n=2if n=3if n=4 if n=5

268 268 Recursive Images L(n) = 4 / 3 L(n-1)    = ( 4 / 3 ) n

269 269

270 270

271 271

272 272

273 273

274 274 Tail Recursion Tail recursion occurs when a linearly recursive method makes its recursive call as its last step. The array reversal method is an example. Such methods can be easily converted to non-recursive methods (which saves on some resources). Example: Algorithm IterativeReverseArray(A, i, j ) Input: An array A and valid indices i & j Output: sub-array A[i..j] reversed while i < j do Swap A[i ] and A[ j ] i  i+1, j  j – 1 end EECS2011: Recursion 274 Last Update: Oct 1, 2014

275 275 Please feel free to ask questions! Please give me feedback so that I can better serve you. Thanks for the feedback that you have given me already.

276 276 End

277 277 Input: Output: s=6*8+((2+42)*(5+12)+987*7*123+15*54) Parsing

278 278 Parsing

279 279 Parsing

280 280 Parsing Algorithm: GetExp( s, i ) Input: s is a string of tokens i is a start index Output: p is a parsing of the longest valid expression j is the end index s=6*8+((2+42)*(5+12)+987*7*123+15*54)

281 281 Parsing Algorithm: GetTerm( s, i ) Input: s is a string of tokens i is a start index Output: p is a parsing of the longest valid term j is the end index s=6*8+((2+42)*(5+12)+987*7*123+15*54)

282 282 Parsing Algorithm: GetFact( s, i ) Input: s is a string of tokens i is a start index Output: p is a parsing of the longest valid factor j is the end index s=6*8+((2+42)*(5+12)+987*7*123+15*54)

283 283 Algorithm: GetExp( s, i ) s=6*8+((2+42)*(5+12)+987*7*123+15*54) p

284 284 Algorithm: GetExp( s, i ) Exp … p + + +

285 285 Algorithm: GetTerm( s, i ) s=6*8+((2+42)*(5+12)+987*7*123+15*54) p

286 286 Algorithm: GetTerm( s, i ) Term … p * * *

287 287 Parsing Algorithm: GetFact( s, i ) s=6*8+((2+42)*(5+12)+987*7*123+15*54)

288 288 Parsing Algorithm: GetFact( s, i ) Fact 42

289 289 Algorithm: GetFact( s, i ) s=6*8+((2+42)*(5+12)+987*7*123+15*54) p

290 290 Algorithm: GetFact( s, i ) Fact p ()

291 291 Parsing Stackframes  nodes in parse tree


Download ppt "1 Recursion Jeff Edmonds York University COSC 2011 Lecture 5 Ruler Example One Step at a Time Stack of Stack Frames Friends and Strong Induction Recurrence."

Similar presentations


Ads by Google