Recursion yet another look To recurse is divine, to iterate is human.

Slides:



Advertisements
Similar presentations
Recursion –a programming strategy for solving large problems –Think “divide and conquer” –Solve large problem by splitting into smaller problems of same.
Advertisements

© Janice Regan, CMPT 102, Sept CMPT 102 Introduction to Scientific Computer Programming Recursion.
CS 106 Introduction to Computer Science I 11 / 09 / 2007 Instructor: Michael Eckmann.
Computer Science II Recursion Professor: Evan Korth New York University.
Unit 181 Recursion Definition Recursive Methods Example 1 How does Recursion work? Example 2 Problems with Recursion Infinite Recursion Exercises.
Slides prepared by Rose Williams, Binghamton University Chapter 11 Recursion.
Slides prepared by Rose Williams, Binghamton University Chapter 11 Recursion.
Chapter 10 Recursion. Copyright © 2005 Pearson Addison-Wesley. All rights reserved Chapter Objectives Explain the underlying concepts of recursion.
Chapter 11 Recursion Copyright © 2010 Pearson Addison-Wesley. All rights reserved.
CS 106 Introduction to Computer Science I 03 / 28 / 2008 Instructor: Michael Eckmann.
CS 106 Introduction to Computer Science I 03 / 30 / 2007 Instructor: Michael Eckmann.
CHAPTER 10 Recursion. 2 Recursive Thinking Recursion is a programming technique in which a method can call itself to solve a problem A recursive definition.
Even Numbers – Any number that can be divided by 2
Recursion James Wright St Peter’s Secondary School 733 Parkhill Road West Peterborough,Ontario K9J-8M4
A Question How many people here don’t like recursion? Why not? A Promise: By the end of this lecture, you will say: “Recursion Rocks My World!”
Recursion Chapter 7 Copyright ©2012 by Pearson Education, Inc. All rights reserved.
20-1 Computing Fundamentals with C++ Object-Oriented Programming and Design, 2nd Edition Rick Mercer Franklin, Beedle & Associates, 1999 ISBN
Lecture 8. How to Form Recursive relations 1. Recap Asymptotic analysis helps to highlight the order of growth of functions to compare algorithms Common.
CMSC 2021 Recursion Recursive Definition – one that defines something in terms of itself Recursion – A technique that allows us to break down a problem.
Sound Check.
1 Decrease-and-Conquer Approach Lecture 06 ITS033 – Programming & Algorithms Asst. Prof. Dr. Bunyarit Uyyanonvara IT Program, Image and Vision Computing.
Unit 11, Part 2: Introduction To Logarithms. Logarithms were originally developed to simplify complex arithmetic calculations. They were designed to transform.
Lecturer: Dr. AJ Bieszczad Chapter 11 COMP 150: Introduction to Object-Oriented Programming 11-1 l Basics of Recursion l Programming with Recursion Recursion.
Slides prepared by Rose Williams, Binghamton University ICS201 Lecture 19 : Recursion King Fahd University of Petroleum & Minerals College of Computer.
Computer Science Department Data Structure & Algorithms Lecture 8 Recursion.
Principles of Programming - NI Simple Recursion Recursion is where a function calls itself. Concept of recursive function: A recursive function is.
Principles of Programming Chapter 11: Recursive Function  In this chapter, you will learn about  Recursion function 1 NI S1 2009/10.
Chapter 8 Recursion Modified.
Chapter 13 Recursion. Learning Objectives Recursive void Functions – Tracing recursive calls – Infinite recursion, overflows Recursive Functions that.
Chapter 4 Recursion. Copyright © 2004 Pearson Addison-Wesley. All rights reserved.1-2 Chapter Objectives Explain the underlying concepts of recursion.
1 Wright State University, College of Engineering Dr. T. Doom, Computer Science & Engineering CS 241 Computer Programming II CS 241 – Computer Programming.
Data Structures R e c u r s i o n. Recursive Thinking Recursion is a problem-solving approach that can be used to generate simple solutions to certain.
Java Programming: Guided Learning with Early Objects Chapter 11 Recursion.
IB Computer Science Unit 5 – Advanced Topics Recursion.
Lecture 7. Solution by Substitution Method T(n) = 2 T(n/2) + n Substitute n/2 into the main equation 2T(n/2) = 2(2(T(n/4)) + n/2) = 4T(n/4) + n And T(n)
Chapter 11Java: an Introduction to Computer Science & Programming - Walter Savitch 1 Chapter 11 l Basics of Recursion l Programming with Recursion Recursion.
Principles of Programming - NI Simple Recursion Recursion is where a function calls itself. Concept of recursive function: A recursive function is.
Winter 2006CISC121 - Prof. McLeod1 Stuff No stuff today!
Recursion A recursive definition is one which uses the word or concept being defined in the definition itself Example: “A computer is a machine.
Recursion Chapter 17 Instructor: Scott Kristjanson CMPT 125/125 SFU Burnaby, Fall 2013.
A Brief Introduction to Recursion. Recursion Recursive methods … –methods that call themselves! –They can only solve a base case –So, you divide a problem.
C++ Programming Lecture 12 Functions – Part IV
1 Recursion Recursive function: a function that calls itself (directly or indirectly). Recursion is often a good alternative to iteration (loops). Its.
Recursion Chapter 7 Copyright ©2012 by Pearson Education, Inc. All rights reserved.
CSC 143 P 1 CSC 143 Recursion [Chapter 5]. CSC 143 P 2 Recursion  A recursive definition is one which is defined in terms of itself  Example:  Compound.
Recursion ITFN The Stack. A data structure maintained by each program at runtime. Push Pop.
Welcome to Recursion! Say what?!? Recursion is… the process of solving large problems by simplifying them into smaller ones. similar to processing using.
Recursion ● Recursion or Iteration ● A Common Recursive Design Pattern ● Computing factorials ● Searching a filesystem tree ● Faster exponentiation ● Slow.
Chapter 13 Recursion Copyright © 2016 Pearson, Inc. All rights reserved.
Introduction to Recursion
Recursion DRILL: Please take out your notes on Recursion
A Question How many people here don’t like recursion? Why not?
Recursion A problem solving technique where an algorithm is defined in terms of itself A recursive method is a method that calls itself A recursive algorithm.
Lesson #6 Modular Programming and Functions.
Decrease-and-Conquer Approach
Lesson #6 Modular Programming and Functions.
More on Recursive Methods
Java Software Structures: John Lewis & Joseph Chase
Recursion Great fleas have little fleas upon their backs to bite 'em, And little fleas have lesser fleas, and so ad infinitum. And the great fleas themselves,
Lesson #6 Modular Programming and Functions.
Recursion Recursive Thinking Recursive Programming
Programming application CC213
Basics of Recursion Programming with Recursion
From Recursion To Iteration: A Case Study
Lesson #6 Modular Programming and Functions.
Recursion yet another look To recurse is divine, to iterate is human
Review of Previous Lesson
MIPS function continued
ICS103 Programming in C Lecture 11: Recursive Functions
Presentation transcript:

Recursion yet another look To recurse is divine, to iterate is human

“Do I Have to Use Recursion?” public static double pow(double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; else { exponent = exponent - 1; return value * pow (value, exponent); } How many would have preferred to do this with a “for loop” structure or some other iterative solution? How many think we can make our recursive method even faster than iteration?

Nota Bene Our power function works through brute force recursion. 2 8 = 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 But we can rewrite this brute force solution into two equal halves: 2 8 = 2 4 * 2 4 and 2 4 = 2 2 * 2 2 and 2 2 = 2 1 * 2 1 and anything to the power 1 is itself!

And here's the cool part = 2 4 * 2 4 Since these are the same we don't have to calculate them both!

AHA! So the trick is knowing that 2 8 can be solved by dividing the problem in half and using the result twice! So only THREE multiplication operations have to take place: 2 8 = 2 4 * = 2 2 * = 2 1 * 2 1

"But wait," I hear you say! You picked an even power of 2. What about our friends the odd numbers? Okay we can do odds like this: 2 odd = 2 * 2 (odd-1)

"But wait," I hear you say! You picked a power of 2. Let’s see an odd one! Okay, how about = 2 * 2 20 (The odd number trick) 2 20 = 2 10 * = 2 5 * = 2 * = 2 2 * = 2 1 * 2 1

"But wait," I hear you say! You picked a power of 2. That's a no brainer! Okay how about = 2 * 2 20 (The odd number trick) 2 20 = 2 10 * = 2 5 * = 2 * = 2 2 * = 2 1 * 2 1 That's 6 multiplications instead of 20 and it gets more dramatic as the exponent increases

The Recursive Insight If the exponent is even, we can divide and conquer so it can be solved in halves. If the exponent is odd, we can subtract one, remembering to multiply the end result one last time. We begin to develop a formula: Pow(x, e) = 1, where e == 0 Pow(x, e) = x, where e == 1 Pow(x, e) = Pow(x, e/2) * Pow(x,e/2), where e is even Pow(x, e) = x * Pow(x, e-1), where e > 1, and is odd

Solution #2 public static double pow (double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; } We have the same base termination conditions as before, right?

Solution #2 public static double pow (double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; else if (exponent % 2 == 0) { } This little gem determines if a number is odd or even.

Solution #2 public static double pow (double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; else if (exponent % 2 == 0) { } public static int isOdd(int num){ if (num==0) return 1; else return isEven(num-1); } public static int isEven(int num){ if (num==0) return 0; else return isOdd(num-1); } Don’t like the mod operator? Get used to it. The alternative is something mutually recursive and wacky, like this:

Solution #2 public static double pow (double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; else if (exponent % 2 == 0) { } public static int isOdd(int num){ if (num==0) return 1; else return isEven(num-1); } public static int isEven(int num){ if (num==0) return 0; else return isOdd(num-1); } That mod operator is starting to look a lot better, eh? It merely tests if the number is evenly divided by two.

Solution #2 public static double pow (double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; else if (exponent % 2 == 0) { exponent = exponent / 2; } We next divide the exponent in half.

Solution #2 public static double pow (double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; else if (exponent % 2 == 0) { exponent = exponent / 2; double half = pow (value, exponent); } We recurse to find that half of the brute force multiplication.

Solution #2 public static double pow (double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; else if (exponent % 2 == 0) { exponent = exponent / 2; double half = pow (value, exponent); return half * half; } And return the two halves of the equation multiplied by themselves

Solution #2 public static double pow (double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; else if (exponent % 2 == 0) { exponent = exponent / 2; double half = pow (value, exponent); return half * half; } else { exponent = exponent - 1; } If the exponent is odd, we have to reduce it by one...

Solution #2 public static double pow (double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; else if (exponent % 2 == 0) { exponent = exponent / 2; int half = pow (value, exponent); return half * half; } else { exponent = exponent - 1; double oneless = pow (value, exponent); } And now the exponent is even, so we can just recurse to solve that portion of the equation.

Solution #2 public static double pow (double value, int exponent){ if (exponent == 0) return 1D; else if (exponent == 1) return value; else if (exponent % 2 == 0) { exponent = exponent / 2; int half = pow (value, exponent); return half * half; } else { exponent = exponent - 1; double oneless = pow (value, exponent); return oneless * value; } We remember to multiply the value returned by the original value, since we reduced the exponent by one.

Recursion vs. Iteration: Those of you who voted for an iterative solution are likely going to produce: O(N) In a Dickensian world, you would be fired for this. While those of you who stuck it out with recursion are now looking at: O(log 2 n) For that, you deserve a raise!

The Cost of Recursion The stack is important – it’s no joke. Computer hardware, it’s a fact of life. We have to live with it.

The Cost of Recursion public class FibTest { public static int fib (int num) { if (num == 0) return 0; else if (num == 1) return 1; else return fib(num-1) + fib(num-2); } public static void main(String[] args) { for (int i=0; i < 10; i++) System.out.println (fib(i)); } }// FibTest Each time you call a method, a new “activation frame” is created. This frame has unique copies of the parameters (Java has IN parameters), and unique copies of any local variables. public class FibTest { public static int fib (int num) { if (num == 0) return 0; else if (num == 1) return 1; else return fib(num-1) + fib(num-2); } public static void main(String[] args) { for (int i=0; i < 10; i++) System.out.println (fib(i)); } }// FibTest public class FibTest { public static int fib (int num) { if (num == 0) return 0; else if (num == 1) return 1; else return fib(num-1) + fib(num-2); } public static void main(String[] args) { for (int i=0; i < 10; i++) System.out.println (fib(i)); } }// FibTest

Recursion Review Recursion is defining a program in such a way that it may call itself. Central to this understanding was the notion of a stack of successive calls. Each recursive call creates a new stack frame time stack height

public int fact ( int num ){ if (num == 0) return 1; else return num * ( fact (num -1) ); } Let’s trace this for 4! fact (4) 4 * fact (3) 4 * 3 * fact (2) 4 * 3 * 2 * fact (1) 4 * 3 * 2 * 1 * fact (0) 4 * 3 * 2 * 1 * 1 Example

fact (4) 4 * fact (3) 4 * 3 * fact (2) 4 * 3 * 2 * fact (1) 4 * 3 * 2 * 1 * fact (0) 4 * 3 * 2 * 1 * 1 public int fact ( int num ){ if (num == 0) return 1; else return num * ( fact (num -1) ); } Problems We don’t calculate anything until the final recursive call. We must save a copy of each call, until we reach the end and ‘unwind’ the recursive call. This is an example of augmentative (head) recursion. Memory usage grows at O(n). This gets expensive!

Analyzing Augmentative Recursion public int fact ( int num ){ if (num == 0) return 1; else return num * ( fact (num -1) ); } The culprit is a recursive call that returns what gets returned from a successive recursive call (which depends on what gets returned from a recursive call, etc., etc.) We leave the multiply hanging… This requires us to save each level of the stack. How can we rewrite this to avoid having to save the state of each frame? AHA!

Tail Recursion Eliminates the one big problem with augmentative recursion: Massive memory use. Requires a compiler/interpreter that recognizes when a module is finished executing. (i.e. the last action is a recursive call and there’s no more work to do.) Requires a slightly different style of recursive module writing.

Tail Recursion public int fact (int product, int count, int max){ if (count == max) return product; else { count = count + 1; product = product * count; return fact (product, count, max); } These values are all precalculated; no need to save each frame! These values are all precalculated; no need to save each frame!

Tail Recursion public int fact(int num){ if (num == 0) return 1; else return fact (1, 1, num); } public int fact (int product, int count, int max){ if (count == max) return product; else { count++; product *= count; return fact (product, count, max); } Method overloading takes place of “helper” method Method overloading takes place of “helper” method Need to “prime the pump” with good starting values. Need to “prime the pump” with good starting values. These values are all precalculated; no need to save each frame! These values are all precalculated; no need to save each frame!

Tracing Tail Recursion public int fact(int num){ if (num == 0) return 1; else return fact (1, 1, num); } public int fact (int product, int count, int max){ if (count == max) return product; else { count++; product *= count; return fact (product, count, max); } fact(4) No stack buildup! Each recursive call makes calculations independent of the prior recursive calls. There’s no need to save the state of each call 1 1 4

Recursion Roundup Tail and Augmentative recursion are nothing more than fancy terms for different structures of recursive methods. Remember, tail recursion means that the last thing that happens in a module is simply the return of a recursive call. Tail: return fact(...); Head: return n * fact(...);