[英]How to implement Dijkstra's Algorithm to find the shortest path in Java
I am absolutely confused on what to do. 我对做什么绝对感到困惑。 I'm trying to code off of the pseudo code that wikipedia has on Dijkstra's with priority queues, but I'm having a tough time making the adjustments to fit what i need to find.
我正在尝试从Wikipedia在Dijkstra的具有优先级队列的伪代码中编写代码,但是我很难进行调整以适应我需要找到的内容。 This is my (incomplete) code so far, and any help would be very much appreciated.
到目前为止,这是我的代码(不完整),非常感谢您的帮助。
public int doDijkstras (String startVertexName, String endVertexName, ArrayList< String > shortestPath) {
PriorityQueue<QEntry> q = new PriorityQueue<QEntry>();
int cost = 0;
int newCost;
QEntry pred = null;
for (String s : this.getVertices()) {
if (!s.equals(startVertexName)) {
cost = Integer.MAX_VALUE;
pred = null;
}
q.add(new QEntry(s, cost, pred, adjacencyMap.get(s)));
}
while (!q.isEmpty()) {
QEntry curr = getMin(q);
for (String s : curr.adj.keySet()) {
newCost = curr.cost + this.getCost(curr.name, s);
QEntry v = this.getVert(q, s);
if (newCost < v.cost) {
v.cost = newCost;
v.pred = curr;
if (!q.contains(curr)) {
q.add(curr);
}
}
}
}
}
private QEntry getMin(PriorityQueue<QEntry> q) {
QEntry min = q.peek();
for (QEntry temp : q) {
if (min.cost > temp.cost) {
min = temp;
}
}
return min;
}
private QEntry getVert(PriorityQueue<QEntry> q, String s) {
for (QEntry temp : q) {
if (temp.name.equals(s)) {
return temp;
}
}
return null;
}
class QEntry {
String name;
int cost;
QEntry pred;
TreeMap<String, Integer> adj;
public QEntry(String name, int cost, QEntry pred, TreeMap<String, Integer> adj) {
this.name = name;
this.cost = cost;
this.adj = adj;
this.pred = pred;
}
}
You are overlooking an important part of the algorithm: when to stop. 您正在忽略算法的重要部分:何时停止。
The pseudocode on Wikipedia is for the variation on Dijkstra's algorithm that computes the shortest path from the start node to every node connected to it. Wikipedia上的伪代码用于Dijkstra算法的变体,该算法计算从起始节点到与其连接的每个节点的最短路径。 Commentary immediately following the big pseudocode block explains how to modify the algorithm to find only the path to a specific target, and after that is a shorter block explaining how to extract paths.
大伪代码块之后的注释说明了如何修改算法以仅查找到特定目标的路径,然后是较短的块,说明如何提取路径。
In English, though, as you're processing your priority queue, you need to watch for the target element being the one selected. 但是,用英语来说,在处理优先级队列时,需要注意目标元素是否被选中。 When (if ever) it is, you know that no shorter path to it can be discovered than the one having the cost recorded in the target's queue entry, and represented (in reverse order) by that entry and its chain of predecessors.
无论何时(如果有的话),您都知道,找到它的最短路径就是将成本记录在目标队列条目中并由该条目及其前身链(以相反顺序)表示的路径。 You fill the path list by walking the chain of predecessors, and you return the value that was recorded in the target queue entry.
通过遍历前辈链来填充路径列表,然后返回目标队列条目中记录的值。
Note, however, that in your code, in the event that the start and target vertexes are not connected in the graph (including if the target is not in the graph at all), you will eventually drain the queue and fall out the bottom of the while loop without ever reaching the target. 但是请注意,在您的代码中,如果起始顶点和目标顶点未在图中连接(包括目标根本不在图中),最终将耗尽队列并跌出底部。而while循环却从未达到目标。 You have to decide what to do with the path list and what to return in that case.
您必须决定如何处理路径列表以及在这种情况下要返回什么。
Note, too, that your code appears to have several errors, among them: 还要注意,您的代码似乎有几个错误,其中包括:
this.getVertices()
, its queue entry will not be initialized with cost 0, and will not likely be the first element chosen from the queue. this.getVertices()
的迭代顺序中的第一个,则其队列条目将不会使用成本0进行初始化,并且不可能是从队列中选择的第一个元素。 QEntry
) do not have a natural order; QEntry
)没有自然顺序。 to create a PriorityQueue
whose elements have such a type, you must provide a Comparator
that defines their relative priorities. PriorityQueue
,必须提供一个Comparator
来定义其相对优先级。 PriorityQueue
as a priority queue, then you must never modify an enqueued object in a way that could change its order relative to any other enqueued object; PriorityQueue
用作优先级队列,则绝不能以可能改变其相对于任何其他排队对象顺序的方式修改排队对象。 instead, remove it from the queue first, modify it, then enqueue it again.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.