Dijkstra 演算法是圖論中使用的經典尋路演算法,用於尋找圖中從來源節點到所有其他節點的最短路徑。在本文中,我們將探索該演算法、其正確性證明,並提供 JavaScript 中的實作。
Dijkstra 演算法是一種貪婪演算法,旨在找到具有非負邊權重的加權圖中從單一來源節點開始的最短路徑。它由 Edsger W. Dijkstra 於 1956 年提出,至今仍然是電腦科學中使用最廣泛的演算法之一。
使用優先權佇列根據距離儲存節點。
重複提取距離最小的節點並鬆弛其鄰居。
s(s)( s ) (v)( v )
(v) 代表任何其他節點。為什麼有效:鬆弛確保我們始終能夠在找到更短路徑時透過逐步更新距離來找到到節點的最短路徑。
隊列操作:
正確性證明
我們用強歸納法證明了Dijkstra演算法的正確性。強歸納法是數學歸納法的變體,用來證明一個命題 ( P(n) ) (P(n))( P(1), P(2), 點, P (k) ) (P(1),P(2),…,P(k)) kk)( P(k 1) ) (>(>k)( P(k) )
證明
(kk1))( P(k 1) )
歸納假設:
假設到目前為止處理的所有節點都有正確的最短路徑距離。
歸納步驟:
下一個節點
(u)
從優先權佇列中出列。自從
u)距離(u))u)u
距離
(u)
// Simplified Queue using Sorting // Use Binary Heap (good) // or Binomial Heap (better) or Pairing Heap (best) class PriorityQueue { constructor() { this.queue = []; } enqueue(node, priority) { this.queue.push({ node, priority }); this.queue.sort((a, b) => a.priority - b.priority); } dequeue() { return this.queue.shift(); } isEmpty() { return this.queue.length === 0; } }
也是正確的。
function dijkstra(graph, start) { const distances = {}; // hold the shortest distance from the start node to all other nodes const previous = {}; // Stores the previous node for each node in the shortest path (used to reconstruct the path later). const pq = new PriorityQueue(); // Used to efficiently retrieve the node with the smallest tentative distance. // Initialize distances and previous for (let node in graph) { distances[node] = Infinity; // Start with infinite distances previous[node] = null; // No previous nodes at the start } distances[start] = 0; // Distance to the start node is 0 pq.enqueue(start, 0); while (!pq.isEmpty()) { const { node } = pq.dequeue(); // Get the node with the smallest tentative distance for (let neighbor in graph[node]) { const distance = graph[node][neighbor]; // The edge weight const newDist = distances[node] + distance; // Relaxation Step if (newDist < distances[neighbor]) { distances[neighbor] = newDist; // Update the shortest distance to the neighbor previous[neighbor] = node; // Update the previous node pq.enqueue(neighbor, newDist); // Enqueue the neighbor with the updated distance } } } return { distances, previous }; } // Example usage const graph = { A: { B: 1, C: 4 }, B: { A: 1, C: 2, D: 5 }, C: { A: 4, B: 2, D: 1 }, D: { B: 5, C: 1 } }; const result = dijkstra(graph, 'A'); // start node 'A' console.log(result);
// Simplified Queue using Sorting // Use Binary Heap (good) // or Binomial Heap (better) or Pairing Heap (best) class PriorityQueue { constructor() { this.queue = []; } enqueue(node, priority) { this.queue.push({ node, priority }); this.queue.sort((a, b) => a.priority - b.priority); } dequeue() { return this.queue.shift(); } isEmpty() { return this.queue.length === 0; } }
D=
流程A:
>4
過程D:
Priority Queue Type | Insert (M) | Extract Min | Decrease Key | Overall Time Complexity |
---|---|---|---|---|
Simple Array | O(1) | O(V) | O(V) | O(V^2) |
Binary Heap | O(log V) | O(log V) | O(log V) | O((V E) log V) |
Binomial Heap | O(log V) | O(log V) | O(log V) | O((V E) log V) |
Fibonacci Heap | O(1) | O(log V) | O(1) | O(V log V E) |
Pairing Heap | O(1) | O(log V) | O(log V) | O(V log V E) (practical) |
Dijkstra 演算法是一種強大而有效的方法,用於在具有非負權重的圖中找到最短路徑。雖然它有限制(例如,無法處理負邊權重),但它廣泛用於網路、路由和其他應用程式。
這裡有一些詳細的資源,您可以在其中探索 Dijkstra 演算法以及嚴格的證明和範例:
此外,維基百科提供了該主題的精彩概述。
引用:
[1] https://www.fuhuthu.com/CPSC420F2019/dijkstra.pdf
歡迎在評論中分享您的想法或改進!
以上是理解 Dijkstra 演算法:從理論到實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!