Integer Programming Approach to Shift Generation
Summary of 2020 Summer Intern Python Development
Approach
Python
Formulation
Python Code
m = Model()
##VARIABLES
# binary for each day, clinician (S), position, base
x = [[[[m.add_var(var_type=BINARY) for d in D] for s in S] for p in P] for b in B]
#maximum of total days assigned per pattern
M = m.add_var(var_type=INTEGER)
##OBJECTIVE FUNCTION
m.objective = maximize(
#maximize covered shifts
1*(xsum(x[b][p][s][d] for b in range(B.shape[0]) for p in range(P.shape[0]) for s in range(S.shape[0]) for d in range(D.shape[0])))
#minimize the max total shifts (shift evenly over staff)
-0.5*M
)
##CONSTRAINTS##
#one assignment per position per base per day
for d in range(D.shape[0]):
for p in range(P.shape[0]) :
for b in range(B.shape[0]):
m += xsum(x[b][p][s][d] for s in range(S.shape[0])) <= 1, 'max one staff per position per day'
for s in range(staffToPattern): #for each pattern
for d in range(D.shape[0]-1):#no consecutive days
m += xsum(x[b][p][s][d] for b in range(B.shape[0]) for p in range(P.shape[0]))+xsum(x[b][p][s][d+1] for b in range(B.shape[0]) for p in range(P.shape[0])) <= 1, 'No consecutive days'
m += xsum(x[b][p][s][0] for b in range(B.shape[0]) for p in range(P.shape[0]))+xsum(x[b][p][s][D.shape[0]-1] for b in range(B.shape[0]) for p in range(P.shape[0])) <= 1, 'No consecutive days--end of pattern'
#to minimize/even out: count ttl shifts per staffer
m += xsum(x[b][p][s][d] for d in range(D.shape[0]) for b in range(B.shape[0]) for p in range(P.shape[0])) <= M, 'count total shifts per staffer'
m.optimize()
Results & Discussion