[英]Complexity of Prims Algorithm using Priority Queue?
我正在使用鄰接矩陣,優先級隊列是數據結構。
根據我的計算,復雜度是V^3 log V
:
V
V
V log v
但是,我到處都讀到復雜度是V^2
請解釋。
如果您使用斐波那契堆,則提取最小值是O(lg V)
攤銷成本,更新其中的條目是O(1)
攤銷成本。
如果我們使用這個偽代碼
while priorityQueue not empty
u = priorityQueue.exractMin()
for each v in u.adjacencies
if priorityQueue.contains(v) and needsWeightReduction(u, v)
priorityQueue.updateKeyWeight(u, v)
假設實現對於priorityQueue.contains(v)
和needsWeightReduction(u, v)
都有固定的時間。
需要注意的是,您可以稍微更緊地檢查鄰接關系。 雖然外部循環運行V
次,並且檢查任何單個節點的鄰接關系是最壞的V
操作,但您可以使用聚合分析來意識到您永遠不會檢查超過E
鄰接關系(因為只有 E 邊緣)。 和E <= V^2
,所以這是一個更好的界限。
所以,你有外循環 V 次,內循環 E 次。 提取最小值運行V
次,更新堆中的條目運行E
次。
V*lgV + E*1
= O(V lgV + E)
同樣,由於E <= V^2
你可以使用這個事實來替代並得到
O(V lgV + V^2)
= O(V^2)
但在考慮稀疏圖時,這是一個更寬松的界限(盡管是正確的)。
使用基於最小堆的優先級隊列,時間復雜度為 O(ElogV)。
正如您所說,外部 while 循環是 O(V),因為它遍歷每個頂點,因為每個頂點都需要添加到 MST 一次。
對於 while 循環中考慮的每個頂點,需要執行以下兩個步驟:
選擇下一條邊添加到 MST。 根據基於最小堆的優先級隊列的屬性,根元素總是最小的元素。 因此,選擇下一個邊,即成本最低的邊,將是對根元素的 O(1) 提取。 提取后剩余的值需要以維持優先級隊列的方式移動。 由於隊列表示平衡二叉樹,因此在最壞的情況下,這種偏移可能會在 O(logV) 內發生。
更新優先級隊列。 與新頂點相關的邊可能需要在隊列中更新它們的成本,因為我們現在將考慮與新添加的頂點及其鄰居之間的邊相關的成本(但是,如果它們通過一條邊與先前添加的頂點相鄰)成本低於新引入的邊緣,成本不會更新,因為我們正在尋找最低成本)。 這也是 O(logV),因為在最壞的情況下,一個頂點需要在代表隊列的平衡二叉樹的整個長度上移動。
步驟 1 發生 V 次,因為它在 while 循環中發生一次,所以總共是 O(VlogV),步驟 2 在最壞的情況下發生 E 次,其中每條邊都連接到當前頂點,因此它們都需要更新,這意味着它是 O(ElogV) 總數。 設置是 O(E),因為它需要將優先級隊列中的每個邊成本初始化為無窮大。
使用基於最小堆的優先級隊列的總時間復雜度 = O(E + VlogV + ElogV) = O(ElogV)
當您閱讀復雜度為 O(V^2) 時,您可能正在查看不使用堆的實現。 在這種情況下,外部 while 循環仍然是 O(V)。 瓶頸在於選擇要添加到 MST 的下一個頂點的步驟,即 O(V),因為您需要檢查與每個相鄰節點相關的成本以找到最低成本,這在最壞的情況下意味着檢查所有其他節點。 因此復雜度為 O(V*V) = O(V^2)。
此外,在非常密集的圖中,O(ElogV) 變為 O(V^2),因為在任何圖中,最多可以有 E = V^2 個總邊。
如果不使用優先級隊列,則使用二叉堆它包括兩個基本步驟: 1.Insertion 使用插入排序算法的插入時間復雜度在最壞情況下為 O(E^2) 2.Deletion 刪除每個出隊需要 O(1) 並且dequeue 相當於頂點數,如果使用映射,否則將幾乎相同所以,這里的總時間復雜度是 O(V+E^2)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.