如何解决护士排班问题与或工具,分配超过 1 名护士轮班
我正在修改 here 中的代码 ,我希望能够根据工人的喜好创建一个轮班时间表,该时间表将分配给早晚班的 2 名工人和夜班的一名工人。 这是原始代码:
def create_shifts():
num_nurses = 5
num_days = 7
num_shifts = 3
all_nurses = range(num_nurses)
all_shifts = range(num_shifts)
all_days = range(num_days)
shift_requests,workers_names = pre_condition_for_creating_shifts(num_nurses,num_days,num_shifts)
# Creates the model.
model = cp_model.CpModel()
# Creates shift variables.
# shifts[(n,d,s)]: nurse 'n' works shift 's' on day 'd'.
shifts = {}
for n in all_nurses:
for d in all_days:
for s in all_shifts:
shifts[(n,s)] = model.NewBoolVar('shift_n%id%is%i' % (n,s))
# Each shift is assigned to exactly one nurse in.
for d in all_days:
for s in all_shifts:
model.Add(sum(shifts[(n,s)] for n in all_nurses) == 1)
# Each nurse works at most one shift per day.
for n in all_nurses:
for d in all_days:
model.Add(sum(shifts[(n,s)] for s in all_shifts) <= 1)
# Try to distribute the shifts evenly,so that each nurse works
# min_shifts_per_nurse shifts. If this is not possible,because the total
# number of shifts is not divisible by the number of nurses,some nurses will
# be assigned one more shift.
min_shifts_per_nurse = (num_shifts * num_days) // num_nurses
if num_shifts * num_days % num_nurses == 0:
max_shifts_per_nurse = min_shifts_per_nurse
else:
max_shifts_per_nurse = min_shifts_per_nurse + 1
for n in all_nurses:
num_shifts_worked = 0
for d in all_days:
for s in all_shifts:
num_shifts_worked += shifts[(n,s)]
model.Add(min_shifts_per_nurse <= num_shifts_worked)
model.Add(num_shifts_worked <= max_shifts_per_nurse)
final_shifts = []
id = []
# pylint: disable=g-complex-comprehension
model.Maximize(sum(shift_requests[n][d][s] * shifts[(n,s)] for n in all_nurses for d in all_days for s in all_shifts))
# Creates the solver and solve.
solver = cp_model.cpsolver()
solver.solve(model)
for s in all_shifts:
for d in all_days:
print('Day',d)
for n in all_nurses:
if solver.Value(shifts[(n,s)]) == 1:
if shift_requests[n][d][s] == 1:
final_shifts.append(workers_names[n])
print('Worker',n,'works shift',s,'(requested).')
else:
final_shifts.append("No submitted")
print('Worker','(not requested).')
print()
post_condition_for_creating_shifts(final_shifts)
# Statistics.
print()
print('Statistics')
print(' - Number of shift requests met = %i' % solver.ObjectiveValue(),'(out of',num_nurses * min_shifts_per_nurse,')')
print(' - wall time : %f s' % solver.WallTime())
代替:
# Each shift is assigned to exactly one nurse in.
for d in all_days:
for s in all_shifts:
model.Add(sum(shifts[(n,s)] for n in all_nurses) == 1)``
我已经改变了这个:
for d in all_days:
for s in all_shifts:
if s==0 or s==1:
model.Add(sum(shifts[(n,s)] for n in all_nurses) == 2)
else:
model.Add(sum(shifts[(n,s)] for n in all_nurses) == 1)
# Each nurse works at most one shift per day.
for n in all_nurses:
week=[]
for d in all_days:
for s in all_shifts:
week.append(shifts[(n,s)])
# week.append(sum(shifts[(n,s)] for s in all_shifts))
model.Add(sum(week) >= 1)
model.Add(sum(week) <= 5)
但我在行中遇到错误
if solver.Value(shifts[(n,s)]) == 1:
那句话:IndexError: list index out of range
解决方法
当前的示例非常有限,因为它使用了轮班次数等于护士人数的假设。对于更完整的示例,我建议查看此示例:
https://github.com/google/or-tools/blob/stable/examples/python/shift_scheduling_sat.py
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。