Как я могу запланировать смены сотрудников с помощью or-tools с учетом необходимого отпуска? - PullRequest
0 голосов
/ 03 июля 2019

Я использую решатель CP-SAT, начиная с этого примера: https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py

Для принудительного отдыха на выходных я ввел эту часть кода:

# Force weekends to OFF.
for e in range(num_employees):
    fixed_assignments.append((e,0,5))
    fixed_assignments.append((e,0,6))
    fixed_assignments.append((e,0,12))
    fixed_assignments.append((e,0,13))
    fixed_assignments.append((e,0,19))
    fixed_assignments.append((e,0,20))
    fixed_assignments.append((e,0,26))
    fixed_assignments.append((e,0,27))

Стем же методом я могу назначить целую неделю отпуска одному сотруднику, исключив ограничение:

shift_constraints = [
    # One or two consecutive days of rest, this is a hard constraint.
    # (0, 1, 1, 0, 2, 2, 0), <-- removed
    # added to facilitate the assignment of the shifts for all the week
    # penalized but not hard to allow even rest days, otherwise the result         
    # would be NOT FEASIBLE
    (1, 5, 5, 2, 5, 5, 2), 
    (2, 5, 5, 2, 5, 5, 2), 
    (3, 5, 5, 7, 5, 5, 7), # <- night shift 
] 

Я также добавил это дополнительное ограничение, чтобы один и тот же сотрудник не выполнял одну и ту же смену в течение двух недель подряд:

weekly_sum_constraints = [
    # Constraints on rests per week.
    #(0, 1, 2, 7, 2, 3, 4),
    # At least 1 shift per week (penalized). At most 5 (hard).
    (1, 0, 1, 3, 5, 5, -2),
    (2, 0, 1, 3, 5, 5, -2),
    (3, 0, 1, 3, 5, 5, 2),
]
# Penalized weeks transitions:
#     (previous_shift, next_shift, penalty (0 means forbidden))
penalized_weeks_transitions = [
    # Night to Night is forbidden.
    (3, 3, 0),
    (2, 2, 0),
    (1, 1, 0),
]

с кодом:

# Penalized weeks transitions
for previous_shift, next_shift, cost in penalized_weeks_transitions:
    for e in range(num_employees):
        for d in range(num_days - 8):
            transition = [
                work[e, previous_shift, d].Not(),
                work[e, next_shift, d + 7].Not()
            ]
            if cost == 0:
                model.AddBoolOr(transition)
            else:
                trans_var = model.NewBoolVar(
                    'wtransition (employee=%i, day=%i)' % (e, d))
                transition.append(trans_var)
                model.AddBoolOr(transition)
                obj_bool_vars.append(trans_var)
                obj_bool_coeffs.append(cost)

Таким образом, я могу получить план, но из-за ограничения на запросы о покрытии смен:

weekly_cover_demands = [
    (14, 14, 7),  # Monday
    (14, 14, 7),  # Tuesday
    (14, 14, 7),  # Wednesday
    (14, 14, 7),  # Thursday
    (14, 14, 7),  # Friday
    (0, 0, 0),  # Saturday
    (0, 0, 0),  # Sunday
]

У меня могут быть сотрудники с отдыхом в течение недели, особенно если им назначена ночная смена.Таким образом, логика такова: если вам нужно только 7 человек в ночную смену, остальные лишние люди получат ход 0 (отдых), так что штраф за ночную смену будет снижен.

С другой стороныЯ хотел бы назначить действительный сдвиг в этих случаях, может быть, утром или днем, но не в остальные смены.

Итак, вопрос в следующем:

1) Как правильно управлятьсотрудник когда он в отпуске?Правильно ли сделать это так, как я сделал принудительное включение поворота в 0 (отдых) в качестве жесткого ограничения?

2) Как я могу написать ограничение, чтобы обеспечить равномерное распределение ночных смен или, возможно, прощеобеспечить, чтобы в течение 4 недель была только одна неделя с ночной сменой?

3) как избежать автоматического назначения остальной смены, если запрос на ночную смену меньше, чем наличие сотрудников?(в этом случае сотрудники должны работать в любом случае, но утром или днем)?

Заранее благодарен за любую помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...