The models
Presents the four different model files used in the vellino example.
In the distributed project, you can see that there are four different model files described in the following sections:
The model for common definitions: vellinocommon.mod contains the declaration of data common to all other models.
The generation model: vellinogenBin.mod is the model to generate the possible configurations for bins. This is a CP model.
The selection model: vellinochooseBin.mod selects a subset of configurations. This is a CPLEX model.
The flow control script: vellino.mod is only a flow control script that executes the two other models in the right order and transfers information from one to the other.
Selection of the bins to use: passing the generated bins to the selection model
The model for common definitions
The model vellinocommon.mod contains definitions that are common to all the models. For example, the tuple definition:
tuple Bin {
key int id;
string color;
int n[Components];
};
is used to represent configurations that are passed between the different models.
The set of available configurations is given by:
{Bin} Bins = ...;
This model is included in other models that use these definitions as follows:
include "vellinocommon.mod";
The generation model
The generation model vellinogenBin.mod starts with the statement:
using CP;
which means that it is solved by the CP Optimizer engine.
The decision variables are:
dvar int color in RColors;
dvar int n[Components] in 0..maxCapacity;
The decision variable color indicates
the color of the generated configuration. Colors are represented by
integer values and each n[c] indicates how
many components of type c are included in
the bin configuration. Then, all the compatibility constraints are
easily written:
subject to {
1 <= sum(c in Components) n[c];
sum(c in Components) n[c] <= capacity_int_idx[color];
color == ord(Colors, "red") =>
n["plastic"] == 0 && n["steel"] == 0 && n["wood"] <= 1;
color == ord(Colors, "blue") =>
n["plastic"] == 0 && n["wood"] == 0;
color == ord(Colors, "green") =>
n["glass"] == 0 && n["steel"] == 0 && n["wood"] <= 2;
n["wood"] >= 1 => n["plastic"] >= 1;
n["glass"] == 0 || n["copper"] == 0;
n["copper"] == 0 || n["plastic"] == 0;
};
Some are just a direct expression of the problem description. For example, this constraint:
n["wood"] >= 1 => n["plastic"] >= 1;
means that if there is at least one wood component, there needs to be at least one plastic component.
Others use intermediate structures. For example, this constraint:
sum(c in Components) n[c] <= capacity_int_idx[color];
states that the total number of components must not exceed the capacity, depending on the color. For this, a preprocessed calculated structure has been created to go from the capacity indexed by strings to the capacity given by color indexes.
int capacity_int_idx[RColors] = [ord(Colors,c) : capacity[c] | c in Colors];
The selection model
The selection model vellinochooseBin.mod is also a very simple CPLEX model.
A variable is created for each available configuration
given as input, by means of the tuple structure Bin and
given in the tuple set Bins:
dvar int produce[Bins] in 0..maxDemand;
The objective is to minimize the number of bins produced.
minimize
sum(b in Bins) produce[b];
The only constraint is to cover the demand in terms of number of components:
subject to {
forall(c in Components)
demandCt: sum(b in Bins) b.n[c] * produce[b] == demand[c];
};
The flow control script
The flow control script defined in vellino.mod links
the other models with each other.
It works as follows:
It solves the generation model as many times as necessary to find all the possible solutions. This is easily done because the CP Optimizer engine can iterate on the feasible solutions.
For each solution, a new
Binis created and added to the current list.The selection model is created and it uses the set of Bins just generated as input data.
Generation of all the configurations
Generating all the possible configurations consists in:
creating an instance of the
vellinogenBin.modmodel using the common datausing the following methods of theIloCP class to iterate on the feasible solutions:
startNewSearchnextendSearch
At each solution, a new tuple is added to Bins from the current solution. You need to call the method postProcess on the generation model to be able to use postprocessing elements.
var genBin = new IloOplRunConfiguration("vellinogenBin.mod");
genBin.oplModel.addDataSource(data);
genBin.oplModel.generate();
genBin.cp.startNewSearch();
while (genBin.cp.next()) {
genBin.oplModel.postProcess();
data.Bins.add(genBin.oplModel.newId,
genBin.oplModel.colorStringValue,
genBin.oplModel.n.solutionValue);
}
genBin.cp.endSearch();
genBin.end();
Selection of the bins to use
As the generated bin configurations have been added to
the Bins data element, you can pass this
data element object to the selection model.
var chooseBin = new IloOplRunConfiguration("vellinochooseBin.mod");
chooseBin.cplex = cplex;
chooseBin.oplModel.addDataSource(data);
chooseBin.oplModel.generate();
if (chooseBin.cplex.solve()) {
chooseBin.oplModel.postProcess();
}
chooseBin.end();