Sudoku is a popular logic and number-based game. Players need to deduce the numbers for all the remaining empty spaces on a 9x9 grid based on the known numbers on the grid. The goal is to ensure that each row, column, and 3x3 sub-grid contains all the numbers from 1 to 9 without repetition. An example of a Sudoku puzzle is shown below:
The solution of the Sudoku problem can also be modeled as a mathematical programming problem.
To do so, we introduce the following decision variables and constraints:
Based on the discussion above, we can establish the following mathematical programming model for solving Sudoku problems:
MindOpt Algebraic Programming Language (MindOpt APL or MAPL) is an efficient algebraic modeling language for optimization. It supports a variety of solvers.
When solving a Sudoku problem, MAPL can model it as shown below:
Among them, use fixed.txt
to give the known numbers and positions for the puzzle in Figure 1.
The * fixed.txt
sudoku.mapl
file can be viewed in the MindOpt Studio Sudoku case.
clear model; #Used when running multiple times to clear the model
option modelname model/sudoku; #link the model file
#--------------------------
# sudoku.mapl
# Declaring sets
set I := {0 .. 8};
set J := {0 .. 8};
set K := {1 .. 9};
set M := {0,1,2};
set N := {0,1,2};
set S := {0,1,2};
set F := { read "./model/sudoku_fixed.txt" as "<1n, 2n, 3n>" }; # Read in the given numbers and positions
# Declaring Variables
var x[I * J * K] binary;
# Declaring constraints
subto Value_Range:
forall {(i,j) in I * J } sum {k in K} x[i,j,k] == 1;
subto Rows:
forall {(i,k) in I * K } sum {j in J} x[i,j,k] == 1;
subto Cols:
forall {(j,k) in J * K } sum {i in I} x[i,j,k] == 1;
subto Cells:
forall {m in M,n in N,k in K}sum{i in S,j in S} x[3*m+i,3*n+j,k] == 1;
subto Fixed:
forall {(i,j,k) in F } x[i,j,k] == 1;
#------------------------------
print "Check the model, such as F:";
print F;
print "==================Solve using MindOpt Solver==================";
option solver mindopt; # select the MindOpt solver
solve;
# Change the solver
#print "==================Solve using Cbc Solver==================";
#option solver cbc; # select the Cbc solver
#solve;
Users can also create a blank document using any text editor and save modeling codes as a sudoku.mapl
file.
Then, run the following code to proceed with the modeling. Here, we can also change the solver to COIN-OR Cbc.
clear model; #Used when running multiple times to clear the model
#------------------------------
model model/sudoku.mapl; # modeling
#------------------------------
print "Check the model, such as F:";
print F;
#print "==================Solve using MindOpt Solver==================";
#option solver mindopt; # select the MindOpt solver
#solve;
# Change the solver
print "==================Solve using Cbc Solver==================";
option solver cbc; # select the Cbc solver
solve;
The results of Method 1 and Method 2 are consistent:
Check the model, such as F:
Multi: |3|{<0,1,2>,<0,4,8>,<0,7,7>,<1,1,7>,<1,0,4>,<1,5,9>,<2,7,2>,<2,5,3>,<2,6,5>,<3,1,9>,<3,6,1>,<3,2,2>,<3,3,3>,<4,1,1>,<4,4,7>,<4,7,3>,<4,8,5>,<5,5,5>,<5,6,6>,<5,2,7>,<5,3,9>,<6,0,7>,<6,6,2>,<6,2,4>,<6,8,6>,<7,4,3>,<7,5,4>,<7,3,6>,<8,4,9>,<8,7,5>,<8,0,6>,<8,8,3>}
==================Solve using MindOpt Solver==================
Running mindoptampl
wantsol=1
MindOpt Version 0.25.1 (Build date: 20230816)
Copyright (c) 2020-2023 Alibaba Cloud.
Start license validation (current time : 24-AUG-2023 16:16:38).
License validation terminated. Time : 0.005s
Model summary.
- Num. variables : 729
- Num. constraints : 324
- Num. nonzeros : 2916
- Num. integer vars. : 697
- Bound range : [1.0e+00,1.0e+00]
- Objective range : [0.0e+00,0.0e+00]
Branch-and-cut method started.
Original model: nrow = 324 ncol = 729 nnz = 2916
Tolerance: primal = 1e-06 int = 1e-06 mipgap = 0.0001 mipgapAbs = 1e-06
Limit: time = 1.79769313486232e+308 node = -1 stalling = -1 solution = -1
presolver terminated; took 1 ms
presolver terminated; took 5 ms
Branch-and-cut method terminated. Time : 0.015s
OPTIMAL; objective 0.00
Completed.
-------------------------------------------------
Check the model, such as F:
Multi: |3|{<0,1,2>,<0,4,8>,<0,7,7>,<1,1,7>,<1,0,4>,<1,5,9>,<2,7,2>,<2,5,3>,<2,6,5>,<3,1,9>,<3,6,1>,<3,2,2>,<3,3,3>,<4,1,1>,<4,4,7>,<4,7,3>,<4,8,5>,<5,5,5>,<5,6,6>,<5,2,7>,<5,3,9>,<6,0,7>,<6,6,2>,<6,2,4>,<6,8,6>,<7,4,3>,<7,5,4>,<7,3,6>,<8,4,9>,<8,7,5>,<8,0,6>,<8,8,3>}
==================Solve using Cbc Solver==================
Running cbc
CBC 2.10.5Completed.
We can use display;
to print the solution. In this case, it displays a lot of content, and multiple runs may make the Notebook kernel busy and stop. If this happens, you can click the restart arrow circle button (located near the play button) above to restart the kernel.
We can also use print
and def
to print a beautiful 9x9 grid.
print "-----------------Display---------------";
#display; # this will print too much, if you need run, uncomment it
print "-----------Location and value of the non-zero variables-----------";
#forall {<i,j,k> in I*J*K with x[i,j,k] >= 1} print 'x[{},{}] = {}' % i,j,k; # this will print too much, if you need run, uncomment it
print "-----------------The 9*9 grid---------------";
# print the 9x9 grid with `def`
# get the location and value set of non-zero variables
def nonzero(m,n) = {<i,j,k> in I*J*K with m == i and n == j and x[i,j,k] >= 1};
# get the value of k
def get_num(m,n) = sum {<i, j, k> in nonzero(m,n)} k;
print "\\ | 0 1 2 | 3 4 5 | 6 7 8 ";
forall {i in 0..8}
if i mod 3 != 0 then print "{} | {} {} {} | {} {} {} | {} {} {}" % i, get_num(i,0), get_num(i,1), get_num(i,2), get_num(i,3), get_num(i,4), get_num(i,5), get_num(i,6), get_num(i,7), get_num(i,8)
else print "--+-------+-------+-------
{} | {} {} {} | {} {} {} | {} {} {}" % i, get_num(i,0), get_num(i,1), get_num(i,2), get_num(i,3), get_num(i,4), get_num(i,5), get_num(i,6), get_num(i,7), get_num(i,8);
The running result is listed below:
-----------------Display---------------
-----------Location and value of the non-zero variables-----------
-----------------The 9*9 grid---------------
\ | 0 1 2 | 3 4 5 | 6 7 8
--+-------+-------+-------
0 | 9 2 5 | 1 8 6 | 3 7 4
1 | 4 7 3 | 5 2 9 | 8 6 1
2 | 1 6 8 | 7 4 3 | 5 2 9
--+-------+-------+-------
3 | 5 9 2 | 3 6 8 | 1 4 7
4 | 8 1 6 | 4 7 2 | 9 3 5
5 | 3 4 7 | 9 1 5 | 6 8 2
--+-------+-------+-------
6 | 7 3 4 | 8 5 1 | 2 9 6
7 | 2 5 9 | 6 3 4 | 7 1 8
8 | 6 8 1 | 2 9 7 | 4 5 3
The answer to this Sudoku puzzle is shown below:
MindOpt - August 24, 2023
MindOpt - August 29, 2023
MindOpt - August 29, 2023
MindOpt - August 29, 2023
Alibaba Cloud Community - September 1, 2023
anycode - November 3, 2021
Alibaba Cloud provides beginners and programmers with online course about cloud computing and big data certification including machine learning, Devops, big data analysis and networking.
Learn MoreFully managed, locally deployed Alibaba Cloud infrastructure and services with consistent user experience and management APIs with Alibaba Cloud public cloud.
Learn MoreAn enterprise-level continuous delivery tool.
Learn More