the reason why I create this new thread instead of just reading the answers to this specific question that was given earlier is because I feel that I just do not fully understand the whole idea behind it. It seems like I can't look back at the whole concept of reverse tracking. So I need to fully understand the rollback, and then solve the specific sudoku problem.
What I understand so far is that backtracking is a way to go back (for example) to a recursive thread if you find that decisions made before the current state led to a deadlock. So, you will return to something else and continue again.
So, in my Sudoku example, I select the first empty cell and try to fill in a natural number from {1 ... 9}, which does not contradict the well-known Sudoku rules. Now I do the same with the next empty cell until I reach the point where a valid number cannot be inserted without conflicts. In my understanding, this should be the point at which the rollback occurs. But how? If I use recursion to return to the last recorded cell, the algorithm will fill in the number again, continue and end the jam in an infinite loop.
So, I searched the Internet for tips and found that this is a pretty well documented and often solved problem. However, many solutions claim to use backtracking. I donβt see how and 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 do not know how to proceed. How to implement backtracking or am I already? This seems like a silly question, but I really don't see any more digressions in the 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; }