You can see the entire program durablem.cpp
here or view it online in the standard distribution.
#include <ilsched/iloscheduler.h>
#include <ilsched/workserv.h>
ILOSTLBEGIN
const IloInt Horizon = 30;
/////////////////////////////////////////////
//
// CREATING THE DURABLE RESOURCES
//
////////////////////////////////////////////
IlcScheduler CreateDurableResources(IloSolver solver0,
IloInt nbOfWorkers,
IloUnaryResource* workers) {
/* CREATE A DURABLE MODEL. */
IloEnv env0 = solver0.getEnv();
IloModel model0(env0);
IloSchedulerEnv schedEnv0(env0);
IloIntervalList blist(env0, 0, 100);
blist.addPeriodicInterval(5, 2, 7, 100);
schedEnv0.setBreakListParam(blist);
IlcInt i=0;
for (i = 0; i < nbOfWorkers; i++){
workers[i] = IloUnaryResource(env0);
model0.add(workers[i]);
}
IlcScheduler durSched(solver0);
durSched.setDurable();
solver0.extract(model0);
/* CLOSE THE DURABLE SCHEDULER. */
durSched.close();
return durSched;
}
///////////////////////////////////////////////
//
// TREATING A REQUEST
//
//////////////////////////////////////////////
ILCGOAL3(TreatRequestIlc,
IlcInt, reqIndex,
IlcUnaryResource*, team,
IlcInt, releaseDate){
/* CREATING A SCHEDULE. */
IloSolver solver = getSolver();
IlcSchedule schedule(solver, 0, Horizon);
/* LOCKING THE NEEDED RESOURCES. */
schedule.lock(4, team);
/* DEFINING THE PROBLEM. */
IlcActivity* act = new (solver.getHeap()) IlcActivity[4];
for (IlcInt i = 0; i < 4; i++){
act[i] = IlcActivity(schedule, 1);
solver.add(act[i].requires(team[i]));
}
solver.add(act[0].startsAfter(releaseDate));
solver.add(act[1].startsAfterEnd(act[0]));
solver.add(act[2].startsAfterEnd(act[0]));
solver.add(act[3].startsAfterEnd(act[1]));
solver.add(act[3].startsAfterEnd(act[2]));
/* SOLVING THE PROBLEM. */
solver.startNewSearch(IlcSetTimes(schedule));
IloBool solved = solver.next();
/* UNLOCKING THE USED COMPUTATIONAL RESOURCES. */
schedule.unlock(4, team);
if (solved) {
/* ACCEPTING OR NOT. */
IlcInt acceptDate = releaseDate + 5;
IlcInt dueDate = act[3].getEndMin();
if (dueDate > acceptDate){
// Not accepting :
solver.out() << "request " << reqIndex << ": refused " << endl;
solver.restartSearch();
}
else {
// Accepting :
solver.out() << "request " << reqIndex
<< ": promised at " << act[3].getEndMin()
<< endl;
}
}
else
solver.out() << "request " << reqIndex
<< ": not solved " << endl;
solver.endSearch();
return 0;
}
ILOCPGOALWRAPPER4(TreatRequest, solver,
IlcScheduler, dSched,
IloInt, reqIndex,
IloUnaryResource*, team,
IloInt, releaseDate) {
IlcUnaryResource* workers = new (solver.getHeap()) IlcUnaryResource[4];
for (IlcInt i = 0; i < 4; i++)
workers[i] = dSched.getResource(team[i]);
return TreatRequestIlc(solver, reqIndex, workers, releaseDate);
}
/////////////////////////////////////////
//
// DEFINING THE REQUESTS
//
/////////////////////////////////////////
const IloInt HowManyReqs = 20;
IloInt StreamOfReqs [HowManyReqs] [2] = { /* pairs type releaseDate */
{1, 5}, // request 0
{2, 15}, // request 1
{2, 7} , // request 2
{1, 24}, // request 3
{2, 2}, // request 4
{1, 10}, // request 5
{1, 25}, // request 6
{1, 17}, // request 7
{2, 8}, // request 8
{1, 15}, // request 9
{2, 21}, // request 10
{2, 5}, // request 11
{1, 15}, // request 12
{2, 17}, // request 13
{2, 24}, // request 14
{2, 2}, // request 15
{1, 10}, // request 16
{2, 28}, // request 17
{1, 17}, // request 18
{2, 10} // request 19
};
int main(int argc, char* argv[]) {
try {
const IloInt nbOfWorkers = 8;
IloUnaryResource workers[nbOfWorkers];
IloUnaryResource* firstTeam = workers;
IloUnaryResource* secondTeam = workers + 4;
/* CREATING THE DURABLE RESOURCES. */
IloEnv env0;
IloSolver solver0(env0);
IlcScheduler sched0 =
CreateDurableResources(solver0, nbOfWorkers, workers);
/* CREATING THE WORKER THREADS. */
IloInt nbOfThreads = 3;
if (argc >= 2)
nbOfThreads = atol(argv[1]);
IlcWorkServer server(sched0, nbOfThreads, "output");
/* TREATING THE REQUESTS. */
for (IloInt j = 0; j < HowManyReqs; j++) {
// Reading a request :
IloInt requestType = StreamOfReqs[j][0];
IloInt releaseDate = StreamOfReqs[j][1];
// Getting a computation environment :
IloEnv env = server.getIdleEnv();
// Solving the specific problem associated with the request:
IloUnaryResource* team = (requestType == 1 ?
firstTeam :
secondTeam);
server.launch(TreatRequest(env, sched0, j, team, releaseDate));
}
/* STOPPING THE WORKER THREADS. */
server.end();
/* PRINTING THE SCHEDULE OF WORKERS. */
IlcScheduler scheduler0(solver0);
IloSchedulerSolution solution(env0);
for (IloInt i = 0; i < nbOfWorkers; i++) {
solver0.out() << endl << "worker" << i << ": " << endl;
solution.store(workers[i], scheduler0);
for (IloNumToNumStepFunctionCursor curs(solution.getLevelMin(workers[i]));
curs.ok();
++curs)
solver0.out() << curs.getSegmentMin() << " .. "
<< IloMin(Horizon, (curs.getSegmentMax() - 1)) << " : "
<< (curs.getValue() == 1 ? "On" : "Off")
<< endl;
}
solver0.printInformation();
env0.end();
} catch (IloException& exc) {
cout << exc << endl;
} return 0;
}
//////////////////////////////////////////////
//
// RESULTS
//
/////////////////////////////////////////////
/* durablem 0
request 0: promised at 10
request 1: promised at 18
request 2: promised at 10
request 3: promised at 29
request 4: promised at 5
request 5: promised at 15
request 6: promised at 30
request 7: promised at 22
request 8: promised at 11
request 9: promised at 18
request 10: promised at 24
request 11: refused
request 12: promised at 19
request 13: promised at 22
request 14: promised at 29
request 15: refused
request 16: refused
request 17: not solved
request 18: refused
request 19: promised at 15
worker0:
0 .. 6 : Off
7 .. 7 : On
8 .. 9 : Off
10 .. 10 : On
11 .. 14 : Off
15 .. 17 : On
18 .. 23 : Off
24 .. 25 : On
26 .. 29 : Off
worker1:
0 .. 7 : Off
8 .. 8 : On
9 .. 10 : Off
11 .. 11 : On
12 .. 15 : Off
16 .. 18 : On
19 .. 24 : Off
25 .. 25 : On
26 .. 27 : Off
28 .. 28 : On
29 .. 29 : Off
worker2:
0 .. 7 : Off
8 .. 8 : On
9 .. 10 : Off
11 .. 11 : On
12 .. 15 : Off
16 .. 18 : On
19 .. 24 : Off
25 .. 25 : On
26 .. 27 : Off
28 .. 28 : On
29 .. 29 : Off
worker3:
0 .. 8 : Off
9 .. 9 : On
10 .. 13 : Off
14 .. 14 : On
15 .. 16 : Off
17 .. 18 : On
19 .. 20 : Off
21 .. 21 : On
22 .. 27 : Off
28 .. 29 : On
worker4:
0 .. 1 : Off
2 .. 2 : On
3 .. 6 : Off
7 .. 8 : On
9 .. 9 : Off
10 .. 10 : On
11 .. 14 : Off
15 .. 15 : On
16 .. 16 : Off
17 .. 17 : On
18 .. 20 : Off
21 .. 21 : On
22 .. 23 : Off
24 .. 24 : On
25 .. 29 : Off
worker5:
0 .. 2 : Off
3 .. 3 : On
4 .. 7 : Off
8 .. 9 : On
10 .. 10 : Off
11 .. 11 : On
12 .. 15 : Off
16 .. 16 : On
17 .. 17 : Off
18 .. 18 : On
19 .. 21 : Off
22 .. 22 : On
23 .. 24 : Off
25 .. 25 : On
26 .. 29 : Off
worker6:
0 .. 2 : Off
3 .. 3 : On
4 .. 7 : Off
8 .. 9 : On
10 .. 10 : Off
11 .. 11 : On
12 .. 15 : Off
16 .. 16 : On
17 .. 17 : Off
18 .. 18 : On
19 .. 21 : Off
22 .. 22 : On
23 .. 24 : Off
25 .. 25 : On
26 .. 29 : Off
worker7:
0 .. 3 : Off
4 .. 4 : On
5 .. 8 : Off
9 .. 10 : On
11 .. 13 : Off
14 .. 14 : On
15 .. 16 : Off
17 .. 17 : On
18 .. 20 : Off
21 .. 21 : On
22 .. 22 : Off
23 .. 23 : On
24 .. 27 : Off
28 .. 28 : On
29 .. 29 : Off
*/