数独算法没有正确回溯

时间:2016-10-01 16:54:19

标签: java

我正在制作一个数独求解器,如果它没有导致解决方案,它会在正方形中尝试每个可能的值并回溯。我相信我有一个近乎工作的算法,但到目前为止它只能用于16个单元拼图的第0,2和3行。

public boolean fillBoard(int[][] board, int row, int col){
    int index = 1;              //Next value to try when an empty is found
    boolean solved = false;

    for(int i = row; i < width; i++){       //For each row
        for(int j = col; j < height; j++){  //For each column
            if(board[i][j]==0){             //0 represents empty
                while(!solved){
                    board[i][j] = index;
                    if(checker.checkRow(board[i]) 
                            && checker.checkColumn(columnToArray(board, j))
                            //&& checker.checkBox(<input>)
                            ){
                            solved = fillBoard(board, i, 0);
                    }else{
                        if(index < width){
                            index++;
                        }else{
                            return false;
                        }
                    }
                }
            }
        }
    }
    puzzle = copyPuzzle(board);
    return true;
}

现在它没有检查第三个Sudoku规则,它只检查列和行。但是,它仍然应该返回遵循行和列规则的拼图,对吧?一旦编写了checkBox方法,它应该能够解决这个难题。我在哪里搞砸了?

编辑,举几个例子:

输入

        {1, 2, 0, 0},
        {0, 4, 0, 0},
        {0, 0, 1, 0},
        {0, 0, 3, 2}

程序返回

1 2 4 3 4 4 4 4 2 3 1 4 4 1 3 2

输入

        {1, 0},
        {2, 0}

它正确地解决了它。

输入

        { 1, 0, 3, 4, 0, 0 },
        { 4, 0, 6, 0, 0, 3 },
        { 2, 0, 1, 0, 6, 0 },
        { 5, 0, 4, 2, 0, 0 },
        { 3, 0, 2, 0, 4, 0 },
        { 6, 0, 5, 0, 0, 2 }

它返回未解决的难题

编辑:checkRow代表

的人
public boolean checkRow(int[]row){
    HashSet<Integer> set = new HashSet<Integer>();
    for(int i = 0; i < row.length;i++){
        if(!set.add(row[i]) && row[i]>0){//Duplicate?
            return false;
                    }
                }
    return true;
}

1 个答案:

答案 0 :(得分:1)

问题是,当值不正确时,它没有将空格重置为0,所以如果它达到最大索引并且不正确,它就会离开它。以下代码有效。只是等待我小组中的另一个人提供盒子检查方法,但我可能最终必须自己做。

public boolean fillBoard(int[][] board, int row, int col){
    int index = 1;              //Next value to try when an empty is found
    boolean solved = false;

    for(int i = row; i < width; i++){       //For each row
        for(int j = col; j < height; j++){  //For each column
            if(board[i][j]==0){             //0 represents empty
                while(!solved){             //While the puzzle is unsolved
                    board[i][j] = index;    //Try to fill with index
                    if(checker.checkRow(board[i]) 
                            && checker.checkColumn(columnToArray(board, j))
                            //&& checker.checkBox(<input>)
                            ){
                            solved = fillBoard(board, i, 0); //Next space
                    }
                    if(!solved) board[i][j] = 0;
                    if(index < width){
                        index++;
                    }else{
                        return false;
                    }                        
                }
            }
        }
    }
    puzzle = copyPuzzle(board);
    return true;
}