Backtracking:

Backtracking is a methodology for solving certain kinds of problems which involve a series of choices or decisions. Generally, for Backtracking to be successful, you need the following three pieces of functionality. The first, generally a function of the form Fail(Choices) tells when the series of choices made so far cannot work. The second piece of functionality is either a function or some code fragment that enables you to make the next choice at this level. The third, again usually some simple function with a name like Success(Choices), tells you when you have made a series of choices that succeeded.

The Backtracking routine works like this:

Start with an empty set of Choices. Call the Backtrack routine. It will first check to see if Success(Choices) is true. If so, it will display or return the Choices set and stop. If not, it will enter a loop that will continue running through all of the reasonable choices. When it makes a choice, it adds that choice to the set Choices and if Fail(Choices) is false, it will then recursively call Backtrack on the new Choices array. If Fail(Choices) is true it goes on to the next possible choice in the loop.

The pseudocode looks like the following:

public void BackTrack(Choices)
{
    if(Success(Choices)) {
        Print Choices;
        Halt;
    }
    else {
        for all valid available choices c {
            Choices=Choices + c;
            if(!Fail(Choices)) BackTrack(Choices);
            Choices=Choices - c;
        }
    }
}

If one wants to find all solutions, remove the Halt. It will then "backtrack" to the previous Backtrack, remove the last choice, and try again. Eventually, every reasonable choice will be found.

Here is an example program that solves the N-queens problem. The problem is "On an NxN chessboard, can you place N Queens so that none of them attack any other. (Clearly more than N is impossible since with more than N you would have to have more than one on one of the N columns or rows.)

Basically, Fail becomes whether the newest Queen added to the board will be under attack by Queens already chosen. Success becomes whether the newest Queen has made the total N with none attacking. Here is the basic code. Our set representation is simple - we have an array Solution of length NumQueens. The value in Solution[i] represents the position of the queen in the ith row. Once NSoFar==NumQueens-1 it follows that we have chosen NQueens queens and they have worked so we dump out the solutions and return. We need the function OK(NSoFar+1) to check the solution - note we have used the inverse of Fail. OK returns true if a solution using these choices is feasible. Notice also that the next choice is easy - we just run through the numbers 0 to NumQueens-1 and try a queen in each position until we get one that works. We call BackTrack with an initial value of -1 to get it started.

   int NumQueens=SIZEOFBOARD;   //hence 8 for an 8x8 chessboard
   int [] Solution=new int[NumQueens];
   boolean SolutionFound=false;

   private void BackTrack(int NSoFar) {
        if(NSoFar<NumQueens-1) {
            for(int NextStep=0;NextStep<NumQueens;NextStep++) {
                Solution[NSoFar+1]=NextStep;
                PlaceQueen(NSoFar+1,NextStep);
                if(OK(NSoFar+1)) BackTrack(NSoFar+1);
                if(SolutionFound) break;
                RemoveQueen(NSoFar+1,NextStep);
            }
        }
        else {
            SolutionFound=true;
            for(int i=0;i<NumQueens;i++) System.out.print(" "+(Solution[i]+1));
            System.out.println("");
        }
    }

    private boolean OK(int NSoFar) {
        for(int i=0;i<NSoFar;i++)
        {
            if(Attacks(i,Solution[i],NSoFar,Solution[NSoFar]))
                return(false);
        }
        return(true);
    }
 
    private boolean Attacks(int x1, int y1, int x2,int y2) {
        return((x1==x2) || (y1==y2) || ((x1-x2)==(y1-y2)) ||
               ((x2-x1)==(y1-y2)));
    }