第25章 単一始点最短路 25.0 はじめ 25.1 最短路と緩和法 25.2 ダイクストラのアルゴリズム 25.0 はじめ • 最短路とは – 京都の地図が与えられていて、隣接する各交差点の 距離がマークされていいるとき、「吉田寮」から「京都 大学10号館」までの最短路を求める – Solve:始点から目的地までのすべての経路を列挙し て、各経路の距離を合計して最短路を選択する – 本章ではこのような問題を効率の良く解く方法につい て述べる 「吉田寮」から「京都大学10号館」までの最短路 25.0 はじめ • 最短路とは 辺を実数値の重みに写象する重み関数𝜔:𝐸 → 𝑅 によって重みが付けられた有向グラフG = (𝑉, 𝐸)が 与えられる。経路p =< 𝑣0 , 𝑣1 , … , 𝑣𝑘 >の重みは: 𝑘 𝜔 𝑝 = 𝜔(𝑣𝑖−1 , 𝑣𝑖 ) 𝑖=1 e.g. 𝜔 0 → 3 → 2 = 50 25.0 はじめ 𝜇から𝜐への最短路の重みは: min{ω(p): μ~v}, 経路が存在 𝛿 𝜇, 𝜈 = ∞ , それ以外の時 e.g. 𝛿 0,2 = min 𝜔 0 → 3 → 2 = 50, 𝜔 0 → 1 → 2 = 60 𝛿 0,2 = 0 → 3 → 2 𝛿 2,0 = ∞ 25.0 はじめ • 単一始点最短路 – 与えられた始点から各頂点までの最短路を求める • 単一目的地最短路 – すべての頂点から与えられた目的地までの最短路を 求める • 単一点対最短路 – 2つ頂点間の最短路を求める • 全点対間最短路 – すべての頂点対について、最短路を求める 25.0 はじめ • 負の重みを持つ辺 – 始点sから到達可能な負の重みの閉路があれば、最短路 の重みは明確に定義できない – Dijkstraアルゴリズムは、与えられた辺がすべて非負であ ると仮定する – Bellman-Fordのアルゴリズムはグラフの負の重みでも使 える。負の重みの閉路が存在すれば、検出できる。 5 A 10 B C 5 5 D -20 E 10 25.0 はじめ • 最短路の表現 – 先行点 𝑣の先行点はグラフには𝑣の直前の頂点である。なければ、NILで表 す。𝜋 𝑣 = 𝑣0 or NIL – 先行点部分グラフ 先行点がNILでないGの頂点の集合に始点sを加えたものである。 𝑉𝜋 = 𝑣 ∈ 𝑉: 𝜋 𝑣 ≠ 𝑁𝐼𝐿 ∪ {𝑠} – 最短路木 始点sを根とする、sから各頂点までの最短経路で 構成する木である 25.0 はじめ • 最短路と最短路木が必ずしも一つではない 25.1 最短路と緩和法 • 最短路の部分構造の最適性 補題25.1:最短路の部分経路は最短路である 証明:(背理法) 最短路𝑤 𝑝 = 𝑤 𝑝1𝑖 + 𝑤 𝑝𝑖𝑗 + 𝑤 𝑝𝑗𝑘 ′ ′ ここで𝑤 𝑝𝑖𝑗 < 𝑤 𝑝𝑖𝑗 の経路𝑝𝑖𝑗 が存在すると仮定 ′ すると、その重み𝑤 𝑝1𝑖 + 𝑤 𝑝𝑖𝑗 + 𝑤 𝑝𝑗𝑘 は 𝑤 𝑝 より小さい、これは𝑤 𝑝 が最短路という前提 に矛盾する。 ∎ 25.1 最短路と緩和法 • 系25.2 – 始点sから頂点vへの最短路がある頂点uと経路𝑝′ に対し 𝑝′ てs→u→vに分割できるものと仮定する。このとき、sからv への最短路の重みは𝛿 𝑠, 𝑣 = 𝛿 𝑠, 𝑢 + 𝜔(𝑢, 𝑣) 証明 補題25.1により、部分経路𝑝′ は最短路である。したがって、 𝛿 𝑠, 𝑣 =𝜔 𝑝 = 𝜔 𝑝′ + 𝜔(𝑢, 𝑣) = 𝛿 𝑠, 𝑢 + 𝜔 𝑢, 𝑣 ■ 25.1 最短路と緩和法 • 補題25.3 – 辺(𝑢, 𝑣)に対して𝛿 𝑠, 𝑣 ≤ 𝛿 𝑠, 𝑢 + 𝑤(𝑢, 𝑣)が成 り立つ。 証明 始点sから頂点vまでの最短路はsからvへ他のど の経路よりも大きな重みをもつことはない。特に、 経路pが始点sから頂点uへの最短路をたどり、そ のあと辺(𝑢, 𝑣)を通る特定の経路より大きな重みを 持つことはない。■ 25.1 最短路と緩和法 • 緩和法 – 初期化:sから各頂点まで最短路を初期化する INITIALIZE-SINGLE-SOURCE(G, s) 1 for each vertex v ∈ V[G] 2 do d[v] ← ∞ 3 π[v] ← NIL 4 d[s] ← 0 Gはグラフ sは始点 d[v] は今まで見つけたsからvまでの最短路の重み π[v]はまで見つけた最短路には、vの直前の頂点 25.1 最短路と緩和法 • 緩和法 – 緩和操作:もしsからvまでもっと短い経路があれば、 d[v]とπ[v]を更新する(補題25.3) RELAX(u, v, w) 1 if d[v] > d[u] + w(u, v) 2 then d[v] ← d[u] + w(u, v) 3 π[v] ← u Gはグラフ sは始点 d[v] は今まで見つけたsからvまでの最短路の重み π[v]はまで見つけた最短路には、vの直前の頂点 25.2 ダイクストラのアルゴリズム • アイデア – 「最短路の部分経路は最短路である」 – 始点sから各頂点への重みを∞で初期化して、各 頂点を対象に重みの緩和操作RELAXを繰り返す – 貪欲法的な手法 – 優先度付きキュー 25.2 ダイクストラのアルゴリズム • コード DIJKSTRA(G, w, s) 1 INITIALIZE-SINGLE-SOURCE(G, s) 2 S←Ø ▹Sを空集合として初期化 3 Q ← V[G] ▹Qを初期化 、 |V|回のQ-INSERT()操作 4 while Q ≠ Ø ▹|V|回の繰り返し 5 do u ← EXTRACT-MIN(Q) ▹重みの最も小さいもの返す 6 S ← S ∪{u} ▹最短路の頂点集合を更新する 7 for each vertex v ∈ Adj[u] ▹ 8 do RELAX(u, v, w) ▹ d[v]とπ[v]を更新する Sは見つけた最短路の頂点集合 Qは優先度付きキュー、QのKEYは頂点vへの最短経路d[v] EXTRACT-MIN(Q)はキューの最優先のものを返す 25.2 ダイクストラのアルゴリズム • 直感的例 – http://www.ntnoi.cn/FLASH/arithmetic/2010-0517/23.html – http://www.cs.usfca.edu/~galles/visualization/Dijk stra.html 25.2 ダイクストラのアルゴリズム • 計算量 DIJKSTRA(G, w, s) 1 INITIALIZE-SINGLE-SOURCE(G, s) 2 S←Ø ▹Sを空集合として初期化 3 Q ← V[G] ▹Qを初期化 、 |V|回のQ-INSERT()操作 4 while Q ≠ Ø |V| Times 5 do u ← EXTRACT-MIN(Q) ▹重みの最も小さいもの返す 6 S ← S ∪{u} ▹最短路の頂点集合を更新する 7 for each vertex v ∈ Adj[u] 8 do RELAX(u, v, w) ▹ d[v]とπ[v]を更新するQ-DECREASEKY 計算量は|V|*Q-INSERT+ |V|* EXTRACT-MINs +|E|* Q-DECREASEKY 各頂点vが集合Sに一度だけ挿入されるから、隣接リストの各辺は7-8行のFor ループにおいてアルゴリズムの実行中一度だけ調べられる。隣接リストの辺数 は|E|であるから… 25.2 ダイクストラのアルゴリズム • 計算量 |V|*Q-INSERT+ |V|* EXTRACT-MIN +|E|* Q-DECREASEKY 実装 Q-INSERT リスト O(1) O(V) O(1) 𝑂(𝑉 2 + 𝐸) 2ーヒープ 𝑂(𝑙𝑔𝑉) 𝑂(𝑙𝑔𝑉) 𝑂(𝑙𝑔𝑉) O( 𝐸 + 𝑉 𝑙𝑔𝑉) フィボナッ チ・ヒープ Q-INSERT+ DECREASE=O(1) 𝑂(𝑙𝑔𝑉) -- O(𝐸 + 𝑉𝑙𝑔𝑉) Q-EXTRACT QDECREASE 合計 25.2 ダイクストラのアルゴリズム • PrimとDijkstraの違いところ – Prim:幅優先探索と最小全域木を求める Dijkstra:単一始点の最短路 – Prim:アルゴリズムが行なっているノートにとってコストが 最も小さいノートを探す; Dijkstra:アルゴリズムが行なっていた ノーたの集合にとって、コストが最も 小さいノートを探す。 • PrimとDijkstraの違いところ
© Copyright 2024 ExpyDoc