Java 深度优先搜索无限循环代码
我试图解决传教士和食人族的问题,我试图实现一个DFS算法来找到最佳解决方案。不幸的是,这段代码把我带到了一个无限循环中,我不明白为什么。有人能帮忙吗?谢谢大家!Java 深度优先搜索无限循环代码,java,infinite-loop,depth-first-search,Java,Infinite Loop,Depth First Search,我试图解决传教士和食人族的问题,我试图实现一个DFS算法来找到最佳解决方案。不幸的是,这段代码把我带到了一个无限循环中,我不明白为什么。有人能帮忙吗?谢谢大家! import java.util.*; public class DFS3 { public State2 exec(State2 root) { if (root==null) return null; Stack<State2> sta
import java.util.*;
public class DFS3 {
public State2 exec(State2 root) {
if (root==null)
return null;
Stack<State2> stack = new Stack<State2>();
Set<State2> visitedNodes = new HashSet<State2>();
//Add the root to the stack
stack.push(root);
while(!stack.isEmpty())
{
State2 n = stack.pop();
//Check to see if node n is the requested node
if(n.isGoal())
return n;
else
{
//Create an array of the leaf nodes to node n
List<State2> children = n.generateSuccessors();
for(int i =0; i<children.size(); i++)
{
//Add the leaf nodes to the stack
if ( !visitedNodes.contains(children.get(i)) ) {
stack.push(children.get(i));
visitedNodes.add(children.get(i));
}
System.out.println(stack.peek());
}
}
}
//Not found so return null
return null;
}
}
这就是我如何创造新的成功者
public List<State2> generateSuccessors() {
List<State2> successors = new ArrayList<State2>();
if (boat == Position.LEFT) {//la dreapta
testAndAdd(successors, new State2(cL, mL - 2, Position.RIGHT,
cR, mR + 2)); // 2 misionari stanga-dreapta
testAndAdd(successors, new State2(cL - 2, mL, Position.RIGHT,
cR + 2, mR)); // doi canibali stanga-dreapta
testAndAdd(successors, new State2(cL - 1, mL - 1, Position.RIGHT,
cR + 1, mR + 1)); // un misionar si un canibal stanga-dreapta
testAndAdd(successors, new State2(cL, mL - 1, Position.RIGHT,
cR, mR + 1)); // un misionar stanga-dreapta
testAndAdd(successors, new State2(cL - 1, mL, Position.RIGHT,
cR + 1, mR)); //un canibal
} else { //la stanga
testAndAdd(successors, new State2(cL, mL + 2, Position.LEFT,
cR, mR - 2));
testAndAdd(successors, new State2(cL + 2, mL, Position.LEFT,
cR - 2, mR));
testAndAdd(successors, new State2(cL + 1, mL + 1, Position.LEFT,
cR - 1, mR - 1));
testAndAdd(successors, new State2(cL, mL + 1, Position.LEFT,
cR, mR - 1));
testAndAdd(successors, new State2(cL + 1, mL, Position.LEFT,
cR - 1, mR));
}
return successors;
}
private void testAndAdd(List<State2> successors, State2 newState) {
if (newState.isValid()) {
newState.setParentState(this);
successors.add(newState);
}
}
看起来这个算法对我有效
import java.util.*;
public class DFS2 {
public static State2 exec(State2 root) {
boolean found = false;
List<State2> visited = new ArrayList<State2>();
Stack<State2> toVisit = new Stack<State2>();
toVisit.push(root);
while (!toVisit.isEmpty() && !found) {
State2 nod = toVisit.pop();
visited.add(nod);
if (nod.isGoal()) {
found = true;
return nod;
}
else {
List<State2> copii=new ArrayList<State2>();
List<State2> children = new ArrayList<State2>();
children = nod.generateSuccessors();
for(int i =0; i<children.size(); i++)
{
//Add the leaf nodes to the stack
if ( !visited.contains(children.get(i)) )
copii.add(children.get(i));
}
toVisit.addAll(0, copii);
}
}
return null;
}
}
您不会将项目从堆栈中移除到循环中。因此,堆栈总是非空的。每次你找不到你的目标节点,你就把五个State2对象推到堆栈上。在下一次迭代中,您测试堆栈顶部的任何内容,如果不是目标,则再推5次,以此类推。在您测试的第5个之前,您从未测试您推送到堆栈上的4个。因此,除非您的目标状态恰好位于树的边缘,否则您的程序可能会永远循环。尝试在每次迭代中打印stack.size。这是我在帮助和改进队列中找到的,需要编辑。由于这个问题本身没有太大的错误,而且相关的代码也在那里,所以我只是稍微整理了一下格式。您可以通过解释您尝试进行的调试以及输出是什么来改进问题,例如,我看到您正在打印stack.peek-这背后的想法是什么,它输出了什么?