Search code examples
optimizationconstraint-programmingminizincdiscrete-optimization

Get number of attached constraints on a variable in MiniZinc


I have two sets of variables in my Minizinc program. Each variable from the first set necessarily has several constraints placed on it, but the variables in the second set are only implicitly constrained via their interactions with variables in the first set. This means that each of the variables in the second set may have anywhere from 0 to ~8 constraints placed on it, depending on the values taken by the variables in the first set.

I see that there is a way to reference the number of constraints placed on a variable at search time via the dom_w_deg search annotation, but I was wondering if there was anyway to access this information at runtime? I want to do this because I would like to specify additional constraints related to the number of constraints already placed on the variables.

I realize this is a weird question, and I may be approaching this whole thing the wrong way, but I've been banging my head against this problem for a while now, so figured I'd ask.


Solution

  • As a general rule, I think that you are approaching your problem erroneously. There are several mis-conceptions in the approach that I can identify leading to this:

    • Different solver back-ends might do very different things with the model and how it is solved
    • "A constraint" is not a meaningful concept for the solver. A single constraint might be multiple propagators in the back-end solver, a single propagator, or even just part of a propagator covering several constraints (assuming that it is a propagator based back-end).
    • Constraint models have monotonic behavior, so you can not in a well-defined and meaningful way change the model based on the number of constraints connected to a variable.
    • Given that a constraint maps to a single propagator, it may still have very different propagation strength, meaning that it might be done early or very late in the solving process.

    Without knowing what you are actually trying to achieve, as a general technique you might be interested in using reification, where the truth of a constraint is reflected onto a binary Boolean variable. In general, it is good practice to have as little reification as possible, since it does not propagate much, but sometimes it is needed.

    As a very simple example of using reification, this is a (probably not very good) model that tries to maximize the number of constraints satisfied.

    set of int: Domain = 1..10;
    var Domain: x;
    var Domain: y;
    var Domain: z;
    array[1..3] of var bool: holds;
    constraint holds[1] <-> x < y;
    constraint holds[2] <-> y < z;
    constraint holds[3] <-> z < x;
    var int: goal;
    constraint goal = sum(holds);
    solve maximize goal;