主要内容

通过整数规划解决数独谜题:具体问题具体分析

这个例子展示了如何使用二进制整数规划解决数独谜题。solver-based方法,请参阅通过整数规划解决数独谜题:Solver-Based

你可能已经看到数独谜题。一个谜是9-by-9网格填充整数从每个整数1到9这只有一次出现在每一行,列,3×3的广场和主要。网格部分填充的线索,你的任务是填写其余的网格。

最初的难题

这是一个数据矩阵B的线索。第一行,B (1、2、2),意味着第一行,第二列有一个线索2。第二行,B (1、5、3),意味着第一行、列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生成解决方案。

二进制整数规划方法

关键思想是把一个难题从正方形网格9-by-9立方9-by-9-by-9数组的二进制值(0或1)。认为立方阵列是9平方网格堆叠在彼此之上,在每一层都对应于一个从1到9的整数。网格顶部,一个正方形的数组,有1无论解决方案或线索有1。第二层有1无论解决方案或线索有2。第九层有1无论解决方案或线索有9。

这个配方正是适合二进制整数规划。

这里不需要目标函数,也可能是一个常数项0。问题是真的找到一个可行的解决方案,意义一个满足所有的约束。然而,对于领带打破内部的整数规划求解,给出解决方案的速度增加,使用一个非常数的目标函数。

数独游戏的规则表示为约束条件

假设一个解决方案 x 表示在一个9-by-9-by-9二进制数组。什么属性 x 有什么?首先,每平方的二维网格(i, j)正好有一个值,这就是一个非零元素的三维数组条目 x ( , j , 1 ) , , x ( , j , 9 ) 。换句话说,每一个 j ,

k = 1 9 x ( , j , k ) = 1

同样,在每一行 二维网格,正是一个值的每个数字从1到9。换句话说,对于每个 k ,

j = 1 9 x ( , j , k ) = 1

和每一列 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个主要网格,就加3或6 j 指数:

= 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 确保所有其他 x ( , j , k ) = 0 k

数独在优化问题的形式

创建一个优化变量x9-by-9-by-9二进制和的大小。

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在每一个坐标方向。

sudpuzzle.Constraints。consx =总和(x, 1) = = 1;sudpuzzle.Constraints。consy =总和(x, 2) = = 1;sudpuzzle.Constraints。consz =总和(x, 3) = = 1;

创建约束,总结主要的网格和一个。

majorg = optimconstr (3、3、9);u = 1:3v = 1:3 arr = x (3 * (u-1) + 1:3 * (u-1) + 3, 3 *(它们)+ 1:3 *(它们)+ 3:);:majorg (u, v) =总和(和(arr, 1), 2) = = 1 (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停在根节点,因为客观价值差距公差内的最优值,选择。AbsoluteGapTolerance = 0。在宽容intcon变量是整数,选项。IntegerTolerance = 1 e-05。
sudsoln =结构体字段:x (9 x9x9双):

的解决方案,以确保所有条目是整数,并显示解决方案。

sudsoln。x=round(sudsoln.x); y = ones(size(sudsoln.x));k = 9 y (:,:, k) = k;%的乘数为每个深度k结束S = sudsoln.x。* y;%每个条目乘以它的深度S =(年代,3)总和;% S 9-by-9和解决难题drawSudoku (S)

你可以很容易地检查解决方案是正确的。

函数把数独谜题

类型drawSudoku
函数drawSudoku (B) %函数图数独板%版权2014年MathWorks公司图;坚持;轴,轴平等%准备画矩形(“位置”,[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是水平距离,我是垂直距离,和%减去0.5中心盒子里的线索。% %如果B是一个9-by-9矩阵,将其转换为3列第一如果大小(B, 2) = = 9% (SM, SN) = 9列meshgrid (1:9);B = %让i, j条目(SN:, SM (:), B ()):;% i, j, k行结束2 = 1:尺寸(B, 1)文本(B (2, 2) -0.5、9.5 - B (ii, 1), num2str (B(2, 3)))推迟结束结束

相关的话题