这个数独求解器如何工作?

时间:2011-11-30 00:35:45

标签: java algorithm

我找到了一些解决数独谜题的代码,但我只理解其中的一部分。

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

static boolean legal(int i, int j, int val, int[][] cells) {
    for (int k = 0; k < 9; ++k)  // row
        if (val == cells[k][j])
            return false;

    for (int k = 0; k < 9; ++k) // col
        if (val == cells[i][k])
            return false;

    int boxRowOffset = (i / 3)*3;
    int boxColOffset = (j / 3)*3;
    for (int k = 0; k < 3; ++k) // box
        for (int m = 0; m < 3; ++m)
            if (val == cells[boxRowOffset+k][boxColOffset+m])
                return false;

    return true; // no violations, so it's legal
}

我理解legal()方法,它只是检查不允许的重复项。不太清楚的是solve()中的递归是如何完成它的。

任何人都可以提供有关该部分如何工作的见解。我真的很想了解它,所以我可以自己实现。

由于

3 个答案:

答案 0 :(得分:6)

该算法使用递归和回溯,基本上它“强力”数独直到找到正确的答案。

它将循环显示数字1 - 9,直到找到目前该单元格合法的数字。当算法不在有效组合中时,算法将回溯(即重置数字)数字。它将完成每个列和行,直到它解决整个难题。

答案 1 :(得分:1)

它尝试每次合法的插入。
当然,只有其中一个会产生真正的解决方案,所以它会检查它们是真还是假。

不正确的尝试将在某处死亡并返回false。

答案 2 :(得分:1)

通俗地说,solve执行以下操作:

solve(position, field):
  for all values of all positions:
    fill current position of field with current value
    solve(neighboring position, field) # solve 'the rest'
    if field is a legal solution:
      return field
    else:
      unfill current position of field
    # the loop proceeds to next position