如何解决跨时间范围内具有多个工作中心的员工轮班安排
我是 ORTools 的新手,正在尝试使用 ORTools 为涉及多个班次和工作中心的员工排班问题实施算法,
https://notebook.community/google/or-tools/examples/notebook/sat/schedule_requests_sat,
https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py,
等等…… 对于给定的工作中心,需要给定班次对员工的需求(例如:3 名员工上班,2 名员工上下午班,1 名员工上晚班。目标是将选定的员工分配到轮班和工作中心。 我在下面为 40 名员工、10 个工作中心和一个月做了这样的事情,但解决方案以一些员工 42 小时而其他员工 7 小时结束......
shift = {}
for n in all_nurses:
for s in all_shifts: # range(num_shifts):
for d in all_days:
for l in all_sites:
shift[(n,s,d,l)] = model.NewBoolVar(
'shift_n%is%id%il%i' % (n,l))
每位护士每天最多工作一班。
for n in all_nurses:
for d in all_days:
model.Add(sum(shift[(n,l)]
for s in range(num_shifts) for l in all_sites) <= 1)
每位护士每周工作 5 天
for n in all_nurses:
week = []
for l in all_sites:
for s in all_shifts:
for d in all_days:
week.append(shift[(n,l)])
# week.append(sum(shifts[(n,s)] for s in all_shifts))
# print(week)
model.Add(sum(week) == 5)
第 d 天第 l 班次的护士人数应小于或等于weekly_cover_demands[l][d][s]
for l in all_sites:
for d in all_days:
for s in range(num_shifts):
model.Add(sum(shift[(n,l)]
for n in all_nurses) <= weekly_cover_demands[l][d][s])
model.Maximize(
sum(shift[(n,l)]
for l in all_sites for d in all_days for n in all_nurses for s in range(num_shifts)))
解决方法
您的源代码存在一些问题。
- 您希望算法每周运行一次,但您提供了每月输入作为输入。您应该每周运行一次或添加周数。
a) 您可以将结束日期更改为 7 天
dates = {'start': '2021-02-01T00:00:00.000Z','end': '2021-02-08T00:00:00.000Z'}
b) 或者您可以使用周数。这个选项可能更难。
all_weeks = range(4)
all_days = range(7)
for n in all_agents:
for s in all_shifts:
for w in all_weeks:
for d in all_days:
for l in all_sites:
...
-
model.Add(sum(week) <= 5)
行缺少制表符空间。
for n in all_agents:
week = []
for d in all_days:
for l in all_sites:
for s in all_shifts:
week.append(shift[(n,s,d,l)])
model.Add(sum(week) <= 5)
- 天范围仅设置在 7 天,其他 21 天没有限制。您应该添加
week number
中描述的2. problem
迭代。或者将问题视为每周一次。
for l in all_sites:
for d in range(7):
for s in range(num_shifts):
model.Add(sum(shift[(n,l)]
for n in all_agents) == weekly_cover_demands[l,s])
- 我建议编写如下输出方法。每次运行后,追加方法都会增加文件大小。在每次迭代中,文件一次又一次地打开,很不方便。
with open('___output.txt','w') as f:
for l in all_sites:
for d in all_days:
for s in all_shifts:
for n in all_agents:
if solver.Value(shift[(n,l)]) == 1:
print("nurse {} covers shift {} on day {} at site {}".format(
agents[n],startschedule + datetime.timedelta(days=d),l),file=f)
结论,ortools找不到任何可行的解决方案。请检查您的约束或输入参数。我认为你应该保持算法简单,每周考虑而不是每月考虑。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。