Search code examples
arraysconstraintsconstraint-programmingminizinc

MiniZinc Assign Different Domain to Each Var in Array


I have an array: array[backpacks] of int: capacity specifying the capacity of each backpack.

Now I want to create an array of variables which the constraint solver will have to satisfy. I want each variable to take values in domain 1..capacity where capacity corresponds to the one specified in the above array.

Would something like this work: array[backpacks] of var capacity: bagcaps ?

Or do I have to do something like: array[backpacks] of var 1..MAX: bagcaps

and then add constraints: constraint forall(i in backpacks) bagcaps[i] <= capacity[i] ?

Thank you.


Solution

  • There is no short cut to restrict the domain of specific element in the array declaration. The traditional version is the one you wrote last:

    constraint forall(i in backpacks) bagcaps[i] <= capacity[i]);
    

    However, you can make this as an predicate (and place it in a separate file which is then imported into the model with include). E.g. some thing like this:

    set of int: backpacks = 1..6;
    array[backpacks] of int: capacity = [10,4,3,7,5,3];
    array[backpacks] of var 1..max(capacity): bagcaps;
    
    solve satisfy;
    
    predicate restrict_domains(array[int] of var int: x, array[int] of int: d) =
            forall(i in index_set(x)) ( x[i] <= d[i] );
    
    constraint
         % forall(i in backpacks) ( bagcaps[i] <= capacity[i] ) % original
         restrict_domains(bagcaps,capacity)
    ;
    
    % output [];
    

    Note that you must still use restrict_domains as a constraint. And I recommend that you always restrict the domain in the declaration as much as possible, i.e. use the declaration using var 1..max(capacity) instead of var int.