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

Slides:



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

Recursion –a programming strategy for solving large problems –Think “divide and conquer” –Solve large problem by splitting into smaller problems of same.
© 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.
Chapter 10 Recursion. Copyright © 2005 Pearson Addison-Wesley. All rights reserved Chapter Objectives Explain the underlying concepts of recursion.
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.
Recursion!. Can a method call another method? YES.
Even Numbers – Any number that can be divided by 2
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.
Sound Check.
1 Decrease-and-Conquer Approach Lecture 06 ITS033 – Programming & Algorithms Asst. Prof. Dr. Bunyarit Uyyanonvara IT Program, Image and Vision Computing.
Lecturer: Dr. AJ Bieszczad Chapter 11 COMP 150: Introduction to Object-Oriented Programming 11-1 l Basics of Recursion l Programming with Recursion Recursion.
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 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.
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.
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.
CMSC201 Computer Science I for Majors Lecture 19 – Recursion (Continued) Prof. Katherine Gibson Prof. Jeremy Dixon Based on slides from UPenn’s.
CMSC201 Computer Science I for Majors Lecture 20 – Recursion (Continued) Prof. Katherine Gibson Based on slides from UPenn’s CIS 110, and from previous.
Introduction to Recursion
Recursion DRILL: Please take out your notes on Recursion
Data Structures and Algorithms
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.
Chapter 11 Recursion Slides prepared by Rose Williams, Binghamton University Kenrick Mock, University of Alaska Anchorage Copyright © 2016 Pearson Inc.
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
Recursion.
Unit 3 Test: Friday.
CS302 - Data Structures using C++
Basics of Recursion Programming with Recursion
From Recursion To Iteration: A Case Study
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.
Java Programming: Chapter 9: Recursion Second Edition
Review of Previous Lesson
MIPS function continued
Dr. Sampath Jayarathna Cal Poly Pomona
ICS103 Programming in C Lecture 11: Recursive Functions
Self-Referencing Functions
Recursive Function Prepared by Harprith ICT2102 Introduction to Data Structure.
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. 28 = 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 But we can rewrite this brute force solution into two equal halves: 28 = 24 * 24 and 24 = 22 * 22 22 = 21 * 21 anything to the power 1 is itself!

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

AHA! So only THREE multiplication operations have to take place: 28 = 24 * 24 24 = 22 * 22 22 = 21 * 21 So the trick is knowing that 28 can be solved by dividing the problem in half and using the result twice!

"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: 2odd = 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 221 221 = 2 * 220 (The odd number trick) 220 = 210 * 210 210 = 25 * 25 25 = 2 * 24 24 = 22 * 22 22 = 21 * 21

"But wait," I hear you say! You picked a power of 2. That's a no brainer! Okay how about 221 221 = 2 * 220 (The odd number trick) 220 = 210 * 210 210 = 25 * 25 25 = 2 * 24 24 = 22 * 22 22 = 21 * 21 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

termination conditions 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 We next divide the exponent in half. 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 We recurse to find that half of the brute force 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.

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; } And return the two halves of the equation multiplied by themselves

Solution #2 If the exponent is odd, we have to reduce it by one . . . 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 . . .

recurse to solve that portion 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(log2n) 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 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 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.

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

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

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! public int fact ( int num ){ if (num == 0) return 1; else return num * ( fact (num -1) ); } fact (4) 4 * fact (3) 3 * fact (2) 2 * fact (1) 1 * fact (0) 1

Analyzing Augmentative Recursion public int fact ( int num ){ if (num == 0) return 1; else return num * ( fact (num -1) ); } AHA! 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?

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.

precalculated; no need 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!

precalculated; no need Tail Recursion Need to “prime the pump” with good starting values. 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; { count++; product *= count; return fact (product, count, max); Method overloading takes place of “helper” method 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; { count++; product *= count; return fact (product, count, max); Each recursive call makes calculations independent of the prior recursive calls. There’s no need to save the state of each call No stack buildup! fact(4) 1 1 4 2 2 4 6 3 4 24 4 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(...);