1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | % % Magic square integer programming version in MiniZinc. % % From GLPK:s example magic.mod % """ % MAGIC, Magic Square % % Written in GNU MathProg by Andrew Makhorin <mao@mai2.rcnet.ru> % % In recreational mathematics, a magic square of order n is an % arrangement of n^2 numbers, usually distinct integers, in a square, % such that n numbers in all rows, all columns, and both diagonals sum % to the same constant. A normal magic square contains the integers % from 1 to n^2. % % (From Wikipedia, the free encyclopedia.) % """ % % This MiniZinc model was created by Hakan Kjellerstrand, hakank@gmail.com % See also my MiniZinc page: http://www.hakank.org/minizinc % % Licenced under CC-BY-4.0 : http://creativecommons.org/licenses/by/4.0/ % square order int : n = 3; % integers to be placed set of 1 .. n * n: N = 1 .. n * n; % x[i,j,k] = 1 means that cell (i,j) contains integer k array [1 .. n, 1 .. n, N] of var 0 .. 1: x; array [1 .. n, 1 .. n] of var 1 .. n * n: square; var int : s; % the magic sum solve :: int_search( [x[i,j,k] | i,j in 1 .. n, k in N] ++ [square[i,j] | i,j in 1 .. n] ++ [s], first_fail, indomain_min, complete % "credit(640, bbs(5))" % "complete" ) satisfy ; constraint s >= 0 /\ s <= n * n * n /\ % each cell must be assigned exactly one integer forall(i in 1 .. n, j in 1 .. n) ( sum (k in N) (x[i,j,k]) = 1 ) /\ % each integer must be assigned exactly to one cell forall(k in N) ( sum (i in 1 .. n, j in 1 .. n) (x[i,j,k]) = 1 ) /\ % the sum in each row must be the magic sum forall(i in 1 .. n) ( sum (j in 1 .. n, k in N) (k * x[i,j,k]) = s ) /\ % the sum in each column must be the magic sum forall(j in 1 .. n) ( sum (i in 1 .. n, k in N) (k * x[i,j,k]) = s ) /\ % the sum in the diagonal must be the magic sum sum (i in 1 .. n, k in N) (k * x[i,i,k]) = s /\ % the sum in the co-diagonal must be the magic sum sum (i in 1 .. n, k in N) (k * x[i,n - i + 1,k]) = s /\ % for output forall(i,j in 1 .. n) ( square[i,j] = sum (k in N) (k * x[i,j,k])) ; output [ "\ns: " , show (s) ] ++ [ if j = 1 then "\n" else " " endif ++ show (square[i,j]) | i,j in 1 .. n ] ++ [ "\n" ]; % printf "\n"; % printf "Magic sum is %d\n", s; % printf "\n"; % for{i in 1..n} % { printf{j in 1..n} "%3d", sum{k in N} k * x[i,j,k]; % printf "\n"; % } % printf "\n"; |