seegongsik
アルゴリズム

最短経路 わかりやすく

地図を開いて道を探すとき、分かれ道の少ない道がいつも速いとは限りません。短く見えても、混んでいたり遠回りだったりすれば遅くなります。道ごとに距離が違うからです。では、いちばん速い道はどうやって探すのでしょうか。

01

線ごとに距離が違う

点と点を線でつなぐ方法は、もう学びました。でも実際の道には、もう一つあります。線ごとに距離が違うということです。
短い道もあれば遠い道もあるので、線の上に数字を書きます。その数字が距離です。
下の道を押して、距離を確かめましょう。

SABCDT
道を押して距離を見て

道を押すと距離が見えます。(線 = 道 · 数字 = その道の距離)

距離が違うことが、なぜ大切なのでしょうか。分かれ道を少ししか通らない道でも、一区間ずつが遠ければ、全体ではもっと遅くなることがあります。
逆に、分かれ道を多く通っても、各区間が近ければ、全体ではもっと速くなることもあります。
だから距離を抜きにして道を選ぶことはできません。

02

近い順に数えるだけでは足りない

前に、近い順に広がる方法を見ました。一マス、二マス、三マスと、出発点から何マス離れているかで数える方法でした。
でもそれは、すべての道がちょうど一マスのときの話です。
道ごとに距離が違えば、マスの数が少ない道がもっと近いとは限りません。

SPXYT
—
—
二つの道をそれぞれ押して比べて

二つの道を押して比べます。(マスが少ない道 vs 距離が短い道 · 同じではない)

分かれ道を少ししか通らない道のほうが、距離ではもっと遠かったのです。マスの数だけ数えると、このわなにはまります。
だからマスの数ではなく、距離を足しながら、本当に近い道を探さなければなりません。

03

近いものから確定する

では、どうすればよいでしょうか。目の前の最善を選ぶ貪欲を思い出しましょう。
出発点から始めて、まだ距離が確定していない点のうち、今いちばん近い点を一つ選び、その距離を確定します。
道の距離がマイナスでなければ、いちばん近い点までもっと短い道はありえないので、確定しても安心です。

2531264S0A2B5CDT
未確定の点のうち、いちばん近い点を押して確定

いちばん近い点を押して確定します。(毎回、未確定の点のうち距離がいちばん短いものを選ぶ)

これが目の前の最善を選ぶということです。地図全体を解くのではなく、今いちばん近い点から一つずつ確定していきます。
一つの点を確定すると、その点を通っていく隣の点の距離も、新しく近くなることがあります。
この方法をダイクストラ法と呼びます。

04

境界を広げていく

確定した点が増えるほど、「距離が決まった範囲」ができ、その範囲のふちが境界です。
毎回、境界のすぐ外からいちばん近い点を一つ取り込めば、範囲が一点ずつ大きくなります。
静かな水に石を投げると、波紋が広がるのに似ています。

SABCDT
境界のすぐ外の点を押して範囲を広げて

境界のすぐ外の点を押すと、範囲が大きくなります。(確定した範囲が一点ずつ外へ育つ)

境界がだんだん外へ広がっていくと、やがてすべての点が確定した範囲に入ります。
そのときには、出発点からどの点までも、いちばん速い距離がすべてわかります。近いところから一歩ずつ、それがこつです。

05

まとめ

いちばん速い道探しを一行にまとめるとこうです。線ごとに距離が違えば、マスの数が少ない道が速い道とは限らないので、近い順に数えるだけでは足りません。
近い点から距離を確定し、境界を一点ずつ広げていけば、その時その時で目の前の最善を選びながら、すべての点までの最短距離が見つかります。

要点を順に押してまとめます

要点を順に押してまとめます。(距離が違う → マスの数ではだめ → 近いものから確定 → 境界を広げる)

地図アプリがいちばん速い道を探してくれるとき、中ではこんなことが起きています。近いところから距離を確定し、境界を少しずつ広げていくのです。
目の前の最善という単純な決まりが、距離がばらばらな複雑な道でも、いちばん速い答えを連れてきます。

一言でいうと線ごとに距離が違えば、分かれ道の少ない道がいちばん速い道とは限らず、近い順に数える方法だけでは足りません。出発点から近い点の順に距離を一つずつ確定し、確定した範囲の境界を一点ずつ外へ広げていきます。その時その時で、まだ確定していない点のうちいちばん近いものを選ぶ、目の前の最善です。境界が全体に広がれば、すべての点までのいちばん速い距離がわかります。
← アルゴリズム
このページがお役に立ったなら支援する