Search code examples
pythonruntimeschedulingor-tools

Maximum length series of shifts in Google OR-tools employee scheduling


I'm developing a nurse scheduling program for one of the departments of the hospital I work with in Python. Various examples of such programs already exist and are shared online. One of these is the following: https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py

So far I have managed to adapt the code in the link above to include various types of labour regulations as well as individual nurse preferences. However I keep struggling to implement the following rule:

  • Employees cannot work more than 5 consecutive days.

The code natively supports bounds on the length of series of the same shift type (e.g. forbid n consecutive morning shifts or night shifts). However, there is no way to limit the length of series of back-to-back shifts if they are not of the same type (e.g. night/night/morning/night/morning).

I managed to implement this rule by adding the following piece of code:

    for e in range(num_employees):
            for d in range(num_days):                 
                   model.Add(work[e, 0, d] == 1).OnlyEnforceIf( (work[e, 1, d-5] or work[e, 2, d-5] or work[e, 3, d-5] or work[e, 4, d-5] )
                                                                and (work[e, 1, d-4] or work[e, 2, d-4] or work[e, 3, d-4] or work[e, 4, d-4] )
                                                                and (work[e, 1, d-3] or work[e, 2, d-3] or work[e, 3, d-3] or work[e, 4, d-3] )
                                                                and (work[e, 1, d-2] or work[e, 2, d-2] or work[e, 3, d-2] or work[e, 4, d-2] )
                                                                and (work[e, 1, d-1] or work[e, 2, d-1] or work[e, 3, d-1] or work[e, 4, d-1] ))

However, this implementation increases the run-time of the program drastically (from 30 seconds without the constraints, to about 15 minutes including it). Therefore I'm looking for a way to prohibit employees from being scheduled 5 or more consecutive days that doesn't increase run-time as much.


Solution

  • You can adapt the code by limiting the length of off_shift.not() literals.