ホームページへ戻る
倉庫番最短歩数解探索 Ver1.2
Sokoban copyright(c) 1982- THINKING RABBIT Inc. Japan
最短歩数の解を探すソルバープログラム(2021年3月)

 ■ Windows版のダウンロード

 実行環境
 Windows
 ダウンロード
 sokoban_mms.exe  (96 KB / 圧縮なし)
 インストール方法
 このソフトは「sokoban_mms.exe」というファイル
 だけで動くので、インストール作業は不要です。
 注意事項
 セキュリティー警告が出る場合は、(ここを参照)

このプログラムは、最短歩数に基づく最短経路の解を探索します。
ただし、荷物の個数は8個までに制限されます。
また訳あって、解を見つけても最後の20歩は非表示になります。

 ■ 実験とその成績


レベルセット名 問題の数 試みた数
BOX<9
解けた数 備考
パーフェクト 306  62  56  詳細
リベンジ 306  49  44  詳細
microban 155  150  149  詳細
masmicroban 135  123  117  詳細
 解けた数 = 最短歩数の解を見つけた数

 ■ アルゴリズムの解説

・完了型から初期型に向かう逆解きを採用

 初期型から探索を開始する通常の探索法では、倉庫番を解くVer2.7に示したように 多くの枝刈りを組み込まないと無駄な探索が大量に発生してしまいます。
 しかし、逆解きでの間違った手順は、自分を閉じ込めて探索を収束させる場合が多く、枝刈りはほぼ不要になります。

通常解きでの失敗例

逆解きでの失敗例
・1回の動作の概念について

 最短歩数の解を求めるのであれば、1回の動作の概念は1歩であるべきですが、無駄に動き回る局面は不要なので、「目的の荷物の手前まで最短で歩き1回だけ荷物を引く」という動作を1回の動作としています。それだと 最短歩数では無く、最小荷押し数(minimum pushes)の解が求まってしまうのでは無いか? いいえ、そうはならない秘策を次の項で述べます。
【親局面】最短で歩き、

【子局面】1回引く
・二次元キューを使った幅優先探索

 このプログラムは、基本的に「第4章: 幅優先探索」を使っています。しかし、待ち行列(キュー)が1個では無くたくさんあります。上図の例では、親局面から子局面まで5歩使っています。この場合は、n歩用のキューから親局面を取り出して、子局面はn+5歩用のキューに登録します。n歩用のキューが空になれば、n+1歩用のキューからの取り出しに移行します。
nから親局面を取り出し、子局面をn+5に登録
・トンネル内での枝刈り

 トンネルとは、幅1マスの直線通路のことです。このトンネル内に荷物を一旦放置する局面は、 最短歩数の解には絶対に到達しないので、子局面として登録しません。(右図参照) 初期状態 
放置禁止 
・マトリックス枝刈り

 N個の荷物とN個のゴールでN組のカップルが成立するかを調べます。例えば荷物が4個(荷物A、荷物B、荷物C、荷物D)あるとして、ある位置pos1には荷物Aしか運べない場合は、Bits[pos1] = 1000 (2進法)とし、位置pos2の場合は、荷物A、荷物B、荷物Dの3つが運べるのなら、Bits[pos2] = 1101 (2進法) として、総てのマスについて荷物を運べる状況(Bits[])を事前に調べておきます。

 逆解き探索中は、4つの荷物(荷物1、荷物2、荷物3、荷物4)の各位置のBits[]の値を右図のように並べてマトリックスを作ります。このマトリックスをN飛車問題(Nクイーン問題の飛車バージョン)として解が存在するかを調べます。
Bits[荷物1位置] = 1000
Bits[荷物2位置] = 1101
Bits[荷物3位置] = 0111
Bits[荷物4位置] = 0110

 ■ ソースコード(C言語)を公開します

・ダウンロード (Ver1.2)

sokoban_mms_src.zip (13 KB)
    【参考】Visual Studio 2019 (無償版) での実行方法
・各ソースコードについて

Header.cグローバルな定数や変数を定義しています。
Loader.cレベルセットを取り込み、C:\temp_soko フォルダーに保存します。
Selector.c指定のレベルを保存フォルダーから読み取ります。枝刈り用データも作成します。
Solver.c最短歩数解の探索を行うソルバー部分です。
ConsoleUI.cコンソール版インターフェイスです。このファイルをビルドして下さい。
・注意事項

☆ C言語のビルド(コンパイル)環境と知識が必要になります。
☆ Windows版のインターフェイスは付属しません。(公開しません)
☆ 最後の20歩非表示の制限は無くなります。
このコードを転用・流用の際は必ずこのページを参考文献として明記してください。


★最も簡単な改造方法(Header.c 内の定数値を変えてみる)
  // 8個までの制限を変更するには、ここを変更します。
  #define MaxBoxes 8 // BOX数の最大値
  // 探索量(CellとQue)を変更するには、ここを変更します。
  #define CE_SIZE 14000000 // C (Cells使用可能量)
  #define QH_SIZE    800000 // H (Queue使用可能量)
 ただし、この単純な改造だけでは残念な結果になるようです。



ホームページへ戻る