対称方陣
ある現実の問題について考えていると、次のようなパズルと等価であることに気づいた。
- Nは偶数
- N x Nの行列の対角線を含まない上三角行列部分を、1からN-1の整数で全て埋める。(それぞれの値をN/2回使用)
- 埋めた値を下三角行列の対称位置にコピーする。
- 行列の全ての行、全ての列で、同じ値は一回しか現れないようにする。(下三角も含めて一回)
N=6の場合、以下のような答えになる。
4 5 3 2 1 3 2 1 5 1 4 2 5 4 3
ラテン方陣というものに似ているみたいだが、対称行列が条件になっている所が違う。
Sugar制約ソルバーを使って解いてみると、N=50の場合でも85sec.で答えを出した。(PicoSAT ver.846をSAT Solverとして使用したとき)
N=50だと、変数の数が1225(= N*(N-1)/2)になるが、この程度の時間で解けるので驚いた。
(例) N=6のときの制約ルール
; Match N=6 (int x00_01 1 5) (int x00_02 1 5) (int x00_03 1 5) (int x00_04 1 5) (int x00_05 1 5) (int x01_02 1 5) (int x01_03 1 5) (int x01_04 1 5) (int x01_05 1 5) (int x02_03 1 5) (int x02_04 1 5) (int x02_05 1 5) (int x03_04 1 5) (int x03_05 1 5) (int x04_05 1 5) (alldifferent x00_01 x00_02 x00_03 x00_04 x00_05) (alldifferent x00_01 x01_02 x01_03 x01_04 x01_05) (alldifferent x00_02 x01_02 x02_03 x02_04 x02_05) (alldifferent x00_03 x01_03 x02_03 x03_04 x03_05) (alldifferent x00_04 x01_04 x02_04 x03_04 x04_05) (alldifferent x00_05 x01_05 x02_05 x03_05 x04_05 ) ; END