Dijkstra的算法java实现bug

时间:2014-05-06 17:36:07

标签: java algorithm graph priority-queue dijkstra

首先,这是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类,以防你想要查看它们。

1 个答案:

答案 0 :(得分:2)

我注意到一个错误:

Q = new PriorityQueue<Integer>();
while (!Q.isEmpty()){ // <-- Q is always empty beсause of previous line