我正在用 java 做一个 8 块益智游戏,我做 DFS 以找到解决方案的分配命令,从随机状态开始。
我有一个 Node 类,每个 Node 对象都知道它使用 int[][] 处于什么状态以及它的父节点是什么。它还知道它可以向哪个方向移动(左、右、上、下)
goal state: start state (random):
[0 1 2] [1 8 0]
[3 4 5] [3 7 4]
[6 7 8] [2 5 6]
从单个节点开始,开始节点,我的程序为其所有可能的子节点创建一个节点。它检查空白方块可以移动的可用方向,它检查它是否不会回到已经属于另一个节点的状态。所以在上面的例子中,起始节点会展开如下:
[1 8 0]
A) [3 7 4]
[2 5 6]
/ \
[1 0 8] [1 8 4]
B) [3 7 4] [3 7 0] C)
[2 5 6] [2 5 6]
/ / / \
... ... [1 8 4] [1 8 4]
D) [3 0 7] [3 7 6] E)
[2 5 6] [2 5 0]
/ / / / \
... ... ... [1 8 4] NO
F) [3 7 6] CHILD
[2 0 5]
/ \
... ...
我处理这个问题的方法是我探索第一个节点并将它的所有子节点推入堆栈,这发生在递归方法中,循环扩展每个节点直到达到目标状态或达到截止(我提供给避免永远循环)
stack = [A]
pop()
stack = []
A -> B
push(B)
stack = [B]
A -> C
push(C)
stack = [C|B]
A -> NO MORE CHILDREN
pop()
stack = [B]
C -> D
push(D)
stack = [D|B]
C -> E
push(E)
stack = [E|D|B|]
C -> NO MORE CHILDREN
pop()
stack = [D|B|]
E -> F
push(F)
stack = [F|D|B]
E -> NO MORE CHILDREN
pup()
stack = [D|B]
只要我的截止值不太高,代码就可以正常工作,如果它比我得到错误:java.lang.StackOverflowError
我究竟做错了什么?
public void expand(Node parent, int cutoff){
cutoff--;
int[][] currentState = parent.getState();
if(Arrays.deepEquals(currentState, goalState)){
found = true;
goalNode = parent;
}
if(cutoff>0 && !found){
if(parent.up){
Node child = createUPnode();
child.setParent(parent);
stack.push(child);
parent.up = false;
expand(parent, cutoff)
}
else if(parent.right){
Node child = createRIGHTnode();
child.setParent(parent);
stack.push(child);
parent.right = false;
expand(parent, cutoff)
}
else if(parent.down){
Node child = createDOWNnode();
child.setParent(parent);
stack.push(child);
parent.down = false;
expand(parent, cutoff)
}
else if(parent.left){
Node child = createLEFTnode();
child.setParent(parent);
stack.push(child);
parent.left = false;
expand(parent, cutoff)
}
else{
Node nextNode = stack.pop();
expand(nextNode, cutoff);
}
}
else{
System.out.println("CUTOFF REACHED");
}
}