The situation is as follows: I am creating a daily schedule for a workplace. Each day is divided into timeslots, and at each timeslot I know how many employees must be present. The schedule is created using two integer decision variables that describe the arrival and departure timeslots of each employee.
Currently, I use an extra variable to tell whether employee i is at work at time t, and then I sum them over employees at each timeslot to compare with the requirement. My code can be boiled down to the following:
using CP;
tuple TimeSlot {
key int id;
int minEmploy;
}
{TimeSlot} TSlots = ...;
{int} timeSlots = {t.id|t in TSlots};
int tMax = max(t in timeSlots) t;
range dayRange = 0..tMax;
range allEmployees = 1..10;
dvar int dayStart[allEmployees] in dayRange;
dvar int dayEnd[allEmployees] in dayRange;
dvar int workTimeT[allEmployees][timeSlots] in 0..1;
minimize ...;
subject to {
/*Indicator constraints*/
forall(i in allEmployees){
forall(t in timeSlots:t>0){
dayStart[i] <= t && t <= dayEnd[i] => workTimeT[i][t] == 1;
dayEnd[i] < t || t < dayStart[i] => workTimeT[i][t] == 0;
}
}
/*Must satisfy requirement*/
forall(t in timeSlots:t>0){
sum(i in allEmployees) workTimeT[i][t] >= item(TSlots,<t>).minEmploy;
}
}
Is there any way to get around this extra variable? It can't possibly be efficient to add #employees times #timeslots variables just to check if a number is between two decision variables.