Presentation is loading. Please wait.

Presentation is loading. Please wait.

15. MORE RECURSIONS Rocky K. C. Chang November 22, 2015.

Similar presentations


Presentation on theme: "15. MORE RECURSIONS Rocky K. C. Chang November 22, 2015."— Presentation transcript:

1 15. MORE RECURSIONS Rocky K. C. Chang November 22, 2015

2 What have we learnt? Recursion is a divide-and-conquer approach to solving a complex problem. Divide, conquer, and glue Recursion has a “ base case ” and an “ inductive step. ” A recursive implementation essentially postpones the work until hitting the base case. Use a recursion tree to visualize the recursion process.

3 Objectives Understand recursive solution  a recursive implementation When (or not) to implement using recursion? Tail recursion

4 A RECURSIVE SOLUTION  A RECURSIVE IMPLEMENTATION

5 When (or not) to use recursion? For many problems, a forward reasoning suffices, i.e., using iteration. E.g., factorial (require 2 local variables and a for loop) E.g., birthday cake cutting (require 1 local variable and a single return statement) For some problems, a best way to implementing an recursive solution is not based recursion which Requires more memory space, and possibly takes a longer computation time for some cases. E.g., Fibonacci numbers

6 A recursion tree for fib(n) Source: Robert L. Kruse and Alexander J. Ryba, Data Structures and Program Design in C++, Prentice-Hall, Inc., 1999.

7 “Linearize” the recursion tree

8 Codes from A7 def main(): def fib(n): if (n==0 or n==1): return n else: last_but_one = 0 # The second previous Fib. number, i.e., fib(n-2) last_value = 1 # The previous Fib. number, i.e., fib(n-1) for i in range(2,n+1): current = last_but_one + last_value # The current Fib. number, i.e., fib(i) last_but_one = last_value # prepare fib(i-2) for the next i last_value = current # prepare fib(i-1) for the next i return current m = eval(input("Please input n for the nth Fibonacci number: ")) print("The",str(m)+"th","Fibonacci number is", fib(m)) main()

9 Tail recursion Tail recursion occurs when the last-executed statement of a function is a recursive call to itself. Are the following tail recursions? fact(n), cake_cut(n), fib(n) Computing , GCD, and Tower of Hanoi The tail recursion can be replaced by an iteration, i.e., an iterative implementation. Some cases involve examining the recursion tree starting from the base case(s), e.g., fact(n) and fib(n). Others involve a careful examination of what actually has taken place in the recursive step.

10 Example 1: Computing   Write R(n) = Q(1) × Q(2) × Q(3) × … × Q(n), where Q(1) = sqrt[ ½ + ½ sqrt( ½ )], Q(2) = sqrt[ ½ + ½ Q(1)], …, Q(n) = sqrt[ ½ + ½ Q(n – 1)].  Therefore, Base: R(1) = Q(1) Inductive step: Given R(n – 1) and Q(n – 1), Q(n) = sqrt[ ½ + ½ Q(n – 1)] and R(n) = R(n – 1) × Q(n).

11 Code from A7 import math def q(n): if n == 1: return math.sqrt(0.5+0.5*math.sqrt(0.5)) else: return math.sqrt(0.5+0.5*q(n-1)) def r(n): if n == 1: return q(1) else: return r(n-1)*q(n) def main(): n = eval(input("Please enter a positive integer for computing the value of Pi: ")) print("n ","The value of the estimated Pi") for i in range(1,n+1): pi = 2*math.sqrt(2)/r(i) print("{0:<5}{1:<0.50f}".format(i,pi)) main()

12 An iterative implementation First of all, observe that Q(n) has been computed repetitively. R(n) = R(n-1)  Q(n) Q(n)  Q(n-1)  …  Q(1) R(n-1) = R(n-2)  Q(n-1) Q(n-1)  Q(n-2)  …  Q(1) Altogether, Q(n-i) has been called i+1 times, where i = 0, …, n-1.

13 EXERCISE 15.1 Use iteration to implement this algorithm of approximating .

14 Example 2: GCD A recursive solution: Base: when b divides a, i.e., a mod b = 0. Induction: gcd(a, b) = gcd(b, a mod b) when a mod b ≠ 0. def gcd(a,b): if a % b == 0: return b else: return gcd(b,a % b) def main(): x, y = eval(input("Please enter two positive integers: ")) print("The GCD of", x, "and", y, "is", gcd(x,y)) main()

15 EXERCISE 15.2 Remove the recursion using iterations. Hint: Note that very recursion simply updates the two arguments until reaching the base case.

16 Example 3: Tower of Hanoi def main(): def Hanoi(n, a, b, c): if n == 1: print("Move a disc from", a, "to", b, "via", c) else: Hanoi(n-1, a, c, b) Hanoi(1, a, b, c) Hanoi(n-1, c, b, a) n = eval(input("Please enter the number of discs: ")) Hanoi(n, "A", "B", "C") print("Game over.") main()

17 Cutting the tail Note that we do not have to invoke the recursive call to move back the count – 1 disks from spare back to the destination. Instead, we can directly move the count – 2 disks from spare to source, which really serves as a spare. And then move the bottom disk from spare to destination. Moreover, this step repeats again for the count – 2 disks. Therefore, we can have an iteration to replace the last recursive call as follows.

18 A recursive-iterative solution def main(): def Hanoi(n, a, b, c): while n > 0: Hanoi(n-1, a, c, b) print("Move a disc from", a, "to", b, "via", c) n -= 1 a, c, b = c, b, a n = eval(input("Please enter the number of discs: ")) Hanoi(n, "A", "B", "C") print("Game over.") main()

19 Dynamic Programming of the Towers of Hanoi For brave souls, you could study http://penguin.ewu.edu/~trolfe/DynamicHanoi/ and www.acta.sapientia.ro/acta-info/C1-1/info1-8.pdf. http://penguin.ewu.edu/~trolfe/DynamicHanoi/ www.acta.sapientia.ro/acta-info/C1-1/info1-8.pdf

20 EXERCISE 15.3 Remove the recursion calls in the program for the basketball scores.

21 Summary A recursion solution  a recursive implementation Some recursive implementations slow down the computation. A tail recursion can be replaced by an iteration. The process of eliminating a tail recursion may not be simple.


Download ppt "15. MORE RECURSIONS Rocky K. C. Chang November 22, 2015."

Similar presentations


Ads by Google