Java 在给定的dijkstra代码中,从优先级队列中添加和删除元素有什么意义?
我正在研究Dijkstra算法代码,在这个链接中-> 有人能解释代码的以下两部分吗 1) 当计算距离较小时,为什么要从优先级队列中添加和删除元素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
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());
}