# Determine the start time
StartTime = time.process_time()
# Define our Linear Program
Solver = pywraplp.Solver('Solver', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
# Define the Preference Coefficient P[i,j], for Residence i working in Week j
n=14
m=35
P = np.zeros(shape=(n, m), dtype=int)
for j in range(m):
for i in range(n):
P[i,j] = InputData[j+1][i]
# Define the binary variable X[i,j], which will equal 1 if Employee i is assigned to Shift j
X = {}
for i in range(n):
for j in range(m):
X[i,j] = Solver.IntVar(0, 1, 'X[%d, %d]' % (i,j))
# Set up our Happiness Function, which maximizes the total number of Happiness Points
HappinessFunction = Solver.Sum(P[i,j]*X[i,j] for i in range(n) for j in range(m))
Solver.Minimize(HappinessFunction)
# Include our first constraint: Each employee must work at least two and at most three shifts
for i in range(n):
Solver.Add(Solver.Sum([X[i,j] for j in range(m)]) >= 2)
Solver.Add(Solver.Sum([X[i,j] for j in range(m)]) <= 3)
# Include our second constraint: Each week must be covered by at least one employee and at most two
for j in range(m):
Solver.Add(Solver.Sum([X[i,j] for i in range(n)]) >= 1)
Solver.Add(Solver.Sum([X[i,j] for i in range(n)]) <= 2)
# Include our third constraint: you can't work a Cave Shift and a Reception Shift at the same time
for i in range(n):
Solver.Add(X[i,3] + X[i,27] <= 1)
Solver.Add(X[i,4] + X[i,28] <= 1)
Solver.Add(X[i,8] + X[i,29] <= 1)
Solver.Add(X[i,9] + X[i,30] <= 1)
Solver.Add(X[i,13] + X[i,31] <= 1)
Solver.Add(X[i,14] + X[i,32] <= 1)
Solver.Add(X[i,18] + X[i,33] <= 1)
Solver.Add(X[i,19] + X[i,34] <= 1)
# Include our fourth constraint: a man can't work during WomXn hours
for i in [0,3,5,7,10,12]:
Solver.Add(X[i,8] + X[i,18] + X[i,27] == 0)
# Solve the Integer Linear program
Output = Solver.Solve()
TotalPoints = round(Solver.Objective().Value())
# Determine the total time of running the program.
TotalTime = round(time.process_time() - StartTime, 4)
# Output one of the possible optimal solutions.
print("Python returns a solution with", TotalPoints, "Total Happiness Points in", TotalTime, "seconds")
pd.options.mode.chained_assignment = None
OutputData = InputData.copy()
for i in range(n):
for j in range(m):
if X[i,j].solution_value()==0:
OutputData[j+1][i] = ""
OutputData