Java的:用斐波那契堆的实现Dijkstra算法(Java: Using a Fibonacci

2019-07-21 13:05发布

新来的,但都被作为潜伏很长一段时间的客人:)

好了,所以我一直在试图做用斐波那契堆(在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实现。 我宁愿使用第一次执行这样做(它只是看起来很多更彻底/专业),但我很遗憾无法弄清楚如何。

Answer 1:

在JDK不提供斐波那契堆的实现。 你必须创建自己的实现,或者你可以找到一个在这个帖子: 斐波那契堆

所有你必须在事后被取代

PriorityQueue<Vertex> vertexQueue = new PriorityQueue<>();

通过

 FibonacciHeap<Vertex> vertexQueue = new FibonacciHeap<>();

然后,只需切换到来电polladdremove了它们在你提供的实现方法。



Answer 2:

看来你缺少添加的所有节点的堆与Double.POSITIVE_INFINITY(除0.0距离源节点)。 这就是为什么你有NullPointerException异常,他们根本不是在堆中。

我做了几个开源的斐波那契堆实现一些测试。 你可以在这里找到测试本身: 做实验与- dijkstras算法 。 另外这是Dijsktra的算法我的优先级队列版本: PriorityQueueDijkstra.java



Answer 3:

我曾与这个算法我自己。 有上述decreaseKey功能,说明了其行为的注释。

降低指定元素的新的优先重点。 如果新的优先级比老的优先级,这个函数抛出IllegalArgumentException。 新的优先级必须是有限的两倍,所以你可以不设置优先级为NAN或+/-无穷大。 这样做也抛出IllegalArgumentException。 假设该条目在这个堆所属。 出于效率的考虑,这不是在运行时检查。

至于实施,我想你会想用myHeap.dequeueMin()的getValue()而不是myHeap.min()。 所不同的是,dequeueMin()工作方式类似于民意调查(),并发现它后,从堆删除。

而不是myHeap.decreaseKey(V,v.minDistance),只需添加它,就像myHeap.insert(V,v.minDistance)。



文章来源: Java: Using a Fibonacci Heap for Implementing Dijkstra's Algorithm