主要内容

このページの翻訳は最新ではありません。ここをクリックして,英語の最新版を参照してください。

整数計画法により数独パズルを解く:問題ベース

この例では,0 - 1整数計画法を使用して数独パズルを解く方法を説明します。ソルバーベースのアプローチについては,整数計画法により数独パズルを解く:ソルバーベースを参照してください。

おそらく数独パズルを见ことがあるでしょでしょうでしょでしょでしょう。グリッドグリッドには埋めるパズルグリッドヒントが表示さておりことことこと表示表示さておりことことが表示さされてヒントが表示表示埋めるパズルてヒントががさ

初期パズル

ヒントのデータ行列Bを以下に示します。最初の行B(1、2、2)は1行2列目にヒント2が表示されていることを意味します。2番目の行B(1、5、3)は1行5列目にヒント3が表示されていることを意味します。全体の行列Bを以下に示します。

B =[1、2、2;1、5、3;1、8、4;2、1、6;2、9、3;3、3、4;3、7、5;4、4、8;4、6、6;5 1 8; 5,5,1; 5,9,6; 6,4,7; 6,6,5; 7,3,7; 7,7,6; 8,1,4; 8,9,8; 9,2,3; 9,5,4; 9,8,2]; drawSudoku(B)有关这个程序的列表,请参阅本例的结尾部分。

このパズルと代替ののMATLAB®解法は,2009年の克里夫的角落で特集されていました。

数量のはようますありますしますしししししししししこのあり例ではにありのと同じようにあるあるのとようようありありでははありありありではあるありのででこのありありでではありありありでででありありありでででありありありありででこのありありありありありありありありありありありありのののであるのののののとにに多ののと

この方法は解のアルゴリズムを指定しないので特に単純です。単に数独のルールを表現し,ヒントを解の制約として記述して,MATLABが解を求めます。

0 - 1整数計画アプローチ

基本となる方は,正方形の9行9列のグリッドを2进数号(0または1)の3次元9 x 9 x 9の配列にすることです.3次元配列を相互です积みられたたたたたたの正方形グリッドとしてますます考えレイヤーが整のの〜の正方形ます最の正方形レイヤー最グリッドグリッドははてがまたはさヒントとして位置に表示されている位置にに表示されているいに2番目のレイヤーは,解またはヒントとして2が表示されているにに

この定式は0 - 1整数計画法に適しています。

ここでは目的关节不合であり,定数项0である可能ありあり実ます解実际すべてのを満たすただしをに求めることをただしただし実际にことことの内部タイタイにことですののタイタイし,解を求める速度をを上させるため非定数据的关节使用し。

数独のルールを制約として記述する

x が9x 9 x 9のバイナリ配列で表されると仮定ますます。 x にはどのような特徴があるでしょうか。まず2次元グリッド(i, j)内の各四角形には厳密に1つの値が存在するので,3次元配列のエントリ x j 1 x j 9 にには厳密にににの非非ゼロ要素ががつまり。つまり,すべての および j について次のようになります。

k 1 9 x j k 1

同様に2次元グリッドの各行 には,1 ~ 9の各数値から厳密に1つの値が含まれます。つまり, k のそれぞれについて次のようになります。

j 1 9 x j k 1

さらに2次元グリッドの各列 j は同じ特徴になり, j k のそれぞれについて次のようになります。

1 9 x j k 1

主な3行3列のグリッドは同様をもちます。グリッドグリッド 1 3. 1 j 3. および 1 k 9 のそれぞれについて次のようになります。

1 3. j 1 3. x j k 1

9つの主なグリッドすべてを表すには,インデックス および j のそれぞれに3または6を加算します。

1 3. j 1 3. x + U j + V k 1 ここで, U V ε. 0 3. 6

ヒントを记述する

各初初(ヒント)は制约として记述することができ。ヒント j は, 1 9 に対して であると仮定します。すると, x j 1 になります。制約 k 1 9 x j k 1 によって, k に対して他はすべて x j k 0 になります。

最適化問題形式の数独

2値でサイズが9 x 9 x 9の最適化変数xを作物成し。

x = optimvar (“x”,9,9,9,“类型”'整数'下界的0,“UpperBound”,1);

やや適当な目的関数で最適化問題を作成します。この目的関数は,問題に内在する対称性を破壊することで,ソルバーの役に立つ場合があります。

sudpuzzle = optimproblem;mul = 1 (1, 1, 9);mul = cumsum (mul 3);sudpuzzle。目标=总和(金额(金额(x, 1), 2)。* mul);

各座标方向のxの和が1になるというを表し表します表し表しますますます。

sudpulzle.constraints.consx = sum(x,1)== 1;sudpulzle.constraints.consy = sum(x,2)== 1;sudpuzzle.constraints.consz = sum(x,3)== 1;

同様に主なグリッドの和の合計が1になるという制約を作成します。

majorg = optimconstr(3、3、9);u = 1:3v = 1:3 arr = x(3 *(u-1)+1:3 *(u-1)+ 3,3 *(v-1)+1:3 *(v-1)+3 ,:);majorg(u,v,:) = sum(sum(arr,1),2)== a(1,1,9);结束结束sudpuzzle.Constraints.majorg = majorg;

ヒントエントリで下限を1に设定して,初期ヒントを含めます。この设定により,対応するエントリの値が1に固定されるため,各ヒント値での解がヒントエントリに设定されます。

U = 1:尺寸(b,1)x.lowerbound(b(u,1),b(u,2),b(u,3))= 1;结束

数独パズルを解きます。

sudsoln =解决(sudpuzzle)
使用intlinprog解决问题。LP:最佳目标值为405.000000。找到最优解。Intlinprog在根节点停止,因为客观值在最优值options的间隙公差范围内。AbsoluteGapTolerance = 0(默认值)。intcon变量是在公差选项内的整数。IntegerTolerance = 1e-05(默认值)。
sudsoln =结构体字段:x (9 x9x9双):

すべてのエントリが確実に整数になるように解を丸め,解を表示します。

sudsoln。x=round(sudsoln.x); y = ones(size(sudsoln.x));k = 2:9 y(:,:,k)= k;每个深度k的%乘数结束S = sudsoln.x。* y;%乘以每个条目的深度s =总和(s,3);% S是9乘9的,并持有已解决的谜题drawSudoku (S)

解が正しいかどうかを容易に確認できます。

数独パズルを描画する関数

类型drawSudoku
function drawSudoku(B) % function for drawing the Sudoku board %公司图;坚持;轴,轴平等%准备画矩形(“位置”,[0 0 9 9],“线宽”,3,“剪裁”,“关闭”)%外边界矩形(“位置”,[3 0 3 9],“线宽”,2)%沉重的竖线矩形(“位置”,[3]0、3、9日,“线宽”,2)%沉重的水平线矩形(“位置”,[1]0 1 9日,“线宽”,1)%小横线矩形(“位置”,[1]0、4、9日,“线宽”,1)矩形(“位置”,[1]0、7、9日,“线宽”,1)矩形(“位置”,[1,0,1,9],“线宽”,1)%小竖线矩形(“位置”,[4 0 1 9],“线宽”,1)矩形(“位置”,[7,0,1,9],“线宽”,1)% % % B的行填写线索的形式(i, j, k),我是%的行数上面,j是列,k是线索。要将条目放入%框中,j是水平距离,10-i是垂直距离,%减去0.5使线索在框中居中。% %如果B是一个9 × 9的矩阵,如果size(B,2) == 9 % 9 columns [SM,SN] = meshgrid(1:9);% make i,j entries B = [SN(:),SM(:),B(:)];% i,j,k row end for ii = 1:size(B,1) text(B(ii,2)-0.5, 3.5 -B(ii,1),num2str(B(ii,3)) end hold off end .(如果你的操作失败,你的操作会失败。

関連するトピック