最短経路 — ダイクストラとA*、そして負の辺
道ごとに距離も混雑も違う現実の地図では、「歩数が少ない=速い」は成り立ちません。枝に重み(コスト)がつく世界で、本当の最短経路を求める。距離ラベルを賢く伸ばすダイクストラ法、ゴールへ当たりをつけて掘るA*、そして負の辺がなぜダイクストラを壊すのか(=ベルマンフォードの出番)まで、動かして掴みます。
1. 重み付きグラフ — 「歩数最小」と「コスト最小」は違う
前章の BFS は、すべての移動が「1歩」で等しいときに最短でした。でも地図では、平地は軽く・山や渋滞は重い。各マスに通行コスト(重み)を与えると、歩数が最も少ない道と、合計コストが最も小さい道は別物になります。
下の図で、水色=歩数最小(BFS)と オレンジ=コスト最小(ダイクストラ)の2本を見比べてください。マスの数字が通行コスト、地の色は緑=軽い/赤=重い。しばしば、遠回りに見えるオレンジのほうが合計コストは小さいのです。
2. ダイクストラ法 — 距離ラベルが染み出す
ダイクストラ法の心臓は2つの操作です。①緩和(relax):あるマスから隣へ「今より短く行けるなら暫定距離を書き換える」。②確定:まだ確定していないマスの中で暫定距離が最小のものを選び、その値を最短として確定する(=優先度つきキュー)。
確定したマスからは二度と値が下がらない、という保証(重みが非負なら成立)が効率の源。再生して、暫定距離の数字がスタートからじわじわ外へ染み出し、最小のマスが次々に確定していき、最後にゴールから最短経路が逆にたどれる様子を見てください。
3. A* — ゴールへ当たりをつけて掘る
ダイクストラは全方位に平等に広がるので、ゴールと反対側まで無駄に調べます。そこでA*(エースター)は、各マスの評価に「ゴールまでの推定残り距離」=ヒューリスティック h を足します。確定する順番を f = 距離 g + 推定 h の小さい順にすると、探索がゴールの方向へ細長い扇(コーン)になり、調べるマスがぐっと減ります。
下は同じ地形での競走。左のダイクストラは円、右の A* はゴールへ向かう扇。h が本当の距離を超えなければ(=許容的なら)、A* もダイクストラと同じ最短経路にたどり着きます — より少ない手間で。
4. 負の辺という落とし穴 — そしてベルマンフォード(まとめ)
ダイクストラの効率は「一度確定したマスは二度と短くならない」という前提に支えられています。ところが負の重みの辺があると、この前提が崩れます。あとから負の辺を通ると、確定済みのマスがさらに短くなり得るのに、ダイクストラは覆せず誤った答えを出します。
下の小さなグラフで確かめましょう。ダイクストラは B を距離2で早々に確定しますが、実は S→A→B = 3+(−3) = 0 が正解。この誤りを直すのが、確定せずに全ての辺を |V|−1 回くり返し緩和するベルマンフォード法です。
- ダイクストラ:暫定距離を緩和し、最小から確定。重みが非負なら最短を保証。全方位に円形に広がる。
- A*:ダイクストラ+ゴールへの推定 h。許容的な h なら最短を保ったまま、探索をゴール方向へ絞って高速化。
- ベルマンフォード:全辺を |V|−1 回緩和。遅いが負の辺に強く、負の閉路も検出できる。
- 選び方:負の辺があるか? ゴールへの良い推定があるか? で使い分ける。