Я пытался следовать некоторому псевдокоду, а именно
https://www.geeksforgeeks.org/a-search-algorithm/ &
http://mat.uab.cat/~alseda/MasterOpt/AStar-Algorithm.pdf,
, чтобы создать AАлгоритм поиска пути звезды для четырехсторонней карты на основе тайлов / ячеек с препятствиями.Я понимаю эту концепцию и могу точно объяснить, как она должна работать в словах / изображениях, но ее вставка в код оказывается сложной задачей.В течение нескольких дней, когда я запускаю свою программу, она падает, и мне приходится вручную останавливать приложение.Я считаю, что это связано с бесконечным циклом.Это смущает меня, потому что программа должна выйти из цикла while, как только найдет конечный пункт назначения, но, очевидно, это не работает.Вот код, который, я думаю, должен заставить его выйти из цикла while после того, как будет найден пункт назначения:
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();
}
}
Я знаю, что есть несколько вещей, которые должны быть изменены в этом коде, однако меня больше всего беспокоит цикл while никогдабыть прекращенным.Любые другие комментарии о моем коде приветствуются, но определенно не нужны.