簡體   English   中英

將現有的Fibonacci堆Java實現與Dijkstra的最短路徑Java實現一起使用

[英]Using Existing Fibonacci Heap Java Implementation with Dijkstra's Shortest Path Java Implementation

我正在嘗試使用Java編程語言以正的邊成本在圖上實現最有效的最短路徑算法。 據我所知,那是Dijkstra的算法,以Fibonacci堆作為優先級隊列。 如鏈接中所述,我借用了Keith Schwarz的以下斐波那契堆實現。 http://keithschwarz.com/interesting/code/?dir=fibonacci-heap

在我的代碼中,我還修改了此問題中介紹的dijkstra算法實現,

Java:使用斐波那契堆實現Dijkstra的算法

這是根據實現情況更新的dijkstra,

public static void SPFibonacciHeap() {
    {

        FibonacciHeap<Node> myHeap = new FibonacciHeap<Node>();

        //adding all nodes to the PQ (heap)
        for(int i=0; i<nodeList.size(); i++)
                    myHeap.enqueue(nodeList.get(i), nodeList.get(i).d);

        while (!myHeap.isEmpty()) {

            //deque the minimum (first iteration will be the source)
            Entry<Node> u = myHeap.dequeueMin();


            // Visit each edge connected from u
            for (AdjacentNode a : u.getValue().adjacents) {

                //getting the adjacent node
                Node v = a.node;
                Entry<Node> vEntry = new Entry<Node>(v,v.d);//WRONG

                //getting the edge weight
                double weight = a.cost;

                double distanceThroughU = u.getValue().d + weight;
                if (distanceThroughU < v.d) {
                    v.d = distanceThroughU;
                    myHeap.decreaseKey(vEntry, v.d); //SHOWS ERROR
                    v.parent = u.getValue();
                }
            }
        }
    }
}

這是我的Node和AdjacentNode類,

class Node{

    Double [] label;
    double d; //node cost
    ArrayList<AdjacentNode> adjacents;
    Node parent;

    public Node(Double[] label, double d,ArrayList<AdjacentNode> adjacents)
    {
        this.label= label;
        this.d=d;
        this.adjacents=adjacents;
        parent=null;

    }




}


class AdjacentNode
{
    Node node;
    double cost;

    public AdjacentNode(Node node, double cost)
    {
        this.node= node;
        this.cost=cost;
    }
}

一切都進行得很好,直到我想減少下一行的鍵,

myHeap.decreaseKey(vEntry, v.d); 

我面臨的問題是vEntry應該是堆中已經存在的節點。 但是,我無法從堆中檢索此節點,因為我想檢索鄰近節點v的唯一方法是使用節點u的neighbors列表。 但是隨后,我在下一行中將其錯誤地表示為新的Entry Node,

Entry<Node> vEntry = new Entry<Node>(v,v.d);

但是,這將創建一個新的條目,該條目保存我要查找的節點,而不是包含我要查找的節點的堆中存在的條目。 這將導致Null指針異常。

我無法解決該問題的解決方案。 對於此堆實現,是否不可能獲得與給定節點條目相鄰的節點條目? 有人可以幫忙嗎? 謝謝。

所以...那是我的代碼。 :-)我想我可以在這里幫忙。

如果您會注意到, enqueue方法將返回Entry<T>該入口表示在Fibonacci堆中與剛剛排隊的對象相對應的內部條目。 目的是,當您將某些東西放入Fibonacci堆中時,您將保存Entry<T>並返回某處,以便以后可以使用它。 實際上,我的網站上實際上也有Dijkstra算法的實現 我完成這項工作的方法是將第二個Map從節點存儲到Entry對象,以便當我需要調用decreaseKey ,可以查找與給定節點相對應的Entry ,然后將其傳遞給decreaseKey

值得一提的是,雖然Dijkstra的Fibonacci堆算法在理論上比使用普通二進制堆快,但實際上,它的速度往往要慢得多,因為Fibonacci堆上的常數要高得多。 這是由於許多因素(大量的指針雜耍,位置不佳的許多鏈接結構等)導致的,因此,如果您的目標是獲得盡可能最快的掛鍾速度,則可能只想使用老式的二進制堆。 即使您確實想使用Fibonacci堆,也可能要嘗試優化我發布的實現-我寫它的目的是正確性和清晰度,而不是原始效率。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM