Or 工具的护士调度问题,分配超过 1 个护士到服务班次
Nurse Scheduling Problem with Or Tools, assign more than 1 nures to servel shifts
我正在修改来自 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, d,
s)] = model.NewBoolVar('shift_n%id%is%i' % (n, d, 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, d, 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, d, 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, d, 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, d, 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, d, 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', n, 'works shift', s, '(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, d, 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, d, s)] for n in all_nurses) == 2)
else:
model.Add(sum(shifts[(n, d, 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, d, s)])
# week.append(sum(shifts[(n,d,s)] for s in all_shifts))
model.Add(sum(week) >= 1)
model.Add(sum(week) <= 5)
但我在行中遇到错误
if solver.Value(shifts[(n, d, s)]) == 1:
那句话:IndexError: list index out of range
当前的示例非常有限,因为它使用轮班人数等于护士人数的假设。如需更完整的示例,我建议查看此示例:
https://github.com/google/or-tools/blob/stable/examples/python/shift_scheduling_sat.py
我正在修改来自 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, d,
s)] = model.NewBoolVar('shift_n%id%is%i' % (n, d, 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, d, 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, d, 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, d, 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, d, 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, d, 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', n, 'works shift', s, '(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, d, 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, d, s)] for n in all_nurses) == 2)
else:
model.Add(sum(shifts[(n, d, 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, d, s)])
# week.append(sum(shifts[(n,d,s)] for s in all_shifts))
model.Add(sum(week) >= 1)
model.Add(sum(week) <= 5)
但我在行中遇到错误
if solver.Value(shifts[(n, d, s)]) == 1:
那句话:IndexError: list index out of range
当前的示例非常有限,因为它使用轮班人数等于护士人数的假设。如需更完整的示例,我建议查看此示例:
https://github.com/google/or-tools/blob/stable/examples/python/shift_scheduling_sat.py