部分解への分割方法の検討
ver.0.13 2010/02/04 daichinあっとexcite.co.jp
   http://hexomino.hp.infoseek.co.jp/

・Version History
 0.13 10/02/04 ペントミノ 2分割パーツ・リストの考察を追加
 0.12 10/02/01 ペントミノ パーツの定義を変更
 0.11 10/01/28 ペントミノ パーツ・リストの考察を追加
 0.10 10/01/23 全面改訂 ペントミノの場合
 0.02 02/12/22 ヘキソミノの場合を追加
 0.01 02/12/17 初稿 ペントミノ場合


 自分でも当然検証を進めていきますが、ちょいと心配です。どなたか、追試、検証をしていただけませんでしょうか?ご意見、ご質問等お待ちしてます。(メールでも、掲示板でも結構です。)


ペントミノの場合

 説明に、左の例を使ってみます。特に意味のある組み合わせではなく、適当に選んだものです。
 Ver.0.02までは、組み合わせた時に重ならないパーツのリストを作成し、それらを組み合わせて、残りの空白部分を探索するという考え方でした。

 その結果、左図の水色3マスを埋める組み合わせが条件となり、薄い灰色の領域に入ります。以下の例のように、1ピースのものもあれば、3ピースからなるものまであることになります。
  

 このパーツ自体は、せいぜい3ピースの組み合せなので、全通り簡単に求まります。(何通りあるかの計算結果が掘り出せない・・・)

 これを4隅に順に組み合わせて、残りの空白部分だけを探索すれば効率的では(?)というのが基本的なアイデアでした。

 実際に実行してみると、組み合わせのほとんどは、解のない無駄なものがほとんどで、組み合わせ数は2339通りを遥かに超え、それを総当たりで探索したのでは、逆に処理時間が長くなってしまいました。

 それではということで、各パーツに対して、数手先までチェックし、解の無いものを枝刈りしたり、せっかく探索するので、その結果をデータとして保存し、その後の探索に利用するとか、いろいろ試してみたのですが、結果として高速化に繋がるような有効なアイデアが見つからず、・・・・フェードアウトしてました。

 ということで、長い前置きがやっと終わって、ここからが今回のアイデアです。(ver.0.12で大幅修正しました)

4分割パーツ・リスト

 ペントミノは全体が6x10マスなので、左図のように3x5の領域に4分割できます。
 図6の薄緑色の領域と、他の領域とオーバーラップさせる為にX印の領域を埋めるというのをパーツの条件にすると、左図の例のようになります。当然ですが、他の領域にはみ出してしまいますが、これでいいんです。この条件のパーツをすべて求めると、それ以上ピースの探索は一切必要ない(のではないか)というのが今回の最大のポイントです。
 では、図7の灰色の残りの部分を どうやって埋めるかなんですが、はみ出しているピースだけを残して、上下反転させると、左図になります。そうなんです、このパターンを含んだパーツは、上で求めた 全パーツリストの中にすでに存在するのです。
(ペントミノの4分割だと、パーツの規模が小さすぎて逆にわかりにくいですね。図8の下側はこの例ではたまたま埋まっていますが、図7のように隙間があるケースもあります。)

 それを見つけてくるのは、「探索」ではなく、「検索」になるというのはわかりますでしょうか?

 このケースでは、以下の2つが検索されてくることになります。これらを上下反転させて図7と組み合わせることにより左半分が埋まり、,次のレベルである2分割パーツとして、2分割パーツ・リストに登録します。
  

2分割パーツ・リスト

 ペントミノの場合は、規模が小さいので、4分割から2分割を作るより、直接2分割を作成したほうが良さそうです。ヘキソミノへの展開を想定しているので、その説明の為に、パーツを段階的に大きくしていくプロセスで進めています。

 ここでは、左図の薄緑の領域とX印を埋めることが条件になります。

 図9の例(図7に合わせて上下反転してあります)では、左図の×印を含む5ピースを左右反転させた、図13のパターンを含むものをパーツ・リストから検索します。
 
 左図が検索され、これを左右反転させて図12と組み合わせることにより、図1が求まります。

 この例に対しての検証をしてませんが、図13の条件だけでは、すでに図12の左側で使用しているピースを含むものも検索されてしまうので、検索条件に、使用ピースを含める必要があることが分かります。また、もし左図と同じピースの組み合わせで、別パターンが存在する場合は、その数をリストに含めて置くことにより複数の解が一度に求まることになります。(パターンではなく、解数のみ)

パーツ・リストの考察 (ver.0.11から0.12への上記変更内容に対しての反映はまだできてません)

 これらのパーツを分類し、検索できるようにし、かつサイズの小さいパーツ・リストを設計する必要があります。

 それぞれのピースに対しては、形状、向きに加えて、上下位置を情報として持つ必要があります。上下位置は、左上からとかルールに従って順に詰める場合には必要ありませんでしたが、パーツ・リストの場合、形状と向きは 図8と同じでも、左図のように別の並べ方が存在するためです。

 ペントミノの場合、12ピースを区別するのに4bit、向きはピースによって異なり、最大で8通りで3bit、上下位置は3通りで2bitになり、1ピースに9bit必要になります。 (2001年のnakaさんとのやり取り

 図7の例では、6ピースが、図6の薄緑色の長方形領域の境界に使われているので、境界を定義するのに、9bit x 6ピース = 54bitが必要になります。

 境界が7コマなので、最大では、7ピースになる可能性があります。適当に手で並べて見たのが左図ですが、これは、この先行き詰まるのが分かります。 (十字を置くところがない) プログラムを作れば簡単に検証できるのですが、まとまった時間が取れず、しばらくは紙の上での思考を続けます。
 図7の例では、すべてのピースが境界に絡んでいるのですが、 下側になる図8の場合は、左図のように境界に絡むのは、4ピースで、絡まないピースが一つあります。(左上、水色のピース)

 パーツを組み合わせる時には、境界のピース以外が重複していない組み合わせを検索できるようにする必要があります。

 また、左図のように、はみ出しが無い場合もあり、境界領域のインデックスを1列ではなく、2列にする必要がありそうです。

 これは、ペントミノの全体が6x10と、縦横とも偶数なためで、ヘキソミノは11x19と、縦横とも奇数なので、1列で済むはずです。

 話を単純化しようとペントミノから話をはじめましたが、ここらで、本題のヘキソミノで話を進めることにします。

と書いたものの、もうちょっとペントミノ上で加筆修正しようと思っている内に日が過ぎて行くのでとりあえずUp

inserted by FC2 system