グラフ理論の基礎(最短経路)
点と線のネットワークから「最も安く」目的地へ到達する経路を見つける
- 1
- グラフとは「頂点(ノード)」と、それらを結ぶ「辺(エッジ)」の集合で、辺には移動コストを表す「重み」を持たせることができる
- 2
- ダイクストラ法は、始点から各頂点までの最短距離を「確定済みの中で最も近い頂点」から順に確定させていく貪欲アルゴリズムで、負の重みがなければ最短経路を必ず正しく求められる
- 3
- カーナビの経路案内、Webサイトのリンク解析、通信ネットワークのルーティングなど、現実世界の「最短で行きたい」問題の多くはグラフの最短経路問題に帰着する
なぜこれを学ぶのか? — 現実社会とテクノロジーでの価値
なぜ生まれたのか?
グラフとは「頂点(ノード)」と、それらを結ぶ「辺(エッジ)」の集合で、辺には移動コストを表す「重み」を持たせることができる
身につく武器・思考力
ダイクストラ法は、始点から各頂点までの最短距離を「確定済みの中で最も近い頂点」から順に確定させていく貪欲アルゴリズムで、負の重みがなければ最短経路を必ず正しく求められる
実社会・ITでの活躍現場
- •カーナビ・ネットワークルーティングにおけるダイクストラ法
- •ITシステム・アルゴリズム実装における論理設計
- •データ分析やシミュレーションにおける数理モデリング
Layer 1 — 直感・シミュレーター
重み付きの小さなネットワーク図から、始点となるノードをクリックし、次に終点となるノードをクリックしてみよう。ダイクストラ法が実行され、最短経路が太い線でハイライトされるとともに、合計コスト(距離)が表示される。別の始点・終点の組み合わせを試して、経路がどう変わるか確認してみよう。
ダイクストラ法で最短経路を求める際、「未確定の頂点の中から選ぶべき次の頂点」はどのような頂点か?
Layer 2 — 定義・受験・証明
定義
グラフ とは、頂点の集合 と、頂点同士を結ぶ辺の集合 の組である。各辺 に非負の重み を割り当てたものを「重み付きグラフ」と呼ぶ。始点 から頂点 までの「最短距離」 とは、 から に至るすべての経路の中で、通過する辺の重みの総和が最小となる値である。
公式・数理モデル
証明・導出
ダイクストラ法の正当性(貪欲選択の妥当性): 確定済み頂点集合を 、各頂点の暫定距離を とし、初期状態は 、、他は とする。 アルゴリズムは、 の中で が最小の頂点 を選び に追加、 に隣接する頂点 について と更新(緩和)することを繰り返す。 数学的帰納法でこの手続きの正しさを示す: のときは自明に正しい。 まで正しいと仮定し、次に選ばれる頂点を とする。 すべての辺の重みが非負であるため、 から へ向かう「 の外を経由する」経路のコストは、途中で を出た時点で既に 以上である(非負性より経路長は単調非減少)。 したがって の外を経由しても より短くはならず、 が選ばれた時点の は真の最短距離と一致する。この論法を繰り返し適用すれば、すべての頂点で正しい最短距離が確定することが示される(負の重みが存在すると、この単調性が崩れ証明は成立しない)。
押さえておきたいポイント
- ダイクストラ法は「負の重みの辺が存在しない」という条件下でのみ正しく動作する貪欲アルゴリズムである
- 優先度付きキュー(二分ヒープ)を使うと、頂点数 、辺数 に対し計算量 で解ける
- 負の重みを許容する場合はベルマン・フォード法、全点対間の最短距離を求めたい場合はワーシャル・フロイド法を用いる
- グラフの探索順序を工夫すること(幅優先探索・深さ優先探索)は最短経路以外にも連結成分の判定やサイクル検出など多くの応用を持つ
本トピックの内容・数理モデルは、文部科学省学習指導要領(算数・数学・情報)および国際標準カリキュラムに準拠し、エンジニアリング現場の実装事例と照らし合わせてMath World Lab編集部により検証・作成されています。
Layer 3 — 工学応用・現場実装
カーナビ・ネットワークルーティングにおけるダイクストラ法
道路網を「交差点=頂点」「道路区間=重み付き辺(距離や所要時間)」としてモデル化すると、カーナビの経路探索は最短経路問題そのものになる。同じアルゴリズムはインターネットのパケットルーティング(OSPFなどのルーティングプロトコル)にも使われている。
1type Graph = Map<string, Map<string, number>>; // 頂点 -> (隣接頂点 -> 重み)23// ダイクストラ法による単一始点最短経路4function dijkstra(graph: Graph, start: string): Map<string, number> {5 const dist = new Map<string, number>();6 const visited = new Set<string>();78 for (const node of graph.keys()) dist.set(node, Infinity);9 dist.set(start, 0);1011 while (visited.size < graph.size) {12 // 未確定の中で距離最小の頂点を選ぶ(貪欲選択)13 let current: string | null = null;14 let minDist = Infinity;15 for (const [node, d] of dist) {16 if (!visited.has(node) && d < minDist) {17 minDist = d;18 current = node;19 }20 }21 if (current === null) break; // 到達不能な頂点のみ残っている22 visited.add(current);2324 // 隣接頂点の距離を緩和(更新)25 const neighbors = graph.get(current) ?? new Map();26 for (const [next, weight] of neighbors) {27 const candidate = dist.get(current)! + weight;28 if (candidate < (dist.get(next) ?? Infinity)) {29 dist.set(next, candidate);30 }31 }32 }33 return dist;34}3536// 例: 4つの交差点からなる簡単な道路網37const roadNetwork: Graph = new Map([38 ["A", new Map([["B", 4], ["C", 1]])],39 ["B", new Map([["D", 1]])],40 ["C", new Map([["B", 2], ["D", 5]])],41 ["D", new Map()],42]);4344console.log(dijkstra(roadNetwork, "A"));45// A->C->B->D という経路で D への最短距離は 4 になる
次に学ぶならコレ!おすすめトピック
この単元と深い繋がりを持つ、あわせて学ぶと理解が深まるおすすめ単元