後戻り防止と双方向探索
後戻り防止の効果
1ステップ毎の後者を1つ排除できる。ステップ数が多くなるほど効果が大きくなる。後者が少ないときに特に効果的。
例:
後者数 | 状態空間 | 倍率 |
2^8 | 256 | − |
3^8 | 6561 | 25.6 |
4^8 | 65536 | 10.0 |
5^8 | 390625 | 6.0 |
双方向探索の効果
ステップ数を最大で半減できる。これもステップ数が多いほど効果が大きくなるが、メモリを多く消費するようになるのが欠点。メモリ消費の倍率の1/2ほど探索する状態空間を削減できる。双方向探索のうち片方はメモリに蓄える必要があるので、そちらに幅優先探索を用いることで、後戻り防止だけでなく、重複する状態に到達する手を全て刈り取ることができる。
両方組み合わせると、大雑把な試算で次のような改善が期待できる。
例:24パズルの解の存在判定 平均後者数:3.2 最大手:8 反復深化のみ 3.2^8 = 10995.12 双方向探索(反復深化+後戻り防止)×(幅優先探索+重複防止) 2.2^4 = 23.4256 23.4*2 = 46.8 改善率:235倍 参考:転倒数の計上のステップ数:24*23/2 = 276
効果はかなり大きい。もっとも、解の判定だけなら転倒数を数えた方がよほど楽だ^^; そんな結論だと残念なので8パズルを解く場合を考える。M.hiroi(パズルに挑戦!)によれば、変形版ではあるが30手が最大なので、その手数で試算すると、
8パズルの解 平均後者数:2.56 反復深化のみ 2.56^30 = 1.766846e12 双方向探索(反復深化+後戻り防止)×(幅優先探索+重複防止) 1.56^15 = 788.6215 800*2 = 1600 改善率:1.125e9倍
となり、反復深化のみでは解くことがまず不可能なレベルの問題が、現実的なコストで解けるようになることがわかる。今回は面倒なので実装はしない(’’
さらなる改良
15パズルになると、これでも大変なので、下限値枝刈り法を用いると良いと思われる。それ以上の問題では、さらに後者関数の数と手順数が増えるので、このような基本戦略が総当たりでの探索は難しい。最短経路探索はあきらめ、問題を分割して考えないと手に負えないだろう。