To search for a solution, we must sequence each machine. The goal IlcSequence
is provided by Scheduler Engine for this purpose. We can guess that having a minimal makespan is closely related to having the smallest possible transition costs and times. That's why the selector of the next activity on a partial sequence uses the minimal energy of the maintenance team workers' resource as tie breaker. Precisely, we select the successor with minimal earliest start time, then minimal transition energy, then minimal latest end time.
The order of execution of the activities on a unary resource suffices to make a solution explicit. This is not true on a discrete resource for which the start time of each activity must be assigned. For that purpose, we use the IlcSetTimes
goal with a selector on the activities requiring the discrete resource, that is, the maintenance activities.
/* CREATE A SELECTOR FOR THE ACTIVITIES ON THE WORKERS RESOURCE. */
ILOPREDICATE0(MaintenanceTaskPredicate, IlcActivity, act) {
return (act.getObject() != 0);
}
/* CREATE SEARCH GOAL. */
ILCGOAL2(SolveIlc,
IlcIntVar, makespan,
IlcTransitionCostObject, enerTCostObjIlc) {
IloSolver solver = getSolver();
IlcScheduler scheduler (solver);
IloPredicate<IlcActivity> predA = !IlcActivityStartVarBoundPredicate(solver)
&& !IlcActivityPostponedPredicate(solver)
&& MaintenanceTaskPredicate(solver);
IloComparator<IlcActivity> compA =
IloComposeLexical(IlcActivityStartMinEvaluator(solver).makeLessThanComparator(),
IlcActivityEndMaxEvaluator(solver).makeLessThanComparator());
IloSelector<IlcActivity,IlcSchedule> maintenanceTaskSelector =
IloBestSelector<IlcActivity,IlcSchedule>(predA, compA);
IloEvaluator<IlcResourceConstraint> eval =
IlcResourceConstraintNextTransitionCostEvaluator(solver,enerTCostObjIlc);
IloTranslator<IlcActivity, IlcResourceConstraint> ac =
IlcActivityResourceConstraintTranslator(solver);
IloSelector<IlcResourceConstraint,IlcResourceConstraint> selector =
IloBestSelector<IlcResourceConstraint,IlcResourceConstraint>(
IloComposeLexical((IlcActivityStartMinEvaluator(solver) << ac).makeLessThanComparator(),
eval.makeLessThanComparator(),
(IlcActivityEndMaxEvaluator(solver) << ac).makeLessThanComparator()));
return IlcAnd(IlcSequence(scheduler, selector),
IlcSetTimes(scheduler, makespan,
maintenanceTaskSelector));
}
ILOCPGOALWRAPPER2(Solve, solver,
IloNumVar, makespan,
IloTransitionParam, enerTParam) {
IlcScheduler scheduler(solver);
return SolveIlc(solver,
solver.getIntVar(makespan),
scheduler.getTransitionCostObject(enerTParam));
}