Skip to content

Constraints

All constraints are located inside src/cp/constraints/*.py. Each constraint is implemented as a function that takes a CpModel1 object and adds the necessary constraints to it. Constraints are considered as hard constraints as they must be satisfied for a valid schedule. For soft constraints, see the Objectives chapter.

All Constraints

Free day after night shift phase 4

According to recommendations for the healthy organization of night and shift work, workers should have at least 24 hours of free time after a night shift. This ensures that workers have sufficient rest after a night shift. Therefore, if an employee works the night shift today and does not work the night shift tomorrow, they must take the day off.

src/cp/constraints/free_day_after_night_shift_phase.py
model.add(day_tomorrow_variable == 0).only_enforce_if(
    [night_shift_today_variable, night_shift_tomorrow_variable.Not()]
)

Max one shift per day

Minimum rest time between shifts 3

Minimum number of staff per shift 2

Each shift has a minimum required number of staff. This is a hard constraint that must be met. The goal is to ensure that the required number of qualified staff members are present for each shift. Therefore, the total number of staff members assigned to a shift must be greater than or equal to the required number of staff for that shift.

src/cp/constraints/min_staffing.py
model.add(sum(potential_working_staff) >= min_staffing)

Staff_Requirements

Staff requirements per weekday and professional group.

Target working time per month 1

Each employee has an individual monthly work target. This target is considered a hard constraint because it must be met within a certain range. A maximum deviation of one day shift is allowed (±7.67 hours), but this is minimized by the objective function to ensure minimal overtime/undertime. Therefore, the total working time must fall within the range of all possible shift combinations and the target working time range.

src/cp/constraints/target_working_time.py
working_time_variable = model.new_int_var_from_domain(
    working_time_domain, f"working_time_e:{employee.get_id()}"
)

model.add(sum(possible_working_time) == working_time_variable)
model.add(working_time_variable <= target_working_time + TOLERANCE_MORE)
model.add(working_time_variable >= target_working_time - TOLERANCE_LESS)

Vacation days and free shifts 1

Vacation days must remain free, and the day before a vacation day no night shift is allowed. Therefore, if an employee has a vacation day or a free shift, the corresponding shift variable must be set to zero. Also considering the night shift the day before a vacation day or free shift.

src/cp/constraints/vacation_days_and_free_shifts.py
if employee.has_vacation(day.day):
    model.add(day_variable == 0)

    if day.day > 1:
        model.add(night_shift_variable == 0)

if employee.has_vacation(day.day, shift.get_id()):
    model.add(shift_variable == 0)

  1. OR Tools Documentation 

  2. Problem definition (PDF file from Moodle) 

  3. Occupational Health and Safety Law (Arbeitsschutzgesetz) (PDF file from Moodle) 

  4. Guidelines for shift work