7.1 KiB
ダイクストラ法 (Dijkstra's Algorithm)
他の言語で読む: English, 한국어, 日本語, 简体中文, 繁體中文, Українська, Español, Français, Deutsch, עברית
ダイクストラ法は、グラフ内のノード間の最短経路を見つけるためのアルゴリズムです。 例えば道路網などを表すことができます。
このアルゴリズムにはいくつかのバリエーションがあります。 ダイクストラの元々の手法は、2つのノード間の最短経路を求めるものでしたが、 より一般的なバージョンでは、1つのノードを「始点(ソース)」として固定し、 その始点から他のすべてのノードまでの最短経路を求め、最短経路木(shortest-path tree)を生成します。
a から b への最短経路を見つけるダイクストラ法。
訪問していないノードの中で最も距離の短いノードを選び、
そのノードを経由して未訪問の隣接ノードへの距離を計算し、
もし短ければその距離を更新します。
すべての隣接ノードを処理したら、そのノードを訪問済み(赤色)としてマークします。
ダイクストラ法の実用例
- GPS / ナビゲーションシステム
- 公共交通機関や航空路線の最適化
- インターネットルーティング(OSPF、IS-IS プロトコル)
- ネットワークトラフィックとレイテンシーの最適化
- ゲームにおける経路探索(マップ上の最短経路)
- 物流および配送ルートの最適化
- サプライチェーンや交通ネットワーク設計
ダイクストラ法のステップごとの例
重み付きグラフがあり、各辺にはノード間の距離が設定されています。
たとえば、ノード A とノード B の距離が 7m であるとします。
このアルゴリズムは、優先度付きキューを使用し、 常に始点から最も近い未訪問ノードを取り出します。
始点ノードは自分自身からの距離が 0m なので、
最初にキューに入っているのはこのノードだけです。
他のノードは、グラフ探索中(隣接ノードを訪問する際)に後でキューに追加されます。
キューから取り出したノードの各隣接ノードについて、始点からの距離を計算します。
たとえば、A から B までの距離は 0m + 7m = 7m です。
初めて訪れる隣接ノードは、始点からの距離を優先度としてキューに追加されます。
ノード B は、後で探索するために最小優先度キューに追加されます。
次に、ノード A のもう一つの隣接ノード C を訪問します。
始点 A から C までの距離は 0m + 9m = 9m です。
ノード C も最小優先度キューに追加されます。
同様に、ノード F の場合、始点 A からの距離は 0m + 14m = 14m です。
ノード F も後で探索するためにキューに追加します。
現在のノードのすべての隣接ノードを確認した後、
そのノードを visited セットに追加します。
このノードは今後再訪しません。
次に、始点から最も近いノードをキューから取り出し、 その隣接ノードを訪問します。
訪問中のノード(この場合は C)がすでにキューに存在する場合、
それは別の経路(A → C)からすでに距離を計算したことを意味します。
もし今回の経路(A → B → C)を通る距離が短ければ更新し、
長ければそのままにします。
たとえば、B 経由で C に行くと (A → B → C)、距離は 7m + 10m = 17m です。
これは既に記録されている距離 9m より長いので、更新しません。
次に、B のもう一つの隣接ノード D を訪問します。
距離は 7m + 15m = 22m です。
D はまだ訪問されておらず、キューにもないため、
距離 22m の優先度でキューに追加します。
この時点で B のすべての隣接ノードを訪問したので、B を visited に追加します。
次に、始点に最も近いノードをキューから取り出します。
ノード C の未訪問の隣接ノードを探索します。
経路 A → C → F を通る F までの距離は 9m + 2m = 11m です。
これは以前の A → F の距離 14m より短いので、
F の距離を 11m に更新し、キューの優先度を変更します。
これでより短い経路が見つかりました。
D についても同様です。
経路 A → C → D は A → B → D より短いため、
距離を 22m から 20m に更新します。
C のすべての隣接ノードを訪問したので、C を visited に追加し、
次に最も近いノード F をキューから取り出します。
E への距離を 11m + 9m = 20m として記録します。
F を visited に追加し、次に最も近い D を取り出します。
D 経由で E に行く距離は 20m + 6m = 26m です。
これはすでに F 経由の距離 20m より長いため、無視します。
ノード D が訪問されました。
ノード E も訪問されました。
グラフ探索が完了しました。
これで、始点ノード A から各ノードへの最短距離がわかりました。
実際には、距離計算の際に各ノードの previousVertices(直前のノード)も記録し、
最短経路の正確な経路を再構築できるようにします。
例えば、A から E への最短経路は A → C → F → E です。
















