Java Priority Queue reordering when editing elements

后端 未结 6 1129
陌清茗
陌清茗 2020-11-29 06:23

I\'m trying to implement Dijkstra\'s algorithm for finding shortest paths using a priority queue. In each step of the algorithm, I remove the vertex with the shortest distan

6条回答
  •  醉话见心
    2020-11-29 06:56

    You can avoid updating items in the queue just marking each node as visited=false by default, and adding new items to the queue as you go.

    Then pop a node from the queue and process it only if it was not visited before.

    Dijkstra's algorithm guarantees that each node is visited only once, so even if you may have stale nodes down the queue you never really process them.

    Also it's probably easier if you separate the algorithm internals from the graph data structure.

    public void dijkstra(Node source) throws Exception{
        PriorityQueue q = new PriorityQueue();
        source.work.distance = 0;
        q.add(new DijkstraHeapItem(source));
    
        while(!q.isEmpty()){
            Node n = ((DijkstraHeapItem)q.remove()).node;
            Work w = n.work;
    
            if(!w.visited){
                w.visited = true;
    
                Iterator adiacents = n.getEdgesIterator();
                while(adiacents.hasNext()){
                    Edge e = adiacents.next();
                    if(e.weight<0) throw new Exception("Negative weight!!");
                    Integer relaxed = e.weight + w.distance;
    
                    Node t = e.to;
                    if (t.work.previous == null || t.work.distance > relaxed){
                        t.work.distance = relaxed;
                        t.work.previous = n;
                        q.add(new DijkstraHeapItem(t));
                    }
                }
            }
        }
    }
    

提交回复
热议问题