I am running the first MiniZinc example in the Handbook, coloring the states and territories of Australia. It runs fine as written.
% Colouring Australia using nc colours
int: nc = 3;
var 1..nc: wa; var 1..nc: nt; var 1..nc: sa; var 1..nc: q;
var 1..nc: nsw; var 1..nc: v; var 1..nc: t;
constraint wa != nt;
constraint wa != sa;
constraint nt != sa;
constraint nt != q;
constraint sa != q;
constraint sa != nsw;
constraint sa != v;
constraint q != nsw;
constraint nsw != v;
solve satisfy;
output ["wa=\(wa)\t nt=\(nt)\t sa=\(sa)\n",
"q=\(q)\t nsw=\(nsw)\t v=\(v)\n",
"t=", show(t), "\n"];
But when I change nc
(the number of colors) to be a decision variable (change int: nc = 3;
to be var 1..10: nc;
) and change solve satisfy;
to be solve minimize nc;
I get an error message saying
MiniZinc: type error: type-inst must be par set but is `var set of int'
I was hoping that MiniZinc would tell me the minimum number of colors needed.
What should I do to get the minimum number of colors?
UPDATE: I found one way to get the answer I want. I added the following.
array[1..7] of var int: ts = [wa, nt, sa, q, nsw, v, t];
var int: min_nc = max(ts);
solve minimize min_nc;
Is there a better way?
This issue occurs because of the declaration of the other variable declarations. They are declared as var 1..nc: X;
. However, now that nc
is a variable, the set 1..nc
becomes a variable as well.
In MiniZinc, it is not allowed to declare an integer variable using a variable set as its domain. (Maybe this feature will be added in the future). What we can do instead is add all variables using the largest domain possible and then restrict it to be within the allowed values. The full model would look like this:
% Colouring Australia using nc colours
var 1..10: nc;
var 1..ub(nc): wa; var 1..ub(nc): nt; var 1..ub(nc): sa; var 1..ub(nc): q;
var 1..ub(nc): nsw; var 1..ub(nc): v; var 1..ub(nc): t;
constraint wa <= nc; % or "wa in 1..nc"
constraint nt <= nc;
constraint sa <= nc;
constraint q <= nc;
constraint nsw <= nc;
constraint v <= nc;
constraint t <= nc;
constraint wa != nt;
constraint wa != sa;
constraint nt != sa;
constraint nt != q;
constraint sa != q;
constraint sa != nsw;
constraint sa != v;
constraint q != nsw;
constraint nsw != v;
solve minimize nc;
output ["colours=\(nc)\nwa=\(wa)\t nt=\(nt)\t sa=\(sa)\n",
"q=\(q)\t nsw=\(nsw)\t v=\(v)\n",
"t=", show(t), "\n"];
Note that ub(nc)
is the upper bound of nc
, the highest possible value nc
will take, in this case 10.