I have a finite number of staff N, and I need to find an optimal schedule (using the least number of staff) meeting the demand
Hour of Day | Demand |
---|---|
0 | d0 |
1 | d1 |
... | ... |
23 | d23 |
where the d0, d1, ..., d23 are real numbers denoting the required amount of people on shift at that hour. Staff can only work one of a number of possible shifts with a specific start and end time given in a table. For example, it will look like this:
Person | Shifts |
---|---|
1 | 0-8, 1-9, 2-10 |
2 | 8-16, 16-24 |
... | ... |
N | 11-16, 15-20 |
So that e.g. person 1 can work from 0-8, and not work any other hour of the day, person 2 can work 8-16 and no other hour of the day, etc.
Ignoring the above constraint on the hours that each member of staff can work, the problem would reduce to:
min x1 + x2 + ... + x(N*24)
xi all binary variables
subject to the 24 constraints
x1 + x2 + ... + xN <= d0
x(N+1) + x(N+2) + ... + x(2*N) <= d1
... (similar constraints)
x(23*N+1) + x(23*N+2) + ... + x(24*N) <= d23
All of which is easy to put into lpSolve or lpSolveAPI.
I am having trouble with trying to input my constraint on the permitted shift starts/times of staff. Mathematically, for person A, this would be something like
xi + ... + x(i+7) = 8 where i is either 1, 2 or 3
xj = 0 for all other j <= 24
But I am finding this very difficult to translate into an R constraint. I have thought about using for loops but I think this is over complicating things.
I think you need to re-formulate your approach.
The key decision variable here is whether person member p
works shift s
where the shifts appear to be particular to that person.
So you have components:
SETS
p ∈ People {Bob, Tim, Cindy, ...}
s[p] ∈ Shifts, indexed by person {1, 2, ... }
h ∈ Hours {1, ..., 24}
PARAMS
coverage[p, s[p], h] ∈ {1, 0} whether p's shift s[p] contributes to hour h
demand[h] ∈ Integers
VARS
x[p, s[p]] ∈ {1, 0} whether person p works s[p]
With that setup, I think the problem falls into place better. It may be a little tricky to handle the indexed set for s[p]
depending on the language used, but that's how I would approach this.