Download
# Licenced under CC-BY-4.0 : http://creativecommons.org/licenses/by/4.0/
MAIN MODEL Main_MagicSquare
DECLARATION SECTION
PARAMETER:
identifier : N
initial data : 4 ;
PARAMETER:
identifier : N2
definition : N*N ;
PARAMETER:
identifier : UseSymmetry1
range : binary
initial data : 0
comment : "To use the constraint Symmetry1 or not." ;
PARAMETER:
identifier : UseSymmetry2
range : binary
initial data : 0 ;
PARAMETER:
identifier : UseSymmetry3
range : binary
initial data : 0 ;
PARAMETER:
identifier : UseSymmetry4
range : binary
initial data : 0 ;
PARAMETER:
identifier : UseFreeTotal
range : binary
initial data : 0
comment : "If Total should be = TotalP or calculated." ;
SET:
identifier : ij
subset of : Integers
indices : i, j
definition : ElementRange(1,N) ;
VARIABLE:
identifier : x
index domain : (i,j)
range : {1..N2} ;
CONSTRAINT:
identifier : Alldifferent
definition : cp::AllDifferent((i,j), x(i,j)) ;
VARIABLE:
identifier : Total
range : {0..inf} ;
VARIABLE:
identifier : NumSolutions
range : integer
definition : GMP::Solution::Count('MagicSquarePlan') ;
PARAMETER:
identifier : TotalP
definition : ( N * (N*N + 1)) / 2 ;
CONSTRAINT:
identifier : EqTotals
definition : if (not UseFreeTotal) then
Total = TotalP
endif ;
CONSTRAINT:
identifier : Sum1
index domain : i
definition : Sum(j, x(i,j)) = Total ;
CONSTRAINT:
identifier : Sum2
index domain : (j)
definition : Sum(i, x(i,j)) = Total ;
CONSTRAINT:
identifier : SumDiagonal1
definition : Sum(i, x(i,i)) = Total ;
CONSTRAINT:
identifier : SumDiagonal2
definition : Sum(i, x(i,N-i-1)) = Total ;
CONSTRAINT:
identifier : Symmetry1
definition : if (UseSymmetry1) then
x(1,1) = 1
endif ;
CONSTRAINT:
identifier : Symmetry2
definition : if (UseSymmetry2) then
x(1,1) < x(1,N)
endif ;
CONSTRAINT:
identifier : Symmetry3
definition : if (UseSymmetry3) then
x(1,N) < x(N,1)
endif ;
CONSTRAINT:
identifier : Symmetry4
definition : if (UseSymmetry4) then
x(1,1) < x(N,N)
endif ;
MATHEMATICAL PROGRAM:
identifier : MagicSquarePlan
direction : minimize
constraints : AllConstraints
variables : AllVariables
type : CSP ;
ENDSECTION ;
PROCEDURE
identifier : MainInitialization
ENDPROCEDURE ;
PROCEDURE
identifier : MainExecution
body :
ShowProgressWindow;
solve MagicSquarePlan;
NumSolutions:=GMP::Solution::Count('MagicSquarePlan');
if (MagicSquarePlan.ProgramStatus <> 'Optimal') then
empty x, Total;
endif;
DialogMessage(NumSolutions + " solutions");
ENDPROCEDURE ;
PROCEDURE
identifier : MainTermination
body :
if ( CaseSaveAll( confirm:2 ) = 1 ) then
return 1;
else
return 0;
endif ;
ENDPROCEDURE ;
ENDMODEL Main_MagicSquare ;