使用递归在Sudoku板中填充正方形

时间:2014-05-11 06:34:28

标签: java recursion

我正在尝试创建一个从txt文件读取数独板的程序,并找到可能的解决方案。 我创建了每个方块的对象并将它们添加到2d数组中: (该板有28种不同的解决方案)

001003
000000
000020
260000
000300
300102

我已成功将方块添加到相应的列,行和框中。但是我的递归方法遇到了麻烦,试图找到可能的电路板解决方案并将每个解决方案添加到不同类中的容器中,该容器使用节点来跟踪所有解决方案。我的容器类中的方法应该使用Square [] [] square作为参数。

我用以下方法启动递归方法:

squares[0][0].fillInRemainingOfBoard();

来自另一个名为Board的课程。

我应该检查所有正方形的递归方法如下所示:

protected void fillInRemainingOfBoard() {
    // If Square is not '0' in the txt file it goes in here
    if(this instanceof SquareDone) {
        // If next != null it goes in here.
        if(next != null) {
            next.fillInRemainingOfBoard();
        }

    // If the square is empty it goes in here
    } else if(this instanceof SquareEmpty) {
        if(next != null) {
            // Searching for possible numbers for square
            // Rows, Column and Box have the same length; 
            //thats why row.getLength() in for-loop
            for(int i=1; i<=row.getLength(); i++) {

            // Set new value to square if this is true,
            // then move on to next square
                if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
                    setNewValue(i);
                    next.fillInRemainingOfBoard();
                }
            }
        } else  {
            for(int i=1; i<=row.get(); i++) {
                if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
                    setNewValue(i);
              // No next.fillInRemainingOfBoard() here because it's the last square
                }
            }
        }
    }
}

我有一个行,列和框的超类,它包含子类的变量和方法。检查合法值的方法如下所示:

public boolean getLegal(int square) {
    for(int i=0; i<rkb.length; i++) {
        if(rute == rkb[i].getVerdi()) {
            return false;
        }
    }
    return true;
}

我的输出看起来像这样

4 2 1 5 6 3
5 3 6 2 1 4
1 4 3 6 2 5
2 6 5 4 3 1
6 1 4 3 5 0
3 0 0 1 0 2

所以我的问题是:为什么我的代码没有为每个方块添加值,如何保存解决方案并将它们发送到另一个类,然后重新开始并检查更多解决方案?

2 个答案:

答案 0 :(得分:1)

它没有为每个方块增加值的原因是因为算法不正确。从数组的位置[5] [4]可以看出,第2行的值和列的值应该是6.这意味着算法搞砸了以前的值而无法找到更多的值。

我怀疑会发生这种情况,因为在下面的部分代码中,setNewValue(i)是为找到的最后一个解决方案设置的,但if语句可能会在程序开头找到多个解决方案,因为没有填充很多正方形,并且并不总是最后的解决方案是好的解决方案。

if(next != null) {
        for(int i=1; i<=row.getLength(); i++) {
            if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
                setNewValue(i);
                next.fillInRemainingOfBoard();
            }
}

要解决此问题,您应该存储与if语句匹配的所有值,并确定以后如何使用它们。 (如果它有超过1个解决方案,可以跳过当前单元格并稍后返回)

这只是我的假设,但您可以使用调试器来查看这是否真的是问题

答案 1 :(得分:0)

这是我几年前实现的Sudoku Solver的快速实现。 https://gist.github.com/dapurv5/e636c85a5a85cd848ca2

您可能希望阅读有关最小剩余值启发式的信息。这是解决CSP(约束满足问题)的标准方法之一