Description
This MIP model finds the maximum number of knights that can be placed on a board. Two different formulations are presented. The second formulation is 'tight' and may perform better with certain MIP codes. Once we found the max number of knights, we solve a series of MIPs to find ALL solutions. We will use lags (relative positions) to describe the allowed moves. The labels H and V indicate horizontal and vertical moves as shown below: 0 0 0 0 X 0 0 0 0
Large Model of Type : MIP
Category : GAMS Model library
Main file : knights.gms
$title Maximum Knights Problem (KNIGHTS,SEQ=158)
$onText
This MIP model finds the maximum number of knights that can be
placed on a board. Two different formulations are presented.
The second formulation is 'tight' and may perform better with certain
MIP codes. Once we found the max number of knights, we solve a series
of MIPs to find ALL solutions.
We will use lags (relative positions) to describe the allowed moves.
The labels H and V indicate horizontal and vertical moves as shown
below:
0 0
0 0
X
0 0
0 0
Dudeney, H E, Amusements in Mathematics. Dover, New York, 1970.
Keywords: mixed integer linear programming, maximum knights problem, mathematics
$offText
Set
i 'size of board' / 1*8 /
n 'number of possible moves' / m1*m8 /;
Alias (i,j,k);
Table move(*,n) 'all possible knight moves'
m1 m2 m3 m4 m5 m6 m7 m8
H -2 -2 -1 -1 +1 +1 +2 +2
V -1 +1 -2 +2 -2 +2 -1 +1;
Variable total;
Binary Variable x(i,j);
Equation
deftotal 'total knights on board'
defmove(i,j) 'move restrictions'
defmovex(n,i,j) 'move restrictions';
deftotal.. total =e= sum((i,j), x(i,j));
defmove(i,j).. sum(n, x(i + move('h',n),j + move('v',n))) =l= card(i)*(1 - x(i,j));
defmovex(n,i,j).. x(i + move('h',n),j + move('v',n)) =l= 1 - x(i,j);
Model
knight / deftotal, defmove /
knightx / deftotal, defmovex /;
option optCr = 0, optCa = .999;
solve knight using mip max total;
solve knightx using mip max total;
* Now we try to see how many different ways are there to arrange
* the same number of knights.
Scalar maxknight;
maxknight = total.l;
total.lo = total.l - 0.5;
option optCr = 1, optCa = 100, limCol = 0, limRow = 0, solPrint = off;
Set
ss 'max number of solutions groups' / seq1*seq20 /
s(ss) 'dynamic set for solution groups';
Parameter cutval 'all possible solutions for cut generation';
Equation cut(ss) 'known solutions to be eliminated';
cut(s).. sum((i,j), cutval(s,i,j)*x(i,j)) =l= maxknight - 1;
Model knight1 / deftotal, defmovex, cut /;
s(ss) = no;
total.lo = maxknight - .5;
knight1.solveStat = %solveStat.normalCompletion%;
knight1.modelStat = %modelStat.optimal%;
loop(ss$(knight1.solveStat = %solveStat.normalCompletion% and
(knight1.modelStat = %modelStat.optimal% or
knight1.modelStat = %modelStat.integerSolution%)),
s(ss) = yes;
cutval(ss,i,j) = x.l(i,j);
solve knight1 maximizing total using mip;
);
option cutval:0:0:1;
display cutval;