Modeling elements of the inventory problem

Examines some modeling aspects specific to constraint programming and discusses the CP Optimizer.

This section:

  • examines some modeling aspects that are specific to constraint programming:

    • specialized constraints

    • aggregate or /and

  • focuses on the search for solutions and how the CP Optimizer engine can be tuned to find better and faster solutions:

    • changing constraint programming parameters

    • using search phases to describe a more specific search

  • explains how you can run this model from the IBM ILOG CPLEX Optimization Studio IDE and how some specific IDE features work in the constraint programming context.

The CP Optimizer engine can currently solve any model than can be solved by the CPLEX engine, provided that all the decision variables are discrete. This means that any modeling object (constraint or expressions) in OPL can be interpreted by this engine. The reverse is not true: some of the new global expressions and constraints can be used only in a CP model to be solved with the CP Optimizer engine.

The solving engine

By default (that is, if nothing different is specified), OPL uses the CPLEX engine to solve an OPL model. To specify that you want your model to be solved by the CP Optimizer engine, you must start the model with this statement:


using CP;

The OPL model

You do not need to learn any new syntax to develop a CP model. The organization of an OPL model for CP does not change. You define and manipulate data and decision variables in the same way. For example, to define an array of integer decision variables indexed by integers from 1 to nbOrders and taking values between 1 and nbSlabs, you can write:

dvar int where[1..nbOrders] in 1..nbSlabs;

Modeling constraints and specialized constraints

As for any OPL model, constraints are stated in a constraints {} or subject to {} block. When the model is solved by the CP Optimizer engine, you can include some specialized constraints in this set of modeling constraints. For example, in the steel mill example, there is a packing constraint.

subject to {  
  packCt: pack(load, where, weight);

This pack constraint is a simple but powerful one-dimensional packing constraint. It constrains the way coils are associated with slabs with respect to the weights of the coils and the capacity of the slabs. More precisely, the decision variable where[i] states with which slab coil i is to be associated. The decision variable load[j] represents the total weight of all the coils associated with slab j, using the values from the array weights as data. In this case, the loads are constrained by the maximum value of maxLoad which is used as upper bound to create the load variables.

The "all" syntax

In the steel mill example, the arrays of values and decision variables used in the specialized constraint are modeling arrays. They make sense as a whole and have been named in the model. Sometimes, you will want to apply a specialized constraint to a set of variables that is not defined as a named array of variables, but that is made of dynamically collected variables. The all keyword is the syntax that enables you to collect variables dynamically in an array. This syntax is important for CP models. It is not illustrated in the steel mill example. See all in the Language Quick Reference for a complete description.

Aggregate and/or

The other constraint of the model illustrates how to use the aggregate or constraint.

  forall(s in 1..nbSlabs)
    colorCt: sum (c in 1..nbColors) (or(o in 1..nbOrders : colors[o] == c) (where[o] == s)) <= 2; 

You use this constraint just as the usual forall constraint or sum expression. The or constraint can express a complex combination of constraints in one single statement. As a result of the expressiveness of the OPL language, the steel mill model uses only two OPL constraints to represent a very complete and realistic model.