pack
Maintains the load on a set of containers given objects sizes and assignments.
Syntax
constraint pack(intExprArray load, intExprArray where, intArray size, intExpr used = null)
Parameters
-
load: An array of integer expressions, each element representing the load (total size of the objects inside) the corresponding container. -
where: An array of integer expressions, each element representing in which container the corresponding object is placed. -
size: An array of integers, each element representing the size of the corresponding object. -
used: (optional) An integer expression indicating the number of used containers. That is, the number of containers with at least one object inside.
Description
The pack constraint is used to represent sub-problems where the requirement
is to assign objects to containers such that the capacities or minimum fill levels of the containers are respected. Let's assume we have n objects
and m containers. The sizes of the array arguments of pack must correspond
to these constants. That is, load must be of size m, whereas where
and size must be of size n.
Given assignments to the where expressions,
the pack constraint will calculate the values of the load and used
expressions.
All counting is done from 0, and so
the interpretation of 5 being assigned to where[3] is that object 3
(the 4th object) is placed into container 5 (the 6th container). This will be
reflected by the inclusion of the size of object 3 (size[3]) being
included in the calculation of the value of load[5].
Naturally, all the arguments (with the exception of size) can
be constrained by additional constraints. The most common form is to limit
the capacity of a container. For example, to limit container 2
to a capacity of 15, one would write load[2] <= 15. Minimum fill level
requirements can also be specified this way: for example load[2] >= 12.
Other more esoteric constraints are possible, for example to say that only
an even number of containers can be used: (used % 2) == 0. If used
is omitted from the signature, then it will not be possible to specifically
constrain the number of containers used.
Example
A decomposition of the pack constraint with n=3 and m=2
could be written as follows. Please note that this form will result in
less inference being made by CP Optimizer during search than using pack:
// Must use at least one container and can't use more than exists
used >= 1;
used <= 2;
// Loads are non-negative and limited to total object size
load[0] >= 0;
load[0] <= sum(size);
load[1] >= 0;
load[1] <= sum(size);
// Objects must be placed in one of the containers
where[0] >= 0;
where[0] <= 1;
where[1] >= 0;
where[1] <= 1;
where[2] >= 0;
where[2] <= 1;
// Load maintenance
load[0] == scalProd(size, [where[0] == 0, where[1] == 0, where[2] == 0]);
load[1] == scalProd(size, [where[0] == 1, where[1] == 1, where[2] == 1]);
// Used
used == (count(where, 0) != 0) + (count(where, 1) != 0);
Requirements
-
The
whereandsizearrays must be the same size. -
Elements of the
sizearray must be non-negative, but may be zero. Placing a zero-sized object in a container still counts as using the container. That is, a container can be considered used even if its load is zero. -
The sum of the elements of the
sizearray must be no larger thanintmax.