The complete program follows. You can also view the entire program online in the file YourSolverHome
/examples/src/carseq.cpp.
#include <ilsolver/ilosolverint.h>
ILOSTLBEGIN
//
// First Model
//
IloModel IloCarSequencing( IloEnv env,
IloInt maxCar,
IloIntArray maxConfs,
IloIntArray confs,
IloIntVarArray sequence){
const IloInt abstractValue=-1; // we assume that confs[i] != -1
const IloInt confs_size=confs.getSize();
const IloInt sequence_size = sequence.getSize();
IloIntArray nval(env, confs_size+1);
IloIntVarArray ncard(env, confs_size+1);
nval[OL]=abstractValue;
ncard[OL]=IloIntVar(env, sequence_size - maxCar, sequence_size);
IloInt i;
for(i=0;i<confs_size;i++){
nval[i+1]=confs[i];
if (maxConfs[i] > maxCar)
ncard[i+1]=IloIntVar(env, 0, maxCar);
else
ncard[i+1]=IloIntVar(env, 0, maxConfs[i]);
}
IloIntVarArray nvars(env,sequence_size);
for (i = 0; i < sequence_size ; i++)
nvars[i] = IloIntVar(env, nval);
IloModel carseq_model(env);
carseq_model.add(IloAbstraction(env, nvars, sequence, confs,abstractValue));
carseq_model.add(IloDistribute(env, ncard, nval, nvars));
return carseq_model;
}
void firstModel(){
IloEnv env;
try {
IloModel model(env);
const IloInt nbOptions = 5;
const IloInt nbConfs = 6;
const IloInt nbCars = 10;
IloIntVarArray cars(env, nbCars,0,nbConfs-1);
IloIntArray confs(env, 6, 0, 1, 2, 3, 4, 5);
IloIntArray nbRequired(env, 6, 1, 1, 2, 2, 2, 2);
IloIntVarArray cards(env, 6);
for(IloInt conf=0;conf<nbConfs;conf++) {
cards[conf]=IloIntVar(env, nbRequired[conf],nbRequired[conf]);
}
model.add (IloDistribute(env, cards, confs, cars));
IloArray<IloIntArray> optConf(env, nbOptions);
optConf[0] = IloIntArray(env, 3, 0, 4, 5);
optConf[1] = IloIntArray(env, 3, 2, 3, 5);
optConf[2] = IloIntArray(env, 2, 0, 4);
optConf[3] = IloIntArray(env, 3, 0, 1, 3);
optConf[4] = IloIntArray(env, 1, 2);
IloIntArray maxSeq(env, 5, 1, 2, 1, 2, 1);
IloIntArray overSeq(env, 5, 2, 3, 3, 5, 5);
IloArray<IloIntArray> optCard(env, nbOptions);
optCard[0] = IloIntArray(env, 3, 1, 2, 2);
optCard[1] = IloIntArray(env, 3, 2, 2, 2);
optCard[2] = IloIntArray(env, 2, 1, 2);
optCard[3] = IloIntArray(env, 3, 1, 1, 2);
optCard[4] = IloIntArray(env, 1, 2);
for (IloInt opt=0; opt < nbOptions; opt++) {
for (IloInt i=0; i < nbCars-overSeq[opt]+1; i++) {
IloIntVarArray sequence(env,(IloInt)overSeq[opt]);
for (IloInt j=0; j < overSeq[opt]; j++)
sequence[j] = cars[i+j];
model.add(IloCarSequencing(env,
(IloInt)maxSeq[opt],
optCard[opt],
optConf[opt],
sequence));
}
}
IloSolver solver(model);
solver.solve(IloGenerate(env,cars,IlcChooseMinSizeInt));
solver.out() << "cars = " << solver.getIntVarArray(cars) << endl;
solver.printInformation();
}
catch (IloException& ex) {
cout << "Error: " << ex << endl;
}
env.end();
}
// Second Model
//
IloArray<IloIntArray> readData(IloEnv env,
IloInt example,
IloInt& nbCars,
IloInt& nbOpt,
IloIntArray& nbMax,
IloIntArray& seqWidth,
IloIntArray& confs,
IloIntArray& nbCarsByConf){
char globalName[200];
switch(example){
case 1:{
strcpy(globalName,"../../../examples/data/carseq1.dat");
} break;
case 2:{
strcpy(globalName,"../../../examples/data/carseq2.dat");
} break;
}
IloInt nbConfs;
ifstream fin(globalName,ios::in);
if (!fin) env.out() << "problem with file:" << globalName << endl;
fin >> nbCars >> nbOpt >> nbConfs;
IloInt i;
confs = IloIntArray(env, nbConfs); // required configurations
for(i=0;i<nbConfs;i++){
confs[i]=i;
}
IloArray<IloIntArray> confsByOption(env, nbConfs);
for (i=0;i<nbConfs;i++){
confsByOption[i] = IloIntArray(env, nbOpt);
}
IloIntArray nbConfsByOption(env, nbOpt);
for (i=0;i<nbOpt;i++){
nbConfsByOption[i]=0;
}
// read the maximum number of cars of each sequence that can take the
// invoked option
nbMax=IloIntArray(env, nbOpt);
for(i=0;i<nbOpt;i++){
fin >> nbMax[i];
}
// read the size of a sequence for each option
seqWidth=IloIntArray(env, nbOpt);
for(i=0;i<nbOpt;i++){
fin >> seqWidth[i];
}
// read the options required by each configuration
nbCarsByConf=IloIntArray(env, nbConfs);
IloInt dummy;
IloInt j;
for(i=0;i<nbConfs;i++){
fin >> dummy;
fin >> nbCarsByConf[i];
for (j=0;j<nbOpt;j++){
fin >> confsByOption[i][j];
if (confsByOption[i][j] == 1){
nbConfsByOption[j]++;
}
}
}
// compute the configurations required by each option
IloArray<IloIntArray> optConf(env, nbOpt);
for(i=0;i<nbOpt;i++){
optConf[i]=IloIntArray(env, (IloInt)nbConfsByOption[i]);
}
IloIntArray ind(env, nbOpt);
for(i=0;i<nbOpt;i++){
ind[i]=0;
}
for(i=0;i<nbConfs;i++){
for (j=0;j<nbOpt;j++){
if (confsByOption[i][j] == 1){
optConf[j][(IloInt)ind[j]]=i;
ind[j]++;
}
}
}
// print the configuration required by each option
env.out() << "number of times each configuration is required:" << endl;
for(i=0;i<nbConfs;i++){
env.out() << nbCarsByConf[i] << " ";
}
env.out() << endl;
env.out() << "configuration required by each option:" << endl;
for(i=0;i<nbOpt;i++){
env.out() << "option:" << i << " ";
for (j=0;j<optConf[i].getSize();j++){
env.out() << optConf[i][j] << " ";
}
env.out() << endl;
}
env.out() << "number of times each option is required" << endl;
for(i=0;i<nbOpt;i++){
IloInt cpt=0;
for(j=0;j<optConf[i].getSize();j++){
cpt += nbCarsByConf[(IloInt)optConf[i][j]];
}
env.out() << "option:" << i << " " << cpt << " x ";
env.out() << nbMax[i] << "/" << seqWidth[i] << endl;
}
return optConf;
}
ILCGOAL1(IlcGenerateAbstractVars, IlcIntVarArray, vars) {
IlcInt index = IlcChooseFirstUnboundInt(vars);
if (index == -1) return 0;
return IlcAnd(IlcDichotomize(vars[index]), this); // first tries vars[index] == 1
}
ILOCPGOALWRAPPER1(IloGenerateAbstractVars, solver, IloIntVarArray, vars) {
return IlcGenerateAbstractVars(solver, solver.getIntVarArray(vars));
}
void secondModel(IloInt mode, IloInt example)
{
IloEnv env;
try {
IloModel model(env);
IloInt nbOptions;
IloInt nbCars;
IloIntArray confs(env); // array of required configurations
IloIntArray nbCarsByConf(env); // number of cars to assign
// to each configuration
IloIntArray nbMax(env);
IloIntArray seqWidth(env);
IloArray<IloIntArray> optConf = readData(env,
example,
nbCars,
nbOptions,
nbMax,
seqWidth,
confs,
nbCarsByConf);
cout << "Pass 1 " << endl;
const IlcInt nbConfs = confs.getSize();
IloInt i,j;
IloIntVarArray cars(env,nbCars,0,nbConfs-1);
IloIntVarArray cards(env,nbConfs);
for (i = 0; i < nbConfs; i++){
cards[i] = IloIntVar(env,nbCarsByConf[i],nbCarsByConf[i]);
}
cout << "Pass 2 " << endl;
model.add(IloDistribute(env, cards, confs, cars));
IloInt opt;
for (opt = 0; opt < nbOptions; opt++) {
IloIntVarArray ncard(env,optConf[opt].getSize());
for(i = 0; i < optConf[opt].getSize(); i++){
ncard[i] = cards[(IloInt)optConf[opt][i]];
}
model.add(IloSequence(env,
0,
(IloInt)nbMax[opt],
(IloInt)seqWidth[opt],
cars,
optConf[opt],
ncard));
}
cout << "Pass 3 " << endl;
IloIntArray order(env, nbOptions);
switch(example){
case 1:{
order[OL]=0;
order[1]=1;
order[2]=4;
order[3]=2;
order[4]=3;
} break;
case 2:{
order[OL]=0;
order[1]=4;
order[2]=1;
order[3]=2;
order[4]=3;
}break;
}
IloBoolVarArray bvars(env,nbOptions*nbCars);
for(i=0;i < nbOptions;i++){
opt=(IloInt)order[i];
IloBoolVarArray bv(env,nbCars);
for (j = 0; j < nbCars; j++)
bv[j] = IloBoolVar(env);
model.add(IloBoolAbstraction(env, bv, cars, optConf[opt]));
for(j=0;j<nbCars;j++){
bvars[i*nbCars + j] = bv[j];
}
}
cout << "Pass 4 " << endl;
IloBoolVarArray tbvars(env,nbOptions*nbCars);
for(j=0;j<nbOptions*nbCars;j+=nbCars){
IlcInt mid=nbCars/2 - 1;
for(i=0;i<mid+1;i++){
tbvars[2*i+j]=bvars[mid-i+j];
tbvars[2*i+1+j]=bvars[mid+i+1+j];
}
}
IloSolver solver(model);
if (mode) {
solver.setDefaultFilterLevel(IlcSequenceCt,IlcExtended);
solver.setDefaultFilterLevel(IlcDistributeCt,IlcExtended);
}
if (solver.solve(IloGenerateAbstractVars(env,tbvars)))
solver.out() << "cars = " << solver.getIntVarArray(cars) << endl;
else
solver.out() << "No solution" << endl;
solver.printInformation();
}
catch (IloException& ex) {
cout << "Error: " << ex << endl;
}
env.end();
}
int main(int argc, char** argv){
IloInt pb=(argc>1)?atoi(argv[1]):1;
if (pb != 1 && pb != 2)
pb=1;
switch(pb){
case 1 :{
firstModel();
} break;
case 2 :{
IlcInt mode = (argc>2)?atoi(argv[2]):1;
if (mode != 0 && mode != 1)
mode=1;
IlcInt example = (argc>3)?atoi(argv[3]):1;
secondModel(mode,example);
} break;
}
return 0;
}