Reputation: 1468
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.
Upvotes: 1
Views: 628
Reputation: 4243
It's not obvious but you can do it like this:
list of set of int: doms = [
1..1, % fixed value
2..3, % range
{4,6}, % values
-infinity..infinity, % no-op
];
function array[$$y] of var int: assign(
array[$$y] of set of int: domains
) = [
let { var s: x, } in
x | s in domains
];
array[int] of var int: x = assign(doms);
constraint trace(join("\n", [
show(dom(x)) | x in x
]) ++ "\n");
output show(X);
Can't say for 100% but I think I have seen cases where the compiler defers the domain propagation in the method shared by hakank to run-time.
The above should guarantee to occur during flattening.
Upvotes: 0
Reputation: 6854
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
.
Upvotes: 2