簡體   English   中英

為什么 Dikstra 算法運行在 O(V + E log V) 而不是 O(V ^ 2)?

[英]Why Does The Dikstra Algorithm Run In O(V + E log V) Instead Of O(V ^ 2)?

其中V是頂點數,E 是邊數,在最壞的情況下,所有節點都是連接的,並且在每個節點上,您會查看所有其他節點。 那不就是O(V ^ 2)嗎? 我查了一下,發現其實是O(V + E log V) ,但是沒有解釋。

不,根據此處,Dijkstra 使用斐波那契堆作為優先級隊列的最佳實現以O(|E|+|V|*log|V|) 請記住,在密集圖中, |E| O(|v|^2)O(|E|+|V|*log|V|)變得等於O(|V|^2) ,這是算法的最壞情況,但在任何情況下這些情況下它在O(|V|+|E|log|V|)

您的分析忽略了優先隊列的成本。 不過,你也不是完全錯了。

它需要 O(|E|) 次減少鍵操作,因為您訪問的幾乎每條邊都可能會這樣做,並且需要 O(|V|) 次刪除最小操作,因為您必須這樣做才能將頂點從隊列中取出。

如果您使用斐波那契堆作為優先隊列,則減少鍵需要恆定時間,但刪除分鍾需要 O(log |V|) 時間,因此您得到 O(|E| + |V| log |V|) . 就 |V| 而言只有,|E| 被替換為 O(|V| 2 ),因為它可能會變得那么高,並且支配着 |V| 日志 |V| 項給出 O(|V| 2 ) 的總復雜度。

所以如果你想給 |V| 一個界限,你是對的僅,但在 |V| 方面給出了一個界限和 |E| 分開是首選,因為它傳達了更多的信息 它告訴您對於稀疏圖,它比 O(|V| 2 ) 快,這可能很重要。

請注意,您查找的 O(V + E log V) 用於使用不同類型的優先級隊列(如二元堆)而不是斐波那契堆的實現。 這在實踐中很常見。

您只考慮全連接圖的情況。 big-O 表示法適用於給定某些輸入參數的最壞情況,並且由於給定的復雜性使用 V 和 E,這意味着全連接圖無關緊要。 對於一般的圖形,Dijkstra 算法將在 O(V+ElogV) 或更快的速度上完成; 對於全連接圖,當 E 大約為 (V^2)/2 時,它將在 O(V^2) 內完成,這確實比 O(V+((V^2)/2)logV) 快。

暫無
暫無

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

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