dijkstra演算法用於構建單源點的最短路徑樹(mst)——即樹中某個點到任何其他點的距離都是最短的。例如,構建地圖應用時查詢自己的座標離某個地標的最短距離。可以用於有向圖,但是不能存在負權值(bellman-ford可以處理負權值)。
dijkstra()
//選初始點r,q是無向圖g中所有點v的權值優先佇列,key可看作源點到u的距離
r.key = 0
q = g,v
while(q != ∅) {
//取出q中權值最小值的點u
u = extractmin(q)
//取點u連線的所有節點(即無向圖g的鄰接表中的第u個鍊錶)
foreach v ∈ g.adj[u] }}
}
prim演算法用於構建最小生成樹——即樹中所有邊的權值之和最小。例如,構建電路板,使所有邊的和花費最少。只能用於無向圖。
//無向圖g, 權值w, 起始點r
mst(g, w, r)
//選初始點r,q是無向圖g中所有點v的權值優先佇列,key可看作u到下乙個節點v的距離
r.key = 0
q = g,v
while(q != ∅) {
//取出q中權值最小值的點u
u = extractmin(q)
//取點u連線的所有節點(即無向圖g的鄰接表中的第u個鍊錶)
for each v ∈ g.adj[u] }}
}
mst中任意ab兩點之間的距離,並不比原始圖中ab的距離短,即原始圖中可能存在邊e(a,b)**小於**mst中的e(a,b)。
注意上述兩個偽演算法的差別只在於最後迴圈體內的鬆弛操作。
簡單總結就是,dijkstra的鬆弛操作加上了到起點的距離,而prim只有相鄰節點的權值。
思想都是使用貪婪和線性規劃,每一步都是選擇權值/花費最小的邊。
貪婪:乙個區域性最有解也是全域性最優解;
線性規劃:主問題包含n個子問題,而且其中有重疊的子問題。
dijkstra演算法通過線性規劃快取了最優子路徑的解,每一步也通過貪婪演算法來選擇最小的邊。
prim演算法通過貪婪來選擇最小的邊,而prim的每個子樹都是最小生成樹說明滿足線性規劃的兩個條件。
時間複雜度
time = θ( v * t1 + e * t2)
其中t1為取出鍵值最小點的時間,t2為降低鍵值的時間,取決於資料結構。
對於稀疏圖來說,e遠小於v*v,所以二叉堆比較好;
而對於密集圖來說,e=v*v,所以陣列比較好;
斐波那契堆是最好的情況。
dijkstra特例
當邊的權值都為1的時候,可以用dfs(廣度優先搜尋)優化時間複雜度。
if d[v] = +∞
優化了取出鍵值最小點的時間t1 = o(1)
總的時間複雜度
time = v + e
Prim演算法 與 dijkstra演算法
有時總將兩者搞混,兩者都是基於貪心策略,且都是將圖中頂點劃分為兩部分,每次取最小值。在這裡對兩者的演算法做乙個區分。prim演算法是解決圖的 最小生成樹 問題,在每次迴圈中,選取乙個點在s中,另乙個點在v s中,且兩點權值最小,直到v s為空。dijkstra演算法是解決圖的 最短路徑 問題,即從某...
prim 與 dijkstra 的比較
他們的不同之處是 兩個集合u,v u是構成最小生成樹的集合,v原圖的集合 prim 每次都是從u的每個點出發,尋找u集合與v集合最近的距離的點,再將v中的該點加入u中 dijksra從原點出發在v找離該點最近的點 p1,將該距離加入到 dis i 接著以p1為原點開始找 舉個例子就知道他們不能亂來了...
Prim演算法和Dijkstra演算法的異同
之前一直覺得prim和dijkstra很相似,但是沒有仔細對比 今天看了下,主要有以下幾點 1 prim是計算最小生成樹的演算法,比如為n個村莊修路,怎麼修花銷最少。dijkstra是計算最短路徑的演算法,比如從a村莊走到其他任意村莊的距離。2 prim演算法中有乙個統計總len的變數,每次都要把到...