Determine whether a Sudoku has a unique solution

我与影子孤独终老i 提交于 2019-12-20 04:31:28

问题


I'm struggling with a backtracking algorithm to determine wether a Sudoku has a unique solution or if it has multiple Solutions. Here's the backtracking code i use:

    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;
}

First approach: If i change

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

i get two different solving-algorithmns which should find different solutions (if different solutions exist). The problem with this approach is, that the algorithm doesn't terminate even though its just a slight change and i don't know why.

Second approach: Reset to backtrack and continue searching for a solution. If i try this, it doesn't work either.

I tried to find a Java example, but i can only find information like "reset on backtrack and continue searching for a second solution".

Could someone please provide a example how to change the algorithm so it tells me if multiple solutions exists (the exact number is not needed)

OR

Could someone please explain to me why my first approach doesn't terminate?

Thanks!


回答1:


If you return a number instead of a boolean, you can distinguish between cases where there are 0, 1, or more than 1 solution(s).

// 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;
}



回答2:


The reset must be inside the for loop and after the if solve condition

 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
        }
    }


来源:https://stackoverflow.com/questions/24343214/determine-whether-a-sudoku-has-a-unique-solution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!