Está en la página 1de 20

Backtracking

What is backtracking? General structure of Backtracking algorithms Backtracking and Recursion

Backtracking
Problem: Find out all 3-bit binary numbers for which the sum of the 1's is greater than or equal to 2. The only way to solve this problem is to check all the possibilities: (000, 001, 010, ....,111) The 8 possibilities are called the search space of the problem. They can be organized into a tree.

Backtracking: Illustration

0__

1__

00_

01_

10_

11_

000

001

010

011

100

101

110

111

Backtracking
For some problems, the only way to solve is to check all possibilities. Backtracking is a systematic way to go through all the possible configurations of a search space. We assume our solution is a vector (a(1),a(2), a(3), ..a(n)) where each element a(i) is selected from a finite ordered set S.

Backtracking
We build a partial solution v = (a(1), a(2),..., a(k)), extend it and test it. If the partial solution is still a candidate solution, proceed. else delete a(k) and try another possible choice for a(k). If possible choices of a(k) are exhausted, backtrack and try the next choice for a(k-1).

Backtracking: Iterative Version


Compute S(1) ,
k = 1 While (k > 0) do While S(k) != emptySet do (*advance*) a(k) = an element in S(k) S(k)= S(k)- a(k) if ( a(1),a(2),...,a(k)) is a solution, print it k = k + 1 Compute S(k) Compute , the candidate k-th element given v. k = k - 1 (*backtrack*)

Backtracking: Recursive Version


Backtrack(a, k) { if a is a solution print(a) else { k = k +1 compute S(k) while do S(k)!=emptySet{ a(k) = an element in S(k) S(k)=S(k)-a(k) } }

Backtracking and Recursion


Backtracking is easily implemented with recursion because: The run-time stack takes care of keeping track of the choices that got us to a given point. Upon failure we can get to the previous choice simply by returning a failure code from the recursive call.

Improving Backtracking: Search Pruning


Search pruning will help us to reduce the search space and hence get a solution faster. The idea is to a void those paths that may not lead to a solutions as early as possible by finding contradictions so that we can backtrack immediately without the need to build a hopeless solution vector.

Eight Queen Problem


Attempts to place 8 queens on a chessboard in such a way that no queen can attack any other. A queen can attack another queen if it exists in the same row, colum or diagonal as the queen. This problem can be solved by trying to place the first queen, then the second queen so that it cannot attack the first, and then the third so that it is not conflicting with previously placed queens.

Eight Queen Problem


The solution is a vector of length 8 (a(1), a(2), a(3), ...., a(8)). a(i) corresponds to the column where we should place the i-th queen.

The solution is to build a partial solution element by element until it is complete.


We should backtrack in case we reach to a partial solution of length k, that we couldn't expand any more.

Eight Queen Problem: Algorithm


putQueen(row) { for every position col on the same row if position col is available place the next queen in position col if (row<8) putQueen(row+1); else success; remove the queen from position col }

Eight Queen Problem: Implementation


Define an 8 by 8 array of 1s and 0s to represent the chessboard The array is initialized to 1s, and when a queen is put in a position (c,r), board[r][c] is set to zero Note that the search space is very huge: 16,772, 216 possibilities. Is there a way to reduce search space? Yes Search Pruning.

Eight Queen Problem: Implementation


We know that for queens: each row will have exactly one queen each column will have exactly one queen each diagonal will have at most one queen This will help us to model the chessboard not as a 2-D array, but as a set of rows, columns and diagonals. To simplify the presentation, we will study for smaller chessboard, 4 by 4

Implementing the Chessboard


First: we need to define an array to store the location of so far placed queens
PositionInRow 1

Implementing the Chessboard Contd


We need an array to keep track of the availability status of the column when we assign queens.

Suppose that we have placed two queens

Implementing the Chessboard Contd


We have 7 left diagonals, we want to keep track of available diagonals after the so far allocated queens

T F T T F T T

Implementing the Chessboard Contd


We have 7 left diagonals, we want to keep track of available diagonals after the so far allocated queens

T F F T T T T

Backtracking

[4,3]

[3,1]

[2,4]

[1,2]

The putQueen Recursive Method


static void putQueen(int row){ for (int col=0;col<squares;col++) if (column[col]==available && leftDiagonal[row+col]==available && rightDiagonal[row-col+norm]== available) { positionInRow[row]=col; column[col]=!available; leftDiagonal[row+col]=!available; rightDiagonal[row-col+norm]=!available; if (row< squares-1) putQueen(row+1); else System.out.println(" solution found"); column[col]=available; leftDiagonal[row+col]=available; rightDiagonal[row-col+norm]= available; } }

También podría gustarte