Reputation: 23
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.
Upvotes: 2
Views: 310
Reputation: 11014
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)
Upvotes: 1