新来的,但作为客人潜伏了很长一段时间:)
好的,所以我一直在尝试使用斐波那契堆(在 Java 中)做 Dijkstra 的最短路径算法。经过一番搜索,我偶然发现了两个代表斐波那契堆的现成实现。第一个实现做得相当漂亮,可以在这里找到。第二个实现,看起来不那么优雅,在这里。
现在,这一切看起来都很好。但是,我想为我的 Dijkstra 算法版本使用其中一种实现,但我还没有运气。Dijkstra在使用中的实现如下:
public void dijkstra(Vertex source) {
{
source.minDistance = 0.;
PriorityQueue<Vertex> vertexQueue = new PriorityQueue<>();
vertexQueue.add(source);
while (!vertexQueue.isEmpty()) {
Vertex u = vertexQueue.poll();
// Visit each edge exiting u
for (Edge e : u.adjacencies) {
Vertex v = e.target;
double weight = e.weight;
double distanceThroughU = u.minDistance + weight;
if (distanceThroughU < v.minDistance) {
vertexQueue.remove(v);
v.minDistance = distanceThroughU;
v.previous = u;
vertexQueue.add(v);
}
}
}
}
}
很明显,此实现使用基于 Java 的 PriorityQueue 类(我相信它基于二进制堆本身)。我希望修改上面的代码,使其使用上述斐波那契堆实现中的任何一个,而不是 Java 的 PriorityQueue。
我已经尝试了很多,但我就是不知道该怎么做,尽管我确信它就像替换几行代码一样简单。
我希望我足够清楚。这实际上是我在这些板上的第一篇文章。
任何帮助将不胜感激。
编辑:为了回应评论,我想我会用我的尝试场景之一来扩展我的帖子。
这是使用前面链接的第二个斐波那契堆实现的上述 Dijkstra 方法的修改版本:
public static void computePathsFibonacciHeap(Node source) {
{
source.minDistance = 0.;
FibonacciHeap myHeap = new FibonacciHeap();
myHeap.insert(source, source.minDistance);
while (!myHeap.isEmpty()) {
Node u = myHeap.min();
// Visit each edge exiting u
for (Edge e : u.adjacencies) {
Node v = e.target;
double weight = e.weight;
double distanceThroughU = u.minDistance + weight;
if (distanceThroughU < v.minDistance) {
v.minDistance = distanceThroughU;
myHeap.decreaseKey(v, v.minDistance);
v.previous = u;
}
}
}
}
}
这几乎是直接从伪代码转换而来的(因此完全有可能我只是没有正确翻译它)。我得到的错误是“decreaseKey() 的值更大”。如果我尝试删除最小值,我会得到 NullPointerException。
我确定我做错了什么,我很想知道它是什么。再次,这是使用第二个 FHeap 实现。我宁愿使用第一个实现来做到这一点(它看起来更彻底/更专业),但不幸的是我不知道如何去做。