【发布时间】:2015-03-06 00:29:40
【问题描述】:
我目前一直在使用 A* 算法学习和编程寻路(在 Java 中)。我遇到的一个问题是,当多个实体试图寻路时,它们都改变了previousNode(计算Node 来自的Node),弄乱了算法,最终导致Node A将指向Node B,Node B 将指向Node A。
如何将算法更改为任一
- 不要使用这个遍布所有 A * 算法的
previousNode系统(我已经看到了) - 更改此系统以同时使用
我试图避免让一个实体完成寻路,然后告诉下一个实体进行寻路,依此类推。就像在 Java 中做 wait() - notify() 对一样。
public Path findPath(int startX, int startY, int goalX, int goalY) {
//Path is basically just a class that contains an ArrayList,
//containing Nodes, which contains the steps to reach a goal.
if(map.getNode(goalX, goalY).isObstacle()) {
return null;
}
map.getNode(startX, startY).setDistanceFromStart(0);
closedList.clear();
openList.clear(); //A List with added getFirst() - gets the first Node in the list
openList.add(map.getNode(startX, startY));
while(openList.size() != 0) {
//Node contains a List that has all of the Nodes around this node, a
//F, G, and H value, and its row(y) and column(x)
Node current = openList.getFirst();
if(current.getX() == goalX && current.getY() == goalY) {
return backtrackPath(current);
}
openList.remove(current);
closedList.add(current);
for(Node neighbor : current.getNeighborList()) {
boolean neighborIsBetter;
//If I've already searched this neighbor/node, don't check it
if(closedList.contains(neighbor)) {
continue;
}
if(!neighbor.isObstacle()) {
float neighborDistanceFromStart = (current.getDistanceFromStart() + map.getDistanceBetween(current, neighbor));
if(!openList.contains(neighbor)) {
openList.add(neighbor);
neighborIsBetter = true;
} else if(neighborDistanceFromStart < current.getDistanceFromStart()) {
neighborIsBetter = true;
} else {
neighborIsBetter = false;
}
if(neighborIsBetter) {
neighbor.setPreviousNode(current);
neighbor.setDistanceFromStart(neighborDistanceFromStart);
neighbor.setHeuristic(getManhattanDistance(neighbor.getX(), neighbor.getY(), goalX, goalY));
}
}
}
}
return null;
}
public Path backtrackPath(Node fromNode) {
Path path = new Path();
while(fromNode.getPreviousNode() != null) {
path.prependWaypoint(fromNode);
fromNode = fromNode.getPreviousNode();
}
return path;
}
我具体说的是(findPath()内)
if(neighborIsBetter) {
neighbor.setPreviousNode(current); //previousNode is a value in the Node class that points to the Node that it came from
neighbor.setDistanceFromStart(neighborDistanceFromStart);
neighbor.setHeuristic(getManhattanDistance(neighbor.getX(), neighbor.getY(), goalX, goalY));
}
【问题讨论】:
-
如果没有代码示例,我们不知道您在说什么。为什么您的寻路代理会更改您的数据,而不是使用他们自己的副本或参考资料?
-
前一个节点是搜索状态的一部分。如果您想进行多个独立搜索,您将需要多个搜索状态,包括标记打开、关闭、上一个节点以及每个节点距起点的当前距离。
-
@rpattiso 你能详细说明一下吗?我不太明白你的意思。
-
从您的节点对象中删除任何 A* 数据,不存储与图表中开始或上一个节点的距离(我认为这也是一种更简洁的设计)。而是将该数据存储在 A* 对象中。有多个 Astar 对象,每个代理一个。这样一来,它们共享图形结构而不是 A* 特定数据,并且它们不会相互干扰。