# 1# 1 vba recursion what is the “base case”? what is the programming stack? cs 105 spring 2010

Post on 01-Jan-2016

228 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

# 1

VBA Recursion

VBA Recursion

What is the “base case”?

What is the programming stack?

CS 105 Spring 2010

# 2

Recursive procedures are defined in terms of themselves; e.g., a function is recursive if it contains calls back to itself or to another function that calls the original function.

Recursive programming usually requires more memory and runs more slowly than non-recursive programs. This is due to the cost of implementing the “stack”.

However, recursion is often a natural way to define a problem.

Recursive Procedures

# 3

1. Problem DefinitionWrite a factorial function. 0! = 1 and n! = n*(n-1)!. Use “recursion” to implement the factorial function.

2. Refine, Generalize, Decompose the problem definition(i.e., identify sub-problems, I/O, etc.)Input = Non-negative integers as input.Output= return the factorial of the input value. Note: that 69! = 1.711224524... x 1098

so our function will only work for small integer values.

Example: Factorial FunctionExample: Factorial Function

# 4

Function fact(intN As Integer) As Integer

If intN = 0 Then ' base case fact = 1 Else fact = intN * fact(intN - 1) 'recursive call End If

End Function

Example: Factorial FunctionExample: Factorial Function

# 5

(push) fact = 3 * fact(3 - 1) (intN = 3)

(push) fact = 2 * fact(2 - 1) (intN = 2)

(push) fact = 1 * fact(0) (intN = 1)

(push/pop) fact = 1 (intN = 0)

(pop) fact = 1 * 1 (intN = 1)

(pop) fact = 2 * 1 (intN = 2)

(pop) fact = 3 * 2 (intN = 3)

fact = 1 (intN = 0) fact = 1 * fact(0) (intN = 1) fact = 2 * fact(2- 1) (intN = 2) fact = 3 * fact(3- 1) (intN = 3)

(STACK)

The “stack” contains “stack frames”

fact = 1 * 1 (intN = 1) fact = 2 * fact(2- 1) (intN = 2) fact = 3 * fact(3- 1) (intN = 3)

fact = 2 * 1 (intN = 2) fact = 3 * fact(3- 1) (intN = 3)

(empty)

fact = 3 * 2 (intN = 3)

# 6

1. Problem DefinitionWrite a solve_maze function. We assume that a maze has been created in the range A1:J10. Write a Subprocedure to display one path that traverses the maze. Use “recursion” to implement the maze subprocedure.

2. Refine, Generalize, Decompose the problem definition(i.e., identify sub-problems, I/O, etc.)Input = The maze in the range A1:J10

Your program will have to find its way through a 10x10 maze where the symbols “ * ” , “O” and “X” denote:

“ * ” are solid walls through which you cannot travel"O" denotes the starting position, "X" is the exit for which you are looking for

Example: Traversing a MazeExample: Traversing a Maze

# 7

* * * * * * * * * ** ** * * * * * O ** * * * ** * * X ** * * * * * ** * ** * * * * * ** * ** * * * * * * * * *

# 8

2. Refine, Generalize, Decompose the problem definitionInput (continued): Read the maze into the 2D array,

*********** ***** * *O* * * **** * *X** ** *** ** * ** *** ** ** * ***********

Dim strMaze(1 to 10, 1 to 10) as String

The upper left-hand corner of the maze has the value strMaze(1,1) . If we want to test whether the cell in thefourth row and fourth column contains a wall then it's enough to use an if statement like this:

if (strMaze(4,4) = “ * “)

Example: Traversing a MazeExample: Traversing a Maze

# 9

2. Refine, Generalize, Decompose the problem definitionOutput : Display a solution as follows:

Example: Traversing a MazeExample: Traversing a Maze

# 10

3. Develop Algorithm

(processing steps to solve problem)

Step 1 Read in the “maze” and find the starting Row and Column (the position of the “O”).

Use variables “intRow” and “intCol” to keep track of the current position as we traverse through the maze (the 2D matrix strMaze).

Step 2 Display the maze.

Step 3 Check to see if current position is an “X” then we are done. Otherwise first try to go up and if not then down and if not then left and if not then right and if you can go up/down/left/right then go back to Step 2. Otherwise, go back to the previous position (intRow,intCol) and try another direction.

Example: Traversing a MazeExample: Traversing a Maze

# 11

Private Sub cmdSolve_Click()

Dim strMaze(1 To 10, 1 To 10) As String

Dim intRow As Integer, intCol As Integer

Dim intStartRow As Integer, intStartCol As Integer

' Read the maze into strMaze and

' find intStartRow, intStartCol

For intRow = 1 To 10

For intCol = 1 To 10

strMaze(intRow, intCol) = Cells(intRow, intCol).Value

If strMaze(intRow, intCol) = "O" Then

intStartRow = intRow

intStartCol = intCol

End If

Next intCol

Next intRow

' SolvMaze is a recursive subprocedure

SolveMaze strMaze, intStartRow, intStartCol

End Sub

# 12

Sub SolveMaze(strMaze() As String, intRow As Integer, intCol As Integer)

'Draw the maze

DrawMaze strMaze, 10, 10

'Check if solution found.

If strMaze(intRow - 1, intCol) = "X" Or _

strMaze(intRow + 1, intCol) = "X" Or _

strMaze(intRow, intCol + 1) = "X" Or _

strMaze(intRow, intCol - 1) = "X" Then

End 'End terminates ALL recursive calls

End If

' Recurse in each possible direction that is empty.

'Move up

If strMaze(intRow - 1, intCol) = "" Then

strMaze(intRow - 1, intCol) = "O"

SolveMaze strMaze, intRow - 1, intCol

strMaze(intRow - 1, intCol) = "“

DrawMaze strMaze, 10, 10

End If

' continued on next slide

# 13

'Move down

If strMaze(intRow + 1, intCol) = "" Then

strMaze(intRow + 1, intCol) = "O"

SolveMaze strMaze, intRow + 1, intCol

strMaze(intRow + 1, intCol) = "“

DrawMaze strMaze, 10, 10

End If

'Move left

If strMaze(intRow, intCol - 1) = "" Then

strMaze(intRow, intCol - 1) = "O"

SolveMaze strMaze, intRow, intCol - 1

strMaze(intRow, intCol - 1) = "“

DrawMaze strMaze, 10, 10

End If

'Move right

If strMaze(intRow, intCol + 1) = "" Then

strMaze(intRow, intCol + 1) = "O"

SolveMaze strMaze, intRow, intCol + 1

strMaze(intRow, intCol + 1) = "“

DrawMaze strMaze, 10, 10

End IfEnd Sub

# 14

Sub DrawMaze(strMaze() As String, intRows As Integer, intCols As Integer)

Dim intRow As Integer, intCol As Integer

For intRow = 1 To intRows

For intCol = 1 To intCols

Cells(intRow, intCol).Value = strMaze(intRow, intCol)

Next intCol

Next intRow

Pause 0.4

End Sub

Sub Pause(sngTime As Single)

Dim sngStart As Single

sngStart = Timer ' Set start time.

Do While Timer < sngStart + sngTime

DoEvents

Loop

End Sub

# 15

According to legend, in the great temple of Benares, beneath the dome which marks the center of the world, rests a brass plate on which are fixed three diamond needles. On one of these needles at creation, there were placed 64 discs of pure gold, the largest disc resting on the brass plate and the others getting smaller up to the top one. This is the TOWERS OF HANOI. Day and night, the people on duty move the discs from one needle to another, according to the two following laws:

Law 1: Only one disc at a time may be moved.

Law 2: A larger disc may never rest on a smaller disc.

The workers labor in the belief that once the tower has been transferred to another needle there will be heaven on earth, so they want to complete the task in the least number of moves.

Example: Towers of HanoiExample: Towers of Hanoi

# 16

Actually, the Tower of Hanoi puzzle was invented in 1883 by the French mathematician Edouard Lucas (1842-1891), who made up the legend to accompany it.

Example: Towers of HanoiExample: Towers of Hanoi

# 17

An elegant and efficient way to solve this problem is to think recursively.

Suppose that you, somehow or other, have found the most efficient way possible to transfer a tower of n-1 disks one by one from one pole to another obeying the restriction that you never place a larger disk on top of a smaller one. Then, what is the most efficient way to move a tower of n disks from one pole to another?

Example: Towers of HanoiExample: Towers of Hanoi

# 18

Assume we know how to move n-1 disks from one peg to another.Then can we move n disks from peg 1 to peg 3 ?

1. Move n-1 disks from peg 1 to peg 2, peg 3 is just a temporary holding area

2. Move the last disk(the largest) from peg 1 to peg 3

3. Move the n-1 disks from peg 2 to peg 3, peg 1 is just a temporary holding area.

1 2 3

n disks

Pseudo-codePseudo-code

# 19Click on Picture to start game

1 2 3

AnimationAnimation

# 20

Private Sub cmdTower_Click()

mintNumDisks = InputBox("How many disks?", "Tower of Hanoi", 8)

' draw the tower

DrawTower

' call recursive subprocedure, hanoi

' peg 1 is the origin, peg 3 is the destination and

' peg 2 is the spare

Hanoi 1, 3, 2, mintNumDisks

End Sub

Towers of HanoiTowers of Hanoi

# 21

Sub Hanoi(intOrigin As Integer, intDestination As Integer, intSpare As Integer, _ intNumDisks As Integer)

If intNumDisks = 1 Then

' move top disk on peg intOrigin to peg intDestination

Pause 0.6

MoveDisks intOrigin, intDestination

Else

' peg intOrigin is the origin, peg intSpare is the

' destination and peg intNumDisks is the spare

Hanoi intOrigin, intSpare, intDestination, intNumDisks - 1

' move top disk on peg intOrigin to peg intDestination

Pause 0.6

MoveDisks intOrigin, intDestination

Hanoi intSpare, intDestination, intOrigin, intNumDisks - 1

End If

End Sub

# 22

Going back to the legend, suppose the workers rapidly move one disk every second. As shown earlier, the minimum sequence of moves must be :

The minimum number of moves needed to transfer a tower of n disks from peg1 to peg3

The minimum number of moves needed to transfer n-1 disks from peg1 to peg2

The minimum number of movesneeded to transfer the n th disk from peg1 to peg3

The minimum number of moves needed to transfer n-1 disks from peg2 to peg3 on top of the n th disk

Therefore, the recurrence relation is moves(n) = 2*moves(n-1) + 1 and initial case is moves(1) = 1 second. For example, moves(2) = 2*moves(1) + 1 = 3,moves(3) = 2*moves(2) + 1 = 7, or in general,moves(n) = 2n-1Then, the time to move all 64 disks from one peg to the other, and end the universe would be moves(64) seconds or 584.9 billion years!!

= + +

Computational ComplexityComputational Complexity

top related