Java 无限while循环的A*算法
我一直试图遵循一些伪代码,即 & , 为带有障碍物的四方向平铺/基于单元的地图创建星形寻路算法。我理解这个概念,并且我可以用文字/图像明确地解释它应该如何工作,但是将其转化为代码是很有挑战性的。现在有几天,每当我运行我的程序,它就会崩溃,我必须手动停止应用程序。我相信这是由于一个无限的while循环。这让我很困惑,因为一旦程序找到了最终目的地,它就应该退出while循环,但显然这不起作用。这是我认为应该让它在找到目的地后退出while循环的代码:Java 无限while循环的A*算法,java,algorithm,while-loop,path-finding,a-star,Java,Algorithm,While Loop,Path Finding,A Star,我一直试图遵循一些伪代码,即 & , 为带有障碍物的四方向平铺/基于单元的地图创建星形寻路算法。我理解这个概念,并且我可以用文字/图像明确地解释它应该如何工作,但是将其转化为代码是很有挑战性的。现在有几天,每当我运行我的程序,它就会崩溃,我必须手动停止应用程序。我相信这是由于一个无限的while循环。这让我很困惑,因为一旦程序找到了最终目的地,它就应该退出while循环,但显然这不起作用。这是我认为应该让它在找到目的地后退出while循环的代码: if (n.getX() == end.getX
if (n.getX() == end.getX() && n.getY() == end.getY()) {
currentNode = n;
break;
}
我希望这篇文章中没有太多的代码,但这是我算法的核心部分,我对每一部分的功能都有评论:
public void attempt2() {
double leastF = Integer.MAX_VALUE;
// Initializes the starting Node and, in the beginning, currentNode is the same
// as the starting node
Node start = new Node(r.getCell());
Node currentNode = start;
start.setParent(start);
closed.add(start);
open.add(start);
start.setEnd(destinationCP);
start.calculateH();
start.isCalculatedH();
while (open.size() > 0) {
// Finds the node with the least F score on Open
for (Node n : open) {
// Calculates the H-score if it hasn't been already
if (n.haveNotCalculatedH()) {
n.setEnd(destinationCP);
n.calculateH();
n.isCalculatedH();
}
// Calculates the g-score, with 1 being the value/distance of a cell
n.setAdditiveDistanceG(n.getAdditiveDistanceG() + 1);
// Calculates the F-score
n.calculateF();
// Actually finds the least F score in the open list and sets currentNode to the
// node with the least F
if (n.getTotalCostF() < leastF) {
leastF = n.getTotalCostF();
currentNode = n;
}
}
//
// Creates easy-access variables for the x and y values of the node on open with
// the least F score
int thisX = currentNode.getX();
int thisY = currentNode.getY();
// if this cell (cell in open w least F) is the end destination cell, stop the calculations
if (thisX == end.getX() && thisY == end.getY()) {
break;
}
//
// Generate 1-4 successors if Robot can pass into the cell
if (World.getCell(thisX + 1, thisY).canEnter(r)) {
successors.add(new Node(World.getCell(thisX + 1, thisY)));
}
if (World.getCell(thisX, thisY + 1).canEnter(r)) {
successors.add(new Node(World.getCell(thisX, thisY + 1)));
}
if (World.getCell(thisX - 1, thisY).canEnter(r)) {
successors.add(new Node(World.getCell(thisX - 1, thisY)));
}
if (World.getCell(thisX, thisY - 1).canEnter(r)) {
successors.add(new Node(World.getCell(thisX, thisY - 1)));
}
//
/*
* Loops through each of the 1-4 neighbors to currentNode (I need to add in to
* erase & add to open/closed every one in here so its empty before new ones are
* generated
*/
for (Node n : successors) {
double successorCurrentCost = 0;
// if this successor is already in the closed list, skip doing all the code for
// this node and add this successor's parent (currentNode) to the closed list
if (isInClosed(n)) {
continue;
}
// if this is the goal/end node, exit the 'successors' for-loop. the step that
// follows this (exiting the loop) is that this particular node/successor is
// added to the closed list
if (n.getX() == end.getX() && n.getY() == end.getY()) {
currentNode = n;
break;
}
//
// Calculates the F cost for each successor to currentNode
if (n.haveNotCalculatedH()) {
n.setEnd(destinationCP);
n.calculateH();
n.isCalculatedH();
}
n.setAdditiveDistanceG(n.getAdditiveDistanceG() + currentNode.getAdditiveDistanceG());
n.calculateF();
successorCurrentCost = n.getTotalCostF();
//
if (!isInOpen(n) && n.getAdditiveDistanceG() > successorCurrentCost
|| n.getAdditiveDistanceG() > successorCurrentCost && !isInClosed(n)) {
open.add(n);
if (n.haveNotCalculatedH()) {
n.setEnd(destinationCP);
n.calculateH();
n.isCalculatedH();
}
} else if (isInClosed(n) && n.getAdditiveDistanceG() <= successorCurrentCost) {
successorCurrentCost = n.getAdditiveDistanceG();
n.setParent(currentNode);
} else {
successorCurrentCost = n.getAdditiveDistanceG();
n.setParent(currentNode);
}
if (isInClosed(n)) {
closed.remove(n);
open.add(n);
}
}
closed.add(currentNode);
if (thisX == end.getX() && thisY == end.getY()) {
break;
}
}
if (currentNode.getMyCell() != this.destinationCP) {
System.out.println("ERROR: open list is empty");
return;
} else {
createPath();
}
}
public void attempt2(){
double leastF=整数最大值;
//初始化起始节点,开始时currentNode相同
//作为起始节点
Node start=新节点(r.getCell());
节点当前节点=开始;
setParent(start);
关闭。添加(开始);
打开。添加(开始);
start.setEnd(destinationCP);
start.calculateH();
start.isCalculatedH();
while(open.size()>0){
//查找打开时F分数最低的节点
用于(节点n:打开){
//如果尚未计算H分数,则计算H分数
如果(n.havenotcalculated h()){
n、 setEnd(目的地CP);
n、 计算();
n、 isCalculatedH();
}
//计算g分数,1表示单元格的值/距离
n、 setAdditiveDistanceG(n.getAdditiveDistanceG()+1);
//计算F分数
n、 calculateF();
//实际查找开放列表中的最低F分数,并将currentNode设置为
//具有最小F的节点
if(n.getTotalCostF()成功或当前成本
||n.getAdditiveDistanceG()>成功或当前成本(&&!IsClosed(n)){
打开。添加(n);
如果(n.havenotcalculated h()){
n、 setEnd(目的地CP);
n、 计算();
n、 isCalculatedH();
}
}else if(isInClosed(n)和&n.getAdditiveInstanceg()查看一些帮助您调试代码的提示。您所指的break
语句打破了周围的for
循环(而不是外部while
循环)。代码学徒是对的:调试时间到了!