Java 在给定的dijkstra代码中,从优先级队列中添加和删除元素有什么意义?

Java 在给定的dijkstra代码中,从优先级队列中添加和删除元素有什么意义?,java,dijkstra,Java,Dijkstra,我正在研究Dijkstra算法代码,在这个链接中-> 有人能解释代码的以下两部分吗 1) 当计算距离较小时,为什么要从优先级队列中添加和删除元素 if( newDistance < v.getDistance() ) { priorityQueue.remove(v); v.setDistance(newDistance); v.setPredecessor(actualVertex); priorityQueue.add(v); } 1) Priorit

我正在研究Dijkstra算法代码,在这个链接中->

有人能解释代码的以下两部分吗

1) 当计算距离较小时,为什么要从优先级队列中添加和删除元素

if( newDistance < v.getDistance() ) {
    priorityQueue.remove(v);
    v.setDistance(newDistance);
    v.setPredecessor(actualVertex);
    priorityQueue.add(v);
}
1) PriorityQueue仅在插入条目时计算优先级。仅更改
v
上的优先级不会导致此评估,因此不会产生任何影响


2)
compareTo
的基本约定是,如果两个实例都存在或被认为相等,则返回0。1如果这被认为是“较大的”-1如果这被认为是“较小的”
Double.compare(…)
Double
值创建此语义。

首先,此代码不好,因为
priorityQueue.remove(v)
需要O(n)个时间,这违背了使用
priorityQueue
的全部目的:

。。。移除(对象)的线性时间

2) Dijkstra算法的一个短语是:选择一个距离最小的未访问顶点。要提取距离最小的顶点,您需要维护一个优先级队列,在该队列中按距离比较顶点(这是您的
compareTo
所做的)。因此,提取的顶点将是距离最小的顶点


1) 数据结构有一些假设。如果违反这些假设,数据结构可能无法正常工作。在
PriorityQueue
的情况下,假设“对于队列中的任何元素,比较结果都不会改变”。而且,由于使用距离进行比较,如果更改距离,则比较结果也可能会更改,从而使您的优先级队列处于潜在无效状态。因此,首先删除元素,然后再更改距离。

您可能需要查看第一部分。与此类似。备注:不必移除带有“旧”的物体与优先级队列的距离。这将破坏性能。由于队列已排序,因此可以确保首先访问距离较短的新对象。因此,当访问旧对象时,您将在访问列表中找到它。测试对象是否在列表、集合、映射或设置了标志,或者您如何实现访问将是f比从队列中间删除对象更有效。@ChristianH.Kuhn,是的。但它需要更多内存,所以我更喜欢另一种选择:使用基于BST的优先级队列(即
TreeSet
,其中min是
first()
)。
TreeSet
不允许不同的顶点具有相同的距离。必须修改
compareTo())
如果距离相等,则基于次要属性返回+ve/-ve值。
@Override
public int compareTo(Vertex otherVertex) {
    return Double.compare(this.distance, otherVertex.getDistance());
}