IBM ILOG Scheduler User's Manual > Advanced Concepts > More Advanced Problem Modeling with Concert Technology > Complete Program and Output |
Complete Program and Output |
INDEX
![]() |
You can see the entire program cassign.cpp
here or online in the standard distribution.
#include <ilsched/iloscheduler.h> ILOSTLBEGIN #if defined(ILO_SDXLOUTPUT) #include "sdxloutput.h" #endif IloInt NumberOfActivities = 10; IloInt NumberOfWorkers = 3; const char* ActivityNames [] = {"masonry ", "carpentry ", "plumbing ", "ceiling ", "roofing ", "painting ", "windows ", "facade ", "garden ", "moving "}; const char* WorkerNames [] = {"joe", "jack", "jim"}; IloNum ProcessingTimes [] = {7, 3, 8, 3, 1, 2, 1, 2, 1, 1}; const char* PossibleAssignments [] = {"joe", "jack", 0, "joe", 0, "jim", 0, "jack", 0, "joe", 0, "jim", "joe", 0, "jim", 0, "jack", "jim", "joe", 0, "jim", "joe", "jack", 0, "joe", "jack", "jim", "joe", 0, "jim"}; /* THE PROBLEM IS TO MINIMIZE EITHER (1) THE MAXIMAL OR (2) THE AVERAGE AMOUNT OF TIME SPENT BY EACH WORKER ON THE CONSTRUCTION SITE GIVEN THAT A WORKER CANNOT LEAVE THE SITE BETWEEN TWO ACTIVITIES. */ /////////////////////////////////////////////////////////////////////////////// // // DEFINITION OF THE WORKER CLASS // /////////////////////////////////////////////////////////////////////////////// class Worker { private: IloUnaryResource _resource; IloActivity _limitedAttendanceOnSite; public: Worker(IloModel, IloNum durMaxOnSite, const char* name); ~Worker(); IloUnaryResource getResource() const { return _resource; } IloActivity getAttendance() const { return _limitedAttendanceOnSite; } IloNumVar getAttendanceProcessingTime() const { return _limitedAttendanceOnSite.getProcessingTimeVariable(); } IloConstraint coverAttendance(IloActivity act); }; Worker::Worker(IloModel model, IloNum durMaxOnSite, const char* name) :_resource(model.getEnv()), _limitedAttendanceOnSite(model.getEnv(), IloNumVar(model.getEnv(), 0, durMaxOnSite, IloNumVar::Int)) { _resource.setName(name); _resource.setCapacityEnforcement(IloMediumHigh); _limitedAttendanceOnSite.setName("Attendance"); _resource.setObject(this); /* NEGATIVE STATEMENT: THE FACT THAT THE WORKER IS ON THE SITE FOR A LIMITED INTERVAL OF TIME MEANS THAT IT IS TO BE CONSIDERED "REQUIRED" BEFORE AND AFTER THIS INTERVAL OF TIME. */ model.add(_limitedAttendanceOnSite.requires(_resource, 1, IloBeforeStartAndAfterEnd)); } Worker::~Worker() {} IloConstraint Worker::coverAttendance(IloActivity act){ return (act.startsAfterStart(_limitedAttendanceOnSite) && _limitedAttendanceOnSite.endsAfterEnd(act)); } /////////////////////////////////////////////////////////////////////////////// // // PROBLEM DEFINITION // /////////////////////////////////////////////////////////////////////////////// void AddTemporalConstraints(IloModel model, IloActivityArray task, IloNum origin) { IloActivity masonry = task[0]; IloActivity carpentry = task[1]; IloActivity plumbing = task[2]; IloActivity ceiling = task[3]; IloActivity roofing = task[4]; IloActivity painting = task[5]; IloActivity windows = task[6]; IloActivity facade = task[7]; IloActivity garden = task[8]; IloActivity moving = task[9]; /* POST THE TEMPORAL CONSTRAINTS. */ masonry.setStartMax(origin); model.add(carpentry.startsAfterEnd(masonry)); model.add(plumbing.startsAfterEnd(masonry)); model.add(ceiling.startsAfterEnd(masonry)); model.add(roofing.startsAfterEnd(carpentry)); model.add(painting.startsAfterEnd(ceiling)); model.add(windows.startsAfterEnd(roofing)); model.add(facade.startsAfterEnd(roofing)); model.add(facade.startsAfterEnd(plumbing)); model.add(garden.startsAfterEnd(roofing)); model.add(garden.startsAfterEnd(plumbing)); model.add(moving.startsAfterEnd(windows)); model.add(moving.startsAfterEnd(facade)); model.add(moving.startsAfterEnd(garden)); model.add(moving.startsAfterEnd(painting)); } IloModel DefineProblem(IloEnv env, IloInt numberOfActivities, IloInt numberOfWorkers, const char** activityNames, const char** workerNames, IloNum* processingTimes, const char** possibleAssignments, IloAltResSet& workersSet, IloNumVar& maxCriterion, IloNumVar& sumCriterion) { /* CREATE THE MODEL. */ IloNum origin = 0; IloNum horizon = 18; IloModel model(env); IloSchedulerEnv schedEnv(env); schedEnv.setOrigin(origin); schedEnv.setHorizon(horizon); /* CREATE THE WORKERS AND SET THE OPTIMIZATION CRITERIA. */ IloUnaryResourceArray workers(env, numberOfWorkers); IloNumVarArray attendancies(env, numberOfWorkers); IloInt i; for (i = 0; i < numberOfWorkers; i++) { Worker* worker = new (env) Worker(model, horizon, workerNames[i]); attendancies[i] = worker->getAttendanceProcessingTime(); workers[i] = worker->getResource(); workersSet.add(workers[i]); } sumCriterion = IloNumVar(env, 0, numberOfWorkers * horizon, IloNumVar::Int); maxCriterion = IloNumVar(env, 0, horizon, IloNumVar::Int); model.add(sumCriterion == IloSum(attendancies)); model.add(maxCriterion == IloMax(attendancies)); /* CREATE THE ACTIVITIES AND THE ASSIGNMENT VARIABLES. IT IS ASSUMED THAT THERE IS AT LEAST ONE POSSIBLE ASSIGNMENT PER ACTIVITY. */ IloInt k = 0; IloActivityArray tasks(env,numberOfActivities); for (i = 0; i < numberOfActivities; i++) { IloActivity activity(env, processingTimes[i]); activity.setName(activityNames[i]); tasks[i] = activity; // RESOURCE ALLOCATION DEMAND IloResourceConstraint alternative = activity.requires(workersSet, 1); // REMOVE UNAVAILABLE WORKERS for (IloInt j = 0; j < numberOfWorkers; j++) { if (!possibleAssignments[k]) { alternative.setRejected(workers[j]); } else { model.add(IloIfThen(env, alternative.select(workers[j]), (((Worker*) workers[j].getObject())->coverAttendance(activity)))); } k++; } model.add(alternative); } AddTemporalConstraints(model, tasks, origin); /* RETURN THE CREATED MODEL. */ return model; } /////////////////////////////////////////////////////////////////////////////// // // PRINTING OF SOLUTIONS // /////////////////////////////////////////////////////////////////////////////// void PrintSolution(IloSolver solver, IlcInt maxCriterionValue, IlcInt sumCriterionValue) { IlcScheduler scheduler(solver); for (IlcAltResSetIterator resIte(scheduler); resIte.ok(); ++resIte) { for(IlcAltResConstraintIterator ite(*resIte); ite.ok(); ++ite) { if ((*ite).getNumberOfPossible() == 1) solver.out() << (*ite).getSelected() << "\t" << (*ite).getActivity() << endl; } } solver.out() << "MAXIMAL ATTENDANCE ON SITE = " << maxCriterionValue << endl; solver.out() << "SUM OF ATTENDANCES ON SITE = " << sumCriterionValue << endl; } /////////////////////////////////////////////////////////////////////////////// // // MAIN FUNCTION // /////////////////////////////////////////////////////////////////////////////// void InitParameters(int argc, char** argv, IloBool& minimizeMax) { if ((argc > 1) && (!strcmp(argv[1], "-minimizeSum"))) minimizeMax = IloFalse; } int main(int argc, char** argv) { try { IloBool minimizeMax = IlcTrue; InitParameters(argc, argv, minimizeMax); IloEnv env; IloNumVar maxCriterion, sumCriterion; IloAltResSet workersSet(env); IloModel model = DefineProblem(env, NumberOfActivities, NumberOfWorkers, ActivityNames, WorkerNames, ProcessingTimes, PossibleAssignments, workersSet, maxCriterion, sumCriterion); IloNumVar criterion = ((minimizeMax) ? maxCriterion : sumCriterion); model.add(IloMinimize(env, criterion)); IloSolver solver(model); IloGoal goal = IloAssignAlternative(env) && IloSetTimesForward(env, criterion, IloSelFirstActMinEndMin); if (solver.solve(goal)) { IlcInt maxCrit = solver.getIntVar(maxCriterion).getMin(); IlcInt sumCrit = solver.getIntVar(sumCriterion).getMin(); PrintSolution(solver, maxCrit, sumCrit); #if defined(ILO_SDXLOUTPUT) IloSDXLOutput output(env); ofstream outFile("cassign.xml"); output.write(IlcScheduler(solver), outFile); outFile.close(); #endif } else solver.out() << "No solution!" << endl; solver.printInformation(); env.end(); } catch (IloException& exc) { cout << exc << endl; } return 0; } /////////////////////////////////////////////////////////////////////////////// // // RESULTS // /////////////////////////////////////////////////////////////////////////////// /* cassign -minimizeMax jim [1] moving [17 -- 1 --> 18] jim [1] garden [15 -- 1 --> 16] jack [1] facade [15 -- 2 --> 17] jim [1] windows [12 -- 1 --> 13] jim [1] painting [13 -- 2 --> 15] jim [1] roofing [11 -- 1 --> 12] joe [1] ceiling [7 -- 3 --> 10] jack [1] plumbing [7 -- 8 --> 15] jim [1] carpentry [8 -- 3 --> 11] joe [1] masonry [0 -- 7 --> 7] MAXIMAL ATTENDANCE ON SITE = 10 SUM OF ATTENDANCES ON SITE = 30 */ /* cassign -minimizeSum joe [1] moving [17 -- 1 --> 18] joe [1] garden [15 -- 1 --> 16] jack [1] facade [15 -- 2 --> 17] joe [1] windows [16 -- 1 --> 17] jim [1] painting [11 -- 2 --> 13] joe [1] roofing [14 -- 1 --> 15] joe [1] ceiling [8 -- 3 --> 11] jack [1] plumbing [7 -- 8 --> 15] joe [1] carpentry [11 -- 3 --> 14] jack [1] masonry [0 -- 7 --> 7] MAXIMAL ATTENDANCE ON SITE = 17 SUM OF ATTENDANCES ON SITE = 29 */
As you can see from the results, if we want to minimize the time that any one worker spends on site, we'll minimize maximal attendance on site, and get results such as the first one, where all workers spend 10 days.
In contrast, if we minimize the total number of days spent on site for all workers, we'll get a solution like the second one, where jim
spends only 5 days, jack
17, and joe
stays 7 days on site.
© Copyright IBM Corp. 1987, 2009. Legal terms. | PREVIOUS NEXT |