倉庫番 攻略ガイドでは、一部ステージを幅優先探索(BFS)の手法で最短経路に更新しています。
このページでは、BFSがどのようにして最短手数を求めているかを解説します。
- 例:STAGE 004 -
- 状態(State)のエンコード -
BFS では各盤面を State としてハッシュマップに登録し、同じ盤面への再訪問を防ぎます。
箱の座標は行番号・列番号から計算した1次元の整数に変換してソート保持しています。これにより同じ盤面かどうかを高速に判定できます。
static int posToInt(Pos p, int width) { return p.r * width + p.c; // 例: Pos(3,2), width=10 → 32 }
- 幅優先探索(BFS)の流れ -
BFS は「キュー(待ち行列)」を使い、手数の少ない状態から順番に展開します。
最初にゴールへ到達した瞬間、それが最短経路です。
Yes → 解答! No → 続行
キューの状態イメージ(色 = 手数)
同じ手数の状態を全部処理してから次の手数へ進む → 最初に到達=最短
- 移動の可否判定 -
箱があるときは「箱の先が空きかどうか」を確認します。壁や別の箱があれば押せません。
- 訪問済み状態の管理 -
異なる手順で同じ盤面に到達することがあります。BFS では最初に到達した経路が最短なので、2回目以降はスキップします。
同じ盤面を何度も処理せず済むため、探索が大幅に高速化されます。
重複排除なしでは同じ盤面を何度も処理してしまい、現実的な時間では解けません。
- BFS 動作デモ(STAGE 004) -
「次の手数を展開」を押すごとに、BFSが手数0→1→2…と状態を広げていく様子を確認できます。盤面をクリックすると右に拡大表示します。
※ STAGE 004は最短114手のステージですが、手数が増えるにつれて状態数が爆発的に増加するため、ここでは手数4までを表示しています。
- 経路文字列の記録 -
各盤面は、そこへ至るまでの手順文字列(U / D / L / R の並び)も一緒に保持しています。ゴールに到達した瞬間、その文字列がそのまま最短経路の解答になります。
- 実装上の工夫と注意点 -
| 工夫 | 内容 | 評価 |
|---|---|---|
| 盤面の一意なキー管理 | 同じ盤面への再訪問を防ぎ、探索を効率化 | 重要 |
| 手順文字列の同時保持 | ゴール到達時に即座に解答を取り出せる | シンプル |
| 手順文字列の全ノード保持 | メモリ消費が大きく、箱が多いと課題になる | 注意 |
| デッドロック検出なし | 解けない盤面も展開するため探索量が増える | 改善余地 |
※ 箱数が増えると探索すべき盤面数が急増します。箱7個のステージでは GCP Cloud Batch(メモリ約100GB)を使用しています。