I am trying to solve the shift scheduling problem according to https://github.com/google/or-tools/blob/39f44709bba203f5ff3bc18fab8098739f189a6d/examples/python/shift_scheduling_sat.py,
but since my problem has multiple 30m shift slots rather than 3, aka shift1-shift22 for 06:00am till 19:00pm allocation, I can't understand or workout how the soft_sum_constraint
would work on my scenario when I need for example max of 5 working days in total per week per person.
Here is a sample of my code:
for e in range(num_employees):
if db['conthoursperweek'][(e)]>0:
max_cont_shifts=round(int(db['conthoursperweek'][e] / 5)*2)
for d in range(7):
if d==6:
if db['optedinsundays'][e]==0:
for s in range(num_of_shifts):
model.Add(work[e, s, 6]==0)
else:
model.Add(sum(work[e, s, d]
for s in range(num_of_shifts)) >= max_cont_shifts)
model.Add(sum(work[e, s, d]
for s in range(num_of_shifts)) < max_cont_shifts + 4)
else:
model.Add(sum(work[e, s, d]
for s in range(num_of_shifts)) >= max_cont_shifts)
model.Add(sum(work[e, s, d]
for s in range(num_of_shifts)) < max_cont_shifts + 4)
for d in range(num_days):
for e in range(num_employees):
for s in range(num_of_shifts-1):
for x in range(s+1,num_of_shifts):
model.Add(work[e,x,d] == 0).OnlyEnforceIf([work[e,s-1,d],work[e,s,d].Not()])
This satisfies my need for shifts per day constraints and them being continuous. I need to do the same for days but nothing I have tried so far works.
Things like below do not work:
for e in range(num_employees):
model.Add(sum(work[e, s, d] for d in range(7) for s in range(num_of_shifts))<=80) #for max shifts per week
#or
work_days=[]
for e in range(num_employees):
for d in range(7):
working=sum(work[e, s, d] for s in range(num_of_shifts))
work_days.append(working)
model.Add(work_days<=5)
#or
for e in range(num_employees):
for d in range(7):
model.Add(sum(work[e, s, d])<=5)
I know the above code is wrong but I can't figure it out. Any help would be greatly appreciated.
Just create one boolean that is true if at least one shift of this day is true. And use it you inter-day constraints.
For the record:
a <=> or(b1, .., bn)
is encoded as
for all i: bi implies a
bool_or(a.Not(), b1, .., bn)