IBM ILOG Solver User's Manual > More on Modeling > Using the Distribute Constraint: Car Sequencing > Model

Once you have written a description of your problem, you can use Concert Technology classes to model it. Before declaring the decision variables and adding constraints, you must create an environment and a model. Once you create a model of your problem, you can use Solver classes to search for a solution.

In the lessons so far, you created decision variables that contained the solution to the problem, once it was solved. In this part, you will use decision variables in more sophisticated ways. You will still declare decision variables that will contain the solution to the problem, but you will also declare other decision variables that are used in finding the solution.

Step 2   -  

Open the example file

Open the example file YourSolverHome/examples/src/tutorial/carseq_basic_partial.cpp in your development environment. In this exercise, you use arrays of constrained integer variables and therefore you use the include file <ilsolver/ilosolverint.h>. The number of cars, nbCars, is set to 8 in this problem and the number of colors, nbColors, is set to 3.

As you know by now, the first step in converting your natural language description of the problem into code using Concert Technology classes is to create an environment and a model. This code is provided for you:

int main() {
  IloEnv env;
  try {
    IloModel model(env);
  

Concert Technology gives you the means to represent the unknown information in this problem--the color each car is painted--as an array of constrained integer variables. You use IloIntVarArray to create an array. Each element in the array will represent the color of a car, and so each variable can take a value from 0 to nbColors-1. The array of decision variables cars will contain the solution to the problem, once it is solved.

Step 3   -  

Declare the decision variables

Add the following code after the comment //Declare the decision variables

    IloIntVarArray cars(env, nbCars, 0, nbColors-1);

To represent the constraint that the first car off the assembly line cannot be painted green, you could declare an array of values to represent the three colors and then use the arithmetic constraint != to represent that the first car off the assembly line cannot be painted green.

But how are you going to represent the other constraints? No more than three cars can be painted green, exactly three cars must be painted yellow, and no more than two cars can be painted blue. It is also important to know the order of the cars on the assembly line, since the first car off the assembly line cannot be painted green. You need a constraint that allows you to count the number of variables (the cars) that take a given value (the color of paint) in an array, while respecting the order of the variables.

Concert Technology provides a type of global constraint that does just that. The global constraint IloDistribute allows you to count the number of variables that take a given value.

Global constraints

Global constraints make it possible to express complicated relations between variables, relations that would require an exponential number of arithmetic constraints, or relations that could not be expressed at all in arithmetic terms.

The predefined constraint IloAllDiff is a global constraint that can be substituted for a very large number of arithmetic inequality constraints (!=).

It would not be possible to express the predefined constraint IloDistribute using only arithmetic constraints.

IloDistribute takes the following parameters: the environment, a counting array, an array of values, and an array of constrained variables. The last parameter is an optional name used for debug and trace purposes. Here is a constructor:

 IloDistribute (const IloEnv env, 
                const IloIntVarArray cards,
                const IloNumArray values,
                const IloNumVarArray vars,
                const char* name = 0);


The constraint IloDistribute takes three arrays: cards, values, and vars. The constrained variables in the array cards are equal to the number of occurrences in the array vars of the values in the array values. More precisely, for each i, cards[i] is equal to the number of occurrences of values[i] in the array vars.

What do you need to do to use the constraint IloDistribute in your car sequencing model? You need to create the three arrays (cards, values, and vars) before you can add the constraint IloDistribute to the model:

Step 4   -  

Declare the array of values

Add the following code after the comment //Declare the array of values

    IloIntArray colors(env, 3, 0, 1, 2);

Now you declare the counting array cards. For each i, cards[i] is equal to the number of occurrences of colors[i] in the array cars. For example, the color green is represented by the element [0] in the array colors. Since no more than three cars can be painted green, you set the element [0] in the array of counting variables cards to be equal to a constrained integer variable with a domain of 0 to 3.

Step 5   -  

Declare the array of decision variables cards

Add the following code after the comment
//Declare the array of decision variables cards

    IloIntVarArray cards(env, nbColors);
    cards[0] = IloIntVar(env, 0, 3);
    cards[1] = IloIntVar(env, 3, 3);
    cards[2] = IloIntVar(env, 0, 2);

Though cards is an array of decision variables, it will not contain the solution to the problem once it is solved. This array of decision variables is instead used in creating the IloDistribute constraint.

Now that you have declared the three arrays that are used in IloDistribute, you can add the constraint to the model.

Step 6   -  

Add the distribute constraint

Add the following code after the comment //Add the distribute constraint

    model.add(IloDistribute(env, cards, colors, cars));

You also add the arithmetic constraint != to represent that the first car off the assembly line cannot be painted green. Explicitly, this constraint means that the value Solver finds for the first element in the array of constrained integer variables cars cannot equal the value for the color green.

Step 7   -  

Add the constraint that the first car cannot be green

Add the following code after the comment
//Add the constraint that the first car cannot be green

    model.add(cars[0] != 0);