[英]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算法實現,
這是根據實現情況更新的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.