3

Is there a possibility to tell MiniZinc to project solutions on a subset of the set of variables? Or is there any other way to enumerate all solutions that are unique wrt to evaluation of some subset of variables?

I have tried to use FlatZinc annotations directly in MiniZinc, but it does not work, since the flattening process adds more defines_var annotations and my annotations are ignored.

jschimpf
  • 4,904
  • 11
  • 24
kostya
  • 33
  • 3
  • Would you mind give a concrete example of what you want to do? Both in term of the problem and the solutions you want to generate. – hakank Jul 25 '14 at 04:34
  • Assume there is a CSP instance where V={v1,v2,v3}, domains D={d1,d2,d3} st d1=d2=d3={1,2,3} and C=\emptyset. The solver will generate a set of solutions comprising 27 possible combinations. Now, the value of variable v3 is not important, but only the fact the domain of the variable is not empty after propagation. A projection of all solutions to the set {v1,v2} will return only 9 combinations. Does this clarify the problem? – kostya Jul 25 '14 at 13:24
  • ASP solvers implement this feature on the solver level. E.g. clingo 4: --project[=] : Project models to named atoms – kostya Jul 25 '14 at 13:25
  • What I know, MiniZinc don't have any (direct) support for this. In certain situations it might be possible to project solutions via explicit constraints, e.g. setting a decision variable to a constant (something like symmetry breaking). Does it work as expected if you add annotations to the FlatZinc file? – hakank Jul 26 '14 at 07:47
  • Haven't tried FlatZinc yet, but I will. I think this might be possible, since flattering also introduces aux variables that are not in solutions, but considered by a solver. FlatZinc manual: "The defines_var annotation should appear on exactly one constraint. This allows a solver to represent x internally as a representation of y+z rather than as a separate constrained variable." – kostya Jul 26 '14 at 14:06
  • I have found something that looks quite useful in Minion. The manual states: "In each VarOrder an instantiation order is specified for a subset of variables. Variables can optionally be \"auxiliary variables\" (add \"AUX\" to the varorder) meaning that if there are several solutions to the problem differing only in the auxiliary variables, only one is reported by minion." – kostya Jul 26 '14 at 16:19
  • Dear Håkan, yes it works in FlatZinc when I model it with `defines_var` annotations. The only problem is that I cannot use MiniZink flattering and have to generate the program by some script. Nevertheless, thanks for readiness to help! – kostya Jul 26 '14 at 21:09
  • I updated my answer with a comment regarding how Gecode work. However, it seems that it's just Gecode that support this projection. – hakank Aug 03 '14 at 08:46
  • I tried a fresh version of or-tools and it returns a lot of duplicates. Anyway Gecode is a good choice for my project. Thank you for help. – kostya Aug 05 '14 at 06:42
  • I tested quite a few FlatZinc solvers on this and what I can see Gecode is the only FlatZinc solver that has this feature. – hakank Aug 05 '14 at 06:47

2 Answers2

3

I tried the following model in MiniZinc 2.0 (https://www.minizinc.org/2.0/index.html) and this seems to work as you expect, i.e. that just x1 and x2 are projected (printed) in the result.

int: n = 3;
var 1..n: x1;
var 1..n: x2;
var 1..n: x3;

solve satisfy;
constraint
  x3 > 1
;

output [  show([x1,x2])];

The result is:

[1, 1]
----------
[2, 1]
----------
[3, 1]
----------
[1, 2]
----------
[2, 2]
----------
[3, 2]
----------
[1, 3]
----------
[2, 3]
----------
[3, 3]
----------
==========

In MiniZinc v 1.6 x1 and x2 are printed repeatedly for each x3 value.

Update:

However, if x3 is involved in any constraints (in any interesting way) it seems to be the same behaviour as in version 1.6. And that's probably not what you want...

Update2:

I asked one of the developers of Gecode about this and he answered:

Regarding the projection semantics, this really depends on the solver. Gecode for instance should not produce duplicate solutions (based on what is mentioned in the output statement), whereas g12fd does, AFAIK. So the answer would be that projection is defined by the output item, but only some solvers guarantee uniqueness.

When we tested this, we found a bug in Gecode that didn't comply with the answer. This is now fixed (in the SVN version).

The following model how just give distinct answers for x1 and x2 (using the fixed Gecode version):

int: n = 5;

var 1..n: x1;
var 1..n: x2;
var 1..n: x3;

solve satisfy;

constraint
   x2 + x1 < 5 /\
   x2 +x3 > x1
;

output [  "x:", show([x1,x2])];

The solutions given (with the fixed Gecode solver) are now:

x:[1, 1]


x:[2, 1]


x:[3, 1]


x:[1, 2]


x:[2, 2]


x:[1, 3]


==========

This works both for MiniZinc 1.6 and MiniZinc 2.0.

hakank
  • 6,629
  • 1
  • 17
  • 27
0

The solution uses FlatZinc directly. Assume that we add a constraint x3=x1+x2

var 1..3: x1 :: output_var;
var 1..3: x2 :: output_var;
var 1..3: x3 :: is_defined_var :: var_is_introduced;

constraint int_plus(x1, x2, x3) :: defines_var(x3);
constraint int_le_reif(1, x3, true);

solve satisfy;

The output of a flatzinc -a returned a correct combination of values:

x1 = 1;
x2 = 1;
----------
x1 = 2;
x2 = 1;
----------
x1 = 1;
x2 = 2;
----------
==========

My observation is that auxiliary variables must be:

  1. declared with annotations is_defined_var and var_is_introduced
  2. must be defined in some constraint defines_var

Annotation of a variable declaration only has no effect at all. The solver treats such a variable as a usual decision variable.

kostya
  • 33
  • 3