首先,这是HW,所以尽量不要立即给我答案,但我在编写Dijstra算法时遇到了麻烦。实验室让我们构建一个优先级队列,我已经制作并传递给定的JUnit测试,所以我认为它是正确的。实验的第二部分让我们在dijstra算法的实现中使用队列。这是Dijkstra的代码
/**
* Compute shortest paths in a graph.
*
* Your constructor should compute the actual shortest paths and
* maintain all the information needed to reconstruct them. The
* returnPath() function should use this information to return the
* appropriate path of edge ID's from the start to the given end.
*
* Note that the start and end ID's should be mapped to vertices using
* the graph's get() function.
*/
class ShortestPaths {
Multigraph graph;
final int INF = Integer.MAX_VALUE;
PriorityQueue<Integer> Q;
int n;
int dist[];
Handle handles[];
Edge edge[];
/**
* Constructor
*/
public ShortestPaths(Multigraph G, int startId) {
Q = new PriorityQueue<Integer>();
graph = G;
n = graph.nVertices();
dist = new int [n];
edge = new Edge [n];
handles = new Handle[n];
for (int i = 0; i<n; i++){
dist[i] = INF;
}
dist[startId] = 0;
Handle h = Q.insert(startId, dist[startId]);
handles[startId] = h;
Q = new PriorityQueue<Integer>();
while (!Q.isEmpty()){
Vertex v = graph.get(Q.min());
Q.extractMin();
while (v.adj().hasNext()){
relax(v.adj().next());
}
}
}
private void relax(Edge e) {
Handle h;
int v = e.from().id();
int w = e.to().id();
if (dist[w] > dist[v] + e.weight()) {
dist[w] = dist[v] + e.weight();
edge[w] = e;
if (handles[w].getIndex() != -1){
Q.decreaseKey(handles[w], dist[w]);
}
else{
h = Q.insert(w, dist[w]);
handles[w] = h;
}
}
}
/**
* Calculates the list of edge ID's forming a shortest path from the start
* vertex to the specified end vertex.
*
* @return the array
*/
public int[] returnPath(int endId) {
int c = 0;
int[] path = new int[edge.length];
for (Edge e = edge[endId]; e != null; e = edge[e.from().id()]) {
path[c] = e.id();
c++;
}
return path;
}
}
您知道,句柄只是一个存储相关键值对索引的对象,我们可以在以后找到它。句柄自动更新,您可以在我的优先级队列中的交换过程中看到这一点。无论如何,问题是我的edge []数组由于某种原因填充了null,所以我无法返回任何路径。如何修复算法以正确更新edge []?任何帮助,将不胜感激。如果您想了解更多信息,请告诉我。此外,我将发布Vertex和Edge类,以防你想要查看它们。
答案 0 :(得分:2)
我注意到一个错误:
Q = new PriorityQueue<Integer>();
while (!Q.isEmpty()){ // <-- Q is always empty beсause of previous line