确定数独是否具有唯一解决方案

时间:2014-06-21 15:42:58

标签: java algorithm sudoku backtracking

我正在努力使用回溯算法确定Sudoku是否有独特的解决方案,或者它是否有多个解决方案。这是我使用的回溯代码:

    static boolean solve(int i, int j, int[][] cells) {
    if (i == 9) {
        i = 0;
        if (++j == 9)
            return true;
    }
    if (cells[i][j] != 0)  // skip filled cells
        return solve(i+1,j,cells);

    for (int val = 1; val <= 9; ++val) {
        if (legal(i,j,val,cells)) {
            cells[i][j] = val;
            if (solve(i+1,j,cells))
                return true;
        }
    }
    cells[i][j] = 0; // reset on backtrack
    return false;
}

第一种方法: 如果我改变

for (int val = 1; val <= 9; ++val) {
for (int val = 9; val >= 1; val--) {

我得到两种不同的求解算法,它们应该找到不同的解决方案(如果存在不同的解决方案)。这种方法的问题是,算法即使只是稍微改变也不会终止,我不知道为什么。

第二种方法: 重置为回溯并继续搜索解决方案。如果我试试这个,它也不起作用。

我试图找到一个Java示例,但我只能找到&#34;在回溯上重置的信息并继续搜索第二个解决方案&#34;。

有人可以提供一个如何更改算法的示例,以便它告诉我是否存在多个解决方案(不需要确切的数字)

OR

有人可以向我解释为什么我的第一种方法不会终止吗?

谢谢!

2 个答案:

答案 0 :(得分:6)

如果返回数字而不是布尔值,则可以区分0,1或多于1个解决方案的情况。

// returns 0, 1 or more than 1 depending on whether 0, 1 or more than 1 solutions are found
static byte solve(int i, int j, int[][] cells, byte count /*initailly called with 0*/) {
    if (i == 9) {
        i = 0;
        if (++j == 9)
            return 1+count;
    }
    if (cells[i][j] != 0)  // skip filled cells
        return solve(i+1,j,cells, count);
    // search for 2 solutions instead of 1
    // break, if 2 solutions are found
    for (int val = 1; val <= 9 && count < 2; ++val) {
        if (legal(i,j,val,cells)) {
            cells[i][j] = val;
            // add additional solutions
            count = solve(i+1,j,cells, count));
        }
    }
    cells[i][j] = 0; // reset on backtrack
    return count;
}

答案 1 :(得分:2)

重置必须在for循环内和if solve条件

之后
 for (int val = 1; val <= 9; ++val) {
        if (legal(i,j,val,cells)) {
            cells[i][j] = val;
            if (solve(i+1,j,cells))
                return true;
            cells[i][j] = 0; // reset on backtrack
        }
    }
相关问题