FRAMES NO FRAMES

IlcSetTimes

public IlcGoal IlcSetTimes(IlcSchedule schedule, IloSelector< IlcActivity, IlcSchedule > aSel=0)
public IlcGoal IlcSetTimes(IlcSchedule schedule, IlcIntVar criterion, IloSelector< IlcActivity, IlcSchedule > aSel=0)
Definition file: ilsched/srchgoal.h
Include file: <ilsched/search.h>

This function creates and returns a goal that assigns a start time to all activities managed by schedule. If the argument criterion is given, then the assignments are made to minimize criterion. The activity selector aSel selects the next activity. By default, that is, if no activity selector is given as an argument, the activity selector used is defined as follows:

 IloSelector<IlcActivity,IlcSchedule> aSel = IlcActivityInScheduleSelector(s);
 sel.setPredicate(!IlcActivityStartVarBoundPredicate(s) &&
		    !IlcActivityPostponedPredicate(s));
 sel.setComparator(IlcLexicalComposition(IlcCompareMin(IlcActivityStartMinEvaluator(s)),
					   IlcCompareMin(IlcActivityEndMaxEvaluator(s))));
 

The goal is designed to efficiently schedule activities in a chronological order. It considers only solutions that can be produced as follows: in each step, choose an unscheduled activity A of minimal earliest start time and schedule it as early as possible, as allowed by the previously scheduled activities (which have smaller start times than A).

Internally, the function uses a schedule-or-postpone method that works as follows:

  1. A selected activity is assigned to its earliest start time.
  2. If that start time leads to a failure, the activity is postponed until its earliest start time has been removed. This removal can occur as a result of a combination of decisions and propagation.

Before assigning the earliest start time to an activity with a candidate start time st, it is determined whether an already postponed activity actP exists that can be or should be scheduled before st, that is, whether actP.getEndMin() <= st or actP.getStartMax() <= st. If this is the case, a fail is generated based on the reasoning that if we have “normal” precedence and resource constraints, the earliest start time of actP will never be removed and thus actP will remain postponed and no solution will be found in this branch of the search tree.

This reasoning can result in an incomplete search (that is, solutions may be missed) in some situations. To take a specific example, suppose we have an activity B that can start as much as 50 units after the start of an activity A. This can be expressed by a precedence constraint with negative delay:

 A.startsAfterStart(B, -50) 

Assume that B cannot be scheduled at a time earlier than 100 because it requires a resource that has a maximal capacity of 0 in the interval [0,100). A, therefore, cannot be scheduled before time 50 even if there are no earlier activities. IlcSetTimes will not find a solution here, because it will attempt to assign A to a start time of 0. When this fails, it will postpone A but then realize that there are no other activities that can be schedule before A and therefore it concludes that there are no solutions. Note that in this very simple case, it is likely that constraint propagation will discover that 50 is the actual earliest start time of A and so IlcSetTimes will successfully find a solution. However, if this situation is part of a larger, more complex constraint interaction, it cannot be guaranteed that constraint propagation will discover the globally consistent earliest start time. In such a situation, then, a solution will be missed.

Another situation where missed solutions can arise is when the processing time of an activity depends on its start or end time. For example, we have three activities, A, B, and C, all of which require the same unary capacity resource. Activities B and C have processing times of 10. Activity A has a processing time of 1 if its start time is in the set {1, 2, 3, 4} and a processing time of 10 otherwise. The scheduling horizon is 25 time units and B and C can only start at or after time unit 1.

The Scheduler Concert Technology code below and the output demonstrate that such a situation leads to a missed solution when IlcSetTimes (extracted from the IloSetTimesForward goal) is used.

 IloEnv env;
 IloModel model(env);

 IloSchedulerEnv schedEnv(env);
 schedEnv.setOrigin(0);
 schedEnv.setHorizon(25);

 IloNumVar ptA(env, 1, 10, ILOINT);
 IloActivity a(env, ptA);
 a.setName("A");

 IloActivity b(env, 10, "B");
 IloActivity c(env, 10, "C");

 model.add(b.startsAfter(1));
 model.add(c.startsAfter(1));

 // processing time is 1 iff start time is in set {1, 2, 3, 4}
 // otherwise processing time is 10

 IloNumVar stA = a.getStartVariable();
 model.add((stA < 1) || (stA > 4) || (ptA == 1));
 model.add(((stA >= 1) && (stA <= 4)) || (ptA == 10));

 IloUnaryResource r(env);
 model.add(a.requires(r));
 model.add(b.requires(r));
 model.add(c.requires(r));

 IloSolver solver(model);
 IloBool solved = solver.solve(IloSetTimesForward(env));
 solver.out() << "First solve: " << solved << endl;

 model.add(a.startsAt(1));
 solved = solver.solve(IloSetTimesForward(env));
 solver.out() << "Solve after adding a.startsAt(1): "
 	     << solved << endl;

 Output:
 First solve: 0
 Solve after adding a.startsAt(1): 1

What happens in this example is that the IlcSetTimes goals tries to assign activity A to start time 0. This leads to a dead-end because this implies that all three activities have a processing time of 10 which cannot be accommodated on a unary resource within the 25 time-unit scheduling horizon. Activity A is then postponed and the goal attempts to assign B to time 1. This fails, as all three activities again would have to have processing times of 10. Finally, the goal tries to schedule activity C at time 1, with the same result as when it tried activity B. Therefore, the goal concludes, there are no solutions.

Clearly, however, there are solutions, as demonstrated when we assign the start time of A to be 1. The processing time of A is therefore 1 and the other two activities can then follow within the scheduling horizon.

In general, IlcSetTimes may miss solutions if there are precedence constraints with negative delay, if the processing time of an activity depends on its start or end time, or if reservoirs are used.

Note
WARNING In order to ensure a purely chronological scheduling, the supplied activity selector should always choose an unscheduled activity of minimal earliest start time. Furthermore, scheduling an activity at time t should not have an impact on the earliest start times of activities that have been scheduled earlier.

In particular, care should be taken in using precedence constraints with a negative delay, activities where the processing time depends on the start or end time of the activity, and reservoirs.

See IloSelector in the IBM ILOG Solver Reference Manual for more information.

See Also: