Joh*_*erg 8 java algorithm path a-star shortest
我的A*算法实现需要一些帮助.当我运行算法时,它确实找到了目标,但路径肯定不是最短的:-P
这是我的代码,请帮我发现错误!我认为可能是重建路径是我的问题,但我不确定.
public class Pathfinder {
public List<Node> aStar(Node start, Node goal, WeightedGraph graph) {
    Node x, y;
    int tentative_g_score;
    boolean tentative_is_better;
    FScoreComparator comparator = new FScoreComparator();
    List<Node> closedset = new ArrayList<Node>();
    Queue<Node> openset = new PriorityQueue<Node>(10, comparator);
    openset.add(start);
    start.g_score = 0;
    start.h_score = heuristic_cost_estimate(start, goal);
    start.f_score = start.h_score;
    while (!openset.isEmpty()) {
        x = openset.peek();
        if (x == goal) {
            return reconstruct_path(goal);
        }
        x = openset.remove();
        closedset.add(x);
        for (Edge e : graph.adj(x)) {
            if (e.v == x) {
                y = e.w;
            } else {
                y = e.v;
            }
            if (closedset.contains(y) || y.illegal) {
                continue;
            }
            tentative_g_score = x.g_score + e.weight;
            if (!openset.contains(y)) {
                openset.add(y);
                tentative_is_better = true;
            } else if (tentative_g_score < y.g_score) {
                tentative_is_better = true;
            } else {
                tentative_is_better = false;
            }
            if (tentative_is_better) {
                y.g_score = tentative_g_score;
                y.h_score = heuristic_cost_estimate(y, goal);
                y.f_score = y.g_score + y.h_score;
                y.parent = x;
            }
        }
    }
    return null;
}
private int heuristic_cost_estimate(Node start, Node goal) {
    return Math.abs(start.x - goal.x) + Math.abs(start.y - goal.y);
}
private List<Node> reconstruct_path(Node current_node) {
    List<Node> result = new ArrayList<Node>();
    while (current_node != null) {
        result.add(current_node);
        current_node = current_node.parent;
    }
    return result;
}
private class FScoreComparator implements Comparator<Node> {
    public int compare(Node n1, Node n2) {
        if (n1.f_score < n2.f_score) {
            return 1;
        } else if (n1.f_score > n2.f_score) {
            return -1;
        } else {
            return 0;
        }
    }
}
}
感谢所有人的所有好答案!我的A*算法现在非常适合你们!:-)
这是我的第一篇文章,这个论坛真是太棒了!
您正在更改PriorityQueue插入后的元素的优先级.这不受支持,因为优先级队列不知道对象已更改.您可以做的是删除并重新添加对象.
优先级在行中更改:y.f_score = y.g_score + y.h_score;.添加y到优先级队列后会发生此行.请注意,openset.add(y);在计算成本后简单地移动线是不够的,因为y可能已在前一次迭代中添加.
从您的代码中还不清楚您使用的启发式是否可以接受.如果不是,它也会导致您获得次优路径.
最后,一个性能说明:该contains方法开启ArrayList并PriorityQueue运行线性时间,这将使您的实施的运行时间不是最佳的.您可以通过向节点添加布尔属性来指示它们是在闭合/打开集中,还是通过使用集合数据结构来改进这一点.