You can see the entire program jobshopm.cpp
here or view it online in the standard distribution.
#include <ilsched/iloscheduler.h>
ILOSTLBEGIN
IloInt ResourceNumbers06 [] = {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 Durations06 [] = { 1, 3, 6, 7, 3, 6,
8, 5, 10, 10, 10, 4,
5, 4, 8, 9, 1, 7,
5, 5, 5, 3, 8, 9,
9, 3, 5, 4, 3, 1,
3, 3, 9, 10, 4, 1};
IloInt ResourceNumbers10 [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 2, 4, 9, 3, 1, 6, 5, 7, 8,
1, 0, 3, 2, 8, 5, 7, 6, 9, 4,
1, 2, 0, 4, 6, 8, 7, 3, 9, 5,
2, 0, 1, 5, 3, 4, 8, 7, 9, 6,
2, 1, 5, 3, 8, 9, 0, 6, 4, 7,
1, 0, 3, 2, 6, 5, 9, 8, 7, 4,
2, 0, 1, 5, 4, 6, 8, 9, 7, 3,
0, 1, 3, 5, 2, 9, 6, 7, 4, 8,
1, 0, 2, 6, 8, 9, 5, 3, 4, 7};
IloInt Durations10 [] = {29, 78, 9, 36, 49, 11, 62, 56, 44, 21,
43, 90, 75, 11, 69, 28, 46, 46, 72, 30,
91, 85, 39, 74, 90, 10, 12, 89, 45, 33,
81, 95, 71, 99, 9, 52, 85, 98, 22, 43,
14, 6, 22, 61, 26, 69, 21, 49, 72, 53,
84, 2, 52, 95, 48, 72, 47, 65, 6, 25,
46, 37, 61, 13, 32, 21, 32, 89, 30, 55,
31, 86, 46, 74, 32, 88, 19, 48, 36, 79,
76, 69, 76, 51, 85, 11, 40, 89, 26, 74,
85, 13, 61, 7, 64, 76, 47, 52, 90, 45};
IloInt ResourceNumbers20 [] = {0, 1, 2, 3, 4,
0, 1, 3, 2, 4,
1, 0, 2, 4, 3,
1, 0, 4, 2, 3,
2, 1, 0, 3, 4,
2, 1, 4, 0, 3,
1, 0, 2, 3, 4,
2, 1, 0, 3, 4,
0, 3, 2, 1, 4,
1, 2, 0, 3, 4,
1, 3, 0, 4, 2,
2, 0, 1, 3, 4,
0, 2, 1, 3, 4,
2, 0, 1, 3, 4,
0, 1, 4, 2, 3,
1, 0, 3, 4, 2,
0, 2, 1, 3, 4,
0, 1, 4, 2, 3,
1, 2, 0, 3, 4,
0, 1, 2, 3, 4};
IloInt Durations20 [] = {29, 9, 49, 62, 44,
43, 75, 69, 46, 72,
91, 39, 90, 12, 45,
81, 71, 9, 85, 22,
14, 22, 26, 21, 72,
84, 52, 48, 47, 6,
46, 61, 32, 32, 30,
31, 46, 32, 19, 36,
76, 76, 85, 40, 26,
85, 61, 64, 47, 90,
78, 36, 11, 56, 21,
90, 11, 28, 46, 30,
85, 74, 10, 89, 33,
95, 99, 52, 98, 43,
6, 61, 69, 49, 53,
2, 95, 72, 65, 25,
37, 13, 21, 89, 55,
86, 74, 88, 48, 79,
69, 51, 11, 89, 74,
13, 7, 76, 52, 45};
///////////////////////////////////////////////////////////////////////////////
//
// DEFINITION OF THE JOB CLASS
//
///////////////////////////////////////////////////////////////////////////////
class Job {
private:
char* _name;
IloInt _index;
IloArray<IloActivity> _inShops;
IloArray<IloUnaryResource> _machines;
public:
Job(IloEnv env,
IloInt index,
IloInt size,
IloInt* durations,
IloInt* resourceNumbers,
IloUnaryResource* resources);
const char* getName() const { return _name;}
IloInt getIndex() const { return _index;}
IloInt getSize() const { return _inShops.getSize();}
IloActivity getActivity(IloInt i) const {
IloAssert(i >= 0, "bad index range");
IloAssert(i < _inShops.getSize(), "bad index range");
return _inShops[i];
}
IloInt getShop(IloActivity act) const;
void addToModel(IloModel model, IloIntVar makespan);
void display(ILOSTD(ostream)& out) const {
out << "Job<" << _name
<< " ," << _index
<< ", " << _inShops.getSize() << ">";
}
};
Job::Job(IloEnv env,
IloInt index,
IloInt size,
IloInt* durations,
IloInt* resourceNumbers,
IloUnaryResource* resources)
:_index(index)
{
char buffer[128];
sprintf(buffer, "J%ld", index);
IlcInt len = strlen(buffer);
_name = new (env) char[len+1];
strcpy(_name, buffer);
IloArray<IloActivity> inShops(env, size);
IloArray<IloUnaryResource> machines(env, size);
IlcInt i;
for(i = 0; i < size; i++) {
sprintf(buffer, "J%ldS%ldR%ld", index, i, resourceNumbers[i]);
IloActivity act(env, durations[i], buffer);
act.setObject(this);
inShops[i] = act;
machines[i] = resources[resourceNumbers[i]];
}
_inShops = inShops;
_machines = machines;
}
IloInt Job::getShop(IloActivity act) const {
IloArray<IloActivity> inShops = _inShops;
IloInt size = inShops.getSize();
IloInt i;
for(i = 0; i < size; i++) {
if (inShops[i].getImpl() == act.getImpl())
return i;
}
return -1;
}
void Job::addToModel(IloModel model, IloIntVar makespan) {
IloArray<IloActivity> inShops = _inShops;
IloInt size = inShops.getSize();
IloInt i;
for(i = 1; i < size; i++)
model.add(inShops[i].startsAfterEnd(inShops[i-1]));
model.add(inShops[size - 1].endsBefore(makespan));
IloArray<IloUnaryResource> machines = _machines;
for(i = 0; i < size; i++)
model.add(inShops[i].requires(machines[i]));
}
///////////////////////////////////////////////////////////////////////////////
//
// PROBLEM DEFINITION
//
///////////////////////////////////////////////////////////////////////////////
#if defined(ILO_SDXLOUTPUT)
#include "sdxljssp.h"
#endif
IloModel
DefineModel(const IloEnv& env,
IloInt numberOfJobs,
IloInt numberOfResources,
IloInt* resourceNumbers,
IloInt* durations,
IloNumVar& makespan,
IloAnyArray& jobs)
{
IloModel model(env);
/* CREATE THE MAKESPAN VARIABLE. */
IloInt numberOfActivities = numberOfJobs * numberOfResources;
IloInt horizon = 0;
IloInt k;
for (k = 0; k < numberOfActivities; k++)
horizon += durations[k];
makespan = IloNumVar(env, 0, horizon, ILOINT);
/* CREATE THE RESOURCES. */
IloSchedulerEnv schedEnv(env);
schedEnv.getResourceParam().setCapacityEnforcement(IloMediumHigh);
IloInt j;
IloUnaryResource *resources =
new IloUnaryResource[numberOfResources];
char buffer[128];
for (j = 0; j < numberOfResources; j++) {
sprintf(buffer, "R%ld", j);
resources[j] = IloUnaryResource(env, buffer);
}
/* CREATE THE ACTIVITIES. */
k = 0;
IloInt i;
jobs = IloAnyArray(env, numberOfJobs);
for (i = 0; i < numberOfJobs; i++) {
IlcInt j = i*numberOfResources;
Job* job = new (env) Job(env, i, numberOfResources,
&durations[j],
&resourceNumbers[j],
resources);
job->addToModel(model, makespan);
jobs[i] = job;
}
/* RETURN THE MODEL. */
delete [] resources;
return model;
}
///////////////////////////////////////////////////////////////////////////////
//
// PRINTING OF SOLUTIONS
//
///////////////////////////////////////////////////////////////////////////////
void
PrintSolution(IloSolver solver,
IloAnyArray jobs,
IloIntVar makespan)
{
solver.out() << " Solution for Makespan "
<< solver.getValue(makespan) << endl;
IlcScheduler scheduler(solver);
IloEnv env = solver.getEnv();
IloInt numberOfJobs = jobs.getSize();
IloInt i;
for(i = 0; i < numberOfJobs; i++) {
Job* job = (Job*) jobs[i];
job->display(solver.out());
solver.out() << endl;
IloInt size = job->getSize();
IloInt j;
for(j = 0; j < size; j++) {
IloActivity act = job->getActivity(j);
solver.out() << "\t" << scheduler.getActivity(act) << endl;
}
}
#if defined(ILO_SDXLOUTPUT)
IloSDXLJobShopOutput output(env);
ofstream outFile("jobshopm.xml");
output.writeJobShop(scheduler, outFile, jobs, makespan);
outFile.close();
#endif
}
///////////////////////////////////////////////////////////////////////////////
//
// MAIN FUNCTION
//
///////////////////////////////////////////////////////////////////////////////
void
InitParameters(int argc,
char** argv,
IloInt& numberOfJobs,
IloInt& numberOfResources,
IloInt*& resourceNumbers,
IloInt*& durations)
{
if (argc > 1) {
IloInt number = atol(argv[1]);
if (number == 10) {
numberOfJobs = 10;
numberOfResources = 10;
resourceNumbers = ResourceNumbers10;
durations = Durations10;
}
else if (number == 20) {
numberOfJobs = 20;
numberOfResources = 5;
resourceNumbers = ResourceNumbers20;
durations = Durations20;
}
}
}
int main(int argc, char** argv)
{
try {
IloEnv env;
IloInt numberOfJobs = 6;
IloInt numberOfResources = 6;
IloInt* resourceNumbers = ResourceNumbers06;
IloInt* durations = Durations06;
InitParameters(argc,
argv,
numberOfJobs,
numberOfResources,
resourceNumbers,
durations);
IloNumVar makespan;
IloAnyArray jobs;
IloModel model = DefineModel(env,
numberOfJobs,
numberOfResources,
resourceNumbers,
durations,
makespan,
jobs);
model.add(IloMinimize(env, makespan));
IloSolver solver(model);
IloGoal goal = IloRankForward(env,
makespan,
IloSelResMinGlobalSlack,
IloSelFirstRCMinStartMax);
if (solver.solve(goal))
PrintSolution(solver, jobs, makespan);
else {
solver.out() << " Failure for Makespan "
<< solver.getMax(makespan) << endl;
}
solver.printInformation();
env.end();
} catch (IloException& exc) {
cout << exc << endl;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
//
// RESULTS
//
///////////////////////////////////////////////////////////////////////////////
/* jobshopm 6
Solution for Makespan 55
J0S0R2 [5..7 -- 1 --> 6..8]
J0S1R0 [6..11 -- 3 --> 9..14]
J0S2R1 [16 -- 6 --> 22]
J0S3R3 [30..36 -- 7 --> 37..43]
J0S4R5 [42..43 -- 3 --> 45..46]
J0S5R4 [49 -- 6 --> 55]
J1S0R1 [0 -- 8 --> 8]
J1S1R2 [8 -- 5 --> 13]
J1S2R4 [13..15 -- 10 --> 23..25]
J1S3R5 [28..29 -- 10 --> 38..39]
J1S4R0 [38..40 -- 10 --> 48..50]
J1S5R3 [48..50 -- 4 --> 52..54]
J2S0R2 [0..2 -- 5 --> 5..7]
J2S1R3 [5..7 -- 4 --> 9..11]
J2S2R5 [9..11 -- 8 --> 17..19]
J2S3R0 [18..19 -- 9 --> 27..28]
J2S4R1 [27..41 -- 1 --> 28..42]
J2S5R4 [42 -- 7 --> 49]
J3S0R1 [8 -- 5 --> 13]
J3S1R0 [13..14 -- 5 --> 18..19]
J3S2R2 [22 -- 5 --> 27]
J3S3R3 [27 -- 3 --> 30]
J3S4R4 [30 -- 8 --> 38]
J3S5R5 [45..46 -- 9 --> 54..55]
J4S0R2 [13 -- 9 --> 22]
J4S1R1 [22 -- 3 --> 25]
J4S2R4 [25 -- 5 --> 30]
J4S3R5 [38..39 -- 4 --> 42..43]
J4S4R0 [48..51 -- 3 --> 51..54]
J4S5R3 [52..54 -- 1 --> 53..55]
J5S0R1 [13 -- 3 --> 16]
J5S1R3 [16 -- 3 --> 19]
J5S2R5 [19 -- 9 --> 28]
J5S3R0 [28 -- 10 --> 38]
J5S4R4 [38 -- 4 --> 42]
J5S5R2 [42..54 -- 1 --> 43..55]
*/
/* jobshopm 10
Solution for Makespan 930
J0S0R0 [119 -- 29 --> 148]
J0S1R1 [445..448 -- 78 --> 523..526]
J0S2R2 [523..526 -- 9 --> 532..535]
J0S3R3 [532..540 -- 36 --> 568..576]
J0S4R4 [568..595 -- 49 --> 617..644]
J0S5R5 [640..644 -- 11 --> 651..655]
J0S6R6 [651..655 -- 62 --> 713..717]
J0S7R7 [721 -- 56 --> 777]
J0S8R8 [792..856 -- 44 --> 836..900]
J0S9R9 [893..909 -- 21 --> 914..930]
J1S0R0 [76 -- 43 --> 119]
J1S1R2 [224..244 -- 90 --> 314..334]
J1S2R4 [355 -- 75 --> 430]
J1S3R9 [430..467 -- 11 --> 441..478]
J1S4R3 [568..576 -- 69 --> 637..645]
J1S5R1 [637..689 -- 28 --> 665..717]
J1S6R6 [713..717 -- 46 --> 759..763]
J1S7R5 [759..767 -- 46 --> 805..813]
J1S8R7 [813 -- 72 --> 885]
J1S9R8 [885..900 -- 30 --> 915..930]
J2S0R1 [308..311 -- 91 --> 399..402]
J2S1R0 [408..411 -- 85 --> 493..496]
J2S2R3 [493..496 -- 39 --> 532..535]
J2S3R2 [532..535 -- 74 --> 606..609]
J2S4R8 [609 -- 90 --> 699]
J2S5R5 [699 -- 10 --> 709]
J2S6R7 [709 -- 12 --> 721]
J2S7R6 [759..763 -- 89 --> 848..852]
J2S8R9 [848..852 -- 45 --> 893..897]
J2S9R4 [893..897 -- 33 --> 926..930]
J3S0R1 [0..6 -- 81 --> 81..87]
J3S1R2 [84..90 -- 95 --> 179..185]
J3S2R0 [185 -- 71 --> 256]
J3S3R4 [256 -- 99 --> 355]
J3S4R6 [355..370 -- 9 --> 364..379]
J3S5R8 [364..379 -- 52 --> 416..431]
J3S6R7 [416..431 -- 85 --> 501..516]
J3S7R3 [637..645 -- 98 --> 735..743]
J3S8R9 [766..830 -- 22 --> 788..852]
J3S9R5 [805..887 -- 43 --> 848..930]
J4S0R2 [210..230 -- 14 --> 224..244]
J4S1R0 [269..272 -- 6 --> 275..278]
J4S2R1 [286..289 -- 22 --> 308..311]
J4S3R5 [308..313 -- 61 --> 369..374]
J4S4R3 [370..404 -- 26 --> 396..430]
J4S5R4 [430 -- 69 --> 499]
J4S6R8 [499 -- 21 --> 520]
J4S7R7 [530..541 -- 49 --> 579..590]
J4S8R9 [593..657 -- 72 --> 665..729]
J4S9R6 [848..877 -- 53 --> 901..930]
J5S0R2 [0..3 -- 84 --> 84..87]
J5S1R1 [84..87 -- 2 --> 86..89]
J5S2R5 [86..90 -- 52 --> 138..142]
J5S3R3 [138..142 -- 95 --> 233..237]
J5S4R8 [233..244 -- 48 --> 281..292]
J5S5R9 [281..292 -- 72 --> 353..364]
J5S6R0 [361..364 -- 47 --> 408..411]
J5S7R6 [420..445 -- 65 --> 485..510]
J5S8R4 [499..510 -- 6 --> 505..516]
J5S9R7 [505..516 -- 25 --> 530..541]
J6S0R1 [86..89 -- 46 --> 132..135]
J6S1R0 [148 -- 37 --> 185]
J6S2R3 [233..237 -- 61 --> 294..298]
J6S3R2 [375..395 -- 13 --> 388..408]
J6S4R6 [388..408 -- 32 --> 420..440]
J6S5R5 [421..440 -- 21 --> 442..461]
J6S6R9 [442..478 -- 32 --> 474..510]
J6S7R8 [520 -- 89 --> 609]
J6S8R7 [668..679 -- 30 --> 698..709]
J6S9R4 [698..740 -- 55 --> 753..795]
J7S0R2 [179..199 -- 31 --> 210..230]
J7S1R0 [275..278 -- 86 --> 361..364]
J7S2R1 [399..402 -- 46 --> 445..448]
J7S3R5 [445..461 -- 74 --> 519..535]
J7S4R4 [519..535 -- 32 --> 551..567]
J7S5R6 [557..567 -- 88 --> 645..655]
J7S6R8 [699..710 -- 19 --> 718..729]
J7S7R9 [718..729 -- 48 --> 766..777]
J7S8R7 [777 -- 36 --> 813]
J7S9R3 [813..851 -- 79 --> 892..930]
J8S0R0 [0 -- 76 --> 76]
J8S1R1 [217..220 -- 69 --> 286..289]
J8S2R3 [294..298 -- 76 --> 370..374]
J8S3R5 [370..374 -- 51 --> 421..425]
J8S4R2 [421..425 -- 85 --> 506..510]
J8S5R9 [506..510 -- 11 --> 517..521]
J8S6R6 [517..527 -- 40 --> 557..567]
J8S7R7 [579..590 -- 89 --> 668..679]
J8S8R4 [668..714 -- 26 --> 694..740]
J8S9R8 [718..782 -- 74 --> 792..856]
J9S0R1 [132..135 -- 85 --> 217..220]
J9S1R0 [256..259 -- 13 --> 269..272]
J9S2R2 [314..334 -- 61 --> 375..395]
J9S3R6 [375..401 -- 7 --> 382..408]
J9S4R8 [416..435 -- 64 --> 480..499]
J9S5R9 [517..521 -- 76 --> 593..597]
J9S6R5 [593..597 -- 47 --> 640..644]
J9S7R3 [735..743 -- 52 --> 787..795]
J9S8R4 [787..795 -- 90 --> 877..885]
J9S9R7 [885 -- 45 --> 930]
*/