Recursion Chapter 5.

Slides:



Advertisements
Similar presentations
Stacks CS 3358 – Data Structures. What is a stack? It is an ordered group of homogeneous items of elements. Elements are added to and removed from the.
Advertisements

Factorial Recursion stack Binary Search Towers of Hanoi
Recursive methods. Recursion A recursive method is a method that contains a call to itself Often used as an alternative to iteration when iteration is.
Backtracking COP Backtracking  Backtracking is a technique used to solve problems with a large search space, by systematically trying and eliminating.
Chapter 10 Recursion Instructor: alkar/demirer. Copyright ©2004 Pearson Addison-Wesley. All rights reserved.10-2 Recursive Function recursive functionThe.
Chapter5 RECURSION. Outline 1. Introduction to Recursion 2. Principles of Recursion 3. Backtracking: Postponing the Work 4. Tree-Structured Programs:
Recursion. 2 CMPS 12B, UC Santa Cruz Solving problems by recursion How can you solve a complex problem? Devise a complex solution Break the complex problem.
Chapter 10 Recursion. Copyright © 2005 Pearson Addison-Wesley. All rights reserved Chapter Objectives Explain the underlying concepts of recursion.
Recursive Algorithms Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Chapter 15 Recursive Algorithms. 2 Recursion Recursion is a programming technique in which a method can call itself to solve a problem A recursive definition.
Recursion A recursive function is a function that calls itself either directly or indirectly through another function. The problems that can be solved.
Data Structures Using C++1 Chapter 6 Recursion. Data Structures Using C++2 Chapter Objectives Learn about recursive definitions Explore the base case.
C++ Programming: Program Design Including Data Structures, Fourth Edition Chapter 16: Recursion.
Data Structures Using C++ 2E Chapter 6 Recursion.
1 C++ Plus Data Structures Nell Dale Chapter 7 Programming with Recursion Slides by Sylvia Sorkin, Community College of Baltimore County - Essex Campus.
A Review of Recursion Dr. Jicheng Fu Department of Computer Science University of Central Oklahoma.
Recursion Chapter 7 Copyright ©2012 by Pearson Education, Inc. All rights reserved.
1 Chapter 1 RECURSION. 2 Chapter 1  Subprogram implementation  Recursion  Designing Recursive Algorithms  Towers of Hanoi  Backtracking  Eight Queens.
Data Structures Using C++ 2E Chapter 6 Recursion.
Recursion Chapter Nature of Recursion t Problems that lend themselves to a recursive solution have the following characteristics: –One or more.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 12: Recursion Problem Solving, Abstraction, and Design using C++
Department of Computer Science Data Structures Using C++ 2E Chapter 6: Recursion Learn about recursive Definitions Algorithms Functions Explore the base.
A Computer Science Tapestry 1 Recursion (Tapestry 10.1, 10.3) l Recursion is an indispensable technique in a programming language ä Allows many complex.
Queues Chapter 3. Objectives Introduce the queue abstract data type. – Queue methods – FIFO structures Discuss inheritance in object oriented programming.
Copyright © 2011 Pearson Education, Inc. Starting Out with Java: Early Objects Fourth Edition by Tony Gaddis Chapter 14: Recursion.
15-1 Chapter-18: Recursive Methods –Introduction to Recursion –Solving Problems with Recursion –Examples of Recursive Methods.
1 CS 132 Spring 2008 Chapter 6 Recursion Read p Skip example 6-3 (Fibonacci), 6-4 (Hanoi) Read example 6-5 (p. 387)
Programming Principles II Lecture Notes 5 Recursion Andreas Savva.
Stephen P. Carl - CS 2421 Recursion Reading : Chapter 4.
Slides prepared by Rose Williams, Binghamton University ICS201 Lecture 19 : Recursion King Fahd University of Petroleum & Minerals College of Computer.
1 Chapter 13 Recursion. 2 Chapter 13 Topics l Meaning of Recursion l Base Case and General Case in Recursive Function Definitions l Writing Recursive.
Recursion Textbook chapter Recursive Function Call a recursive call is a function call in which the called function is the same as the one making.
224 3/30/98 CSE 143 Recursion [Sections 6.1, ]
1 7.Algorithm Efficiency What to measure? Space utilization: amount of memory required  Time efficiency: amount of time required to process the data Depends.
Computer Science Department Data Structure & Algorithms Lecture 8 Recursion.
Review Introduction to Searching External and Internal Searching Types of Searching Linear or sequential search Binary Search Algorithms for Linear Search.
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.
Recursion: Backtracking
Recursion Recursion Chapter 12. Outline n What is recursion n Recursive algorithms with simple variables n Recursion and the run-time stack n Recursion.
Data Structures Using C++ 2E1 Recursion and Backtracking: DFS Depth first search (a way to traverse a tree or graph) Backtracking can be regarded as a.
Introduction to Stacks Chapter 2. Objectives Introduce abstract data types. Discuss implementation types. – Static – Dynamic – Contiguous Introduce the.
CSC 221: Recursion. Recursion: Definition Function that solves a problem by relying on itself to compute the correct solution for a smaller version of.
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.
1 Data Structures CSCI 132, Spring 2014 Lecture 17 Backtracking.
Data Structures Using Java1 Chapter 5 Recursion. Data Structures Using Java2 Chapter Objectives Learn about recursive definitions Explore the base case.
Chapter 11Java: an Introduction to Computer Science & Programming - Walter Savitch 1 Chapter 11 l Basics of Recursion l Programming with Recursion Recursion.
1 Recursion Recursion is a powerful programming technique that provides elegant solutions to certain problems. Chapter 11 focuses on explaining the underlying.
1 Data Structures CSCI 132, Spring 2014 Lecture 18 Recursion and Look-Ahead.
CSE 143 Lecture 13 Recursive Backtracking slides created by Ethan Apter
Recursion Chapter 17 Instructor: Scott Kristjanson CMPT 125/125 SFU Burnaby, Fall 2013.
1 Recursion Recursive function: a function that calls itself (directly or indirectly). Recursion is often a good alternative to iteration (loops). Its.
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.
1 7.Algorithm Efficiency These factors vary from one machine/compiler (platform) to another  Count the number of times instructions are executed So, measure.
Recursion Powerful Tool
Recursion Data Structure Submitted By:- Dheeraj Kataria.
Chapter Topics Chapter 16 discusses the following main topics:
Chapter 10 Recursion Instructor: Yuksel / Demirer.
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Java Software Structures: John Lewis & Joseph Chase
Announcements Final Exam on August 17th Wednesday at 16:00.
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
7.4 Problem Solving with Recursion
Chapter 12 Recursion (methods calling themselves)
Recursion Data Structures.
Dr. Sampath Jayarathna Cal Poly Pomona
Presentation transcript:

Recursion Chapter 5

Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. Recurrence relations Base case Simplification step Designing recursive algorithms Solve the Towers of Hanoi problem. Recursive design Computational complexity Discuss when not to use recursion. Tail recursion Solve the 8 Queens problem. Solving mazes recursively.

Homework Overview Written (max 18 points) Programming (max 20 points) 5.1 E1 (a, c, e) (2 pts each) 5.1 E2 (a, c, e) (2 pts each) 5.2 E2 (d) (2 pts) 5.2 E4 (b) (3 pts) 5.3 E1 (3 pts) 5.3 E2 (4 pts) Programming (max 20 points) 5.1 P1 (10 pts) 5.2 E2 (a ,b, c) (5 pts each) 5.2 E4 (a) (8 pts) Group Project (38 points) 5.3 P3 (38 pts)

System Stack The computer keeps track of function calls (and all the associated local variables) using a stack. Suppose A, B, C and D are functions while M is the main function. Every time a function is called it is pushed onto the stack. Every time a function ends it is popped off the stack.

Tree Representation We can draw this same series of function calls using a tree. We traverse the tree from left to right.

Factorials The factorial function is defined Example: We can also define the factorial in terms of itself using a recurrence relation.

Factorials We can write this definition in C++. int fact(int n) { if (n==0) return 1; else Return n * fact(n-1); } Calculating a particular value is messy but straightforward. 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))) = 4*(3*(2*1)) = 4*(3*2) = 4*6 = 24

Factorials The sequence of stack frames: The tree representation:

Recursive Process A recursive process has two parts: A base case (or cases) that are processed directly without recursion. A general method that reduces all the other cases to one (or more) cases that are simpler (closer to the base case). This allows us to think of the big picture and leave the details to the compiler and system stack.

Towers of Hanoi The Towers of Hanoi is a puzzle with three posts some number of different sized disks. The disks are placed on a post in increasing order by size. You can only move one disks one at a time, never placing a larger disk on a smaller one. The goal is to move the entire stack from post 1 to post 3.

Towers of Hanoi Algorithm Idea – we will do this recursively. We know how to move one disk so this will be our base case. We will divide the problem of moving n disks into the problem of moving the top n-1 disks and moving the bottom one. Moving n-1 disks is closer to moving 1 disk (the base case) than the problem of moving n disks. Don’t worry how we will move the n-1 disks. We will use recursion to solve that problem.

Towers of Hanoi Algorithm To move the 7 disks from post 1 to post 3 we will divide the problem into 3 parts. Move the top 6 from post 1 to post 2. Move the bottom disk from post 1 to post 3. Move the top 6 from post 2 to post 3.

Towers of Hanoi Algorithm Let’s create a function to implement this recursive idea. void move (int count, int start, int finish, int temp); count – the number of disks to move start – the post we are moving the disks from. finish – the post we want to move the disks to. temp – the third post which we can used as temporary storage.

Towers of Hanoi Algorithm To move the 7 disks from post 1 to post 3 the code will look like this. move(6, 1, 2, 3); cout << “move disk 7 from post 1 to post 3” << endl; move(6, 2, 3, 1);

Towers of Hanoi Algorithm Our recursive process is as follows: The base case is moving 0 disks, there is nothing to do. The general rule is that to move n disks from post start to post finish using post temp we do the following. Move n-1 disks from start to temp. Move the bottom disk from start to finish. Move n-1 disks from temp to finish.

Towers of Hanoi Code #include<iostream> using namespace std; const int disks = 8; // Keep this small for an actual program run void move(int count, int start, int finish, int temp); /* Post: The first count disks have been moved from post start to post finish. */ int main() /* Post: The simulation of the Towers of Hanoi has terminated. */ { move(disks, 1, 3, 2); } void move(int count, int start, int finish, int temp) /* Post: The first count disks have been moved from post start to post finish. */ if (count > 0) { move(count - 1, start, temp, finish); cout << "Move disk " << count << " from " << start << " to " << finish << "." << endl; move(count - 1, temp, finish, start);

Towers of Hanoi Recursion Tree Think of the recursion tree: How many times will the function be called? The number of moves will be

Towers of Hanoi Complexity Suppose there are 64 disks. How long will it take the computer to solve the problem? The function will be called times. There will be moves.

Towers of Hanoi Complexity On my computer it takes 0.001551 seconds to do the problem with 8 disks. This is function calls. This means it would take seconds. This is 1774216 years!

Homework – Section 5.1 (page 169) Written E1 (a, c, e) (written on paper) (2 pts each) E2 (a, c, e) (written on paper) (2 pts each) Programming P1 (email code, include analysis of results on your computer, see footnote) (10 pts)

Designing Recursive Algorithms The steps to designing a recursive algorithm are: Key step – find a way to describe the solution of the problem in terms of “simpler” versions of the same problem. Stopping rule – find a simple case (base case) that you can solve directly. Check for termination – make sure that when you repeatedly simplify the problem you will eventually reach the base case. Recursion that does not terminate is deadly! Outline – combine the key step and the stopping rule and find a test to determine which rule to use. Recursion tree – if you are concerned about how long the algorithm will take you can analyze the recursions tree.

Fibonacci Numbers The Fibonacci numbers can be calculated recursively. This seems like a perfect situation for recursion. We have two base cases. We have a simplification rule. For any natural number n we will eventually get to the base cases.

Recursive Fibonacci Code int fibonacci(int n) { if (n <= 0) return 0; else if (n == 1) return 1; else return fibonacci(n-1) + fibonacci(n-2); } This is simple enough, but is it a good way to solve the problem? Let’s look at the recursion tree and find out.

Fibonacci Recursion Tree This is the recursion tree for fibonacci(6). There are 25 function calls. Notice that fibonacci(2) is calculated 5 different times. This doesn’t seem very efficient.

A Better Fibonacci Algorithm It is must faster to start at the small Fibonacci numbers and work our way up, remembering the numbers as we go. f(0) = 0 f(1) = 1 f(2) = f(1) + f(0) = 1 + 0 = 1 f(3) = f(2) + f(1) = 1 + 1 = 2 f(4) = f(3) + f(2) = 2 + 1 = 3 f(5) = f(4) + f(3) = 3 + 2 = 5 f(6) = f(5) + f(4) = 5 + 3 = 8

Improved Fibonacci Code int fibonacci(int n) /* Pre: The parameter n is a nonnegative integer. Post: The function returns the nth Fibonacci number. */ { int last_but_one; // second previous Fibonacci number, F(n-2) int last_value; // previous Fibonacci number, F(n-1) int current; // current Fibonacci number, F(n) if (n <= 0) return 0; else if (n == 1) return 1; else { last_but_one = 0; last_value = 1; for (int i = 2; i <= n; i++){ current = last_but_one + last_value; last_but_one = last_value; last_value = current; } return current;

Reconsidering Recursion Recursion is a powerful tool but it is easy to use in cases when it is not the best solution. Essentially, recursion just uses the system stack to keep track of functions calls. We could always write a program that maintains the same information without recursion. Any recursive program can be written iteratively (using a loop). Recursion also faces a performance penalty due to all the function calls. Recursion is best used when it would be difficult to maintain the information directly.

Tail Recursion Tail recursion – a function that: Calls itself only once. Calls itself as the last thing it does. As an example consider this following recursive function to calculate factorials. int factorial (int n) { if(n == 0) return 1; else return n * factorial(n-1); }

When to Avoid Recursion It is always relatively easy to turn a function that uses tail recursion into one that uses a loop. Any other recursive function that only calls itself one time can also be converted. It is usually easiest with tail recursion. Recursion may not be the best choice if the recursion tree has lots of duplication.

Homework – Section 5.2 (page 181) Written E2 (d) (written on paper) (2 pts) E4 (b) (written on paper) (3 pts) Programming E2 (a, b, c)(email code) (5 pts each) E4 (a)(email code) (8 pts)

8 Queens Problem 8 Queens Problem – can you place 8 Queens on a chess board so that no two Queens have each other in check? Queens more in straight lines. Horizontally Vertically Diagonally The chess board is made up 8 rows and 8 columns of squares.

8 Queens Problem This is not a solution: The Queens on the upper left and lower right share the same diagonal.

Solution Strategies Here are some ideas for solving the problem: Place Queens at random and check the results. This will eventually produce solutions. We will never know if we have found all the solutions (if there are more than one). If we don’t find a solution it is hard to know when to quit. Look for a pattern (use mathematics). Best method, if we can do it. It may take a lot of thinking. Place Queens in a systematic way looking at all possible configurations. Lots of work – use a computer. It will find all the solutions.

8 Queens Algorithm solve_from(Queen_config) { if Queen_config has 8 queens print the result else for every open chessboard square p { add Queen on square p Remove queen from square p } Backtracking – we proceed (blindly) with the problem until we hit a dead-end. Then we backtrack until new options open up.

8 Queens Algorithm Since there are 8 Queens and 8 rows, there must be a Queen in each row. Let’s start with the first row and place a Queen. Then we can move to the second row, find an open square and place a second Queen. Continue with the remaining rows. If we reach a point where a row does not have any open squares then we will backtrack to find unexplored configurations.

8 Queens Data Storing the chess board turns out not to be the easiest approach. We would need functions to test which diagonals, and columns are open. It is easier to simply store arrays that represent the diagonals and the columns. For each row, we will store the column for the Queen in that row. We will also maintain an array that keeps track of which columns are free to add a queen. We could calculate this from the first array, but this is easier.

8 Queens Column Data Suppose we have placed 3 Queens. They will be in rows 0, 1 and 2. queen_in_row col_free 2 4 F T

8 Queens Diagonal Data We will also keep track of which diagonals are free. 15 upward diagonals. 15 downward diagonals. The number of each type of diagonal is 2 * board_size – 1 We will maintain two arrays upward_free downward_free

8 Queens Diagonal Data The number of the upward diagonal is row + column upward_free F T

row - column + board_size - 1 8 Queens Diagonal Data The number of the downward diagonal is row - column + board_size - 1 downward_free T F

Queens Class To implement our backtracking algorithm we will create a Queens class that will keep track of all the data. This class will have the following methods: Constructor – set up an empty game board. is_solved – determine if the current configuration solves the problem. ungaurded – determine if a given square is open. insert – add a queen to the board in a particular square. remove – remove a queen from the board in a particular square. print – print out the solution.

Queens Class const int max_board = 30; class Queens { public: Queens(int size); // Constructor /* Post: The Queens object is set up as an empty configuration on a chessboard with size squares in each row and column. */ bool is_solved() const; /* Post: Returns true if the current configuration contains board_size queens and returns false otherwise. */ void print() const; /* Post: Prints the current configuration. */ bool unguarded(int col) const; /* Post: Returns true or false according as the square in the first unoccupied row (row count) and column col is not guarded by any queen. */ void insert(int col); /* Pre: The square in the first unoccupied row (row count) and column col is not guarded by any queen. Post: The queen has been inserted into the square at row count and column col; count has been incremented by 1. */ void remove(int col); /* Pre: The square located at row count and column col is occupied by a queen. Post: The queen has been removed from the square at row count and column col; count has been decremented by 1. */

Queens Class int board_size; // dimension of board = maximum number of queens private: int count; // current number of queens = first unoccupied row bool col_free[max_board]; bool upward_free[2 * max_board - 1]; bool downward_free[2 * max_board - 1]; int queen_in_row[max_board]; // column number of queen in each row };

Queens Methods void Queens::insert(int col) /* Pre: The square in the first unoccupied row (row count) and column col is not guarded by any queen. Post: The queen has been inserted into the square at row count and column col; count has been incremented by 1. */ { queen_in_row[count] = col; col_free[col] = false; upward_free[count + col] = false; downward_free[count - col + board_size - 1] = false; count++; } void Queens::remove(int col) /* Pre: The square located at row count and column col is occupied by a queen. Post: The queen has been removed from the square at row count and column col; count has been decremented by 1. */ count--; col_free[col] = true; upward_free[count + col] = true; downward_free[count - col + board_size - 1] = true;

Queens Methods Queens::Queens(int size) /* Post: The Queens object is set up as an empty configuration on a chessboard with size squares in each row and column. */ { board_size = size; count = 0; for (int i = 0; i < board_size; i++) col_free[i] = true; for (int j = 0; j < (2 * board_size - 1); j++) upward_free[j] = true; for (int k = 0; k < (2 * board_size - 1); k++) downward_free[k] = true; } bool Queens::unguarded(int col) const /* Post: Returns true or false according as the square in the first unoccupied row (row count) and column col is not guarded by any queen. */ return col_free[col] && upward_free[count + col] && downward_free[count - col + board_size - 1];

Queens Methods bool Queens::is_solved() const /* Post: Returns true if the current configuration contains board_size queens and returns false otherwise. */ { return (count == board_size); } void Queens::print() const /* Post: Prints the current configuration. */ int row, col; for (row = 0; row < count; row++){ for (col = 0; col < board_size; col++) cout << ((col == queen_in_row[row]) ? "Q" : "."); cout << endl; for (row = count; row < board_size; row++){ cout << ".";

Queens Main void solve_from(Queens &configuration) /* Pre: The Queens configuration represents a partially completed arrangement of nonattacking queens on a chessboard. Post: All n-queens solutions that extend the given configuration are printed. The configuration is restored to its initial state. Uses: The class Queens and the function solve_from, recursively. */ { if (configuration.is_solved()) configuration.print(); else for (int col = 0; col < configuration.board_size; col++) if (configuration.unguarded(col)) { configuration.insert(col); solve_from(configuration); // Recursively continue to add queens. configuration.remove(col); }

Queens Main Backtracking void solve_from(Queens &configuration) /* Pre: The Queens configuration represents a partially completed arrangement of nonattacking queens on a chessboard. Post: All n-queens solutions that extend the given configuration are printed. The configuration is restored to its initial state. Uses: The class Queens and the function solve_from, recursively. */ { if (configuration.is_solved()) configuration.print(); else for (int col = 0; col < configuration.board_size; col++) if (configuration.unguarded(col)) { configuration.insert(col); solve_from(configuration); // Recursively continue to add queens. configuration.remove(col); }

Queens Main int main() /* Pre: The user enters a valid board size. Post: All solutions to the n-queens puzzle for the selected board size are printed. Uses: The class Queens and the recursive function solve_from.*/ { int board_size; print_information(); cout << "What is the size of the board?" << flush; cin >> board_size; if (board_size < 0 || board_size > max_board) cout << "The number must be between 0 and " << max_board << endl; else { Queens configuration(board_size); // initialize empty configuration solve_from(configuration); // Find all solutions extending configuration }

More Backtracking - Mazes Solving a maze is another application of backtracking. Suppose we have the following maze. The goal is to find a path starting at S and ending at F that only uses white space.

Maze Algorithm Start at S Look at all possible paths from the current location in a fixed order. Up Down Right Left Make one move in the chosen direction. Repeat steps 2 and 3 until F is found or a dead end is reached. If a dead end is reached, backtrack until there are unexplored options.

Homework – Section 5.3 (page 196) Written E1 (written on paper) (3 pts) E2 (written on paper) (4 pts) Group Project P3 (email code) (33 pts)