我的方法应该多次迭代但不是,为什么?

时间:2013-12-06 04:46:01

标签: java recursion methods arraylist sudoku

我正在编写一个数独求解算法,我正在尝试实现一个演绎方法来解决这个难题。但是我必须对递归或其他东西有一个松散的把握,因为我的算法似乎只是最多改变一次板,即使我设置的条件应该多次返回true。这是我的方法

public void CRME() {
    for (Node n : cells) {
        scanColumn(n);
        scanRow(n);
        scanMiniGrid(n);
        sortBoardVals();
    }
}

这将扫描每个列,行和小型网格,并在代表棋盘的arraylist中敲出每个节点的可能值。

    public void solve(){
    boolean canChange = false;
    ArrayList<Node> before = new ArrayList<Node>(cells);
    CRME();
    for(Node n : cells){
        int i = cells.indexOf(n);
        if(n.isEqual(before.get(i))){
            canChange = false;
        } else {
            canChange = true;
            break;
        }

    }
    if(canChange){
        System.out.println("Solving...");
        solve();
    }
}

这是解决算法,它应该回想起来,直到它完全耗尽。

这是我的节点类

public class Node {
public ArrayList<Integer> posVals = new ArrayList<Integer>(9) {{
    add(1);
    add(2);
    add(3);
    add(4);
    add(5);
    add(6);
    add(7);
    add(8);
    add(9);
}};
private int ROW_ID;
private int COL_ID;
private int MG_ID;
static boolean hasChanged = true;

int value = 0;

public boolean isEqual(Node n){
    if(this.posVals.size() == n.posVals.size()){
        return true;
    }
    else return false;
}
}

我可能正在考虑重新考虑我的项目,因为我正在考虑使用arraylist使问题复杂化。

CRME中的方法基本上扫描每个节点并找到包含在同一列Row和MiniGrid中的每个节点的值,并从节点的可能值的arraylist中消除它们。

sort board values方法然后检查节点中的arraylist是否为1的大小值,如果是,则将该节点的值设置为Arraylist中的最后一个值。

    public void sortBoardVals() {
    for (Node n : cells) {
        if (n.posVals.size() == 1) {
            if (n.value == 0)
                n.value = n.posVals.get(0);
        }
    }
}

public void scanColumn(Node n) {
    for (Node node : cells) {
        ArrayList<Integer> toRemove = new ArrayList<Integer>();
        if (node.get_COL_ID() == n.get_COL_ID()) {
            toRemove.add(node.getValue());
        }

        n.posVals.removeAll(toRemove);

    }

}

public void scanRow(Node n) {
    for (Node node : cells) {
        ArrayList<Integer> toRemove = new ArrayList<Integer>();
        if (node.get_ROW_ID() == n.get_ROW_ID()) {
            toRemove.add(node.getValue());
        }

        n.posVals.removeAll(toRemove);

    }
}

public void scanMiniGrid(Node n) {
    for (Node node : cells) {
        ArrayList<Integer> toRemove = new ArrayList<Integer>();
        if (node.get_MG_ID() == n.get_MG_ID()) {
            toRemove.add(node.getValue());
        }
        n.posVals.removeAll(toRemove);
    }
}

1 个答案:

答案 0 :(得分:1)

在第二个窗格中,看起来你需要复制一个单元格并在之前调用它。

然后你要比较单元格中的项目,之前不知道CRME中的功能是什么,简单的答案似乎是单元格和之前的单元格相等。

我也不知道你是如何设置实际拼图的。你确实意识到,对于大多数未解决的数独中的大量细胞,这个值不会受到限制,对吗?

我首先要设置一个完整的拼图,除了一个单元格,然后在尝试解决该单元格时,通过调试器跟踪代码。

HTH!