VBA Recursion What is the base case What
VBA Recursion What is the “base case”? What is the programming stack? CS 105 Spring 2010 #1
Recursive Procedures 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. #2
Example: Factorial Function 1. Problem Definition Write 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. #3
Example: Factorial Function fact(int. N As Integer) As Integer If int. N = 0 Then ' base case fact = 1 Else fact = int. N * fact(int. N - 1) 'recursive call End If End Function #4
(STACK) (push) fact = 3 * fact(3 - 1) (push) fact = 2 * fact(2 - 1) (push) fact = 1 * fact(0) (push/pop) fact = 1 (int. N = 3) fact = = 1 (int. N = 0) 1 * fact(0) (int. N = 1) 2 * fact(2 - 1) (int. N = 2) 3 * fact(3 - 1) (int. N = 3) (int. N = 2) (int. N = 1) fact = 1 * 1 (int. N = 1) fact = 2 * fact(2 - 1) (int. N = 2) fact = 3 * fact(3 - 1) (int. N = 3) (int. N = 0) (pop) fact = 1 * 1 (int. N = 1) (pop) fact = 2 * 1 (int. N = 2) fact = 3 * fact(3 - 1) (int. N = 3) fact = 3 * 2 (pop) fact = 3 * 2 (int. N = 3) (empty) The “stack” contains “stack frames” #5
Example: Traversing a Maze 1. Problem Definition Write a solve_maze function. We assume that a maze has been created in the range A 1: J 10. 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 A 1: J 10 Your program will have to find its way through a 10 x 10 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 #6
Example: Traversing a Maze 2. Refine, Generalize, Decompose the problem definition Input (continued): Read the maze into the 2 D array, ***** * *O* * * *** * * *X* * ** * * * *** ** * * ***** Dim str. Maze(1 to 10, 1 to 10) as String The upper left-hand corner of the maze has the value str. Maze(1, 1). If we want to test whether the cell in the fourth row and fourth column contains a wall then it's enough to use an if statement like this: if (str. Maze(4, 4) = “ * “) #8
Example: Traversing a Maze 2. Refine, Generalize, Decompose the problem definition Output : Display a solution as follows: #9
Example: Traversing a Maze 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 “int. Row” and “int. Col” to keep track of the current position as we traverse through the maze (the 2 D matrix str. Maze). 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 (int. Row, int. Col) and try another direction. # 10
Private Sub cmd. Solve_Click() Dim str. Maze(1 To 10, 1 To 10) As String Dim int. Row As Integer, int. Col As Integer Dim int. Start. Row As Integer, int. Start. Col As Integer ' Read the maze into str. Maze and ' find int. Start. Row, int. Start. Col For int. Row = 1 To 10 For int. Col = 1 To 10 str. Maze(int. Row, int. Col) = Cells(int. Row, int. Col). Value If str. Maze(int. Row, int. Col) = "O" Then int. Start. Row = int. Row int. Start. Col = int. Col End If Next int. Col Next int. Row ' Solv. Maze is a recursive subprocedure Solve. Maze str. Maze, int. Start. Row, int. Start. Col End Sub # 11
Sub Solve. Maze(str. Maze() As String, int. Row As Integer, int. Col As Integer) 'Draw the maze Draw. Maze str. Maze, 10 'Check if solution found. If str. Maze(int. Row - 1, int. Col) = "X" Or _ str. Maze(int. Row + 1, int. Col) = "X" Or _ str. Maze(int. Row, int. Col + 1) = "X" Or _ str. Maze(int. Row, int. Col - 1) = "X" Then End 'End terminates ALL recursive calls End If ' Recurse in each possible direction that is empty. 'Move up If str. Maze(int. Row - 1, int. Col) = "" Then str. Maze(int. Row - 1, int. Col) = "O" Solve. Maze str. Maze, int. Row - 1, int. Col str. Maze(int. Row - 1, int. Col) = "“ Draw. Maze str. Maze, 10 End If ' continued on next slide # 12
'Move down If str. Maze(int. Row + 1, int. Col) = "" Then str. Maze(int. Row + 1, int. Col) = "O" Solve. Maze str. Maze, int. Row + 1, int. Col str. Maze(int. Row + 1, int. Col) = "“ Draw. Maze str. Maze, 10 End If 'Move left If str. Maze(int. Row, int. Col - 1) = "" Then str. Maze(int. Row, int. Col - 1) = "O" Solve. Maze str. Maze, int. Row, int. Col - 1 str. Maze(int. Row, int. Col - 1) = "“ Draw. Maze str. Maze, 10 End If 'Move right If str. Maze(int. Row, int. Col + 1) = "" Then str. Maze(int. Row, int. Col + 1) = "O" Solve. Maze str. Maze, int. Row, int. Col + 1 str. Maze(int. Row, int. Col + 1) = "“ Draw. Maze str. Maze, 10 End If End Sub # 13
Sub Draw. Maze(str. Maze() As String, int. Rows As Integer, int. Cols As Integer) Dim int. Row As Integer, int. Col As Integer For int. Row = 1 To int. Rows For int. Col = 1 To int. Cols Cells(int. Row, int. Col). Value = str. Maze(int. Row, int. Col) Next int. Col Next int. Row Pause 0. 4 End Sub Pause(sng. Time As Single) Dim sng. Start As Single sng. Start = Timer ' Set start time. Do While Timer < sng. Start + sng. Time Do. Events Loop End Sub # 14
Example: Towers of Hanoi 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. # 15
Example: Towers of Hanoi 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. # 16
Example: Towers of Hanoi 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? # 17
Pseudo-code 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 n disks 2 3 # 18
Animation 1 2 3 Click on Picture to start game # 19
Towers of Hanoi Private Sub cmd. Tower_Click() mint. Num. Disks = Input. Box("How many disks? ", "Tower of Hanoi", 8) ' draw the tower Draw. Tower ' call recursive subprocedure, hanoi ' peg 1 is the origin, peg 3 is the destination and ' peg 2 is the spare Hanoi 1, 3, 2, mint. Num. Disks End Sub # 20
Sub Hanoi(int. Origin As Integer, int. Destination As Integer, int. Spare As Integer, _ int. Num. Disks As Integer) If int. Num. Disks = 1 Then ' move top disk on peg int. Origin to peg int. Destination Pause 0. 6 Move. Disks int. Origin, int. Destination Else ' peg int. Origin is the origin, peg int. Spare is the ' destination and peg int. Num. Disks is the spare Hanoi int. Origin, int. Spare, int. Destination, int. Num. Disks - 1 ' move top disk on peg int. Origin to peg int. Destination Pause 0. 6 Move. Disks int. Origin, int. Destination Hanoi int. Spare, int. Destination, int. Origin, int. Num. Disks - 1 End If End Sub # 21
Computational Complexity 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 = needed to transfer+ a tower of n disks n-1 disks from peg 1 to peg 3 peg 1 to peg 2 The minimum number of moves needed to transfer + n-1 disks from peg 2 the n th disk from to peg 3 on top of peg 1 to peg 3 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) = 2 n-1 Then, 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!! # 22
- Slides: 22