You can see the entire program tcost.cpp
here or view it online in the standard distribution.
#include <ilsched/iloscheduler.h>
ILOSTLBEGIN
const IloInt Horizon = 10000;
const IloInt NumberOfJobs = 6;
const IloInt NumberOfResources = 6;
const IloInt NumberOfWorkers = 5;
const IloInt NumberOfTypes = 4;
IloInt ResourceNumbers [] = {2, 0, 1, 3, 5, 4,
1, 2, 4, 5, 0, 3,
2, 3, 5, 0, 1, 4,
1, 0, 2, 3, 4, 5,
2, 1, 4, 5, 0, 3,
1, 3, 5, 0, 4, 2};
IloInt ProcessingTimes [] = { 10, 30, 60, 70, 30, 60,
80, 50, 100, 100, 100, 40,
50, 40, 80, 90, 10, 70,
50, 50, 50, 30, 80, 90,
90, 30, 50, 40, 30, 10,
30, 30, 90, 100, 40, 10};
IloInt Types [] = { 0, 1, 2, 2, 0, 3,
1, 3, 2, 3, 3, 0,
2, 3, 1, 1, 0, 1,
2, 1, 0, 0, 1, 1,
3, 3, 2, 0, 1, 1,
3, 1, 2, 0, 3, 3};
IloInt TableDurations [] = { 0, 16, 14, 19,
12, 0, 8, 15,
15, 10, 0, 14,
16, 15, 17, 0};
IloInt SetupDurations [] = { 7, 0, 6, 7};
IloInt TableCapacities [] = { 0, 2, 3, 1,
2, 0, 4, 2,
3, 3, 0, 2,
1, 2, 3, 0};
IloInt SetupCapacities [] = { 2, 1, 1, 1};
///////////////////////////////////////////////////////////////////////////////
//
// PROBLEM DEFINITION
//
///////////////////////////////////////////////////////////////////////////////
/* CREATION OF A MACHINE WITH ITS TRANSITION TIME AND COSTS. */
IloUnaryResource
MakeMachine(IloModel model,
IloTransitionParam durTransParam,
IloTransitionParam enrTransParam,
IloNumVar cost,
const char* name) {
IloUnaryResource machine(model.getEnv(), name);
IloTransitionTime durTrans(machine, durTransParam);
IloTransitionCost enrTrans(machine, enrTransParam);
model.add(enrTrans.getCostSumVar() <= cost);
return machine;
}
/* CREATION OF A TASK */
IloActivity
MakeTask(IloModel model,
IloUnaryResource machine,
IloInt type,
IloInt procTime,
IloInt setupTime,
const char* name) {
IloActivity task(model.getEnv(), procTime, type, name);
task.setStartMin(setupTime);
model.add(task.requires(machine));
return task;
}
void
DefineProblem(IloModel model,
IloInt horizon,
IloInt numberOfJobs,
IloInt numberOfResources,
IloInt numberOfWorkers,
IloInt numberOfTypes,
IloInt* resourceNumbers,
IloInt* processingTimes,
IloInt* types,
IloInt* tableDurations,
IloInt* tableCapacities,
IloInt* setupDurations,
IloInt* setupCapacities,
IloNumVar& makespan,
IloNumVar& cost,
IloTransitionParam& enrTransParam) {
/* CREATE THE MAKESPAN VARIABLE. */
IloEnv env = model.getEnv();
makespan = IloNumVar(env, 0, horizon, IloNumVar::Int);
/* CREATE THE COST VARIABLE. */
IloInt maxEnergy = horizon * numberOfWorkers;
cost = IloNumVar(env, 0, maxEnergy, IloNumVar::Int);
char buffer[128];
IloInt i, j, k;
/* CREATE THE TRANSITION FUNCTIONS. */
enrTransParam = IloTransitionParam(env, numberOfTypes, IloFalse);
IloTransitionParam durTransParam(env, numberOfTypes, IloFalse);
for(i = 0; i < numberOfTypes; ++i) {
enrTransParam.setSetup(i, setupDurations[i] * setupCapacities[i]);
IloInt index = i * numberOfTypes;
for(j = 0 ; j < numberOfTypes; ++j) {
durTransParam.setValue(i, j, tableDurations[index]);
enrTransParam.setValue(i, j,
(tableDurations[index] * tableCapacities[index]));
++index;
}
}
/* CREATE THE RESOURCES. */
IloUnaryResource* resources =
new (env) IloUnaryResource[numberOfResources];
for (j = 0; j < numberOfResources; j++) {
sprintf(buffer, "Machine%ld", j);
resources[j] = MakeMachine(model, durTransParam, enrTransParam,
cost, buffer);
}
/* CREATE THE ACTIVITIES AND THE TEMPORAL CONSTRAINTS. */
k = 0;
for (i = 0; i < numberOfJobs; i++) {
IloActivity previousTask;
for (j = 0; j < numberOfResources; j++) {
IloInt number = resourceNumbers[k];
sprintf(buffer, "J%ldS%ldR%ldT%ld", i, j, number, types[k]);
IloActivity task = MakeTask(model,
resources[number],
types[k],
processingTimes[k],
setupDurations[types[k]],
buffer);
if (j != OL)
model.add(task.startsAfterEnd(previousTask));
previousTask = task;
k++;
}
model.add(previousTask.endsBefore(makespan));
}
}
///////////////////////////////////////////////////////////////////////////////
//
// PRINTING OF SOLUTIONS
//
///////////////////////////////////////////////////////////////////////////////
void PrintSolution(IloSolver& solver) {
IlcScheduler schedule(solver);
for(IlcUnaryResourceIterator iter(schedule); iter.ok(); ++iter) {
IlcUnaryResource machine = *iter;
solver.out() << endl << "Machine : " << machine << endl;
IloInt index = machine.getSetupVar().getValue();
IloInt sink = machine.getTeardownIndex();
while(index != sink) {
IlcResourceConstraint task = machine.getSequenceRC(index);
solver.out() << "\t" << task.getActivity() << endl;
index = task.getNextVar().getValue();
}
}
}
int main() {
try {
IloEnv env;
IloModel model(env);
IloNumVar makespan;
IloNumVar cost;
IloTransitionParam enrTransParam;
DefineProblem(model,
Horizon,
NumberOfJobs,
NumberOfResources,
NumberOfWorkers,
NumberOfTypes,
ResourceNumbers,
ProcessingTimes,
Types,
TableDurations,
TableCapacities,
SetupDurations,
SetupCapacities,
makespan,
cost,
enrTransParam);
IloSolver solver(model);
IloGoal goal = IloSequenceForward(env, cost, enrTransParam) &&
IloInstantiate(env, makespan) &&
IloSetTimesForward(env);
if (solver.solve(goal)) {
env.out() << " Solution with " << endl
<< "\tenergy : " << solver.getIntVar(cost) << endl
<< "\tmakespan : " << solver.getIntVar(makespan) << endl;
PrintSolution(solver);
}
else
solver.out() << "No Solution" << endl;
env.end();
} catch (IloException& exc) {
cout << exc << endl;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
//
// RESULTS
//
///////////////////////////////////////////////////////////////////////////////
/* tcost
Solution with
energy : [168]
makespan : [971]
Machine : Machine4 [1]
J4S2R4T2 [450 -- 50 --> 500]
J1S2R4T2 [500 -- 100 --> 600]
J3S4R4T1 [610 -- 80 --> 690]
J2S5R4T1 [756 -- 70 --> 826]
J5S4R4T3 [841 -- 40 --> 881]
J0S5R4T3 [881 -- 60 --> 941]
Machine : Machine5 [1]
J5S2R5T2 [450 -- 90 --> 540]
J2S2R5T1 [550 -- 80 --> 630]
J0S4R5T0 [642 -- 30 --> 672]
J4S3R5T0 [672 -- 40 --> 712]
J1S3R5T3 [731 -- 100 --> 831]
J3S5R5T1 [846 -- 90 --> 936]
Machine : Machine3 [1]
J2S1R3T3 [56 -- 40 --> 96]
J0S3R3T2 [326 -- 70 --> 396]
J5S1R3T1 [420 -- 30 --> 450]
J3S3R3T0 [476 -- 30 --> 506]
J4S5R3T1 [776 -- 10 --> 786]
J1S5R3T0 [931 -- 40 --> 971]
Machine : Machine1 [1]
J1S0R1T1 [0 -- 80 --> 80]
J0S2R1T2 [266 -- 60 --> 326]
J3S0R1T2 [326 -- 50 --> 376]
J5S0R1T3 [390 -- 30 --> 420]
J4S1R1T3 [420 -- 30 --> 450]
J2S4R1T0 [746 -- 10 --> 756]
Machine : Machine0 [1]
J0S1R0T1 [236 -- 30 --> 266]
J3S1R0T1 [376 -- 50 --> 426]
J5S3R0T0 [540 -- 100 --> 640]
J2S3R0T1 [656 -- 90 --> 746]
J4S4R0T1 [746 -- 30 --> 776]
J1S4R0T3 [831 -- 100 --> 931]
Machine : Machine2 [1]
J2S0R2T2 [6 -- 50 --> 56]
J4S0R2T3 [70 -- 90 --> 160]
J1S1R2T3 [160 -- 50 --> 210]
J0S0R2T0 [226 -- 10 --> 236]
J3S2R2T0 [426 -- 50 --> 476]
J5S5R2T3 [881 -- 10 --> 891]
*/