Constraint propagation

Constraint propagation is the process of communicating the domain reduction of a decision variable to all of the constraints that are stated over this variable.

Constraint propagation is the process of communicating the domain reduction of a decision variable to all of the constraints that are stated over this variable. This process can result in more domain reductions. These domain reductions, in turn, are communicated to the appropriate constraints. This process continues until no more variable domains can be reduced or when a domain becomes empty and a failure occurs. An empty domain during the initial constraint propagation means that the model has no solution.

For example, consider the decision variables y with an initial domain [0..10], z with an initial domain [0..10] and t with an initial domain [0..1], and the constraints


     y + 5*z <= 4
     t != z
     t != y

over these three variables.

The domain reduction of the constraint y + 5*z <= 4 reduces the domain of y to [0..4] and z to [0]. The variable z is thus fixed to a single value. Constraint propagation invokes domain reduction of every constraint involving z. Domain reduction is invoked again for the constraint y + 5*z <= 4, but the variable domains cannot be reduced further. Domain reduction of the constraint t != z is invoked again, and because z is fixed to 0, the constraint removes the value 0 from the domain of t. The variable t is now fixed to the value 1, and constraint propagation invokes domain reduction of every constraint involving t, namely t != z and t != y. The constraint that can reduce domains further is t != y. Domain reduction removes the value 1 from the domain of y.

Constraint propagation is performed on constraints involving y; however, no more domain reduction can be achieved and the final domains are:

  • y = [0 2..4],

  • z = [0] and

  • t = [1].

To invoke the constraint propagation process in CP Optimizer, the propagate function of the optimizer object is called. In the C++ API, this function is IloCP::propagate; in the Java™ API, this function is IloCP.propagate; and in the C# API, this function is CP.Propagate. This function invokes domain reduction on every constraint of the model and propagates the domain reductions. It returns true (IloTrue in the C++ API) if propagation succeeds; in other words, if no empty domains result. It returns false (IloFalse in the C++ API) otherwise.

As an example using the C++ API, a code that invokes propagation on the model above is;


    IloIntVar y(env, 0, 10);
    IloIntVar z(env, 0, 10);
    IloIntVar t(env, 0, 1);
    IloModel model(env);
    model.add(y + 5*z <= 4);
    model.add(t != z);
    model.add(t != y);
    IloCP cp(model);
    if (cp.propagate()){
      cp.out() << " Domains reduced: " << std::endl;
      cp.out() << " Domain of y = " << cp.domain(y) << std::endl;
      cp.out() << " Domain of z = " << cp.domain(z) << std::endl;
      cp.out() << " Domain of t = " << cp.domain(t) << std::endl;
    }else{
      cp.out() << " Model has no solution." << std::endl;
    }

The call to the method IloCP::domain(IloIntVar x) is directed to an output stream to display the current domain of the decision variable x. Running this code produces the output:


 Domains reduced:
 Domain of y = [0 2..4]
 Domain of z = [0]
 Domain of t = [1]