ShiftSolver modelling faqs

Please contact us if you have a question which is not answered here.


General questions

Can an employee be assigned more than one shift on a single day or 'split-shifts'?

Yes, this can be allowed by using the SplitShifts constraint in <Contract>.

Can shifts contain more than one activity?

Yes, this can be allowed by using the AllowTaskTransfers constraint in <Contract>. If this constraint is used then the solver will create shifts which contain more than one activity. For example, an employee may be assigned to a particular activity at the start of the shift and then switch to another activity in the middle of the shift and then switch again to a different activity for the final part of the shift.

How do I leave employee(s) unscheduled if possible?

This can be modelled using the UseIfNeeded constraint in <Contract>.

How do I model the constraints at boundaries between planning periods?

The schedule for each employee in the current planning period is clearly also affected by the employee's schedule in the previous planning period. To model this there are two options:

1. Include the previous planning period (or as much of it as is relevant) in the current planning period (by making the start date earlier) and then fix all these assignments in place using <FixedAssignments> so they cannot be changed.
2. The second option is to enter constraints (in the contracts) which are based on the assignments made in the previous schedules. For example, if a night shift can only followed by a night shift or a day off and the last day of the previous schedule has a night shift, then enter a constraint (e.g. using <Sequence>) in this scheduling horizon which ensures that only a night shift or day off is assigned on the first day.

The second method is slightly more efficient for the solver but may be more effort to model. An effective compromise is to include some of the previous roster (fixed in place) and then add additional constraints for the ones which would require long sections of the previous schedule.

What options are there for defining shift break requirements?

Break configurations can set based on a shift's length, start time, end time, type (e.g. early shift, night shift etc) and day of the week. There are no limits on the number of breaks that a shift can contain. See <BreakDefinitions> for more information.

Can shifts span midnight or more than one day?

Yes, shifts can span midnight and there is no limit on shift lengths.

Can I assign different priorities to each constraint?

Yes. Weights can be set for each constraint which reflect the priority of the constraint. The higher the weight the more important it is to satisfy that constraint.

Can I choose linear, quadratic and constant penalty functions?

Yes. By default most soft constraints use linear penalty functions. This means if a maximum constraint is exceeded (or a minimum is not reached) then the solution's penalty is increased by the amount over the maximum (or the amount under the minimum) multiplied by the weight. In some circumstances it may be preferable however to not penalise the solution too much if it only breaks the constraint a small amount, but penalise it more heavily as the excess (or deficit) increases. This can be done by using a quadratic function. It means that if a constraint is broken the solution's penalty is increased by the excess (or deficit) squared and then multiplied by the weight.


Employee Constraints

How do I model a minimum rest time between shifts?

This can be modelled using the MinRestTime constraint in <Contract>.

Example

<Contract ID="C1">
  <MinRestTime>720</MinRestTime>  
</Contract>

How do I ensure shifts only start or finish at a range of possible times?

This can be modelled using the <Range> tag in the <ShiftStartTimes> and <ShiftEndTimes> constraints. If more than one Range tag is provided then it means that the shifts must start within one of the specified Ranges. For example, to ensure shifts can only start at 06:00, 14:00 or 22:00 use:

Example

<ShiftStartTimes>
  <Range>
    <Min>06:00</Min>
    <Max>06:00</Max>
  </Range>
  <Range>
    <Min>14:00</Min>
    <Max>14:00</Max>
  </Range>
  <Range>
    <Min>22:00</Min>
    <Max>22:00</Max>
  </Range>
</ShiftStartTimes>

How do I restrict which activities an employee can switch between during a shift?

This is modelled using the ValidTaskTransfers constraint in <Employee>.

How do I restrict the minimum or maximum amount of time an employee is assigned consecutively to a particular activity?

To model limits on consecutive activity lengths use the TaskLengths constraint in <Contract>.

How do I restrict which activities an employee can be assigned?

This is modelled using the ValidTasks constraint in <Employee>.

How do I model employees preferring not to cover certain activities if possible?

Use the ValidTasks constraint in <Employee> but provide a weight for the tasks which should not be assigned if possible.

How do I categorise shifts into general types for use in other constraints such as "Max 5 Night shifts"?

Shifts can be categorised into general types based on their start times, end times and lengths. See <ShiftTypes>.

How do I model requests to work (or not work) particular days or shifts on particular days?

This is modelled using Requests.

How do I fix in place, shifts, days off or part days off in the schedules so they cannot be changed?

See FixedAssignments.

How do I differentiate between breaks which do not count as work time and those that do?

Use the <WorkLength> tag in the <Break> tags in <BreakDefinitions>. If the break does not count as work (e.g. for <Workload> constraints) then set the WorkLength as zero.

How do I model "maximum or minimum days on/off" constraints?

This can be modelled using the MaxTot constraint.

Example

  <MaxTot label="Max 18 days on" value="18" shift="$" weight="1000"/>
  
  <MaxTot label="Max 10 days off" value="10" shift="-" weight="1000"/>
  
  <MinTot label="Min 16 days on" value="16" shift="$" weight="1000"/>

It can also be modelled using the Sequence constraint. Define a pattern which matches a single day on (or off) and impose a maximum or minimum number of matches of that pattern.

Example

<Sequence>
  <Max count="18" weight="1000" label="Max 18 days on"/>
  <Min count="16" weight="1000" label="Min 16 days on"/>
  <Pattern>
    <Shift>$</Shift>
  </Pattern>
</Sequence>
  
<Sequence>
  <Max count="10" weight="1000" label="Max 10 days off"/>
  <Pattern>
    <Shift>-</Shift>
  </Pattern>
</Sequence>

How do I model "maximum or minimum shift types (optionally between two dates)" constraints?

This can be modelled using the MaxTot constraint.

Example

<MaxTot label="Max 4 night shifts between days 0 to 6" value="4" shift="N" start="0" end="6" weight="100"/>

It can also be modelled using the Sequence constraint.

Example

<Sequence>
  <Max count="4" weight="1000" label="Max 4 night shifts between days 0 to 6"/>
  <PeriodStart>0</PeriodStart>
  <PeriodEnd>6</PeriodEnd>
  <Pattern>
    <Shift>N</Shift>
  </Pattern>
</Sequence>

How do I model "maximum or minimum consecutive days on" constraints?

The easiest way to model this is using the MaxSeq constraint.

Example

<MaxSeq label="Max 6 consecutive working days" value="6" shift="$" weight="1000"/>
  
<MinSeq label="Min 2 consecutive working days" value="2" shift="$" weight="5"/>

It can also be modelled using the Sequence constraint.

Example

<Sequence>
  <Max count="0" weight="1000" label="Max 6 consecutive working days"/>
  <Pattern>
    <Shift>$</Shift>
    <Shift>$</Shift>
    <Shift>$</Shift>
    <Shift>$</Shift>
    <Shift>$</Shift>
    <Shift>$</Shift>
    <Shift>$</Shift>
  </Pattern>
</Sequence>
  
<Sequence>
  <Max count="0" weight="1000" label="Min 2 consecutive working days"/>
  <Pattern> <!-- Include this pattern if the last day of the previous schedule was off -->
    <Start>0</Start>
    <Shift>$</Shift>
    <Shift>-</Shift>
  </Pattern> 
  <Pattern>
    <Shift>-</Shift>
    <Shift>$</Shift>
    <Shift>-</Shift>
  </Pattern>
</Sequence>

How do I model "maximum or minimum consecutive days off" constraints?

The easiest way to model this is using the MaxSeq constraint.

Example

<MaxSeq label="Max 3 consecutive days off" value="3" shift="-" weight="20"/>
  
<MinSeq label="Min 2 consecutive days off" value="2" shift="-" weight="10"/>

It can also be modelled using the Sequence constraint.

Example

<Sequence>
  <Max count="0" weight="1000" label="Max 3 consecutive days off"/>
  <Pattern>
    <Shift>-</Shift>
    <Shift>-</Shift>
    <Shift>-</Shift>
    <Shift>-</Shift>
  </Pattern>
</Sequence>

<Sequence>
  <Max count="0" weight="1000" label="Min 2 consecutive days off"/>
  <Pattern> <!-- Include this pattern if the last day of the previous schedule was on -->
    <Start>0</Start>
    <Shift>-</Shift>
    <Shift>$</Shift>
  </Pattern> 
  <Pattern>
    <Shift>$</Shift>
    <Shift>-</Shift>
    <Shift>$</Shift>
  </Pattern>
</Sequence>

How do I model "maximum or minimum consecutive shift types" constraints?

The easiest way to model this is using the MaxSeq constraint.

Example

<MaxSeq label="Max 4 consecutive N shifts" value="4" shift="N" weight="1000"/>
  
<MinSeq label="Min 2 consecutive N shifts" value="2" shift="N" weight="100"/>

It can also be modelled using the Sequence constraint.

Example

<Sequence>
  <Max count="0" weight="1000" label="Min 2 consecutive N shifts"/>
  <Pattern>
    <NotShift>N</NotShift>
    <Shift>N</Shift>
    <NotShift>N</NotShift>
  </Pattern>
</Sequence>

<Sequence>
  <Max count="0" weight="1000" label="Max 4 consecutive N shifts"/>
  <Pattern>
    <Shift>N</Shift>
    <Shift>N</Shift>
    <Shift>N</Shift>
    <Shift>N</Shift>
    <Shift>N</Shift>
  </Pattern>
</Sequence>

How do I model "illegal shift transitions/sequences" constraints?

The easiest way to model this is using the Sequence constraint.

Example

<Sequence>
  <Max count="0" weight="1000" label="No N-E"/>
  <Pattern>
    <Shift>N</Shift>
    <Shift>E</Shift>
  </Pattern>
</Sequence>
<Sequence>
  <Max count="0" weight="1000" label="No E-D"/>
  <Pattern>
    <Shift>E</Shift>
    <Shift>D</Shift>
  </Pattern>
</Sequence>

How do I model "both Saturday and Sunday on or off" constraints?

This can be modelled using the <Sequence constraint.

Example

<Sequence>
  <Max count="0" weight="1000" label="No half weekends"/>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>$</Shift>
    <Shift>-</Shift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>-</Shift>
    <Shift>$</Shift>
  </Pattern>
</Sequence>

How do I model "no night shift before a weekend off" constraints?

This can be modelled using the Sequence constraint.

Example

<Sequence>
  <Max count="0" weight="1000" label="No night shift before a weekend off"/>
  <Pattern>
    <Start>Friday</Start>
    <Shift>N</Shift>
    <Shift>-</Shift>
    <Shift>-</Shift>
  </Pattern>
</Sequence>

How do I model "no shift changes during a weekend" constraints?

This can be modelled using the Sequence constraint.

Example

<Sequence>
  <Max count="0" weight="1000" label="Identical shift types during weekend"/>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>N</Shift>
    <NotShift>N</NotShift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <NotShift>N</NotShift>
    <Shift>N</Shift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>D</Shift>
    <NotShift>D</NotShift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <NotShift>D</NotShift>
    <Shift>D</Shift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>E</Shift>
    <NotShift>E</NotShift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <NotShift>E</NotShift>
    <Shift>E</Shift>
  </Pattern>
</Sequence>

How do I model "minimum days off after night shifts" constraints?

The easiest way to model this is using the Sequence constraint.

Example

<Sequence>
  <Max count="0" weight="1000" label="At least two free days after a night shift"/>   
  <Pattern>
    <Shift>N</Shift>
    <Shift>-</Shift>
    <Shift>$</Shift>
  </Pattern>
</Sequence>

How do I model "maximum or minimum specific days of the week worked" constraints?

This can be modelled using the Sequence constraint.

Example

<Sequence> 
  <Max count="2" weight="1000" label="Max 2 Fridays"/> 
  <Pattern>
    <Start>Friday</Start>
    <Shift>$</Shift>
  </Pattern>
</Sequence>

<Sequence>
  <Max count="2" weight="1000" label="Max 2 Mondays"/> 
  <Pattern>
    <Start>Monday</Start>
    <Shift>$</Shift>
  </Pattern>
</Sequence>

How do I model "maximum or minimum weekends with (or without) work" constraints?

This can be modelled using the Sequence constraint.

Example

<Sequence>
  <Max count="2" weight="1000" label="Max 2 weekends off"/> 
  <Pattern>
    <Start>Saturday</Start>
    <Shift>-</Shift>
    <Shift>-</Shift>
  </Pattern>
</Sequence>

<Sequence>
  <Max count="2" weight="1000" label="Max 2 weekends off (night shift on Friday counts as weekend work)"/> 
  <Pattern>
    <Start>Friday</Start>
    <NotShift>N</NotShift>
    <Shift>-</Shift>
    <Shift>-</Shift>
  </Pattern>
</Sequence>

<Sequence> 
  <Min count="1" weight="1000" label="Min 1 weekend off"/> 
  <Pattern>
    <Start>Saturday</Start>
    <Shift>-</Shift>
    <Shift>-</Shift>
  </Pattern>
</Sequence>
          
<Sequence>
  <Max count="3" weight="1000" label="Max 3 weekends on"/> 
  <Pattern>
    <Start>Saturday</Start>
    <Shift>$</Shift>
    <Shift>-</Shift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>-</Shift>
    <Shift>$</Shift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>$</Shift>
    <Shift>$</Shift>
  </Pattern>    
</Sequence>

How do I model "maximum or minimum consecutive weekends with (or without) work" constraints?

This can be modelled using the Sequence constraint. For example, if there must be a maximum of two consecutive weekends with work then it is equivalent to a maximum of two weekends with work in every three week period.

Example

<Sequence>
  <Max count="2" weight="1000" label="Max 2 consecutive working weekends"/> 
  <PeriodStart>5</PeriodStart>
  <PeriodEnd>20</PeriodEnd> <!-- Only match within the first three weeks -->
  <Pattern>
    <Start>Saturday</Start>
    <Shift>$</Shift>
    <Shift>-</Shift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>-</Shift>
    <Shift>$</Shift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>$</Shift>
    <Shift>$</Shift>
  </Pattern>
</Sequence>
<Sequence>
  <Max count="2" weight="1000" label="Max 2 consecutive working weekends"/>
  <PeriodStart>12</PeriodStart>
  <PeriodEnd>27</PeriodEnd> <!-- Only match within the second three week period -->
  <Pattern>
    <Start>Saturday</Start>
    <Shift>$</Shift>
    <Shift>-</Shift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>-</Shift>
    <Shift>$</Shift>
  </Pattern>
  <Pattern>
    <Start>Saturday</Start>
    <Shift>$</Shift>
    <Shift>$</Shift>
  </Pattern>
</Sequence>

How do I model "maximum or minimum days between shift types" constraints?

The easiest way to model this is using the Sequence constraint.

Example

<Sequence>
  <Max count="0" weight="1000" label="Max 6 days between D shifts"/>
  <Pattern>
    <Shift>D</Shift>
    <NotShift>D</NotShift>
    <NotShift>D</NotShift>
    <NotShift>D</NotShift>
    <NotShift>D</NotShift>
    <NotShift>D</NotShift>
    <NotShift>D</NotShift>
    <NotShift>D</NotShift>
  </Pattern>
</Sequence>

<Sequence>
  <Max count="0" weight="1000" label="Min 6 days between N shifts"/>
  <Pattern>
    <Shift>N</Shift>
    <Shift>*</Shift>
    <Shift>N</Shift>
  </Pattern>
  <Pattern>
    <Shift>N</Shift>
    <Shift>*</Shift>
    <Shift>*</Shift>
    <Shift>N</Shift>
  </Pattern>
  <Pattern>
    <Shift>N</Shift>
    <Shift>*</Shift>
    <Shift>*</Shift>
    <Shift>*</Shift>
    <Shift>N</Shift>
  </Pattern>
  <Pattern>
    <Shift>N</Shift>
    <Shift>*</Shift>
    <Shift>*</Shift>
    <Shift>*</Shift>
    <Shift>*</Shift>
    <Shift>N</Shift>
  </Pattern>
  <Pattern>
    <Shift>N</Shift>
    <Shift>*</Shift>
    <Shift>*</Shift>
    <Shift>*</Shift>
    <Shift>*</Shift>
    <Shift>*</Shift>
    <Shift>N</Shift>
  </Pattern>
</Sequence>