【问题标题】:PriorityQueue not working [duplicate]PriorityQueue 不起作用[重复]
【发布时间】:2017-05-04 12:02:19
【问题描述】:

我正在尝试在 java 中自己实现 Dijkstra 算法。我有一个最小优先级队列,它存储按当前最短路径排序的节点。

第一步进展顺利,我将起始节点设置为距离 0,其他设置为 Integer.MAX_VALUE。起始节点已正确轮询。但是,在我删除第一个节点之后,被删除的第二个节点不是距离最小的节点。我不知道为什么。有意见吗?

这是我的代码

public void Dijkstra(Node s){
    initialize(s);
    List<Node> set = new ArrayList<Node>();
    Comparator<Node> c = new CompareNode();
    PriorityQueue<Node> Q = new PriorityQueue<Node>(V,c);
    for (Node q: Nodes){
        Q.add(q);
    }
    while (Q.size()!=0){
        Node u = Q.remove();
        System.out.println();
        System.out.println(u + " is removed with dis " + u.getD());
        set.add(u);
        for (Node w: u.getWeightedAdj().keySet()){
            relax(u,w);
        }
    }
}

public void initialize(Node s){
    for (Node v: Nodes){
        v.setD(Integer.MAX_VALUE);
        v.setPredecessor(null);
    }
    s.setD(0);
}

public void relax(Node u, Node w){
    if (w.getD()>u.getD()+u.getWeightedAdj().get(w)){
        w.setD(u.getD()+u.getWeightedAdj().get(w));
        w.setPredecessor(u);
    }
}

比较器类

import java.util.Comparator;

public class CompareNode implements Comparator<Node> {

@Override
public int compare(Node o1, Node o2) {
    if (o1.getD()>o2.getD())
        return 1;
    if (o1.getD()<o2.getD())
        return -1;
    return 0;
    }
}

当我运行它时,结果是这样的

A is removed with dis 0

E is removed with dis 2147483647

C is removed with dis 2

D is removed with dis -2147483648

B is removed with dis 3

【问题讨论】:

  • 请注意,您的代码缺少更改优先级步骤。在 Java 优先级队列中更改优先级不是自动的。而且它不提供更改优先级方法。有关更多信息,请参阅链接问题

标签: java algorithm dijkstra


【解决方案1】:

问题在于,PriorityQueue 在添加元素时对元素进行排序,并假设顺序不能更改。

在您的示例中,当将节点添加到队列(开始节点除外)时,您的所有距离都是 MaxInt,因此它们以有效的随机顺序放置到队列中。

然后您调整距离,但 PriorityQueue 不知道这些调整,因此继续按原始顺序返回元素。

对此的标准方法是在距离发生变化时在优先级队列中插入元素。 (当一个元素从队列中移除时,你需要测试你是否已经访问过这个元素,因为同一个元素可以在队列中出现多次。)

【讨论】:

  • 谢谢!在我发现优先级没有改变之前,我已经为此工作了几个小时......
【解决方案2】:

当节点被发现时,将它们添加到队列中会更容易。 IE。一开始只添加根节点,然后在每次迭代中添加新发现的尚未处理的节点。在迭代步骤中,您需要检查新节点是否在队列中,如果新距离更短,则可能更新它们。

【讨论】:

    猜你喜欢
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 2013-08-11
    • 2017-07-19
    • 2015-07-04
    相关资源
    最近更新 更多