Sudoku Backtracking Recursion(Java)

时间:2018-01-13 17:57:42

标签: java recursion backtracking sudoku recursive-backtracking

这个应该创建一个有效的数独字段。我已经删除了方格检查,这不是我现在遇到的问题的一部分,所以不要为此烦恼。

我的问题是,当无法正确添加9时,方法会中断。我不知道如何让它回到前一点并计算起来,这将创造一条新的"路径",所以我想如果我做对了,一切都应该没问题。我仍然在努力使用递归: - /

我可以告诉我认为sudokuCorrect()做了应有的事情。 编辑:您可以忽略布尔测试。我知道我不会使用它,我试着想办法,但显然我不知道如何使用它。

输出

  

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

     

| 2 | 1 | 4 | 3 | 6 | 5 | 8 | 7 | 9 |

分别在集成squarechecker时,它看起来像

  

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

     

| 4 | 5 | 6 | 2 | 3 | 7 | 9 | 0 | 0 |

之后,无论选择哪种变体都行。所以问题是一样的。

  

| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |

public static boolean sudoku(int i, int j) {

        boolean test = false;
        for (int n = 1; n < 10; n++) {
            feld[i][j] = n;

            if (sudokuCorrect(i, j)) {
                if (j < 8) {
                    test = sudoku(i, j + 1);
                } else if (i < 8) {
                    test = sudoku(i + 1, 0);
                }

                System.out.println(i + ", " + j);
                if ((i == 8 && j == 8 && feld[i][j] > 0) || feld[i][j] > 0) {
                    return true;
                } else {
                    return false;
                }
            }

        }
        if (test) {
            return true;
        } else {
            return false;
        }

    }

    public static boolean sudokuCorrect(int i, int j) {
        for (int a = 0; a <= j; a++) {
            map.get(i + 10).add(feld[i][a]);
        }
        if (map.get(i + 10).size() == j + 1) {
            // wenn Zeilen korrekt sind, so prüfe Spalte
            for (int a = 0; a <= i; a++) {
                map.get(j).add(feld[a][j]);
            }
            if (map.get(j).size() == i + 1) {
                return true;
            }

        }
        map.get(i + 10).clear(); // leert das HashSet
        map.get(j).clear();

        return false;

    }

1 个答案:

答案 0 :(得分:0)

我不会查看检查正确状态的代码(因为它不完整),只是尝试不同解决方案的代码。

你应该做的是测试当前位置的数字。如果这是一个可行的解决方案,那么如果这是最后一个字段(8,8),我们就完成了。如果没有,请尝试在下一个字段中放置一个数字。如果那是成功的那么我们就完成了(因为那时所有数字都是正确的)。如果不成功,请尝试下一个数字。

如果没有数字工作,那么我们处于无法继续的状态,返回false,所以我们尝试替换前面字段中的一个数字。

此外,我认为您需要在回溯之前清理当前字段以简化正确性检查。

这样的事情:

public static boolean sudoku(int i, int j) {
    for (int n = 1; n < 10; n++) {
        // Try using n
        feld[i][j] = n;
        if (sudokuCorrect(i, j)) {
            if (i == 8 && j == 8) {
                // Last digit successful, we are done
                return true;
            }
            boolean followingSolved;
            if (j < 8) {
                followingSolved = sudoku(i, j + 1);
            } else {
                followingSolved = sudoku(i + 1, 0);
            }

            if (followingSolved) {
                // All following numbers successful, we are done
                return true;
            }
        }
        // n didn't fit, try next
    }
    // No number fit, current state not possible
    feld[i][j] = 0; // Cleanup attempt
    return false;
}