地図/探索/経路探索

ゴールの方へ細く伸びる — A スター

ダイクストラは全方向へ平等に広がる。ゴールがどっちにあろうと、距離の近い順に律儀に確定していく。ゴールまでの見当(ヒューリスティック)を持っているなら、ゴールから遠ざかる方向の探索は後回しにできる。

確定済みのコスト g に、ゴールまでの見当 h を足した f を見て、f の小さいマスから優先して開く。g だけ見るのがダイクストラ、g + h で先を急ぐのが A スター。見る量がひとつ増えただけで、枠組みは同じ。

A スター。g + h を評価値にして探索する経路アルゴリズム。g はスタートから今のマスまでの確定済みコスト、h はそのマスからゴールまでの見積もり(ヒューリスティック)で、f = g + h を最小化する向きにマスを開く。h が実際のコストを決して上回らない(admissible・許容的)かぎり、最短経路になる。マンハッタン距離やチェビシェフ距離は壁を無視して測るので許容的になる。h を常に 0 にすると f = g となりダイクストラに一致し、g を無視して h だけ見ると貪欲最良優先探索(greedy best-first)になる。A スターはその中間に位置する。Hart, Nilsson, Raphael が 1968 年に定式化した。

未確定のマスから、ダイクストラは g の最小を選んでいた。A スターは g + h の最小に変える。h はゴールまでのマンハッタン距離、横の差と縦の差を足したもの。これだけで、選ばれるマスがゴールの方角へ傾く。

// 未確定(open)の中から f = g + h が最小のマスを選ぶ
let bi = 0
for (let i = 1; i < open.length; i++) {
  const fi = gScore[open[i]] + hCost(open[i]) // g に見当 h を足す
  if (fi < gScore[open[bi]] + hCost(open[bi])) bi = i
}

hCost を 0 にすれば f = g に戻り、選び方はダイクストラと同じになる。h を足したぶん、ゴールから逸れたマスの f が底上げされて後回しになる。マスは未踏 / open(縁に並んで待つ)/ closed(確定済み)の3つの状態を行き来する。open は f が最小のものから取り出し、開いたら closed に移す。

確定済み(明るいマス)の広がりが、全方向の円ではなく、スタートからゴールへ細く傾いて伸びる。見当 h がゴールから逸れる方向の f を底上げして後回しにするので、無駄な方角をあまり開かない。hCost(i)0 にすると f = g になってダイクストラと同じ選び方に戻り、確定の塗りがまた全方向の円に広がる。壁(暗いマス)に当たると open の縁がそこで途切れ、開いた隙間を縫ってゴール側へ回り込む。

来た道を一マスごとに覚えておくと、ゴールに届いた瞬間その親をスタートまで遡って経路の線が引ける。確定(明るい)と探索の縁(中間調)と壁(暗い)の3つの濃淡に、遡った経路を最も暗い線で重ねると、細い探索の帯の中に一本の道が浮かぶ。

見当を本当の距離より大きく見積もると(weighted A スター)、探索はもっと細く速くなる代わりに、最短である保証は崩れる。h に掛ける係数が、速さと最適さのつまみになる。