鉛筆パズルの整数計画法による解法定式化集 3. 2015.5.20 改訂 2015.6.20 二訂 2015.6.30 三訂 スリザーリンク *1 (www.nikoli.comスリザーリンクのお試し問題) 解答 例題(お試し問題2より) 1 0 1 1 0 2 2 0 0 1 0 3 3 3 1 1 2 1 2 2 0 1 3 2 0 3 0 1 0 3 3 3 2 3 3 1 2 2 0 1 0 1 1 0 0 1 0 3 3 3 1 1 2 1 2 2 0 1 3 2 0 3 0 1 0 3 3 3 2 3 3 1 ルール *1のパズルのルール参照のこと。 ①点を繋いで全体が一つの輪になるような線を引いてゆく。 ②数字は、その周りに何本の線を引くかを表す。 ③数字のないところは、まわりに何本の線を引くか自由。 ④線は交差したり、枝分かれしてはならない。 スリザーリンクは、上記ルール①の全体が一つの輪になるというところで苦労する。 お試し問題2を例題としたのは、*1のルール説明のサンプルやお試し問題1では、 単に線を切れ目無く、交差・枝分かれなく引くだけで全体が繋がってしまい、 スリザーリンクの一番苦労する特徴が出ないからである。 行番号 I=0 1 2 3 . . Nc 列番号 J=0 1 2 3 . . まずは、切れ目無く、交差・枝分かれなく引くだけだと、どうなるかやってみる。 点配列に下図のように行番号、列番号、マス番号を振り、水平線、鉛直線に名前を付ける。 マス(I,J) 鉛直線 v(I,J) 水平線 h(I,J) Nr 変数 h(I,J) =1 ,v(I,J)=1 =0 〃 点間に線を引くとき 引かないとき 目的関数 minimize (ダミー) x 制約式 subject to 1.数字Nのあるマスの座標を(In,Jn)として、数字の周りにはN本の線を引くから、 h(In-1,Jn)+h(In,Jn)+v(In,Jn-1)+v(In,Jn)=N (数字のあるマスすべてについて 座標 (In-1,Jn) など周辺部調整必要) } 2.線は枝分かれしないから、 h(I,J)+h(I,J+1)+v(I,J)+v(I+1,J)≦ 2 (I=0,1….…Nr-1) (J=0,1….…Nc-1) 3.線は繋がっているから、v(I,J)=1であれば、v(I,J)の上端には必ず線があるから h(I-1,J)+h(I-1,J+1)+v(I-1,J)≧ v(I,J) (I=1,2….…Nr) (J=1,2….…Nc-1) v(I,J)下端、h(I,J)左右端についても同様の式が立つ。 上下界 bounds 変数型 binary h(I,J) v(I,J) (I=0,1….…Nr) (J=0,1….…Nc) 終端 end 以上の定式化に基づいて解いた結果は、下図のようになる。当然のことながら全体は繋がらない。 1 0 1 1 0 2 2 0 0 1 0 3 3 3 1 1 2 1 2 2 0 1 2 3 3 0 0 1 0 3 3 3 2 3 3 1 そこでh(I,J)、v(I,J)に矢印を付け、矢の先に矢をつなぎ、1から順に番号を振ることにより 全体を繋ぐことにする。マスは前ページの図のように黒白に塗り分けておく。 追加変数 B(I,J) = = W(I,J) = = マス(I,J)が黒塗り(線の内側)とき 〃 外のとき マス(I,J)が白塗り(線の外側)とき 〃 内のとき 1 0 1 0 hL(I,J) = = vD(I,J) = = hR(I,J) = 1 0 1 0 1 = 0 vU(I,J) = 1 = 0 格子点をつなぐ矢が左向きのとき 〃 でないとき 格子点をつなぐ矢が下向きのとき 〃 でないとき 格子点をつなぐ矢が右向きのとき 〃 でないとき 格子点をつなぐ矢が上向きのとき 〃 でないとき K(I,J)= M 格子点(I,J)がM番目の点のとき 追加制約式 4.マスは白マスまたは黒マスである (I=1,2….…Nr) (J=1,2….…Nc) B(I,J)+W(I,J) = 1 v(I,J) 5.v(I,J)=1の線を跨ぐとB(I,J) は0から1に変わるから、 B(I,J)+v(I,J)+B(I,J+1) ≦ B(I,J)+B(I,J+1) ≧ v(I,J) v(J,I)+B(I,J+1) ≧ B(I,J) B(I,J)+v(J,I) ≧ 2 B(I,J+1) } } h(I,J) B(I,J) また、h(I,J)=1の線を跨ぐとB(I,J) は0から1に変わるから、 B(I,J)+h(I,J)+B(I+1,J) ≦ B(I,J)+B(I+1,J) ≧ h(I,J) h(I,J)+B(I+1,J) ≧ B(I,J) B(I,J)+h(I,J) ≧ B(I+1,J) 2 B(I,J) B(I,J+1) B(I+1,J) (I=0,1….…Nr) (J=0,1….…Nc) ただし、実領域の外周に1層ダミーのマス を設けW(I,J)=1、B(I,J)=0としておく。 6.v(I,J)には上下の矢印が付く v(I,J) = vU(I,J)+vD(I,J) (I=0,1….…Nr) (J=0,1….…Nc) 7.h(I,J)には左右の矢印が付く h(I,J) = hL(I,J)+hR(I,J) (I=0,1….…Nr) (J=0,1….…Nc) 2015.6.30 三訂 追加 解析時間に大きく影響する 7A.黒マスは隣接する B(I,J) ≦ B(I,J-1)+B(I,J+1)+B(I-1,J)+B(I+1,J) (J=1,2….…Nc) (I=1,2….…Nr) 8.矢印は黒マス領域を左側に見て進むことにする 黒マス左辺には上向き矢印は付かない B(I,J)+vU(I,J-1) ≦ 1 (I=1,2….…Nr) (J=1,2….…Nc) 黒マス右辺には下向き矢印は付かない B(I,J)+vD(I,J) ≦ 1 同様に B(I,J)+vR(I-1,J) ≦ 1 B(I,J)+vL(I,J) ≦ 1 条件7.の定義に注意、hRは辺(I,J)に付く 二訂 K(I,J)≧K(I,J-1)+1 だけでよい。 増加して行けばよく、1づつである 9.矢印付け根の格子点に番号を振って行く 必要はない。 出発点(わかっているものとし、座標(Is,Js)とする) 解析結果は1づつになる。 K(Is,Js)= 1 hR(I,J-1)=1のときに限り K(I,J)=K(I,J-1)+1 であるから K(I,J)≦ K(I,J-1)+1 の不等号の大なる方にbigMを付けて K(I,J)≧ K(I,J-1)+1 } K(I,J)≦ K(I,J-1)+1+bigM*{1-hR(I,J-1)} (I=1,2,.....Nr) (J=1,2,.....Nc) ただし、(Is,Js)以外 K(I,J)+bigM*{1-hR(I,J-1)}≧ K(I,J-1)+1 同様にして、 K(I,J)≦ K(I+1,J)+1+bigM*{1-vU(I+1,J)} K(I,J)+bigM*{1-vU(I+1,J)}≧ K(I+1,J)+1 K(I,J)≦ K(I,J+1)+1+bigM*{1-hL(I,J+1)} K(I,J)+bigM*{1-hL(I,J+1)}≧ K(I,J+1)+1 K(I,J)≦ K(I-1,J)+1+bigM*{1-vD(I-1,J)} K(I,J)+bigM*{1-vD(I-1,J)}≧ K(I-1,J)+1 注)bigMとしてはマス数=Nr*Ncを使っているパズルが多いがスリリンでは その2倍ぐらいにしないと不足する。 上下界追加 K(I,J)≦bigM (I=0,1….…Nr) (J= 0,1.…… Nc ) 変数型追加 binary B(I,J) W(I,J) (I=0,1….…Nr+1) (J=0,1….…Nc+1) hL(I,J) hR(I,J) (I=0,1….…Nr) (J= 1,2.…… Nc ) vU(I,J) vD(I,J) (I=1,2….…Nr) (J= 0,1.…… Nc ) general K(I,J) (I=0,1….…Nr) (J= 0,1.…… Nc ) 出発点について ループでつながっている点に1から番号を振って行くので、ループをどこかで切断し起点を 決めてやらなければならない。そのためには、初めから黒マスになるのが確実なマス一つと その白マスとの境界辺を知っておかなければならない。次のような型がある。 1.隅の1、0 2.隅の3 1 0 3.隅の3、0 3 注)盤の外枠より外側は白マスと考える。 従って外枠マスの0は必ず白マスになる。 4.隅の3、3 3 3 0 3 5.辺の2、0 6.辺の3、0 2 0 7.辺の3、0(タテ) 3 0 8.辺の0、3(タテ) 3 0 0 3 これらの型が一つもなく、出発点が求まらない問題があり、そのときは適当に当たるまで変えてみる。 「クリーク」と同じように、出発点を自動探索させるのは解析時間が長くなって使えない。 格子点に番号付して全体を繋ぐことにしたので、形式的にはスッキリしたが、解けるのは盤の大きさが 18x10ぐらいまでで、36x20になると、動かなくなる問題も出てくる。黒マスに矢印を付けた 旧プログラムも捨てがたいものがある。
© Copyright 2024 ExpyDoc