Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Tirgul 11: Recursion & Backtracking. 2 Elements of a recursive solution (Reminder) A base case that is so simple we need no computation to solve it.

Similar presentations


Presentation on theme: "1 Tirgul 11: Recursion & Backtracking. 2 Elements of a recursive solution (Reminder) A base case that is so simple we need no computation to solve it."— Presentation transcript:

1 1 Tirgul 11: Recursion & Backtracking

2 2 Elements of a recursive solution (Reminder) A base case that is so simple we need no computation to solve it. A simplifying step that gets us a bit closer to the base case.

3 3 Mutual Recursion A recursion can be more complex that just a function that calls itself. We can have several functions that call each other. Example: Method A calls method B Method B calls method A.

4 4 Odd or Even? public static boolean odd(int n){ if(n==1){ return true; } return even(n-1); } public static boolean even(int n){ if(n==1){ return false; } return odd(n-1); }

5 5 Backtracking

6 6 We can use recursion to go over many options, and do something for each case. Example: printing all subsets of the set {0, …,n-1}. Difficult to do with loops (but possible). Much simpler with recursion.

7 The basic idea The recursive decomposition: Print all subsets that an item, Then print all the subsets that do not contain it. Keep track of our current “state”. items that are in the set, items not in the set, items we did not decide about. 7

8 8 PowerSet public class PowerSet { private boolean[] _set; public PowerSet(){} private void printCurrentSet() { System.out.print("{ "); for(int i=0; i<_set.length; i++){ if(_set[i]) System.out.print(i + " "); } System.out.println("}"); }... Holds the set we are currently building. A default constructor that does nothing. Prints the current set

9 9 PowerSet (cont.) public void printPowerSet(int n){ _set = new boolean[n]; powerSetHelper(0); _set = null; //free memory. } private void powerSetHelper(int index) { if(index==_set.length){ printCurrentSet(); return; } _set[index]=true; powerSetHelper(index+1); _set[index]=false; powerSetHelper(index+1); } This is the not the recursive method. It calls the recursive method that does the real work. Base case: we picked out all the items in the set – print it. Print all sets that include index Print all sets that exclude index

10 10 PowerSet and the stack ??? ??t ?tt?ft tttftttftfft index=0 index=1 index=2 {0,1,2} {0,1} {0,2}{0}

11 11 PowerSet and the stack ??? ??f??t ?tt?ft tttftttftfft ?tf?ff ttfftftfffff {0,1,2} {0,1} {0,2}{0} {1,2}{1} {2} {}

12 Basics of Backtracking A backtracking alg. can be used to find a solution (or all solutions) to a combinatorial problem. Solutions are constructed incrementally At if there are several options to advance incrementally, the algorithm will try one option, then backtrack and try more options. 12

13 13 N-Queens The problem: On an NxN board, place N queens so that no queen threatens the other (no other queen allowed in same row,col or diagonal). Print only one such board. Simplifying step: Place 1 queen somewhere in an available column then solve the problem of placing all other queens. Base case: All queens have been placed.

14 14 The N-Queen Problem public class NQueens { private boolean[][] _board; public NQueens(){} private boolean illegalPlacement(int row, int col){…} public void placeQueens(int boardSize){ _board = new boolean[boardSize][boardSize]; if(placeQueenAtCol(0)){ printBoard(); } else{ System.out.println("No Placement Found!"); } _board = null; }... This method uses a recursive helper method that really does the work to check if queen can be at row,col:

15 15 The N-Queen Problem private boolean placeQueenAtCol(int col) { if(col == _board[0].length){ return true; } for(int row=0; row<_board.length; row++){ if(illegalPlacement(row,col)){ continue; } _board[row][col]=true; if(placeQueenAtCol(col+1)){ return true; } _board[row][col]=false; } return false; } Base case: we have passed the last column. Iterate over rows until it is okay to place a queen. Place the queen Check if we can fill up the remaining columns If not, remove the queen and keep iterating. If no placement works, give up.

16 16 The N-Queen Problem private boolean illegalPlacement(int row, int col) { for(int delta = 1; delta<=col; delta++){ if(_board[row][col-delta] || (row-delta>=0 && _board[row-delta][col-delta]) || (row+delta<_board.length && _board[row+delta][col-delta])){ return true; } return false; } Note: it is enough to look for threatening queens in lower columns Check for queen in the same row Check for queen in upper diagonal Check for queen in lower diagonal

17 17 Output of N-Queens Q - - - - - - - - - - - - - Q - - - - - Q - - - - - - - - - - Q - Q - - - - - - - - - Q - - - - - - - - - Q - - - - Q - - - - -

18 18 Traveling Knight Goal: on an NxN board, try to move a knight so it visits every square exactly once. Print all possible ways to manage this. Example of output for one path starting at top left corner: 11223183 221721124 13815419 162162510 7149205

19 19 Traveling Knight public class TravelingKnight { private static final int[][] KNIGHT_MOVES = {{1,2},{2,1},{-1,2},{-2,1}, {-1,-2},{-2,-1},{1,-2},{2,-1}}; private int[][] _board; public TravelingKnight(){} public void travel(int boardSize, int row, int col){ _board = new int[boardSize][boardSize]; travelHelper(row,col,1); }... All possible moves The board An interface method that calls the private recursive one.

20 20 Traveling Knight private void travelHelper(int row, int col, int stepNum){ _board[row][col] = stepNum; if(stepNum==_board.length*_board[0].length){ printBoard(); } else{ for(int i=0; i<KNIGHT_MOVES.length; i++){ int newRow = row+KNIGHT_MOVES[i][0]; int newCol = col+KNIGHT_MOVES[i][1]; if(canGo(newRow,newCol)) travelHelper(newRow, newCol,stepNum+1); } _board[row][col] = 0; } Do the move into this square Base case: This is the last move Simplifying step: try each possible move. Backtrack -- Cancel the move

21 21 Traveling Knight private boolean canGo(int row, int col) { return (row>=0 && row<_board.length && col>=0 && col<_board[row].length) && _board[row][col]==0; } Simply check if the square is in bounds and that we did not step in it already.

22 22 All Permutations Goal: Print all permutations of the numbers 1 … n Simplifying step? Base Case?

23 23 All Permutations private static void printArray(int[] array) {…} private static void swap(int[] array, int i, int j) {…} public static void allPermutations(int n){ int[] array = new int[n]; for(int i=0; i<n; i++){ array[i]=i+1; } permutationHelper(array,0); } An interface method. Inits the array and calls the recursive method.

24 24 All Permutations private static void permutationHelper(int[] array, int ind) { if(ind==array.length){ printArray(array); return; } for(int i=ind; i<array.length; i++){ swap(array,ind,i); permutationHelper(array, ind+1); swap(array,ind,i); } Base Case: we selected the order of all elements in the array. Print it. Try out all options for placement in current index. Note that when we backtrack we restore the array to its previous form

25 25 The output: 3 2 1 4 3 2 4 1 3 1 2 4 3 1 4 2 3 4 1 2 3 4 2 1 4 2 3 1 4 2 1 3 4 3 2 1 4 3 1 2 4 1 3 2 4 1 2 3 1 2 3 4 1 2 4 3 1 3 2 4 1 3 4 2 1 4 3 2 1 4 2 3 2 1 3 4 2 1 4 3 2 3 1 4 2 3 4 1 2 4 3 1 2 4 1 3

26 Latin Squares An NxN Latin square is a square that contains the number 1…N exactly once in each row and column. They are a primitive version of Sudoku puzzles. Example: Our task: to print all Latin squares of size N. 26 1432 2143 3214 4321

27 27 public static void allLatinSquares(int size){ int[][] board = new int[size][size]; allSquaresHelper(board,0,0); } private static void allSquaresHelper(int[][] board, int row, int col){ if(row==board.length && col==board.length-1){ printBoard(board); return; } if(row == board.length){ row = 0; col++; } for(int symbol=1; symbol<=board.length; symbol++) if(canPut(board,row,col,symbol)){ board[row][col] = symbol; allSquaresHelper(board,row+1,col); } }

28 28 private static boolean canPut(int[][] board, int row, int col, int symbol){ for(int i=0; i<row; i++) if(board[i][col]==symbol) return false; for(int i=0; i<col; i++) if(board[row][i]==symbol) return false; return true; }


Download ppt "1 Tirgul 11: Recursion & Backtracking. 2 Elements of a recursive solution (Reminder) A base case that is so simple we need no computation to solve it."

Similar presentations


Ads by Google