MiniZinc Tutorial by Ralph Becket
MiniZinc Tutorial by Ralph Becket
MiniZinc Tutorial by Ralph Becket
Ralph Becket
[email protected]
18 June 2007
1 Modelling in MiniZinc
A Golomb ruler R is a set of integers such that all pairwise differences are
different — that is, ∀ distinct a, b, c, d ∈ R.(a − b) = (c − d) ⇒ (a, b) = (c, d).
Figure 1 shows a MiniZinc model of the problem (line numbers in the figure
are there for reference and should not be included in the model file) and
1
1 MODELLING IN MINIZINC 2
1 % Golomb rulers.
2
3 include "globals.mzn";
4
5 int: n = 4;
6
7 array [1..n] of var 0..(n * n): mark;
8
9 constraint mark[1] = 0;
10 constraint forall (i in 1..(n - 1)) (mark[i] < mark[i + 1]);
11 constraint
12 all_different (i in 1..n, j in (i + 1)..n) (mark[j] - mark[i]);
13
14 solve minimize mark[n];
15
16 output ["golomb: ", show(mark)];
the output from evaluating it with the zinc interpreter. Let’s examine the
model in more detail.
Line 1 is a comment. Comments begin with % and extend to the end of the
line. Comments can occur anywhere in a model.
Line 3 includes the standard MiniZinc library file globals.mzn, which de-
fines various global constraints (such as all_different used on line 12). All
MiniZinc items that are not comments must be terminated with a semicolon.
Line 14 specifies the problem goal: to find values for the mark ar-
ray such that the last is minimized (the other possible solve goals are
solve maximize mark[n]; or solve satisfy; which looks for any solu-
tion).
Line 16 specifies how to print a solution if one is found. The function show
converts its argument into a printable string. If a solution cannot be found
then No solution will be printed instead. Omitting the output item will
cause all of the variables in a model to be printed, one per line, if a solution
is found.
Assuming that the model lives in the file golomb.mzn (note that all files that
contain MiniZinc models must have the extension ”.mzn”), we can convert
it to FlatZinc as follows:
$ mzn2fzn golomb.fzn
If the model contains errors then mzn2fzn will report them, otherwise it will
output a FlatZinc version of golomb.mzn in the file golomb.fzn. (FlatZinc
files must have the extension ”.fzn”.)
We can then evaluate the model using a FlatZinc interpreter. The G12
FlatZinc interpreter is called flatzinc . It is invoked as follows:
$ flatzinc golomb.fzn
[ 0, 1, 4, 6 ]
The model uses convenient syntactic sugar for the forall and all_different
constraints. In fact, both of these constraints take a single array argument.
The form
1 MODELLING IN MINIZINC 4
Similarly
all_different([
mark[2] - mark[1], mark[3] - mark[1], mark[4] - mark[1],
mark[3] - mark[2], mark[2] - mark[2],
mark[4] - mark[3]]);
You can use the special syntactic sugar in any expression where a function
symbol is applied to a single array.
Figure 1 shows a MiniZinc model of the problem (line numbers in the figure
are there for reference and should not be included in the model file) and
the output from evaluating it with the zinc interpreter. Let’s examine the
model in more detail.
1 MODELLING IN MINIZINC 5
1 % Sudoku solver.
2
3 include "globals.mzn";
4
5 array [1..9, 1..9] of var 1..9: sq;
6
7 predicate row_diff(int: r) =
8 all_different (c in 1..9) (sq[r, c]);
9
10 predicate col_diff(int: c) =
11 all_different (r in 1..9) (sq[r, c]);
12
13 predicate subgrid_diff(int: r, int: c) =
14 all_different (i, j in 0..2) (sq[r + i, c + j]);
15
16 constraint forall (r in 1..9) (row_diff(r));
17 constraint forall (c in 1..9) (col_diff(c));
18 constraint forall (r, c in {1, 4, 7}) (subgrid_diff(r, c));
19
20 sq = [
21 _, _, _, _, _, _, _, _, _,
22 _, 6, 8, 4, _, 1, _, 7, _,
23 _, _, _, _, 8, 5, _, 3, _,
24 _, 2, 6, 8, _, 9, _, 4, _,
25 _, _, 7, _, _, _, 9, _, _,
26 _, 5, _, 1, _, 6, 3, 2, _,
27 _, 4, _, 6, 1, _, _, _, _,
28 _, 3, _, 2, _, 7, 6, 9, _,
29 _, _, _, _, _, _, _, _, _
30 ];
31
32 solve satisfy;
33
34 output ["sq = ", show(sq)];
Line 5 defines sq, a two dimensional array of squares, indexed by row and
column number respectively, of integer variables in the range 1..9.
Line 32 tells the solver to search for any solution and halt.
Running the model we get the following solution (which has been tidied up
for visual effect):
$ zinc sudoku.mzn
sq =
[ 5, 9, 3, 7, 6, 2, 8, 1, 4,
2, 6, 8, 4, 3, 1, 5, 7, 9,
7, 1, 4, 9, 8, 5, 2, 3, 6,
3, 2, 6, 8, 5, 9, 1, 4, 7,
1, 8, 7, 3, 2, 4, 9, 6, 5,
4, 5, 9, 1, 7, 6, 3, 2, 8,
9, 4, 2, 6, 1, 8, 7, 5, 3,
8, 3, 5, 2, 4, 7, 6, 9, 1,
6, 7, 1, 5, 9, 3, 4, 8, 2 ];
1 % Perfect squares.
2
3 int: n = 10; % Consider squares up to n*n.
4 array [0..n] of 0..n*n: sq = [y*y | y in 0..n];
5 array [0..n] of var 0..n: s; % Decreasing indices into sq.
6 var 0..n: x; % Compute sum equal to sq[x]
7 var 0..n: j; % from this many sub-squares.
8
9 constraint forall (i in 1..n) (s[i] > 0 -> s[i - 1] > s[i]);
10 constraint s[0] < x;
11 constraint sum (i in 0..n) (sq[s[i]]) = sq[x];
12 constraint s[j] > 0;
13
14 solve maximize j;
15
16 output [
17 "x = ", show(x), "\n",
18 "s = ", show(s)
19 ];
Figure 3: MiniZinc model for computing squares equal to the sum of distinct
smaller squares.
1 MODELLING IN MINIZINC 8
Figure 3 shows a MiniZinc model for computing perfect squares. Let’s ex-
amine the model in more detail.
Line 3 fixes an upper bound n on the number of squares the model will
consider.
Line 5 defines an array s of variables, each being an index into the array sq
(we are going to compute x2 = i ∈ 0..n sq[s[i]] — this is our encoding
P
Line 14 requires the solver to find the largest set S given the bound n.
x = 10
s = [ 7, 5, 4, 3, 1, 0, 0, 0, 0, 0, 0 ]
Lines 3 and 4 define two integer sets giving symbolic names to each product
and resource kind.
Lines 7 to 9 define arrays giving the expected demand, the in-house pro-
duction cost, and the outsourcing production cost for each product. Note
that we can use set expressions (products in this case) as the index sets for
arrays. Note also that in MiniZinc floating point constants must include a
fractional part: 42 is an int; 42.0 is a float.
Line 17 defines an array giving the available stocks of each resource kind.
Lines 20 and 21 define arrays of problem variables for the amount of each
product to manufacture in-house and outsource respectively.
Lines 28 to 32 state that in-house production cannot use more than the
available resource stocks.
1 % Contrived problem.
2
3 include "globals.mzn";
4
5 var 0..9: x;
6 var 0..9: y;
7 var 0..9: z;
8
9 constraint all_different([x, y, z]);
10 constraint y - 3 < x /\ x < y + 3;
11 constraint z - 3 < y /\ y < z + 3;
12
13 solve satisfy;
14
15 output ["x = ", show(x), "; ",
16 "y = ", show(y), "; ",
17 "z = ", show(z)];
Consider the contrived problem model in figure 5 which states that x must
be within 3 of y, y must be within 3 of z, and all three variables must
be distinct in the range 0..9 (observe the use of the logical conjunction
operator /\ which isn’t strictly necessary — conjunctions can be split into
separate constraints — but does improve readability here).
solve
:: int_search([x, y, z], "first_fail", "indomain_median", "complete")
satisfy;
1 MODELLING IN MINIZINC 12
we get x = 5; y = 6; z = 7 .
Multiple annotations can appear and are carried out in the given order. For
example, with:
solve
:: int_search([x], "first_fail", "indomain_median", "complete")
:: int_search([y, z], "smallest", "indomain_max", "complete")
satisfy;
we get x = 5; y = 7; z = 9; .
Bugs can reported via the G12 bug tracking system at bugs.g12.csse.unimelb.edu.au.
Comments, questions and suggestions should be sent to the G12 Users mail-
ing list. You can subscribe to the list by sending an e-mail containing the
word subscribe in the body to [email protected].
Thereafter, mail may be sent to [email protected].