recursion chapter 5. objectives discuss the system stack in more detail. introduce the tree...

52
Recursion Chapter 5

Upload: benjamin-jefferson

Post on 28-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Recursion

Chapter 5

Page 2: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 3: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Homework Overview

• Written (max 18 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)

Page 4: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 5: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Tree Representation

• We can draw this same series of function calls using a tree.

• We traverse the tree from left to right.

Page 6: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Factorials

• The factorial function is defined

• Example: • We can also define the factorial in terms

of itself using a recurrence relation.

Page 7: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Factorials

• We can write this definition in C++.int fact(int n){

if (n==0)return 1;

elseReturn 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

Page 8: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Factorials

• The sequence of stack frames:

• The tree representation:

Page 9: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Recursive Process

A recursive process has two parts:1. A base case (or cases) that are

processed directly without recursion.2. 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.

Page 10: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 11: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 12: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Towers of Hanoi Algorithm

• To move the 7 disks from post 1 to post 3 we will divide the problem into 3 parts.1. Move the top 6 from post 1 to post 2.

2. Move the bottom disk from post 1 to post 3.

3. Move the top 6 from post 2 to post 3.

Page 13: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 14: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Towers of Hanoi Algorithm

• To move the 7 disks from post 1 to post 3 the code will look like this.1. move(6, 1, 2, 3);

2. cout << “move disk 7 from post 1 to post 3” << endl;

3. move(6, 2, 3, 1);

Page 15: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Towers of Hanoi Algorithm

Our recursive process is as follows:1. The base case is moving 0 disks, there is

nothing to do.2. The general rule is that to move n disks

from post start to post finish using post temp we do the following.

1. Move n-1 disks from start to temp.2. Move the bottom disk from start to

finish.3. Move n-1 disks from temp to finish.

Page 16: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Towers of Hanoi Code#include<iostream>using namespace std;

const int disks = 8; // Keep this small for an actual program runvoid 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);

}}

Page 17: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Towers of Hanoi Recursion Tree

• Think of the recursion tree:

• How many times will the function be called?

• The number of moves will be

Page 18: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 19: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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!

Page 20: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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)

Page 21: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Designing Recursive Algorithms

The steps to designing a recursive algorithm are:1. Key step – find a way to describe the solution of the

problem in terms of “simpler” versions of the same problem.

2. Stopping rule – find a simple case (base case) that you can solve directly.

3. 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!

4. Outline – combine the key step and the stopping rule and find a test to determine which rule to use.

5. Recursion tree – if you are concerned about how long the algorithm will take you can analyze the recursions tree.

Page 22: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 23: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 24: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 25: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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

Page 26: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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;

}}

Page 27: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 28: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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);

}

Page 29: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 30: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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)

Page 31: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 32: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

8 Queens Problem

• This is not a solution:

• The Queens on the upper left and lower right share the same diagonal.

Page 33: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Solution Strategies

Here are some ideas for solving the problem:1. 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.

2. Look for a pattern (use mathematics).– Best method, if we can do it.– It may take a lot of thinking.

3. Place Queens in a systematic way looking at all possible configurations.– Lots of work – use a computer.– It will find all the solutions.

Page 34: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

8 Queens Algorithm

solve_from(Queen_config){

if Queen_config has 8 queens print the resultelse

for every open chessboard square p {add Queen on square psolve_from(Queen_config)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.

Page 35: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 36: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 37: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

8 Queens Column Data

• Suppose we have placed 3 Queens.– They will be in rows 0, 1 and 2.

queen_in_row

0

2

4

F

T

F

T

F

T

T

T

col_free

Page 38: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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

Page 39: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

8 Queens Diagonal Data

• The number of the upward diagonal isrow + column

upward_free

F

T

T

F

T

T

F

T

T

T

T

T

T

T

T

Page 40: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

8 Queens Diagonal Data

• The number of the downward diagonal isrow - column + board_size - 1

downward_free

T

T

T

T

T

F

F

F

T

T

T

T

T

T

T

Page 41: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 42: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Queens Classconst 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. */

Page 43: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Queens Classint board_size; // dimension of board = maximum number of queens

private:int count; // current number of

queens = first unoccupied rowbool 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

};

Page 44: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Queens Methodsvoid 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;

}

Page 45: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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];

}

Page 46: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Queens Methodsbool 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++){

for (col = 0; col < board_size; col++)cout << ".";

cout << endl;}cout << endl;

}

Page 47: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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();elsefor (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);}

}

Page 48: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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();elsefor (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);}

}

Page 49: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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

}}

Page 50: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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.

Page 51: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

Maze Algorithm

1. Start at S2. Look at all possible paths from the current location

in a fixed order.– Up– Down– Right– Left

3. Make one move in the chosen direction.4. Repeat steps 2 and 3 until F is found or a dead end is

reached.5. If a dead end is reached, backtrack until there are

unexplored options.

Page 52: Recursion Chapter 5. Objectives Discuss the system stack in more detail. Introduce the tree representation of stack operations. Introduce recursion. –

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)