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

ページ内リンク
 ヘキソミノ: 分割方法組み合わせ順序パーツ・リスト
 ペントミノ: 4分割パーツ・リスト2分割パーツ・リストパーツ・リスト考察

 Version History


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


ヘキソミノの場合  to Top

分割方法

 ヘキソミノは、完全な長方形でない為、上下対称ではありません。パーツ分割する時に、
この部分をどう扱うかが、効率化の一つの鍵になるかと思います。 

 左図で、黄色の部分は、セルのJ1とJ12にさまざまなピースを置いた時に埋まる可能性のある領域です。

 その部分を境界にし、同型を4個切り出すことを考えると、@ABの3種類のパーツ・リストが必要になります。これをベースにいろいろ検討をしたのですが、AとBに共通する部分が多いことと、@の形状が面積に対して境界線が長いため、インデックスの階層がより深くなることが不利になるように思われます。

 今現在、検討しているのは、この方法です。本来、上側と下側は形状が異なるので、別々のパーツ・リストが必要になるのですが、途中までは全く同じですので、後半部分だけ2つのパターンについて探索を行い枝分岐の中で合わせて分類、管理すればよいように思われます。

 これをベースに、より小さいパーツに分割するかどうかは、後ほど改めて検討しようと思います。

 ここからは、中村さんのサイトにあった、左のサンプルを使って検討を進めようと思います。

 上の分割方法に従うと、このサンプルは、以下の4つのパーツから構成されていることになります。

 

        
   

 

 

パーツ細分化

 やはり4分割では、規模がまだ大きく、探索にかなりの時間がかかってしまうことが予想されるので、さらなる細分化を検討してみます。

 いろいろな形状を検討したところ、中央上部を除くと、それ以外の部分は、a と b のパーツの組み合わせで作ることができます。細長い形状は、インデックス化に不利にも思えますが、なるべくパーツの種類を少なくするという観点からはメリットがありそうです。a も b の一部なのですが、とりあえず別パーツとして扱う方がシンプルに思えます。(大した根拠はないので、再考の予定)

 上のサンプルから抜き出すと以下のようなパーツになります。

 右上部分も左右反転させて、以下のようになります。

 中央部分は、J1の出っ張りを埋めているピースが左側にどれだけ伸びているかによって、パーツの幅を変える必要があります。

 これらの特性を考慮に入れると、以下の3種8分割が、ちょうど良いように思われます。

 だいぶ話が込み入ってきたので、整理する上でも、次回は、パーツ・リストから解を求めていく流れをまとめてみようと思います。

組み合わせ順序  to Top

 4つのパーツの組み合わせ方として、
   −1.左の2つを組み合わせ、2分割パーツ・リストを作成してから、左右を合わせる
   −2.左の2つを組み合わせ、それに右上のパーツ、最後に右下のパーツを合わせる

 パーツ作成と同時に解が求まっていくことがモチベーションの維持に有効
  パーツを階層化する場合でも、単にサブ・パーツを延々準備するのはつまらない。

 というあたりを考慮して、−2.で進めてみる。

パーツ・リスト  to Top

 まず、境界上に並ぶピースを順に、それぞれピース番号、向き、上下位置の3つを定義して行きます。
この例では、

 を の向きで、5段目の位置に置くという情報になります。

 35ピースの定義に6ビット、最大8通りの向きに3ビット、最大6段の位置に3ビットで、合計12ビット必要になります。

 横方向の境界が10マスですので、最大で10ピースが使われる可能性があります。上の例では右下のパーツが9ピースを使用。1ピースの12ビットなので、横方向だけで12x10=120ビットになります。

 縦方向の境界は残り5マスで、12x5=60ビット、35ピースのどれが、パーツに使用されているか、いないかにそれぞれ1bitで表現して35ビット、これらのトータル215ビットで1パーツが定義できます。形状情報がすべて境界上のピース並びに包含されるので、かなりコンパクトになります。

 実際にパーツ・リストから検索して使う時には、使用しているピースが同じで、境界上のピースも同じだけれど、それ以外のピースの置き方が異なるものについては一括して処理できるので、その個数を保存する領域が必要になります。その数がどのくらいになるかは、よくわからないので、まずは、パーツ・リストをフラットに作成し、インデックス化する時に再検討することになるかと思います。

 この部分、文章ではわかりにくいので、図示化をそのうちに・・・

 

 
 

ペントミノの場合  to Top

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

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

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

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

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

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

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

4分割パーツ・リスト  to Top

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

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

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

2分割パーツ・リスト  to Top

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

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

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

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

パーツ・リストの考察  to Top (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

 


Version History   to Top

 0.15 10/02/14 ヘキソミノ 細分化 -> 8分割
 0.14 10/02/07 ヘキソミノ 4分割
 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 初稿 ペントミノ場合


 

 

 

 

 

 

 

 

 

inserted by FC2 system