简体   繁体   English

Dijkstra的算法java实现bug

[英]Dijkstra's algorithm java implementation bug

So first of all this is HW, so try not to just give me the answer right away, but I'm having trouble programming Dijstra's Algorithm. 所以首先这是HW,所以尽量不要马上给我答案,但是我在编写Dijstra算法时遇到了麻烦。 The lab has us build a priority Queue, which I have made and passes the given JUnit tests so I think it's correct. 实验室让我们构建一个优先级队列,我已经制作并传递给定的JUnit测试,所以我认为这是正确的。 The second part of the lab had us use the queue in an implementation of dijstra's algorithm. 实验的第二部分让我们在dijstra算法的实现中使用队列。 Here is my code for Dijkstra's 这是我对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;
    }


}

Just so you know, a handle is simply an object which stores the index of the associated key-value pair, that way we can find it later. 您知道,句柄只是一个存储相关键值对索引的对象,我们可以在以后找到它。 The handles update automatically, you can see this in the swap procedure in my priority queue. 句柄自动更新,您可以在我的优先级队列中的交换过程中看到这一点。 Anyway, The issue is that my edge[] array is populated with null for some reason, so I can't return any paths. 无论如何,问题是我的edge []数组由于某种原因填充了null,所以我不能返回任何路径。 How do I fix my algorithm to update edge[] correctly? 如何修复算法以正确更新edge []? Any help would be appreciated. 任何帮助,将不胜感激。 Just tell me if you would like more information. 如果您想了解更多信息,请告诉我。 Also I will post the Vertex and Edge classes in case you want to look at those. 此外,我将发布Vertex和Edge类,以备您查看。

I noticed one error: 我注意到一个错误:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM