welcome: please sign in

2010-01-05 02:14:31時点のリビジョン26

メッセージを消す
location: 解のある配置を作る

ばらばらにする

右下の1つを除いた他のピースをばらばらに入れ替えた後、 スライドするだけで元の位置に戻すのがこのパズル(15ゲーム)の問題です。

どんなにばらばらに配置しても元の位置にもどせるのかというと、そうではありません。

どんな配置だと元にもどせるかを解説した後、 元にもどせる配置だけを作成するメソッドを示します。


ちょっと数学的な説明

並び

並べるものの一つ一つを数で表すことにすると、 例えば5つのものの並び

のように書けます。

並び(4,3,2,5,1)は

並んでいることを表しています。

置換

たとえば

も置換の1つです。

互換

たとえば

は互換の1つです。

交換される2つ以外の要素の位置は変わりません。

互換の積

どんな置換(入れ替え)も、互換(2つの入れ替え)を繰り返すことで行うことができるという意味です。

たとえば、並び(1,2,3,4,5)を並び(1,3,5,4,2)に変えるには

と、2回の互換で行うことができました。

==== 偶置換、奇置換 ===

何回かの互換を繰り返すことで置換ができることがわかりました。

上の例では2回の互換で目的の置換ができましたが他の手順も考えられます。

4回の互換で行うことができました。

ほかにもいろいろな手順が考えられます。

しかしどの方法をとっても、 並び(1,2,3,4,5)を並び(1,3,5,4,2)に変えるには 互換の回数は偶数回になります。

奇数回の互換で表される置換を偶置換といいます。

偶数回の互換で表せれる置換を奇置換といいます。


15ゲームが解ける条件

15ゲームでは 偶置換の問題は解けますが、奇置換の問題は解けません。

偶置換の問題だけを作るようにプログラムを作成します。


プログラム

最初に正しい位置に配置した後で 互換を偶数回行うことで問題を作成します。

メソッドshokikaに次の処理を追加してください。

   1         void shokika()
   2         {
   3                 int x, y, x2, y2, w, cnt;
   4                 ...
   5                 ...
   6                 for (cnt = 0; cnt < (tate*yoko*2); cnt++)
   7                 {
   8                         x = (int)(Math.random() * (yoko-1));
   9                         y = (int)(Math.random() * (tate-1));
  10                         if(Math.random() < 0.5)
  11                         {
  12                                 x2 = x;
  13                                 y2 = y + 1;
  14                         }
  15                         else
  16                         {
  17                                 x2 = x + 1;
  18                                 y2 = y;
  19                         }
  20                         w = ban[x][y];
  21                         ban[x][y] = ban[x2][y2];
  22                         ban[x2][y2] = w;
  23                 }
  24         }

プログラムの解説

1つ1つの互換は ban[x][y]にある内容を、その右隣または直下の内容と入れ替える操作にします。

入れ替え元の位置を(x,y)、入れ替え先の位置を(x2,y2)とすると 入れ換えの操作は20~22行目のように書けます。

右隣と入れ換えるときは

直下と入れ換えるときは

となっていればよい。

10~19行目で乱数の値により、そのどちらかを行っています。

8,9行目ではxとyの値を乱数で決めています。 乱数は横の数、縦の数より1つ小さい範囲に制限しています。 この結果、互換は下図のどれかが行われることになります。

右下隅のピースは入れ換えられないことに注意してください。

右下隅のピースはゲーム中は取り除くので、このピースを除いた他のピースの置換(互換)だけを考えなければなりません。

以上8~19行目の処理が1つの互換になります。

その外側のforループを偶数回繰り返すことで偶置換の問題を作り出しています。