Consider a restaurant that plans weekly schedules for the kitchen. The
restaurant shifts are Monday through Friday from 12hr to 23hr. There are five
employees that can perform three roles: Station chef
, Head chef
and Sous
chef
. On every shift, there needs to be two employees working as a Station
chef
with high priority and one employee working as a Sous chef
with medium
priority. Additionally, a Head chef
is required on Tuesdays and Fridays with
medium priority. The only other scheduling constraint is for one of the
employees, Liam
, who requested work on the "Wednesday-2023-05-03", but not to
work on the Friday-2023-05-05
shift.
Role coverage for every shift
Coverage for a specific role can be specified for a given set of shifts with a coverage requirement. For example, the first shift of this problem can be represented as:
{
"shifts": [
{
"id": "Monday-2023-05-01",
"startDateTime": {
"year": 2023,
"month": 5,
"day": 1,
"hours": 12
},
"endDateTime": {
"year": 2023,
"month": 5,
"day": 1,
"hours": 23
}
}
]
}
Assuming all five shifts are: Monday-2023-05-01
, Tuesday-2023-05-02
,
Wednesday-2023-05-03
, Thursday-2023-05-04
, and Friday-2023-05-05
, the
coverage requirement for the Station chef
and Sous chef
roles is represented
as:
{
"coverageRequirements": [{
"shiftIds": ["Monday-2023-05-01", "Tuesday-2023-05-02",
"Wednesday-2023-05-03", "Thursday-2023-05-04",
"Friday-2023-05-05"]
"roleRequirements": [{
"roleId": "Station chef",
"targetEmployeeCount": 2,
"priority": "PRIORITY_HIGH"
}, {
"roleId": "Sous chef",
"targetEmployeeCount": 1,
"priority": "PRIORITY_MEDIUM"
}]
}
]
}
To consider the requirement for a Head chef
, an additional coverage
requirement can be specified on the necessary shifts. The complete list of
coverage requirements is:
{
"coverageRequirements": [{
"shiftIds": ["Monday-2023-05-01", "Tuesday-2023-05-02",
"Wednesday-2023-05-03", "Thursday-2023-05-04",
"Friday-2023-05-05"],
"roleRequirements": [{
"roleId": "Station chef",
"targetEmployeeCount": 2,
"priority": "PRIORITY_HIGH"
}, {
"roleId": "Sous chef",
"targetEmployeeCount": 1,
"priority": "PRIORITY_MEDIUM"
}]
},
{
"shiftIds": ["Tuesday-2023-05-02", "Friday-2023-05-05"],
"roleRequirements": [{
"roleId": "Head chef",
"targetEmployeeCount": 1,
"priority": "PRIORITY_MEDIUM"
}]
}
]
}
Employee requests
Employee requests are represented with the shift request
field. In this example, Liam
has requested to work on the Wednesday shift, but
not to work on the Friday shift. This is represented (along with his roles)
as:
{
"employees": [{
"id": "Liam",
"roleIds": ["Station chef", "Head chef"],
"shiftRequests": [
{
"priority": "PRIORITY_HIGH",
"shiftIds": ["Wednesday-2023-05-03"],
"type": "STATUS_WORK"
},
{
"priority": "PRIORITY_HIGH",
"shiftIds": ["Friday-2023-05-05"],
"type": "STATUS_NOT_WORK"
}
]
}]
}
Example with all five employees
{
"employees": [
{
"id": "Liam",
"roleIds": [
"Station chef",
"Head chef"
],
"shiftRequests": [
{
"priority": "PRIORITY_HIGH",
"shiftIds": [
"Wednesday-2023-05-03"
],
"type": "STATUS_WORK"
},
{
"priority": "PRIORITY_HIGH",
"shiftIds": [
"Friday-2023-05-05"
],
"type": "STATUS_NOT_WORK"
}
]
}
, {
"id": "Olivia",
"roleIds": ["Station chef"]
}, {
"id": "Noah",
"roleIds": ["Station chef"]
}, {
"id": "Emma",
"roleIds": ["Head chef"]
}, {
"id": "Oliver",
"roleIds": ["Station chef", "Sous chef"]
}
]
}
Example of a complete request
{
"employees": [
{
"id": "Liam",
"roleIds": [
"Station chef",
"Head chef"
],
"shiftRequests": [
{
"priority": "PRIORITY_HIGH",
"shiftIds": [
"Wednesday-2023-05-03"
],
"type": "STATUS_WORK"
},
{
"priority": "PRIORITY_HIGH",
"shiftIds": [
"Friday-2023-05-05"
],
"type": "STATUS_NOT_WORK"
}
]
},
{
"id": "Olivia",
"roleIds": [
"Station chef"
]
},
{
"id": "Noah",
"roleIds": [
"Station chef"
]
},
{
"id": "Emma",
"roleIds": [
"Head chef"
]
},
{
"id": "Oliver",
"roleIds": [
"Station chef",
"Sous chef"
]
}
],
"shifts": [
{
"id": "Monday-2023-05-01",
"startDateTime": {
"year": 2023,
"month": 5,
"day": 1,
"hours": 12
},
"endDateTime": {
"year": 2023,
"month": 5,
"day": 1,
"hours": 23
}
},
{
"id": "Tuesday-2023-05-02",
"startDateTime": {
"year": 2023,
"month": 5,
"day": 2,
"hours": 12
},
"endDateTime": {
"year": 2023,
"month": 5,
"day": 2,
"hours": 23
}
},
{
"id": "Wednesday-2023-05-03",
"startDateTime": {
"year": 2023,
"month": 5,
"day": 3,
"hours": 12
},
"endDateTime": {
"year": 2023,
"month": 5,
"day": 3,
"hours": 23
}
},
{
"id": "Thursday-2023-05-04",
"startDateTime": {
"year": 2023,
"month": 5,
"day": 4,
"hours": 12
},
"endDateTime": {
"year": 2023,
"month": 5,
"day": 4,
"hours": 23
}
},
{
"id": "Friday-2023-05-05",
"startDateTime": {
"year": 2023,
"month": 5,
"day": 5,
"hours": 12
},
"endDateTime": {
"year": 2023,
"month": 5,
"day": 5,
"hours": 23
}
}
],
"coverageRequirements": [
{
"shiftIds": [
"Monday-2023-05-01",
"Tuesday-2023-05-02",
"Wednesday-2023-05-03",
"Thursday-2023-05-04",
"Friday-2023-05-05"
],
"roleRequirements": [
{
"roleId": "Station chef",
"targetEmployeeCount": 2,
"priority": "PRIORITY_HIGH"
},
{
"roleId": "Sous chef",
"targetEmployeeCount": 1,
"priority": "PRIORITY_MEDIUM"
}
]
},
{
"shiftIds": [
"Tuesday-2023-05-02",
"Friday-2023-05-05"
],
"roleRequirements": [
{
"roleId": "Head chef",
"targetEmployeeCount": 1,
"priority": "PRIORITY_MEDIUM"
}
]
}
],
"roleIds": [
"Station chef",
"Head chef",
"Sous chef"
]
}
Response example
The response of the solver contains the assignment of employees to the restaurant shifts and the status of the optimization procedure. For example, the shifts assigned to one of the employees are returned as:
{
"solutionStatus": "OPTIMAL",
"shiftAssignments": [
{
"employeeId": "Liam",
"shiftId": "Monday-2023-05-01",
"roleId": "Station chef"
},
{
"employeeId": "Liam",
"shiftId": "Tuesday-2023-05-02",
"roleId": "Station chef"
},
{
"employeeId": "Liam",
"shiftId": "Wednesday-2023-05-03",
"roleId": "Station chef"
},
{
"employeeId": "Liam",
"shiftId": "Thursday-2023-05-04",
"roleId": "Station chef"
}, ...
]
}
Example of a complete response
{
"solutionStatus": "OPTIMAL",
"shiftAssignments": [
{
"employeeId": "Liam",
"shiftId": "Monday-2023-05-01",
"roleId": "Station chef"
},
{
"employeeId": "Liam",
"shiftId": "Tuesday-2023-05-02",
"roleId": "Station chef"
},
{
"employeeId": "Liam",
"shiftId": "Wednesday-2023-05-03",
"roleId": "Station chef"
},
{
"employeeId": "Liam",
"shiftId": "Thursday-2023-05-04",
"roleId": "Station chef"
},
{
"employeeId": "Olivia",
"shiftId": "Friday-2023-05-05",
"roleId": "Station chef"
},
{
"employeeId": "Noah",
"shiftId": "Monday-2023-05-01",
"roleId": "Station chef"
},
{
"employeeId": "Noah",
"shiftId": "Tuesday-2023-05-02",
"roleId": "Station chef"
},
{
"employeeId": "Noah",
"shiftId": "Wednesday-2023-05-03",
"roleId": "Station chef"
},
{
"employeeId": "Noah",
"shiftId": "Thursday-2023-05-04",
"roleId": "Station chef"
},
{
"employeeId": "Noah",
"shiftId": "Friday-2023-05-05",
"roleId": "Station chef"
},
{
"employeeId": "Emma",
"shiftId": "Tuesday-2023-05-02",
"roleId": "Head chef"
},
{
"employeeId": "Emma",
"shiftId": "Friday-2023-05-05",
"roleId": "Head chef"
},
{
"employeeId": "Oliver",
"shiftId": "Monday-2023-05-01",
"roleId": "Sous chef"
},
{
"employeeId": "Oliver",
"shiftId": "Tuesday-2023-05-02",
"roleId": "Sous chef"
},
{
"employeeId": "Oliver",
"shiftId": "Wednesday-2023-05-03",
"roleId": "Sous chef"
},
{
"employeeId": "Oliver",
"shiftId": "Thursday-2023-05-04",
"roleId": "Sous chef"
},
{
"employeeId": "Oliver",
"shiftId": "Friday-2023-05-05",
"roleId": "Sous chef"
}
]
}