Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 CMPSCI 187 Computer Science 187 Introduction to Introduction to Programming with Data Structures Lecture 15 More on Recursion Lecture 15 More on Recursion.

Similar presentations


Presentation on theme: "1 CMPSCI 187 Computer Science 187 Introduction to Introduction to Programming with Data Structures Lecture 15 More on Recursion Lecture 15 More on Recursion."— Presentation transcript:

1 1 CMPSCI 187 Computer Science 187 Introduction to Introduction to Programming with Data Structures Lecture 15 More on Recursion Lecture 15 More on Recursion

2 2 CMPSCI 187 Computer Science 187 Introduction to Introduction to Programming with Data Structures AnnouncementsAnnouncements 1.Programming project 4 is up. 2.Next OWL assignment is up. 3.No….I haven’t.

3 3 CMPSCI 187 Summing Digits l Design a recursive method that inputs an int and returns the sum of its digits. F Now the recursive case isn't handed to us in the problem description. Here we have to be creative. F When you are stuck, try to think of another problem that's similar to the one you are trying to solve, but easier. F For example, instead of adding up all the digits, maybe we could start by just printing out each of the digits. F Also make simplifying assumptions. e.g. assume you only have to work with positive integers.

4 4 CMPSCI 187 Summing Digits: Recursive Solution Base Case? Recursive Case? Printing

5 5 CMPSCI 187 By the way….. public void digits(int n) { if (n < 10) System.out.println(n); else { System.out.println(n%10); digits(n/10); } What happens if we reverse these two lines?

6 6 CMPSCI 187 Nested Method Calls The stack of method calls else { System.out.println(n%10); digits(n/10); } This executes all the println statements while we're pushing calls onto the stack: 2 … 5 … 4 … digits (8) digits (84) digits (845) digits (8452)

7 7 CMPSCI 187 Nested Method Calls digits (8) digits (84) digits (845) digits (8452) The stack of method calls else { digits(n/10); System.out.println(n%10); } This executes all the println statements while we're popping calls from the stack: 8 … 4 … 5 …

8 8 CMPSCI 187 Pushing vs. Popping l If you ever want to reverse the order of something in a recursive method, switch from pushing to popping: F Anything executed before a recursive call happens when you push to the stack. F Anything executed after a recursive call happens when you pop from the stack.

9 9 CMPSCI 187 Reversing an Array l Given an n-element array A, we want to create a new array in which the elements from A are reversed. F A[]=(1, 2, 3) --> B[]=(3, 2, 1). l Suppose A[m:n] denotes the subarray of A consisting of the m-th through n-th elements of A.

10 10 CMPSCI 187 Decomposition Methods l Can now define several different forms of decomposition F First and Rest: split A into A[m] and A[m+1:n] F Last and All But Last: A[m:n-1] and A[n] F Halves: let middle=(n+m)/2 and split A into the left half A[m:middle] and the right half A[middle+1:n] (also called Divide and Conquer) l And another one: F Edges and Center: split A[m:n] into its edges A[m] and A[n] and its center A[m+1: n-1]

11 11 CMPSCI 187 Recursive Array Reversal using Center and Edges [ 13 9 22 45 0 87 53 ] 1. Reverse the edges 2. Apply algorithm to center. A: reverse(A,1,5)A: 53 9 22 45 0 87 13

12 12 CMPSCI 187 The reverse method public void reverse(int[] A, int m, int n) { if (m<n) { int temp=A[m]; A[m]=A[n]; A[n] = temp; reverse(A, m+1, n-1); } Notice no base case!

13 13 CMPSCI 187 The Importance of the Base Case l The base case terminates the recursive calls and starts the reassembly process. l Recursive algorithms can get caught in an infinite loop just like iterative algorithms. l Two common reasons H there is no base case to stop the recursion H the base case never gets ‘called’ or ‘executed’ public int sumOfSquares(int m, int n) { if (m=n) return m*m; //solution is the square of m else //solution is obtained by adding the square of //m to the sum of squares in the range (m+1):n. return m*m+sumOfSquares(m+1,n); } What happens if m > n on first call to this method??? Exception Occurred: java.lang.StackOverflowError

14 14 CMPSCI 187 Printing a List Recursively l Method for the LinkedList class l General idea F Check to see if list is empty F If not, print the first element in the list F Recursively apply the method to the list starting at the next element F Stop when we've reached the last element in the list Head 13 22 Tail 5 Print this Apply method recursively to this list Stop here Null

15 15 CMPSCI 187 Recursive List Print public void recListPrint( Node node ) { if ( node != null) { //print out the data in the node System.out.println(node.getData()); //now print the rest of the list recListPrint(node.next);+ } Probably need a cast here in practice

16 16 CMPSCI 187 Types of Recursion l A method invoking itself is considered to be direct recursion l A method could invoke another method, which invokes another, etc., until eventually the original method is invoked again l For example, method m1 could invoke m2, which invokes m3, which invokes m1 again l This is called indirect recursion l It is often more difficult to trace and debug

17 17 CMPSCI 187 Abstractly…..

18 18 CMPSCI 187 The Towers of Hanoi l Given 3 disks stacked as shown on peg A l Move pile one disk at a time to stack C l Cannot place a big disk on top of a little disk RULES ABC

19 19 CMPSCI 187 Observations moveTowers(3) is shown moveTowers(2) and moveTowers(1) are trivial moveTowers(N) is the general case ABC

20 20 CMPSCI 187 Tower(1) ABC To solve moveTowers(1): move disk A to C A trivial case that we know how to solve immediately!

21 21 CMPSCI 187 Tower(2) ABC To solve moveTowers(2): do moveTowers(1), directed from A => B move big disk to C do moveTowers(1) again, directed from B => C 1 2 3

22 22 CMPSCI 187 The Towers of Hanoi l The Towers of Hanoi is a natural recursive problem in the following sense: in a fairly obvious way it can be solved with the help of a smaller version of the same problem ABC To solve moveTowers(4): 1. do moveTowers(3), directed from A => B 2. move big disk to C 3. do moveTowers(3) again, only from B => C

23 23 CMPSCI 187 The General Case public void moveTowers(int n, char start, char finish, char spare) { if (n==1) (move one disk directly from start peg to finish peg ) else { (move a tower of n-1 disks from start-peg to spare- peg) (move one disk directly from start-peg to finish-peg) (move a tower of n-1 disks from spare-peg to finish-peg) } ABC

24 24 CMPSCI 187 The moveTowers method public void moveTowers(int n, char start, char finish, char spare) { // method to move a tower of n disks from the start peg to the // finish peg using the spare peg as temporary storage. if(n==1) System.out.println(“Move a disk from peg ” + start + “ to peg ” + finish); else { moveTowers(n-1, start, spare, finish); System.out.println(“Move a disk from peg ”+ start + “ to peg ” + finish); moveTowers(n-1, spare, finish, start); }

25 25 CMPSCI 187 A Test Program l Test program contains the line: moveTowers(3/*disks*/, /*from peg*/ ‘A’, /*to peg*/ ‘C’, /*using spare peg*/ ‘B’); l Program prints: Move a disk from peg A to peg C Move a disk from peg A to peg B Move a disk from peg C to peg B Move a disk from peg A to peg C Move a disk from peg B to peg A Move a disk from peg B to peg C Move a disk from peg A to peg C

26 26 CMPSCI 187 What’s the Complexity of moveTowers l Can count the number of instructions printed as a function of n: n number of instructions printed 1 23 37 415 531 663 7127 8255 Do these numbers look familiar? 2 n -1

27 27 CMPSCI 187 So When Does the Universe End? l 2 n -1 is an exponential function ~2 n l Moving a tower of 64 golden disks, at one per second, will take l Or approximately 2 64 -1 seconds (2 64 -1)/31,536,000secs/yr ~ 584,942,417,355 years! (Sun’s lifetime ~ 10,000,000,000 years)

28 28 CMPSCI 187 …and the moral is? Avoid algorithms of exponential complexity like the plague! Don’t apply exponential algorithms to very big problems and expect them to finish in your lifetime. or if you MUST use one

29 29 CMPSCI 187 Computational Complexity of Recursive Algorithms l Revisit the recursive factorial method: l let T(n) = amount of time it takes to compute factorial(n). l we don't need exact solution for T(n), just big-O l if n = 1, computing factorial takes some small fixed amount of time F call it a, so T(1) = a public static int factorial(int n) { if (n <= 1) return 1; else return n * factorial(n-1); }

30 30 CMPSCI 187 Computational Complexity Recursive Factorial l Suppose n > 1. What must we do to compute factorial(n)? F compare n <= 1 F call factorial(n-1) F multiply n * result F return answer l Time for this is some constant (doesn't depend on n) plus time it takes to call factorial(n-1). l So T(n) = T(n-1) + b, for some constant b. public static int factorial(int n) { if (n <= 1) return 1; else return n * factorial(n-1); }

31 31 CMPSCI 187 Recurrence Relation for Factorial l Recurrence relation for T(n): F T(1) = a F T(n) = T(n-1) + b, n > 1 l Want a closed form solution for the complexity of factorial. l Informal way to solve the recurrence relation: unrolling. F T(n) = T(n-1) + b F = [T(n-2) + b] + b = T(n-2) + 2b F = [T(n-3) + b] + 2b = T(n-3) + 3b F = T(n-4) + 4b, and so on l And we see a pattern: for any k (k is number of unrolling steps): F T(n) = T(n-k) + kb l We'd like to get rid of the T( ) term on the right hand sides so choose k = n-1: F T(n) = T(1) + b(n-1) = a + b(n-1) = O(n) l So factorial is O(n)

32 32 CMPSCI 187 Note About Unrolling l Unrolling is a very informal process - doesn't prove that our solution is correct. l To prove that: use mathematical induction (not in 187). l Sanity check to satisfy ourselves our solution is right: try a few values l Recurrence relation is: F T(1) = a F T(n) = T(n-1) + b, n > 1 l Solution is: T(n) = a + b(n-1), n >= 1 l from solution, T(1) = a + b(0) = a F T(2) from recurrence relation: T(2) = T(1) + b = a + b F T(2) from solution: a + b F T(3) from recurrence relation: T(3) = T(2) + b = a + b + b = a + 2b F T(3) from solution: a + 2b

33 33 CMPSCI 187 Complexity of Tower of Hanoi l let T(n) = time to execute moveTowers with numdisks = n. l T(1) = some constant a l if n > 1: call hanoi twice with numdisks = n-1, plus a comparison and some printing (constant time) l so T(n) = 2T(n-1) + b when n > 1, for some constant b public void moveTowers(int numDisks, char start, char finish, char spare) { // method to move a tower of n disks from the start peg to the // finish peg using the spare peg as temporary storage. if(numDisks==1) System.out.println(“Move a disk from peg ” + start + “ to peg ” + finish); else { moveTowers(numDisks-1, start, spare, finish); System.out.println(“Move a disk from peg ”+ start + “ to peg ” + finish); moveTowers(numDisks-1, spare, finish, start);} }

34 34 CMPSCI 187 Solve the Recurrence Relation T(1) = a T(n) = 2T(n-1) + b, n > 1 Unroll: T(n) = 2T(n-1) + b = 2[2T(n-2) + b] + b = 4T(n-2) + 3b = 4[2T(n-3) + b] + 3b = 8T(n-3) + 7b = 16T(n-4) + 15b we see a pattern after k steps: T(n) = 2 k T(n-k) + (2 k -1)b after n-1 steps: T(n) = (2 n -1)T(1) + (2 n -1-1)b = (2 n -1)(a+b) – b = O(2 n ) So our Tower of Hanoi problem has exponential complexity =2 4 T(n-4)+(2 4 -1)b

35 35 CMPSCI 187 Steps for Determing Complexity l For a recursive method: F Let T(n) = time to execute method with parameter n (or n is some measure of parameter size) F Examine method and get a recurrence relation for T(n) F Unroll to find solution for T(n) l General case: may not be solution for T(n). l For recurrence relations arising from simple computer programs: F usually is a solution.

36 36 CMPSCI 187 Recursion vs. Iteration l Just because we can use recursion doesn't mean we should F requires overhead of extra method calls F not the best way to solve factorial problem HOWEVER.... l some algorithms are easy to express recursively,hard to express iteratively F in these cases, recursion is a very useful tool l use when it's natural to define the big problem in terms smaller versions of the same problem F good example: recursive sorting (later in course), trees,… l trade-off: efficiency vs. simplicity l note: recursion adds constant factors – doesn't necessarily change basic complexity

37 37 CMPSCI 187 The N Queens Problem l Simple problem related to chess l For a chessboard of size N (N is 8 for chess), can N queens be placed on the board such that no queen is attacking another queen F (Queens attack vertically, horizontally, and diagonally)

38 38 CMPSCI 187 Strategies l Guess a solution. F Not great: there are 4,426,165,368 ways to arrange 8 queens on a chessboard of 64 squares. l Observation: no queen can reside in a row or column that contains another queen F Reduces solution space to 40,320 possible arrangements l Provide organization for the guessing game F Place queens one column at a time F If we reach an impasse, backtrack to the previous column and try another row

39 39 CMPSCI 187 Backtracking l Backtracking: a solution strategy for searching for a solution and backing up when no solution can be found. l Think about games…..and our maze l Backtracking can be implemented using recursion. F More on this later when we talk about trees and tree searches.

40 40 CMPSCI 187 Recursive Solution to the N- Queens Problem l A recursive algorithm that places a queen in a column: F Base Case: If there are no more columns to consider, we are done. F Recursive Case: H If we have successfully placed a queen in the current column, consider the next column. H If we cannot place a queen in the current column, we need to backtrack. l Example:

41 41 CMPSCI 187 Illustration of Backtracking 5 queens that can not attack each other but can attack all of column 6. Backtracking to col 5 to try another square for the queen. Backtracking to col 4 to try another square for the queen and then reconsidering column 5 See it in Action

42 42 CMPSCI 187 Preliminaries l Suppose we had a class Board that contained the following public methods: F public Board(int size) H construct an empty board of given size F public boolean safe(int row, int col) H is it safe to place a queen at [row, col]? F public void place(int row,int col) H place queen at [row, col] F public void remove(int row, int col) H remove queen previously placed at [row, col] F public int size() H returns size of board F public void print() H display board to System.out

43 43 CMPSCI 187 The Queens Class l Contains four public methods: F public static void main(String[] args) F public static void giveIntro() H Explain program to user. F public static boolean explore(Board b, int col) H Recursively search the board for a solution starting at col; assumes that queens have been placed in all columns less than col. Returns true if a solution is found, false otherwise F public static void solve(Board solution) H Search for a solution to the 8 queens problem and report result. l Three of these: main, giveIntro, and solve are trivial.

44 44 CMPSCI 187 Main and giveIntro public static void main(String[] args) { giveIntro(); int size=8; System.out.println("Using a board of size: "+size); Board b = new Board(size); solve(b); } public static void giveIntro() // Explain program to user. { System.out.println("This program solves the classic '8 queens' problem,"); System.out.println("placing queens on a chessboard so that no two queens"); System.out.println("threaten each other."); System.out.println(); } All code by Stuart Reges, University of Arizona www.cs.arizona.edu/reges

45 45 CMPSCI 187 Solve Isn’t Hard either. public static void solve(Board solution) //Search for a solution to the 8 queens problem with this // board, reporting result. { if (!explore(solution, 1)) System.out.println("No solution."); else { System.out.println("One solution is as follows:"); solution.print(); }

46 46 CMPSCI 187 Neither is Explore public static boolean explore(Board b, int col) // Recursively search the board for a solution starting at col, // printing all solutions; assumes that queens have been placed // in all columns less than col { if (col > b.size()) return true; else { for(int row = 1; row <= b.size(); row++) if (b.safe(row, col)) { b.place(row, col); if (explore(b, col + 1)) return true; b.remove(row,col); } return false; } Base CaseRecursive Case

47 47 CMPSCI 187

48 48 CMPSCI 187 A Second Example l Suppose you are given a computer with no integer multiply, so you want to write a function to do it. l Suddenly, you remember that multiplication is nothing more than repeated addition: multiply(M,N) = M + M +.....+ M N times but this is just multiply(M,N-1)! multiply(M,N) = M + multiply(M, N-1) A Recursive Solution!

49 49 CMPSCI 187 Multiply in Java public static int multiply(int m, int n) { if (n == 1) return m; else return m + multiply(m, n-1); } NOTE: base, or stopping case: N=1 recursive step: N > 1 notice how multiply appears in second return - with parameters - an instance of a smaller problem

50 50 CMPSCI 187 Another View K = multiply(5,3); multiply(5,3) else multiply = m + multiply(5,2) end; multiply(5,2) else multiply = m + multiply(5,1) end; multiply(5,1) then multiply = m end; make a copy when done, where do I return to?

51 51 CMPSCI 187 Memory Usage in Java

52 52 CMPSCI 187 Pascal’s Triangle l The binomial coefficients are the coefficients that result from the expansion of a binomial expression of the form (x+1) n. F (x+1) 3 = x 3 + 3x 2 + 3x + 1 ~ [1 3 3 1] F (x+1) 6 = x 6 +6x 5 +15x 4 +20x 3 +15x 2 +6x+1 l Also called Pascal’s triangle:

53 53 CMPSCI 187 Recursive Pascal’s Triangle pascal(n,k)= 1 k=0,k=n pascal(n-1,k-1)+pascal(n-1,k) otherwise

54 54 CMPSCI 187 Recursive Solution public int pt(int n, int k) { if (we're on one of the edges) return 1; else return the sum of the two parents ; }

55 55 CMPSCI 187 Pascal’s Triangle 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1................... pt(n, m) = pt(n-1,k-1) + pt(n-1,k) pt(n, 0) = 1 for all n pt(n, n) = 1 for all n

56 56 CMPSCI 187 Recursive Solution public int pt(int n, int k) { if (n == k || k == 0) return 1; else return pt(n-1,k-1) + pt(n-1,k) ; } double recursion


Download ppt "1 CMPSCI 187 Computer Science 187 Introduction to Introduction to Programming with Data Structures Lecture 15 More on Recursion Lecture 15 More on Recursion."

Similar presentations


Ads by Google