| Overview | Group | Tree | Graph | Deprecated | Index | Concepts |

The IloPropagatorI class offers a simple way
to define a custom constraint, that is, one where
you define the propagation rules via some C++ code. You do this
by creating your own sub-class of IloPropagatorI.
There are normally two reasons for writing a custom constraint.
One is that CP Optimizer does not have the modeling features required
to express the constraint, and IloAllowedAssignments
and IloForbiddenAssignments
are not efficient (for example, the number of tuples required would
be too high). The second reason is the opportunity to
perform stronger inferences (propagation) than CP Optimizer would typically
perform. This can be the case where, for example, the same expression
is used in more than one place in a constraint.
The IloPropagatorI class has a simple interface,
and requires you to define one virtual function execute,
which will perform the required propagation. In addition, you must
explicitly state which variables are involved in the constraint.
Whenever one of the variables that you identify changes its domain,
the propagator is called.
The following code shows how to write a propagator that maintains the sign of an integer variable (-1 corresponds to strictly negative, +1 to strictly positive, and zero to zero).
class SignI : public IloPropagatorI {
private:
IloIntVar _x;
IloIntVar _sgn;
public:
SignI(IloIntVar x, IloIntVar sgn)
: IloPropagatorI(x.getEnv()), _x(x), _sgn(sgn) {
addVar(x);
addVar(sgn);
}
void execute() {
if (!isInDomain(_sgn, -1)) setMin(_x, 0);
if (!isInDomain(_sgn, +1)) setMax(_x, 0);
if (!isInDomain(_sgn, 0)) removeValue(_x, 0);
if (getMin(_x) >= 0) removeValue(_sgn, -1);
if (getMax(_x) <= 0) removeValue(_sgn, +1);
}
IloPropagatorI* makeClone(IloEnv env) const {
return new (env) SignI(_x, _sgn);
}
};
All modifications made to variables inside a propagator are
buffered. This means that the changes you make to
variable domains are not visible inside the propagator,
but are recorded and applied when the propagator exits. Your code
needs be aware of this if it examines a variable's domain after
modifying it. For example, the following code will not case the
assertion to fail, but the minimum of _x will be set
to one greater than its current value when the propagator exits.
IlcInt min = getMin(_x);
setMin(_x, min + 1);
assert(getMin(_x) == min);
A constraint created using IloPropagatorI cannot be used as
an expression, it could be used only as top-level constraint.
See Also:
IlcCustomConstraint, IloCustomConstraint
| Method Summary | |
|---|---|
public void | addVar(IloNumVar var) |
public virtual void | execute() |
public IloInt | getDomainSize(IloNumVar var) const |
public IloNum | getMax(IloNumVar var) const |
public IloNum | getMin(IloNumVar var) const |
public IloNum | getValue(IloNumVar var) const |
public | IloPropagatorI(IloEnv env) |
public IloBool | isFixed(IloNumVar var) const |
public IloBool | isInDomain(IloNumVar var, IloInt value) const |
public IloCPEngine::IntVarIterator | iterator(IloNumVar var) |
public virtual IloPropagatorI * | makeClone(IloEnv env) const |
public void | removeValue(IloIntVar var, IloInt value) |
public void | setMax(IloNumVar var, IloNum max) |
public void | setMin(IloNumVar var, IloNum min) |
public void | setRange(IloNumVar var, IloNum min, IloNum max) |
public void | setValue(IloNumVar var, IloNum value) |
public void | violate() |
public | ~IloPropagatorI() |
| Method Detail |
|---|
The constructor of the propagator takes an
environment env.
As IloPropagatorI is an abstract class, a virtual
destructor is provided.
This function should be called in the constructor of your
sub-class of IloPropagatorI for each variable
involved in the custom constraint you are defining.
When sub-classing the IloPropagatorI class to create
your own custom constraint, it is the execute function that you
define. When you overload this function in your sub-class, this
function should update the domains of the variables of the
constraint to make them consistent.
The member function returns the number of domain elements of
the variable var. Note that as domain modifications
are buffered inside propagators, this value does not include
the domain modifications done since the execute
method of the propagator was entered.
The member function returns the maximum value of the domain of
variable var. Note that as domain modifications
are buffered inside propagators, this value does not include
the domain modifications done since the execute
method of the propagator was entered.
The member function returns the minimum value of the domain of
variable var. Note that as domain modifications
are buffered inside propagators, this value does not include
the domain modifications done since the execute
method of the propagator was entered.
The member function returns the value of the
variable var. If the var
was not fixed on entry to the execute
function, an exception is raised.
The member function determines if the variable var
is fixed to a value. Note that as domain modifications
are buffered inside propagators, this function will only return true
if var was fixed on entry to the execute
method of the propagator.
The member function determines if the value value
is in the current domain of the variable var.
Note that as domain modifications are buffered inside propagators,
this function will return true if var had
value in its domain on entry to the execute
method of the propagator. This is the case even if that value
has subsequently been removed from var during the
current execution of execute.
This member function creates an iterator (an instance of
IloPropagatorI::IntVarIterator) which iterates
over the elements of the domain of var. Note
that as modifications are buffered inside a propagator, this
iteration will scan all values in the domain of var
as they were when the execute member function was
entered.
When sub-classing the IloPropagatorI class to create
your own custom constraint, you should define this method that will
clone the propagator to use in the CP Optimizer engine.
This function can be called from the execute member
function of your sub-class of IloPropagatorI. It removes
value value from the domain of variable
var. Note that that this modification is
buffered. See the class
documentation for an explanation of this.
This function can be called from the execute member
function of your sub-class of IloPropagatorI. It sets
the maximum value of var to max. Note
that this modification is buffered. See the class
documentation for an explanation of this.
This function can be called from the execute member
function of your sub-class of IloPropagatorI. It sets
the minimum value of var to min. Note
that this modification is buffered. See the class
documentation for an explanation of this.
This function can be called from the execute member
function of your sub-class of IloPropagatorI. It sets
the minimum value of var to min and the
maximum value to max. Note that
that this modification is buffered. See the class
documentation for an explanation of this.
This function can be called from the execute member
function of your sub-class of IloPropagatorI. It sets
the value of var to value.
Note that that this modification is buffered. See the class
documentation for an explanation of this.
This function can be called from the execute member
function of your sub-class of IloPropagatorI. It indicates
to the solver that the constraint which the propagator is maintaining
is violated.