我试图实现伪造的A *搜索:
http://web.mit.edu/eranki/www/tutorials/search/
虽然搜索终止并找到目标,但我的print route()方法
> private void printRoute() {
MyNode i = this.getGoalNode();
while (i != this.getStartNode()) {
System.out.println(i.getId());
i = i.getParent();
}
}
陷入了打印循环:
8
7
8
7
8
7
8
7
8
7
我正在解析Open Street地图数据来进行搜索,但我已经验证了我的解析正在使用成功的BFS和DFS。这是我制作的简化模型,用于表示简单的网格。我在从节点1到节点12搜索: 1 2 3 4
5 6 7 8
9 10 11 12
所以1扩展为2和5等
搜索完成时关闭的设置如下所示:
在设置父级时,我的逻辑中必定存在缺陷,但我无法看到它。真的很感激任何帮助。
感谢, MJB
完整的A *代码
import java.util.ArrayList;
import java.util.LinkedList;
public class AStar extends Search {
private LinkedList<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 LinkedList<MyNode>();
closedList = new ArrayList<MyNode>();
}
public void Search() {
openList.add(this.getStartNode());
while (!openList.isEmpty()) {
MyNode q = openList.get(0);
// find the node with the lowest heuristic value
for (MyNode node : openList) {
if (node.getF() < q.getF())
q = node;
}
openList.remove(q);
ArrayList<MyNode> successors = q.getSuccessors();
for (MyNode node : successors) {
node.setParent(q);
if (isGoal(node)) {
System.out.println("search completed- goal found");
printRoute();
System.exit(0);
}
double g = node.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.setF(g + h);
if (openList.contains(node)) {
int openIndex = openList.indexOf(node);
if (openList.get(openIndex).getF() < node.getF()) {
// do nothing.
}
}
if (closedList.contains(node)) {
int closedIndex = closedList.indexOf(node);
if (closedList.get(closedIndex).getF() < node.getF()) {
// do nothing.
}
} else {
openList.add(node);
}
}
closedList.add(q);
}
}
// checks the goal and returns a boolean.
private Boolean isGoal(MyNode node) {
boolean toReturn = false;
if (node.equals(this.getGoalNode())) {
toReturn = true;
}
return toReturn;
}
private void printRoute() {
MyNode i = this.getGoalNode();
while (i != this.getStartNode()) {
System.out.println(i.getId());
i = i.getParent();
}
}
}
编辑:实现了下面的更改(谢谢),但仍然遇到陷入循环的相同问题。还尝试将printRoute()的条件更改为while(i.getParent()!= null),但再次收到相同的错误。
答案 0 :(得分:0)
您似乎没有错误地实施节点分数。节点的分数应等于:路径从开始到此节点的长度+ 估计路径长度到结束。当你实现它时:估计路径长度从开始到此节点+ 估计路径长度从此节点到完成。
要正确实现算法,您需要存储用于从起始节点获取的路径的长度。所以不要这样:
double g = node.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.setF(g + h);
你需要这样的东西:
node.setPathLen(q.getPathLen() + dist(q, node)); // set actual length of an actual path from start to this node
double g = node.getPathLen();
double h = Search.distFrom(this.getGoalNode().getLat(), this.getGoalNode().getLon(), q.getLat(), q.getLon());
node.setF(g + h); // save estimation of a path to a goal node
其中dist() - 是附近节点之间的实际距离(在您的情况下为1)
请参阅正确的代码here。
也很少有建议:
使用openList的优先级队列而不是通常的列表
使用哈希映射存储访问过的笔记(实施中的closeList)