ダイクストラのアルゴリズムは、グラフ理論でソース ノードからグラフ内の他のすべてのノードへの最短パスを見つけるために使用される古典的な経路探索アルゴリズムです。この記事では、アルゴリズムとその正しさの証明を検討し、JavaScript での実装を提供します。
ダイクストラのアルゴリズムは、非負のエッジ重みを持つ重み付きグラフ内の単一のソース ノードからの最短パスを見つけるように設計された貪欲なアルゴリズムです。これは 1956 年に Edsger W. Dijkstra によって提案され、現在でもコンピューター サイエンスで最も広く使用されているアルゴリズムの 1 つです。
距離の初期化:
優先キューを使用して、距離に基づいてノードを保存します。
距離が最小のノードを繰り返し抽出し、その近傍を緩和します。
どこ (s) はソースノードであり、 (v) 他のノードを表します。
機能する理由: 緩和により、より短いパスが見つかった場合に距離を段階的に更新することで、ノードへの最短パスが常に見つかるようになります。
キュー操作:
強帰納法を使用してダイクストラのアルゴリズムの正しさを証明します。
強い帰納法は数学的帰納法の変形であり、ステートメントを証明するために、 (P(n)) 、私たちは次の真実を仮定します (P(1),P(2),…,P(k)) 証明する ( P(k 1)) 。これは、次のことだけを前提とする通常の誘導とは異なります。 (P(k)) 証明する ( P(k 1)) 。私の他の投稿で詳しく調べてください。
基本ケース:
ソースノード
(s)
で初期化されます
距離(s)=0
正解です。
帰納仮説:
これまでに処理されたすべてのノードには正しい最短パス距離があると仮定します。
帰納的ステップ:
次のノード
(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; } }
これは、優先キューを使用したダイクストラのアルゴリズムの JavaScript 実装です。
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; } }
距離の初期化:
プロセス A:
プロセス B:
プロセス C:
プロセス 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) |
ダイクストラのアルゴリズムは、非負の重みを持つグラフ内の最短経路を見つけるための強力かつ効率的な方法です。制限はありますが (負のエッジの重みを処理できないなど)、ネットワーキング、ルーティング、その他のアプリケーションで広く使用されています。
ここでは、厳密な証明と例とともにダイクストラのアルゴリズムを探索できる詳細なリソースをいくつか紹介します。
さらに、ウィキペディアではこのトピックの優れた概要が提供されています。
引用:
[1] https://www.fuhuthu.com/CPSC420F2019/dijkstra.pdf
ご意見や改善点をコメントでお気軽に共有してください!
以上がダイクストラアルゴリズムを理解する: 理論から実装までの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。