每天有多个班次时如何添加使用 ORTools 的最大天数
How to add a max sequence of days working with ORTools when having multiple shifts per day
我正在尝试根据https://github.com/google/or-tools/blob/39f44709bba203f5ff3bc18fab8098739f189a6d/examples/python/shift_scheduling_sat.py解决排班问题,
但由于我的问题有多个 30m 的班次槽而不是 3 个,也就是 06:00am 到 19:00pm 分配的 shift1-shift22,我无法理解或锻炼 soft_sum_constraint
如何在我的场景中工作例如,当我需要每人每周总共最多 5 个工作日时。
这是我的代码示例:
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()])
这满足了我对每天轮班限制的需求,并且它们是连续的。我几天都需要做同样的事情,但到目前为止我没有尝试过。
像下面这样的东西不起作用:
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)
我知道上面的代码是错误的,但我想不通。任何帮助将不胜感激。
只需创建一个布尔值,如果这一天的至少一个班次为真,则为真。
并使用它 inter-day 约束。
备案:
a <=> or(b1, .., bn)
编码为
for all i: bi implies a
bool_or(a.Not(), b1, .., bn)
我正在尝试根据https://github.com/google/or-tools/blob/39f44709bba203f5ff3bc18fab8098739f189a6d/examples/python/shift_scheduling_sat.py解决排班问题,
但由于我的问题有多个 30m 的班次槽而不是 3 个,也就是 06:00am 到 19:00pm 分配的 shift1-shift22,我无法理解或锻炼 soft_sum_constraint
如何在我的场景中工作例如,当我需要每人每周总共最多 5 个工作日时。
这是我的代码示例:
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()])
这满足了我对每天轮班限制的需求,并且它们是连续的。我几天都需要做同样的事情,但到目前为止我没有尝试过。
像下面这样的东西不起作用:
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)
我知道上面的代码是错误的,但我想不通。任何帮助将不胜感激。
只需创建一个布尔值,如果这一天的至少一个班次为真,则为真。 并使用它 inter-day 约束。
备案:
a <=> or(b1, .., bn)
编码为
for all i: bi implies a
bool_or(a.Not(), b1, .., bn)