the reason why I am creating this new thread instead of just reading the answers to this particular question that have been given before is that I feel I just don't fully understand the whole idea behind it. I can't seem to get my head around the whole backtracking concept. So I need to fully understand backtracking and then solve the particular sudoku problem.
What I understand so far is that backtracking is a technique to go back, in (e.g.) a recursive flow if one discovers that decisions made prior to the current state led to a dead end. So you go back try something else and continue again.
So in my sudoku example I pick the first empty cell and try to fill in a natural number out of {1...9} that doesn't conflict with the well know sudoku rules. Now I do the same thing with the next empty cell until I get to the point where no valid number may be inserted without conflicts. As of my understanding this should be the point where backtracking comes into play. But how? If I use recursion to go back to the last written cell the algorithm will fill in the number again, continue and end up stuck in an endless loop.
So I searched the Internet for hints and found this to be a quite well documented and frequently solved problem. Yet many solutions claim to use backtracking I don't see how or where they do it even if I have the source code right in front of me.
Examples are: Sudoku solver in Java, using backtracking and recursion or http://www.heimetli.ch/ffh/simplifiedsudoku.html
Here is my (not working) source code:
private boolean isSolvable( Sudoku sudoku, int row, int col ){
//if the method is called for a row > 8 the sudoku is solved
if(row > 8)
return true;
//calculate the next cell, jump one row if at last column
int[] nextCell = (col < 8) ? new int[]{row,col+1} : new int[]{row+1,0};
//check if the current cell isWritable() that is if it is not a given cell by the puzzle
//continue recursively with the next cell if not writable
if(!sudoku.isWritable(row, col))
isSolvable(sudoku, nextCell[0], nextCell[1]);
else{
//set the current cell to the lowest possible not conflicting number
for(int i=1; i< 10; i++){
if(!conflictAt(sudoku, row, col, i)){
sudoku.setValue(row, col, i);
//continue recursively with the next cell
isSolvable(sudoku, nextCell[0], nextCell[1]);
}
}
}
return false;
}
Now I don't know how to continue. How to implement the backtracking or did I already? This seems like a stupid question but I really don't see more backtracking going on in source codes mentioned in the links above.
EDIT: Final (working) version:
private boolean isSolvable( Sudoku sudoku, int row, int col ){
//if the method is called for a row > 8 the Sudoku is solved
if(row > 8)
return true;
//if the cell is not writable, get the next writable cell recursively
if(!sudoku.isWritable(row,col))
return isSolvable(sudoku, (col<8) ? row : row + 1, (col<8) ? col + 1 : 0);
//brute forcing for solution
for(int i=1; i<=9; i++){
if(!conflictAt(sudoku, row, col, i)){
sudoku.setValue(row, col, i);
if(isSolvable(sudoku, (col<8) ? row : row + 1, (col<8) ? col + 1 : 0)) return true;
}
}
sudoku.setValue(row, col, 0);
return false;
}