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