Java 有趣的system.exit()行为和中断行为-发生了什么?
我正在尝试按如下方式实施BFS:Java 有趣的system.exit()行为和中断行为-发生了什么?,java,break,Java,Break,我正在尝试按如下方式实施BFS: package search; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.Qu
package search;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
import common.MyNode;
import common.Parser;
public class BFS extends Search {
Queue<MyNode> frontier;
Queue<MyNode> visited;
ArrayList<MyNode> route;
Parser p;
boolean found = false;
private int toWriteInt = 0;
private double distance;
public BFS(MyNode startNode, MyNode goalNode, Parser p) {
super(startNode, goalNode, p);
frontier = new LinkedList<MyNode>();
visited = new LinkedList<MyNode>();
this.p = p;
route = new ArrayList<MyNode>();
}
public void Search() {
visited.add(this.getStartNode());
if (isGoal(this.getStartNode())) {
System.out.println("goal found at start");
goalFound();
}
ArrayList<MyNode> successors = this.getStartNode().getSuccessors();
for (int i = 0; i < successors.size(); i++) {
successors.get(i).setParent(this.getStartNode());
if (!(visited.contains(successors.get(i)))
&& !(frontier.contains(successors.get(i)))) {
if (isGoal(successors.get(i))) {
visited.add(successors.get(i));
System.out.println("goal found at start successor");
goalFound();
break;
} else {
frontier.add(successors.get(i));
}
}
}
while (!frontier.isEmpty()) {
MyNode current = frontier.poll();
ArrayList<MyNode> currentSuccessors = current.getSuccessors();
visited.add(current);
for (int i = 0; i < currentSuccessors.size(); i++) {
if (!(visited.contains(currentSuccessors.get(i)))
&& !(frontier.contains(currentSuccessors.get(i)))) {
currentSuccessors.get(i).setParent(current);
if (isGoal(currentSuccessors.get(i))) {
visited.add(currentSuccessors.get(i));
System.out.println("goal found in loop");
goalFound();
break;
} else {
frontier.add(currentSuccessors.get(i));
}
}
}
}
}
private boolean isGoal(MyNode toCheck) {
boolean goal = false;
if (toCheck.equals(this.getGoalNode())) {
goal = true;
}
return goal;
}
private void goalFound() {
System.out.println("goal found with " + visited.size());
printRoute();
System.exit(0);
}
public void printRoute() {
MyNode i = this.getGoalNode();
while (i.getParent() != null) {
System.out.println(i.getId());
distance = distance
+ Search.distFrom(i.getLat(), i.getLon(), i.getParent()
.getLat(), i.getParent().getLon());
i = i.getParent();
}
System.out.println(this.startNode.getId());
System.out.println("completed routing");
System.out.println("path length of " + distance + "km");
}
}
再一次,这可以很好地工作并打印出正确的路线。但是,如果我删除system.exit(0),代码将不起作用,printRoute()的while循环将永远打印,将相同的两个节点打印两次(i和i.getParent()。我觉得这真的很奇怪,因为该方法必须已经完成,才能命中我的system.exit
谁能告诉我这是为什么?必须调用system.exit是非常有问题的,因为我想在代码中嵌入BFS,这意味着我不能
谢谢,
MJB
编辑:下面有人建议退货可以解决我的问题。以下是一个*搜索,显示相同的行为,仅在我返回系统时有效。即使返回,也要退出:
package search;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Stack;
import common.MyNode;
import common.Parser;
public class AStar extends Search {
private ArrayList<MyNode> openList; // This is basically our frontier
private ArrayList<MyNode> closedList;// This is the visited set.
public AStar(MyNode startNode, MyNode goalNode, Parser p) {
super(startNode, goalNode, p);
openList = new ArrayList<MyNode>();
closedList = new ArrayList<MyNode>();
}
public Stack<MyNode> Search() {
Stack<MyNode> toReturn = new Stack<MyNode>();
openList.add(this.getStartNode());
while (!openList.isEmpty()) {
Collections.sort(openList);
MyNode q = openList.remove(0);
openList.remove(q);
// generate q's 8 successors and set their parents to q
// if successor is the goal, stop the search
if (isGoal(q)) {
System.out.println("search completed- goal found");
MyNode i = this.getGoalNode();
while (i.getParent() != null) {
toReturn.add(i);
i = q.getParent();
}
return toReturn;
}
closedList.add(q);
ArrayList<MyNode> successors = q.getSuccessors();
for (MyNode node : successors) {
if (closedList.contains(node)) {
continue;
}
node.setParent(q);
/*
* successor.g = q.g + distance between successor and q
* successor.h = distance from goal to successor
* successor.f=successor.g + successor.h
*/
double g = q.getG()
+ Search.distFrom(q.getLat(), q.getLon(),
node.getLat(), node.getLon());
double h = Search.distFrom(this.getGoalNode().getLat(), this
.getGoalNode().getLon(), q.getLat(), q.getLon());
node.setG(g);
node.setH(h);
node.setF(g + h);
// if a node with the same position as successor is in the OPEN
// list
// has a lower f than successor, skip this successor
int openIndex = openList.indexOf(node);
int closedIndex = closedList.indexOf(node);
if (openIndex > -1) {
if (openList.get(openIndex).compareTo(node) == -1)
continue;
}
// if a node with the same position as successor is in the
// CLOSED list
// which has a lower f than successor, skip this successor
if (closedIndex > -1) {
if (closedList.get(closedIndex).compareTo(node) == -1)
continue;
}
if (openIndex > -1)
openList.remove(openIndex);
Collections.sort(openList);
if (closedIndex > -1)
closedList.remove(closedIndex);
openList.add(node);
Collections.sort(openList);
}
closedList.add(0, q);
}
return toReturn;
}
这些节点具有以下属性:
node [id=21295291, lat=52.4737031, lon=-1.8747258]
node [id=119126329, lat=52.4701337, lon=-1.8716235]
代码
断开内部循环(for),但也有外部while循环。您可以使用“return;”此处不是“break”(或标记为break)。您尝试过使用调试器吗?您在循环中调用了goalFound(),因此很明显,它会在找到目标后继续循环。该系统。退出(0)会中断每个循环。当然它是有效的,但我强烈反对它,这是一个廉价的修复方案,可能会带来问题。请您更新您的问题正文,因为您声称有一个“getRoute()”方法,但很明显,您没有在代码段中使用它。@SotiriosDelimanolis是的-我可以看到他们一遍又一遍地将自己设置为家长,非常奇怪。@tiago7请你给我举个例子,说明我如何能正确地打破一切?这已经给我带来了问题,因为我不希望搜索结束成为我程序的结束。我还有一个例子,我可以展示,即使我返回时也会做同样的事情。我已经添加了它。@MJB另外,你能在提供输入数据的地方发布你的
main
?因为我怀疑你的I.getParent()!=null
条件,正如您所说,它将在此处继续循环。这只意味着你将有多个父母在那里?添加了@hagubear和更多的信息。
node [id=21295291, lat=52.4737031, lon=-1.8747258]
node [id=119126329, lat=52.4701337, lon=-1.8716235]
goalFound();
break;