Shift Filling
Input
Filling in pre-defined shifts with employees according to contractual agreements that enforce fair and cost efficient rosters. The input requires you to make up:
- contract definitions
- open shifts
- available employees
Additionally you can customise the solver behaviour by also changing the weights and priority of the constraints
Contract
A contract definition consists of a multitude of labour restricting constraints such as the maximum number of consecutive working days, the maximum number of shifts per day, number of resting days, etc...
Property | Type | Description |
---|---|---|
name | string | Unique name identifier for a contract. |
max | string (duration iso8601) | Maximum duration of all assigned shifts per employee. |
min | string (duration iso8601) | Minimum total duration of all assigned shifts per employee. |
maxConsecutiveWorkDays | integer | Maximum number of days that one employee is allowed to work in a row. |
maxShiftsDay | integer | Maximum number of shifts during one day. |
minRestBetweenShiftsSameDay | string (duration iso8601) | Minimum duration between two shifts on the same day. |
maxWorkingDays | integer | Maximum number of days working in the planning period. |
latestShiftStart | string (time iso8601) | Latest time an employee can start his shift. |
earliestShiftStart | string (time iso8601) | Earliest time an employee can start his shift. |
{
"name": "FULL",
"max": "PT38H",
"min": "PT5H",
"maxConsecutiveWorkDays": 5,
"maxShiftsDay": 2,
"minRestBetweenShiftsSameDay": 30,
"maxWorkingDays": 6,
"latestShiftStart": "10:00:00",
"earliestShiftStart": "02:00:00"
}
Shifts
The shifts represent the demand. These shifts need to be filled in with employees.
A shift in its simplest form can be defined by a shift start time (from
) and an end time (to
).
Shifts are uniquely identified by a name
and require a specific skill
.
You can define the number of employees that need to be assigned to this shift with value
.
Property | Type | Description |
---|---|---|
name | string | Unique id of the shift |
from | string (datetime) | Starting time of the shift |
to | string (datetime) | End time of the shift |
skills | array of strings | Skill name references |
cost | number | Financial cost related to this shift. Will be minimised when overconstrained. |
value | number | Actual number of employees that should be assigned to this shift |
priority | number | Forces a priority constraint on this shift with 1 being highest priority and 10 being the lowest. |
employees | array of strings | List of planned employees. Or can be used to pre-plan. |
Employees
Define the resources or employees with whom you want to fill up the shifts.
Property | Type | Description |
---|---|---|
name | string | Unique identifier for this employee |
contract | string | Reference to contract for this employee. |
skills | array of string | List of skill references. |
lastRestDate | string (date) | The last date on which the employee had a rest before the planning period. |
availability | array of string | Available date-time range of employee. |
preference | array of string | Preference towards certain shifts. (shift name) |
periodRules | array of PeriodRule | List of Period Rule |
Period Rule
A shift rule for an employee that applies to a period of time.
Property | Type | Description |
---|---|---|
period | PlanningPeriod | Planning period for this period rule. |
maxWorkingDays | integer | Maximum number of total days working in planning period. |
minWorkingDays | integer | Minimum number of total days working in planning period. |
minWorkingDuration | string | Minimum duration to work in the planning period. |
maxWorkingDuration | string | Maximum duration to work in the planning period. |
minRestDurationBetweenShiftsSameDay | string | Minimum duration between two shifts on the same day in this planning period. |
minRestDuration | string | Minimum duration between any two shifts in this planning period. |
Fairness
For a select group of employees
and shifts
you can require fair distribution of shifts per planning period. The planning period can be the entire planning period or a subset of it.
{
//...
"fairnessBuckets":
[
{
"employees": ["John", "Andrew"],
"shifts": ["shift1", "shift2"],
"period": {
"from": "2020-01-01",
"to": "2020-01-15"
}
}
]
}
Output
Simply fetch the solution in the jobs/:id/solution
endpoint and receive the shift assignments.
For every shift defined by its name
we will assign the best employee
.
[
{
"name": "Morning Shift 1",
"from": "2020-06-26T08:00:00",
"to": "2020-06-30T08:00:00",
"employee": "John Dory",
"skills": [
"waiter",
"bar"
]
}
]
Weights
We take into account many constraints. Let us know if there are any constraints that you think are missing.
Name | Property | Default priority | Description |
---|---|---|---|
Maximum Working Days | maxWorkingDays | HARD | An employee should not work more than contract.maxWorkingDays days in the planning horizon. |
Maximum Hours | maxHours | HARD | An employee should not work more than contract.max hours in the planning horizon. |
Minimum Hours | minHours | HARD | An employee should not work less than contract.min hours in the planning horizon. Please ensure minimum feasibility over the whole workforce. |
Earliest Shift Start | shiftStart | HARD | Earliest time contract.earliestShiftStart in a day when an employee is allowed to work |
Latest Shift Start | latestShiftStart | HARD | Earliest time contract.latestShiftStart in a day when an employee is allowed to start work |
Latest Shift End | shiftEnd | HARD | Latest time contract.latestShiftEnd in a day when an employee is allowed to end work |
Maximum Shift Length | maxShift | HARD | Maximum time contract.maxShiftLength that an employee is allowed to work |
DayOfWeek Working | dayOfWeek | HARD | Restricts employee availability based on days in the week that |
Minimum Shift Length | minShift | HARD | Minimum time contract.maxShiftLength that an employee is allowed to work |
Maximum Shifts On Same Day | sameDay | HARD | Maximum number of shifts that an employee is allowed to work |
Minimum Rest On Same Day | sameDayMinRest | HARD | Minimum resting period between two shifts on the same day |
Employee Availability | availability | HARD | Date-time range of employee's availability |
Locked Assignment | locked | HARD | Take into account assignments that are fixed during the solve |
Maximum Consecutive Working Days | maxConsecutive | HARD | No more than contract.maxConsecutiveWorkDays consecutive shifts. |
Minimum Rest | minRest | HARD | Minimum resting between two shifts (irrespective of shifts) |
No Concurrent Assignments | concurrent | HARD | An employee cannot have two assignments on the same time. (This should never happen) |
Skill Requirement for shifts | requirements | HARD | Multiple shifts can have a shared requirement for a skill |
Employee Skill Match | skills | HARD | Assign employees to match according to their skills and the required skills for a shift |
Travel Time | distance | SOFT | Travel from home to shift location |
Priority | priority | SOFT | Shift Priorities |
Shift Employee Preference | pref | MEDIUM | A preference for a certain shift assignment for an employee |
Financial Costs | costs | SOFT | Some shifts incur a higher cost when they are assigned to (opposite of priority) |
Wage Costs per Employee | wages | SOFT | Hourly wage cost per employee influences choice of employee |
Unassigned Employee | unassigned | MEDIUM | Minimise the number of unassigned employees |
Employee Skill Match Soft | softSkills | SOFT | Assign employees to match according to their skills and the required skills for a shift (soft rule) |
Employee Critical Skill Match | criticalSkills | SOFT | Prefer assigning critical shifts first |
Employee working days | working | HARD | Respect employees working days |
Shift blakclist | blacklist | HARD | Do not assign shift to blacklisted employees |
Efficiency | efficiency | SOFT | Weight of the efficiency cost per employee |
Employee skill level match | softSkillLevel | SOFT | Match the skill level |
The weights and priorities of these constraints can be set in the solve request by adding a weights
object to the request where each property that we want to customise has a string with the format "<weight
><priority
>" where <weight
> is a positive integer number and <priority
> can assume one of the following values: soft
, medium
and hard
. hard
constraints are more important than medium
constraints and medium
constraints are more important than soft
. Between violations of two constraints with the same priority, the solver will choose the one with the minimum weight. In the example below we are customising the weights for the locked
and unassigned
constraints.
{
"weights":{
"locked" : "100hard",
"unassigned" : "5soft"
}
}
Updated about 1 year ago