Rostering Problems
Introduction
In workforce management, rostering means assigning named resources to days and shifts while respecting operational rules. The required number of resources per day and shift might come from a scheduling model, a demand forecast, or a manual planning process.
The meaning of “optimal” is defined by an objective function. In this solver, the objective is to minimize scheduled hours while still satisfying the required coverage and roster constraints.
pyworkforce solves this problem with MinHoursRoster.
MinHoursRoster
This method assigns a list of resources to a list of required positions per day and shifts; it considers restrictions such as shift bans, non-sequential shifts, rest days, minimum hours, and other roster rules. It can also use soft preferences, such as a resource preferring a particular shift.
The “optimal” criterion is the minimum total scheduled hours, optionally weighted by resource shift preferences.
Let’s start by introducing the variables that the model uses.
Name |
Type |
Description |
|---|---|---|
\(D\) |
Set |
Days on the planning horizon |
\(S\) |
Set |
Shifts in a day |
\(N\) |
Set |
Resources available to schedule |
\(\delta_s\) |
Parameter |
Number of hours in the shift s |
\(\mu\) |
Parameter |
Maximum number of days off per resource in the planning horizon |
\(R_{ds}\) |
Parameter |
Number of resources required at day d for the shift s |
\(\tau_{ij}\) |
Parameter |
1 if a resource cannot work shift j the day after shift i, 0 otherwise |
\(\sigma_{nds}\) |
Parameter |
1 if resource n cannot work shift s on day d, 0 otherwise |
\(\phi_{ns}\) |
Parameter |
1 if resource n prefers shift s, 0 if there is no specific preference |
\(\alpha_{n}\) |
Parameter |
Weight used to reward resource n when one of their shift preferences is met |
\(X_{nds}\) |
Decision variable |
1 if the resource n is scheduled at day d for the shift s, 0 otherwise |
In this case, the variables \(\tau_{ij}\), \(\phi_{ns}\), and \(\alpha_{n}\) are optional for the solver.
Under this definition, the objective function is formulated as:
If the shift preference term \(\phi_{ns}\) is not used, or if it is set to \(\phi_{ns} = 0_{n,s}\), the objective function simplifies to the total number of scheduled hours:
The model uses these restrictions:
The number of resources in the roster for day d and shift s must be greater or equal to the number of required resources for that day and shift.
The total days off for resource n cannot be greater than the maximum allowed days.
Each resource can be scheduled at most once per day.
A resource cannot work forbidden shift sequences, according to \(\tau_{ij}\).
Resources with a banned shift cannot be assigned to that shift.
We’ll solve an example using pyworkforce with the following conditions:
We want to plan a 7-day operation
The resources are people, and there are 55 resources available
There are four shifts: Morning, Afternoon, Night, and Mixed. All last 8 hours except Mixed, which lasts 6 hours
The minimum working hours in the 7-day horizon are 40
Each resource can be off at most one day in this planning horizon
A resource who works Night cannot work Morning the following day
e.johnston@randatmail.com cannot work Night on day 0 or Morning on day 3
d.harper@randatmail.com cannot work Mixed on day 1
d.harper@randatmail.com prefers Morning or Mixed shifts when possible
c.campbell@randatmail.com prefers Afternoon shifts when possible
There is no special prioritization among resource shift preferences
The minimum required resources per shift and day are encoded in
required_resources
This data encodes all the previous conditions:
shifts_info = {
"num_days": 7,
"resources": ["e.johnston@randatmail.com", "d.harper@randatmail.com", "m.hawkins@randatmail.com",
"m.ellis@randatmail.com", "b.campbell@randatmail.com", "s.richards@randatmail.com",
"j.evans@randatmail.com", "s.brooks@randatmail.com", "a.montgomery@randatmail.com",
"c.hunt@randatmail.com", "v.owens@randatmail.com", "a.brown@randatmail.com",
"r.armstrong@randatmail.com", "m.murray@randatmail.com", "b.evans@randatmail.com",
"m.brown@randatmail.com", "s.thompson@randatmail.com", "a.ryan@randatmail.com",
"r.carter@randatmail.com", "j.payne@randatmail.com", "s.perkins@randatmail.com",
"t.west@randatmail.com", "d.stevens@randatmail.com", "l.gibson@randatmail.com",
"m.crawford@randatmail.com", "a.barnes@randatmail.com", "m.howard@randatmail.com",
"t.chapman@randatmail.com", "s.harris@randatmail.com", "a.farrell@randatmail.com",
"d.douglas@randatmail.com", "a.douglas@randatmail.com", "j.cole@randatmail.com",
"v.myers@randatmail.com", "l.owens@randatmail.com", "h.robinson@randatmail.com",
"s.spencer@randatmail.com", "v.brooks@randatmail.com", "h.turner@randatmail.com",
"e.elliott@randatmail.com", "a.adams@randatmail.com", "m.higgins@randatmail.com",
"j.cole@randatmail.com", "m.ryan@randatmail.com", "l.wilson@randatmail.com",
"j.higgins@randatmail.com", "v.ryan@randatmail.com", "c.perry@randatmail.com",
"c.wright@randatmail.com", "f.myers@randatmail.com", "c.allen@randatmail.com",
"c.stevens@randatmail.com", "c.campbell@randatmail.com", "d.taylor@randatmail.com",
"h.myers@randatmail.com"],
"shifts": ["Morning", "Afternoon", "Night", "Mixed"],
"shifts_hours": [8, 8, 8, 6],
"min_working_hours": 40,
"max_resting": 1,
"non_sequential_shifts": [{"origin": "Night", "destination": "Morning"}],
"banned_shifts": [{"resource": "e.johnston@randatmail.com", "shift": "Night", "day": 0},
{"resource": "e.johnston@randatmail.com", "shift": "Morning", "day": 3},
{"resource": "d.harper@randatmail.com", "shift": "Mixed", "day": 1}],
"required_resources": {"Morning": [9, 12, 8, 10, 13, 10, 14],
"Afternoon": [11, 13, 10, 11, 9, 11, 7],
"Night": [8, 7, 5, 15, 7, 8, 6],
"Mixed": [2, 4, 18, 7, 10, 5, 17]},
"resources_preferences": [{"resource": "d.harper@randatmail.com", "shift": "Morning"},
{"resource": "d.harper@randatmail.com", "shift": "Mixed"},
{"resource": "c.campbell@randatmail.com", "shift": "Afternoon"}]
}
With this information, we can start using the MinHoursRoster solver.
from pyworkforce.rostering.binary_programming import MinHoursRoster
from pprint import PrettyPrinter
solver = MinHoursRoster(num_days=shifts_info["num_days"],
resources=shifts_info["resources"],
shifts=shifts_info["shifts"],
shifts_hours=shifts_info["shifts_hours"],
min_working_hours=shifts_info["min_working_hours"],
max_resting=shifts_info["max_resting"],
non_sequential_shifts=shifts_info["non_sequential_shifts"],
banned_shifts=shifts_info["banned_shifts"],
required_resources=shifts_info["required_resources"],
resources_preferences=shifts_info["resources_preferences"])
pp.pprint(solver.solve())
The output is large, so this section explains the important fields first. The full printed solution is included at the end of this article.
First, the OPTIMAL status means that the solver found the best feasible roster for the model.
There are 330 assigned shifts, representing 2388 scheduled working hours.
resource_shifts is a list of dictionaries. Each item tells you which resource is scheduled
on which day and shift. For example, the first item means that e.johnston@randatmail.com works
the Mixed shift on day 0:
{ 'day': 0, 'resource': 'e.johnston@randatmail.com', 'shift': 'Mixed'}
resting_resource tells you which resource is off on each day. For example, the first item
means that e.johnston@randatmail.com is off on day 3:
{'day': 3, 'resource': 'e.johnston@randatmail.com'}
resting_days is 55, the total number of days off in the planning horizon. Since there are
55 resources and each resource can rest at most one day, this means every resource rests exactly once.
Now let’s inspect a few resources with special conditions:
e.johnston@randatmail.com has two banned shifts: Night on day 0 and Morning on day 3. The solver respects both conditions by assigning Mixed on day 0 and a rest day on day 3.
[ { 'day': 0, 'resource': 'e.johnston@randatmail.com', 'shift': 'Mixed'},
{ 'day': 1, 'resource': 'e.johnston@randatmail.com', 'shift': 'Morning'},
{ 'day': 2, 'resource': 'e.johnston@randatmail.com', 'shift': 'Night'},
{ 'day': 4, 'resource': 'e.johnston@randatmail.com', 'shift': 'Morning'},
{ 'day': 5, 'resource': 'e.johnston@randatmail.com', 'shift': 'Morning'},
{ 'day': 6, 'resource': 'e.johnston@randatmail.com', 'shift': 'Morning'} ]
d.harper@randatmail.com cannot work Mixed on day 1 and prefers Morning or Mixed shifts. The ban is respected because he is off on day 1. The solver also assigns him to Morning shifts, which matches one of his preferences. Preferences are soft constraints: the solver tries to satisfy them without making the model infeasible or sacrificing optimality.
[{ 'day': 0, 'resource': 'd.harper@randatmail.com', 'shift': 'Morning'},
{ 'day': 2, 'resource': 'd.harper@randatmail.com', 'shift': 'Morning'},
{ 'day': 3, 'resource': 'd.harper@randatmail.com', 'shift': 'Morning'},
{ 'day': 4, 'resource': 'd.harper@randatmail.com', 'shift': 'Morning'},
{ 'day': 5, 'resource': 'd.harper@randatmail.com', 'shift': 'Morning'},
{ 'day': 6, 'resource': 'd.harper@randatmail.com', 'shift': 'Morning'}]
c.campbell@randatmail.com prefers Afternoon shifts:
[{ 'day': 0, 'resource': 'c.campbell@randatmail.com', 'shift': 'Afternoon'},
{ 'day': 1, 'resource': 'c.campbell@randatmail.com', 'shift': 'Afternoon'},
{ 'day': 2, 'resource': 'c.campbell@randatmail.com', 'shift': 'Afternoon'},
{ 'day': 3, 'resource': 'c.campbell@randatmail.com', 'shift': 'Afternoon'},
{ 'day': 4, 'resource': 'c.campbell@randatmail.com', 'shift': 'Afternoon'},
{ 'day': 5, 'resource': 'c.campbell@randatmail.com', 'shift': 'Afternoon'}]
Here is the full print of the solution found by the solver:
{'cost': 2376.0,
'resource_shifts': [ { 'day': 0,
'resource': 'e.johnston@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'e.johnston@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 'e.johnston@randatmail.com',
'shift': 'Night'},
{ 'day': 4,
'resource': 'e.johnston@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'e.johnston@randatmail.com',
'shift': 'Morning'},
{ 'day': 6,
'resource': 'e.johnston@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 'd.harper@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 'd.harper@randatmail.com',
'shift': 'Morning'},
{ 'day': 3,
'resource': 'd.harper@randatmail.com',
'shift': 'Morning'},
{ 'day': 4,
'resource': 'd.harper@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'd.harper@randatmail.com',
'shift': 'Morning'},
{ 'day': 6,
'resource': 'd.harper@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 'm.hawkins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'm.hawkins@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 'm.hawkins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'm.hawkins@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'm.hawkins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'm.hawkins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'm.ellis@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'm.ellis@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 'm.ellis@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 3,
'resource': 'm.ellis@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'm.ellis@randatmail.com',
'shift': 'Morning'},
{ 'day': 6,
'resource': 'm.ellis@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'b.campbell@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 'b.campbell@randatmail.com',
'shift': 'Morning'},
{ 'day': 3,
'resource': 'b.campbell@randatmail.com',
'shift': 'Morning'},
{ 'day': 4,
'resource': 'b.campbell@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 'b.campbell@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'b.campbell@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 's.richards@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 's.richards@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 's.richards@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 3,
'resource': 's.richards@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 's.richards@randatmail.com',
'shift': 'Morning'},
{ 'day': 6,
'resource': 's.richards@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 'j.evans@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 'j.evans@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'j.evans@randatmail.com',
'shift': 'Night'},
{ 'day': 4,
'resource': 'j.evans@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'j.evans@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'j.evans@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 0,
'resource': 's.brooks@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 's.brooks@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 's.brooks@randatmail.com',
'shift': 'Night'},
{ 'day': 4,
'resource': 's.brooks@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 5,
'resource': 's.brooks@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 6,
'resource': 's.brooks@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 'a.montgomery@randatmail.com',
'shift': 'Morning'},
{ 'day': 1,
'resource': 'a.montgomery@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'a.montgomery@randatmail.com',
'shift': 'Morning'},
{ 'day': 3,
'resource': 'a.montgomery@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 'a.montgomery@randatmail.com',
'shift': 'Night'},
{ 'day': 6,
'resource': 'a.montgomery@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'c.hunt@randatmail.com',
'shift': 'Morning'},
{ 'day': 1,
'resource': 'c.hunt@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 'c.hunt@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'c.hunt@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 'c.hunt@randatmail.com',
'shift': 'Night'},
{ 'day': 6,
'resource': 'c.hunt@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 'v.owens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'v.owens@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 'v.owens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'v.owens@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'v.owens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'v.owens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'a.brown@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'a.brown@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 'a.brown@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 3,
'resource': 'a.brown@randatmail.com',
'shift': 'Morning'},
{ 'day': 4,
'resource': 'a.brown@randatmail.com',
'shift': 'Night'},
{ 'day': 6,
'resource': 'a.brown@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 'r.armstrong@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'r.armstrong@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 'r.armstrong@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 3,
'resource': 'r.armstrong@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'r.armstrong@randatmail.com',
'shift': 'Morning'},
{ 'day': 6,
'resource': 'r.armstrong@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 'm.murray@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'm.murray@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 'm.murray@randatmail.com',
'shift': 'Morning'},
{ 'day': 3,
'resource': 'm.murray@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'm.murray@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 6,
'resource': 'm.murray@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'b.evans@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 'b.evans@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 'b.evans@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 3,
'resource': 'b.evans@randatmail.com',
'shift': 'Morning'},
{ 'day': 4,
'resource': 'b.evans@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'b.evans@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 'm.brown@randatmail.com',
'shift': 'Morning'},
{ 'day': 1,
'resource': 'm.brown@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 'm.brown@randatmail.com',
'shift': 'Morning'},
{ 'day': 3,
'resource': 'm.brown@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 'm.brown@randatmail.com',
'shift': 'Night'},
{ 'day': 6,
'resource': 'm.brown@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 's.thompson@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 's.thompson@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 's.thompson@randatmail.com',
'shift': 'Morning'},
{ 'day': 3,
'resource': 's.thompson@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 's.thompson@randatmail.com',
'shift': 'Morning'},
{ 'day': 6,
'resource': 's.thompson@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'a.ryan@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 'a.ryan@randatmail.com',
'shift': 'Night'},
{ 'day': 3,
'resource': 'a.ryan@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 'a.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 'a.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'a.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'r.carter@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'r.carter@randatmail.com',
'shift': 'Night'},
{ 'day': 3,
'resource': 'r.carter@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 'r.carter@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'r.carter@randatmail.com',
'shift': 'Morning'},
{ 'day': 6,
'resource': 'r.carter@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'j.payne@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 'j.payne@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 3,
'resource': 'j.payne@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 'j.payne@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'j.payne@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'j.payne@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 's.perkins@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 's.perkins@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 's.perkins@randatmail.com',
'shift': 'Morning'},
{ 'day': 3,
'resource': 's.perkins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 's.perkins@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 's.perkins@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 't.west@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 't.west@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 't.west@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 't.west@randatmail.com',
'shift': 'Morning'},
{ 'day': 4,
'resource': 't.west@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 't.west@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 'd.stevens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'd.stevens@randatmail.com',
'shift': 'Night'},
{ 'day': 3,
'resource': 'd.stevens@randatmail.com',
'shift': 'Morning'},
{ 'day': 4,
'resource': 'd.stevens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 'd.stevens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'd.stevens@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 0,
'resource': 'l.gibson@randatmail.com',
'shift': 'Morning'},
{ 'day': 1,
'resource': 'l.gibson@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 'l.gibson@randatmail.com',
'shift': 'Night'},
{ 'day': 4,
'resource': 'l.gibson@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'l.gibson@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'l.gibson@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'm.crawford@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'm.crawford@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'm.crawford@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'm.crawford@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'm.crawford@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 5,
'resource': 'm.crawford@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 'a.barnes@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'a.barnes@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 'a.barnes@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'a.barnes@randatmail.com',
'shift': 'Morning'},
{ 'day': 4,
'resource': 'a.barnes@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 5,
'resource': 'a.barnes@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 'm.howard@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 'm.howard@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 'm.howard@randatmail.com',
'shift': 'Night'},
{ 'day': 4,
'resource': 'm.howard@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 5,
'resource': 'm.howard@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'm.howard@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 't.chapman@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 't.chapman@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 't.chapman@randatmail.com',
'shift': 'Morning'},
{ 'day': 3,
'resource': 't.chapman@randatmail.com',
'shift': 'Morning'},
{ 'day': 4,
'resource': 't.chapman@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 't.chapman@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 's.harris@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 's.harris@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 's.harris@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 3,
'resource': 's.harris@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 's.harris@randatmail.com',
'shift': 'Morning'},
{ 'day': 6,
'resource': 's.harris@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'a.farrell@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 'a.farrell@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 'a.farrell@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 3,
'resource': 'a.farrell@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'a.farrell@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 6,
'resource': 'a.farrell@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 'd.douglas@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'd.douglas@randatmail.com',
'shift': 'Morning'},
{ 'day': 2,
'resource': 'd.douglas@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'd.douglas@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'd.douglas@randatmail.com',
'shift': 'Morning'},
{ 'day': 6,
'resource': 'd.douglas@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'a.douglas@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'a.douglas@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'a.douglas@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'a.douglas@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'a.douglas@randatmail.com',
'shift': 'Night'},
{ 'day': 6,
'resource': 'a.douglas@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 'j.cole@randatmail.com',
'shift': 'Night'},
{ 'day': 2,
'resource': 'j.cole@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'j.cole@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'j.cole@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 5,
'resource': 'j.cole@randatmail.com',
'shift': 'Morning'},
{ 'day': 6,
'resource': 'j.cole@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 0,
'resource': 'v.myers@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'v.myers@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'v.myers@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'v.myers@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 'v.myers@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 5,
'resource': 'v.myers@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 'l.owens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'l.owens@randatmail.com',
'shift': 'Night'},
{ 'day': 3,
'resource': 'l.owens@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 'l.owens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 'l.owens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'l.owens@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 'h.robinson@randatmail.com',
'shift': 'Night'},
{ 'day': 2,
'resource': 'h.robinson@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'h.robinson@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'h.robinson@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 5,
'resource': 'h.robinson@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'h.robinson@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 's.spencer@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 's.spencer@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 's.spencer@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 's.spencer@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 's.spencer@randatmail.com',
'shift': 'Night'},
{ 'day': 6,
'resource': 's.spencer@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 0,
'resource': 'v.brooks@randatmail.com',
'shift': 'Morning'},
{ 'day': 1,
'resource': 'v.brooks@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'v.brooks@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'v.brooks@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'v.brooks@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 6,
'resource': 'v.brooks@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 0,
'resource': 'h.turner@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'h.turner@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'h.turner@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'h.turner@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'h.turner@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 5,
'resource': 'h.turner@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 'e.elliott@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'e.elliott@randatmail.com',
'shift': 'Night'},
{ 'day': 3,
'resource': 'e.elliott@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'e.elliott@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'e.elliott@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 6,
'resource': 'e.elliott@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'a.adams@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'a.adams@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'a.adams@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'a.adams@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'a.adams@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 6,
'resource': 'a.adams@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'm.higgins@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 'm.higgins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'm.higgins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'm.higgins@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'm.higgins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'm.higgins@randatmail.com',
'shift': 'Night'},
{ 'day': 1,
'resource': 'j.cole@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'j.cole@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'j.cole@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 'j.cole@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 'j.cole@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'j.cole@randatmail.com',
'shift': 'Morning'},
{ 'day': 0,
'resource': 'm.ryan@randatmail.com',
'shift': 'Night'},
{ 'day': 2,
'resource': 'm.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'm.ryan@randatmail.com',
'shift': 'Morning'},
{ 'day': 4,
'resource': 'm.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 'm.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'm.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'l.wilson@randatmail.com',
'shift': 'Morning'},
{ 'day': 1,
'resource': 'l.wilson@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'l.wilson@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'l.wilson@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'l.wilson@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'l.wilson@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 0,
'resource': 'j.higgins@randatmail.com',
'shift': 'Morning'},
{ 'day': 1,
'resource': 'j.higgins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'j.higgins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'j.higgins@randatmail.com',
'shift': 'Night'},
{ 'day': 5,
'resource': 'j.higgins@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 6,
'resource': 'j.higgins@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'v.ryan@randatmail.com',
'shift': 'Night'},
{ 'day': 2,
'resource': 'v.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'v.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'v.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 'v.ryan@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 6,
'resource': 'v.ryan@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'c.perry@randatmail.com',
'shift': 'Night'},
{ 'day': 2,
'resource': 'c.perry@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 3,
'resource': 'c.perry@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'c.perry@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 'c.perry@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 6,
'resource': 'c.perry@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 0,
'resource': 'c.wright@randatmail.com',
'shift': 'Night'},
{ 'day': 2,
'resource': 'c.wright@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'c.wright@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'c.wright@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 'c.wright@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 6,
'resource': 'c.wright@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'f.myers@randatmail.com',
'shift': 'Night'},
{ 'day': 2,
'resource': 'f.myers@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'f.myers@randatmail.com',
'shift': 'Morning'},
{ 'day': 4,
'resource': 'f.myers@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'f.myers@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'f.myers@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'c.allen@randatmail.com',
'shift': 'Morning'},
{ 'day': 1,
'resource': 'c.allen@randatmail.com',
'shift': 'Mixed'},
{ 'day': 2,
'resource': 'c.allen@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'c.allen@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'c.allen@randatmail.com',
'shift': 'Night'},
{ 'day': 6,
'resource': 'c.allen@randatmail.com',
'shift': 'Mixed'},
{ 'day': 0,
'resource': 'c.stevens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'c.stevens@randatmail.com',
'shift': 'Night'},
{ 'day': 3,
'resource': 'c.stevens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'c.stevens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 5,
'resource': 'c.stevens@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'c.stevens@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 'c.campbell@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 1,
'resource': 'c.campbell@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 2,
'resource': 'c.campbell@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 3,
'resource': 'c.campbell@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 4,
'resource': 'c.campbell@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 5,
'resource': 'c.campbell@randatmail.com',
'shift': 'Afternoon'},
{ 'day': 0,
'resource': 'd.taylor@randatmail.com',
'shift': 'Night'},
{ 'day': 2,
'resource': 'd.taylor@randatmail.com',
'shift': 'Mixed'},
{ 'day': 3,
'resource': 'd.taylor@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'd.taylor@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'd.taylor@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'd.taylor@randatmail.com',
'shift': 'Night'},
{ 'day': 0,
'resource': 'h.myers@randatmail.com',
'shift': 'Mixed'},
{ 'day': 1,
'resource': 'h.myers@randatmail.com',
'shift': 'Night'},
{ 'day': 3,
'resource': 'h.myers@randatmail.com',
'shift': 'Mixed'},
{ 'day': 4,
'resource': 'h.myers@randatmail.com',
'shift': 'Morning'},
{ 'day': 5,
'resource': 'h.myers@randatmail.com',
'shift': 'Mixed'},
{ 'day': 6,
'resource': 'h.myers@randatmail.com',
'shift': 'Night'}],
'resting_days': 55,
'resting_resource': [ {'day': 3, 'resource': 'e.johnston@randatmail.com'},
{'day': 1, 'resource': 'd.harper@randatmail.com'},
{'day': 4, 'resource': 'm.hawkins@randatmail.com'},
{'day': 4, 'resource': 'm.ellis@randatmail.com'},
{'day': 0, 'resource': 'b.campbell@randatmail.com'},
{'day': 4, 'resource': 's.richards@randatmail.com'},
{'day': 3, 'resource': 'j.evans@randatmail.com'},
{'day': 3, 'resource': 's.brooks@randatmail.com'},
{'day': 5, 'resource': 'a.montgomery@randatmail.com'},
{'day': 5, 'resource': 'c.hunt@randatmail.com'},
{'day': 4, 'resource': 'v.owens@randatmail.com'},
{'day': 5, 'resource': 'a.brown@randatmail.com'},
{'day': 4, 'resource': 'r.armstrong@randatmail.com'},
{'day': 4, 'resource': 'm.murray@randatmail.com'},
{'day': 6, 'resource': 'b.evans@randatmail.com'},
{'day': 5, 'resource': 'm.brown@randatmail.com'},
{'day': 4, 'resource': 's.thompson@randatmail.com'},
{'day': 2, 'resource': 'a.ryan@randatmail.com'},
{'day': 2, 'resource': 'r.carter@randatmail.com'},
{'day': 0, 'resource': 'j.payne@randatmail.com'},
{'day': 6, 'resource': 's.perkins@randatmail.com'},
{'day': 6, 'resource': 't.west@randatmail.com'},
{'day': 2, 'resource': 'd.stevens@randatmail.com'},
{'day': 3, 'resource': 'l.gibson@randatmail.com'},
{'day': 6, 'resource': 'm.crawford@randatmail.com'},
{'day': 6, 'resource': 'a.barnes@randatmail.com'},
{'day': 3, 'resource': 'm.howard@randatmail.com'},
{'day': 6, 'resource': 't.chapman@randatmail.com'},
{'day': 4, 'resource': 's.harris@randatmail.com'},
{'day': 4, 'resource': 'a.farrell@randatmail.com'},
{'day': 4, 'resource': 'd.douglas@randatmail.com'},
{'day': 5, 'resource': 'a.douglas@randatmail.com'},
{'day': 1, 'resource': 'j.cole@randatmail.com'},
{'day': 6, 'resource': 'v.myers@randatmail.com'},
{'day': 2, 'resource': 'l.owens@randatmail.com'},
{'day': 1, 'resource': 'h.robinson@randatmail.com'},
{'day': 5, 'resource': 's.spencer@randatmail.com'},
{'day': 4, 'resource': 'v.brooks@randatmail.com'},
{'day': 6, 'resource': 'h.turner@randatmail.com'},
{'day': 2, 'resource': 'e.elliott@randatmail.com'},
{'day': 4, 'resource': 'a.adams@randatmail.com'},
{'day': 4, 'resource': 'm.higgins@randatmail.com'},
{'day': 0, 'resource': 'j.cole@randatmail.com'},
{'day': 1, 'resource': 'm.ryan@randatmail.com'},
{'day': 4, 'resource': 'l.wilson@randatmail.com'},
{'day': 4, 'resource': 'j.higgins@randatmail.com'},
{'day': 1, 'resource': 'v.ryan@randatmail.com'},
{'day': 1, 'resource': 'c.perry@randatmail.com'},
{'day': 1, 'resource': 'c.wright@randatmail.com'},
{'day': 1, 'resource': 'f.myers@randatmail.com'},
{'day': 5, 'resource': 'c.allen@randatmail.com'},
{'day': 2, 'resource': 'c.stevens@randatmail.com'},
{'day': 6, 'resource': 'c.campbell@randatmail.com'},
{'day': 1, 'resource': 'd.taylor@randatmail.com'},
{'day': 2, 'resource': 'h.myers@randatmail.com'}],
'shifted_hours': 2388,
'status': 'OPTIMAL',
'total_resources': 55,
'total_shifts': 330}