溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Dijkstra算法與Prim算法有什么區(qū)別

發(fā)布時間:2021-09-06 13:40:32 來源:億速云 閱讀:111 作者:小新 欄目:開發(fā)技術

這篇文章給大家分享的是有關Dijkstra算法與Prim算法有什么區(qū)別的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

Dijkstra簡述

Dijkstra算法用于構建單源點的最短路徑樹(MST)——即樹中某個點到任何其他點的距離都是最短的。例如,構建地圖應用時查找自己的坐標離某個地標的最短距離??梢杂糜谟邢驁D,但是不能存在負權值(Bellman-Ford可以處理負權值)。

  • 偽代碼

Dijkstra() {
    for each u in G,V {
        //此處做初始化操作,給每個節(jié)點u賦鍵值+∞,設置空為父節(jié)點
        u.key = +∞
        u.parent = NULL
    }
    //選初始點r,Q是無向圖G中所有點V的權值優(yōu)先隊列,key可看作源點到u的距離
    r.key = 0
    Q = G,V
    while(Q != ?) {
          //取出Q中權值最小值的點u
          u = extractMin(Q) 
          //取點u連接的所有節(jié)點(即無向圖G的鄰接表中的第u個鏈表)
          for each v ∈ G.Adj[u] {
              if (v ∈ Q) and (w(u, v) < key) {
                  //若該節(jié)點仍在Q中且權值w(w,v)小于其原始權值,則進行松弛操作!
                  v.parent = u
                  v.key = w(u, v) + u.key
              }
          }
      }
}

Prim簡述

Prim算法用于構建最小生成樹——即樹中所有邊的權值之和最小。例如,構建電路板,使所有邊的和花費最少。只能用于無向圖

  • 偽代碼

//無向圖G, 權值w, 起始點r
MST(G, w, r) {
    for each u in G,V {
        //此處做初始化操作,給每個節(jié)點u賦鍵值+∞,設置空為父節(jié)點
        u.key = +∞
        u.parent = NULL
    }
    //選初始點r,Q是無向圖G中所有點V的權值優(yōu)先隊列,key可看作u到下一個節(jié)點v的距離
    r.key = 0
    Q = G,V
    while(Q != ?) {
          //取出Q中權值最小值的點u
          u = extractMin(Q) 
          //取點u連接的所有節(jié)點(即無向圖G的鄰接表中的第u個鏈表)
          for each v ∈ G.Adj[u] {
              if (v ∈ Q) and (w(u, v) < key) {
                  //若該節(jié)點仍在Q中且權值w(w,v)小于其原始權值,則進行松弛操作!
                  v.parent = u
                  v.key = w(u, v)
              }
          }
      }
}

MST中任意AB兩點之間的距離,并不比原始圖中AB的距離短,即原始圖中可能存在邊E(A,B)**小于**MST中的E(A,B)。

注意上述兩個偽算法的差別只在于最后循環(huán)體內的松弛操作

  • 最小生成樹只關心所有邊的和最小,所以有v.key = w(u, v),即每個點直連其他點的最小值(最多只有兩個節(jié)點之間的權值和)

  • 最短路徑樹只搜索權值最小,所以有v.key = w(u, v) + u.key,即每個點到其他點的最小值(最少是兩個節(jié)之間的權值和)

簡單總結就是,Dijkstra的松弛操作加上了到起點的距離,而Prim只有相鄰節(jié)點的權值。

思想

都是使用貪婪和線性規(guī)劃,每一步都是選擇權值/花費最小的邊。
貪婪:一個局部最有解也是全局最優(yōu)解;
線性規(guī)劃:主問題包含n個子問題,而且其中有重疊的子問題。

Dijkstra算法通過線性規(guī)劃緩存了最優(yōu)子路徑的解,每一步也通過貪婪算法來選擇最小的邊。
Prim算法通過貪婪來選擇最小的邊,而Prim的每個子樹都是最小生成樹說明滿足線性規(guī)劃的兩個條件。

時間復雜度

Time = θ( V * T1 + E * T2)
其中T1為取出鍵值最小點的時間,T2為降低鍵值的時間,取決于數據結構。

  • 數組
    T1= O(V), T2 = O(1), TIME = O(V * V + E) = O(V * V)

  • 二叉堆
    T1 = O(lgV), T2 = O(lgV), TIME = O(V * lgV + E * lgV) 

  • 斐波那契堆
    T1 = O(lgV), T2 = O(1), TIME = O(V * lgV + E) = O(V * lgV)

對于稀疏圖來說,E遠小于V*V,所以二叉堆比較好;
而對于密集圖來說,E=V*V,所以數組比較好;
斐波那契堆是最好的情況。

Dijkstra特例

當邊的權值都為1的時候,可以用DFS(廣度優(yōu)先搜索)優(yōu)化時間復雜度。

  • 使用FIFO(先進先出)隊列代替優(yōu)先隊列,優(yōu)化了降低鍵值T2的操作為O(1)

  • 松弛操作改為

if d[v] = +∞ {
        d[v] = d[u] + 1
        enqueue(Q, v)
    }

優(yōu)化了取出鍵值最小點的時間T1 = O(1)

總的時間復雜度

TIME = V + E

感謝各位的閱讀!關于“Dijkstra算法與Prim算法有什么區(qū)別”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI