简体   繁体   English

Dijkstra 算法 - 优先级队列问题

[英]Dijkstra's algorithm - priority queue issue

I have a Graph class with a bunch of nodes, edges, etc. and I'm trying to perform Dijkstra's algorithm.我有一个带有一堆节点、边等的 Graph 类,我正在尝试执行 Dijkstra 算法。 I start off adding all the nodes to a priority queue.我开始将所有节点添加到优先级队列。 Each node has a boolean flag for whether it is already 'known' or not, a reference to the node that comes before it, and an int dist field that stores its length from the source node.每个节点都有一个布尔标志,表示它是否已经“已知”,一个对它之前的节点的引用,以及一个存储其从源节点开始的长度的 int dist 字段。 After adding all the nodes to the PQ and then flagging the source node appropriately, I've noticed that the wrong node is pulled off the PQ first.在将所有节点添加到 PQ 并适当标记源节点后,我注意到错误的节点首先从 PQ 中拉出。 It should be that the node with the smallest dist field comes off first (since they are all initialized to aa very high number except for the source, the first node off the PQ should be the source... except it isn't for some reason).应该是具有最小 dist 字段的节点首先出现(因为除了源之外,它们都被初始化为一个非常高的数字,所以 PQ 中的第一个节点应该是源......除了它不是某些原因)。 Below is my code for the algorithm followed by my compare method within my Node class.下面是我的算法代码,然后是我的 Node 类中的比较方法。

    public void dijkstra() throws IOException {
    buildGraph_u();
    PriorityQueue<Node> pq = new PriorityQueue<>(200, new Node());

    for (int y = 0; y < input.size(); y++) {
        Node v = input.get(array.get(y));
        v.dist = 99999;
        v.known = false;
        v.prnode = null;
        pq.add(v);
    }

    source.dist = 0;
    source.known = true;
    source.prnode = null;
    int c=1;
    while(c != input.size()) {
        Node v = pq.remove();
        //System.out.println(v.name);
                    //^ Prints a node that isn't the source
        v.known = true;
        c++;
        List<Edge> listOfEdges = getAdjacent(v);
        for (int x = 0; x < listOfEdges.size(); x++) {
            Edge edge = listOfEdges.get(x);
            Node w = edge.to;
            if (!w.known) {
                int cvw = edge.weight;
                if (v.dist + cvw < w.dist) {
                    w.dist = v.dist + cvw;
                    w.prnode = v;
                }
            }
        }
    }
}

public int compare (Node d1, Node d2) {
       int dist1 = d1.dist;
       int dist2 = d2.dist;
       if (dist1 > dist2) 
         return 1;
       else if (dist1 < dist2) 
         return -1;
       else 
         return 0;
     }

Can anyone help me find the issue with my PQ?谁能帮我找到 PQ 的问题?

The priority queue uses assumption that order doesn't change after you will insert the element.优先级队列假设插入元素后顺序不会改变。

So instead of inserting all of the elements to priority queue you can:因此,您可以:

  1. Start with just one node.从一个节点开始。

  2. Loop while priority queue is not empty.优先级队列不为空时循环。

  3. Do nothing, if element is "known".如果元素是“已知的”,则什么都不做。

  4. Whenever you find smaller distance add it to priority queue with "right" weight.每当您发现较小的距离时,将其添加到具有“正确”权重的优先级队列中。

  5. So you need to store a sth else in priority queue, a pair: distance at insertion time, node itself.所以你需要在优先级队列中存储一个其他的东西,一对:插入时的距离,节点本身。

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

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