Download presentation
Presentation is loading. Please wait.
Published byBelinda Bishop Modified over 9 years ago
1
1 Exceptions – quick review Exceptions – quick review Recursion Recursion Power Function Power Function Towers of Hanoi Towers of Hanoi Fibonacci Numbers Fibonacci Numbers Recursive Algorithm Recursive Algorithm Dynamic Programming Approach Dynamic Programming Approach Iterative Solution Iterative Solution Permutations Permutations Eight Queens Eight Queens Backtracking Backtracking Summary Summary CSE 30331 Lecture 6 – Exceptions, Recursion
2
2 Quick Aside Group Project Guidelines … are posted on web page Due: Tuesday, September 26 th (correction) Initial Group membership Brief description of project you plan to complete Initial references you have found …
3
3 Exceptions When something unexpected happens in a block of code, and the proper handling of that event depends on where the call to the block came from … Throw an exception Expect the calling code to determine and take the proper action Otherwise, use standard techniques, if(error) act; in the code where the error occurs
4
4 Standard Exceptions Defined in the following headers are … #include exception and bad_exception, the base classes #include bad_alloc #include bad_cast and bad_typeid #include logic_error, out_of_range, length_error, invalid_argument, domain_error, runtime_error, range_error, overflow_error, and underflow_error #include ios_base::failure
5
5 Throwing a standard exception In a function we can throw an error and set its message string as shown below … #include double myFunct(int index) {... if (index < 0) throw out_of_range(“in MyFunct() : index < 0”);... }
6
6 What happens when the exception is thrown? Once the exception is thrown … ALL following code in the same block is SKIPPED Control returns to the calling code, and … ALL code following the call is SKIPPED This process of backing out of the call stack continues UNTIL … A call is found in a TRY block, and then … ALL code is skipped in the rest of the block, BUT … Code execution continues in the appropriate CATCH block that follows the TRY… UNLESS none is found, in which case eventually the program TERMINATES with a generic “unhandled” exception message
7
7 Try & Catch In code that calls a function which might generate an exception … Place the call in a try block Follow the code with a catch block that will deal appropriately with the error Appropriate may be nothing more than output of the exception message, and a hasty exit of the program
8
8 Try & Catch Example try {... cout << “Which value?:”; cin >> num; x = myFunct(num); // this might throw an exception // the rest of this code in block may get skipped cout << x;... } catch (out_of_range& e) { // every std exception has a what() method that // returns its message cout << e.what(); exit(1); }
9
9 Try & Multiple Catches while (...) { try {... x = myOtherFunct(num); // might throw several exceptions... } catch (out_of_range& e) { // exception was a simple out of range error cout << e.what(); // inform user and... continue; // try again -- get a better input }... } catch (exception& e) { // if exception was not a range error, abort cout << e.what(); exit(2); }
10
10 Making your own exceptions Best way is to customize your exception from one of the standard ones Use inheritance For examples, See … Ford & Topp, pp 68-74 Josutis, pp 25-31
11
11 Recursive Algorithms A recursive function generally implements a recursive algorithm. Both function and algorithm must consists of … 1. One or more stopping conditions (base cases) that can be directly evaluated for certain arguments. 2. One or more recursive steps in which a current value of the function can be computed by calling the function with arguments that will eventually arrive at a stopping condition.
12
12 Recursive Definition of the Power Function A recursive definition of x n distinguishes between … n = 0 (starting point) where x n = x 0 = 1 and n 1 where x n can be calculated using the calculated value of x n-1
13
13 Implementing the Recursive Power Function // pre: n is non-negative double power(double x, int n) { if (n == 0) // base case return 1.0; else // recursive step return x * power(x,n-1); }
14
14 The Towers of Hanoi Given a stack of 64 disks of decreasing size Initially stacked on peg 1 of three pegs Move the stack, one disk at a time to peg 3 Using peg 2 as needed Such that you NEVER have a larger disk on top of a smaller disk NOTE: When the problem is solved the world will end!!!!! So say the priests of the Temple of Brahma.
15
15 Solving the Tower of Hanoi Puzzle using Recursion
16
16 Solving the Tower of Hanoi Puzzle using Recursion
17
17 Towers of Hanoi void hanoi (int n, char src, char dest, char spare) { if (n > 1) { hanoi(n-1,src,spare,dest); cout << “move ” << src << “ to ” << dest << ‘\n’; hanoi(n-1,spare,dest,src); } else // last disk (n == 1) cout << “move ” << src << “ to ” << dest << ‘\n’; }
18
18 Efficiency – Towers of Hanoi The algorithm is exponential T(2) = 2T(1)+1 = 3 = 2 2 -1 T(3) = 2T(2)+1 = 7 = 2 3 -1 T(4) = 2T(3)+1 = 15 = 2 4 -1 T(n) = 2 n -1 So T(64) = 2 64 (about 500 billion years) Maybe the priests were right!
19
19 Recursive Definition of the Fibonacci numbers A recursive definition of fib(n) distinguishes between … n = 0 or 1 (starting points) where fib(n) = n and n > 1 where fib(n) can be calculated using the calculated values of fib(n-1) and fib(n-2)
20
20 Fibonacci Numbers (Recursive solution) int fib (int n) { if ((n == 0) || (n == 1)) // base cases return n; else // general case // (sum of previous two values) return (fib(n-1) + fib(n-2)); } The sequence of Fibonacci numbers. {0, 1, 1, 2, 3, 5, 8, 13, 21, 34,...}
21
21 Recursive calls for fib(5)
22
22 How many calls is that? It’s exponential, Θ( Φ n ) Fibonacci numbers are related to the GoldenRatio Φ The efficiency of the recursive algorithm is … Expanding that we get the series for n >= 2 3 5 9 15 25 41 67 109 … Which is the same as … T(n)=2*fib(n+1)-1 or …
23
23 How many calls is that? It’s exponential, Θ( Φ n ) Examining the cost versus the values n...... 0 1 2 3 4 5 6 7 8 9 10 fib(N).. 0 1 1 2 3 5 8 13 21 34 55 T(n).... 3 5 9 15 25 41 67 109 We see that T(n) = 2*fib(n+1)-1 = 2* Φ n+1 - 1 or …
24
24 Dynamic Programming Basic idea Remember values computed in previous steps for use in later steps Avoids recalculation of previously determined values Trims tree of recursive calls significantly (See tree of fib(5) on following slide)
25
25 Affects of Using Dynamic Programming on fib(5) Circles: saved values used Gray: calls avoided
26
26 Fibonacci with Dynamic Programming // pre: fibList contains n values, all -1 int fibDyn (int n, vector & fibList) { int fibValue; if(fibList[n] >= 0) // previously computed return fibList[n]; if (n <= 1) // base cases (0 & 1) fibValue = n; else fibValue = fibDyn(n-1,fibList) + fibDyn(n-2,fibList); fibList[n] = fibValue; // save value in fibList return fibValue; }
27
27 Fibonacci Numbers using Iteration int fibiter (int n) // pre: n >= 0 { int oneback = 1, twoback = 1, current; if (n == 0 || n == 1) // base cases return n; else // compute successive terms for (int i = 3; i <= n; i++) { current = oneback + twoback; twoback = oneback; oneback = current; } return current; }
28
28 Permutations … Recursive Approach Permutations of a list of n values include all possible re-orderings of those values The number of permutations is n! A vector (permList) holds the values At each level of recursion (i), n-i recursive calls are made Prior to each recursive call permList[i] is swapped with permList[j], for all i < j < n The permutation prefix is permList[0]..permList[i-1] The swapping of permList[i] and permList[j] effectively creates all possible prefixes perList[0]..permList[i] differing in only the last value Each recursive call then finds all list permutations beginning with the given prefix and containing some permutation of the suffix permList[i+1].. permList[n-1]
29
29 Permutations void permute (vector permList, int index) { // permList must be value parameter int vSize = permList.size(); if (index == vsize-1) writeList(permList); // show result else { permute(permList, index+1); // permute tail of list for (int i=index+1; i<vSize; i++) { int temp = permList[index]; // swap last prefix val permList[index] = perList[i]; permList[i] = temp; // shuffle positions index+1.. vsize-1 permute(permList, index+1); // permute tail of list }
30
30 Permutations This is a sequence of calls to find permutations of [4 5 8] Permutation prefixes are underlined P([4 5 8],0) P([4 5 8],1) P([4 5 8],2) – writes out 4 5 8 P([4 8 5],2) – writes out 4 8 5 P([5 4 8],1) P([5 4 8],2) – writes out 5 4 8 P([5 8 4],2) – writes out 5 8 4 P([8 5 4],1) P([8 5 4],2) – writes out 8 5 4 P([8 4 5],2) – writes out 8 4 5
31
31 The 8-Queens Problem How can 8 queens be placed on a chess board such that none of them are under attack? Basic Strategy: Place a queen at top of column 0 Place a queen on row r=0 of column 1 While under attack, move queen to next row … Place a queen in row r=0 of column 2 … Whenever queen cannot be paced anywhere in the next column, back up to previous column, move queen further down, and continue …
32
32 Queens Attack along rows, columns and diagonals
33
33 The 8-Queens Example (placing queen in column 4, …) Place next queen at (3,5) Then no place in column 6 is free So back up, no other free place in column 5 So back up again No other free place in column 4 So back up again Place queen at (6,3) and move forward again Then to get Here …
34
34 Eight Queens bool placeQ (vector & qList, int col) { bool found = false; if (col == 8) found = true; // all 8 queens placed else { int row = 0; while (row < 8 && !found) // place queen in column { if (safeLoc(row,col,qList)) { qList[col] = row; // place queen on row found = placeQ(qList,col+1); // place the rest? if (!found) row++; // try next row this column } else row++; // not safe, move queen to next row } return found; // found complete solution? }
35
35 Eight Queens bool queens (vector & qList, int row) { qList[0] = row; // start at board[row,0] return placeQ(qList,1); // continue in column 1 } bool safeLoc (int row, int col, const vector & qList) { for (int qCol = 0; qCol < col; qCol++) { int qRow = qList[qCol]; if ((qRow == row) || (qCol-qRow == col-row) || (qCol+qRow == col+row) ) return false; // on same row or diagonal } return true; // safe, not under attack }
36
36 8-Queens … Each solution is a sequence of 8 numbers, 0..7, representing the queen’s position in each column There are 8 8 = (2 3 ) 8 = 2 24 or 4+ million such arrangements of queens, but … Queens cannot be on the same row, so … There are only 8! = 40,320 arrangements that might actually be solutions How many actual solutions are there? Only 92. How might we measure the algorithm efficiency?
37
37 Knight’s Tour Similar to the 8-queens problem For an nxn board, n >= 1 Is there a sequence of moves that a knight can follow that will systematically visit every board position, without visiting any position more than once? Approach: make a move, then another, … When no moves possible, back up and make an alternative move from the previous position Continue extending path and retreating until No solution is possible, knight backs off of board A solution is found
38
38 Knight’s Tour Example Now, what will be move #12? (1,5) or (2,4) or (2,2) 0 1 2 3 4 5 6 7 012 3 4567 0 1 2 3 4 5 6 8 7 11 10 9? ? ?
39
39 Summary An algorithm is recursive if it applies itself to the solution of smaller problems of the same type. Eventually, these problems must lead to one or more stopping conditions (base cases). The solution at a stopping condition leads to the solution of previous problems. A recursive C++ function calls itself.
40
40 Summary … Dynamic Programming (top down) Fibonacci function Uses a vector to store Fibonacci numbers as a recursive function computes them Avoids redundant recursive calls and leads to an O(n) algorithm to find the n th Fibonacci number. Recursive Fibonacci function that does not apply dynamic programming has exponential running time.
41
41 Summary … Backtracking Algorithm (8 Queens) Find a consistent partial solution (place a queen safely in current column) try to recursively extend the partial solution to a complete solution (place queen in next column …) If recursive step fails to find a complete solution, it returns and the algorithm tries again from a new consistent partial solution. (replace queen in current column & continue, or return to previous column if necessary)
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.