I need help to tackle this coding problem. I have a very simple pulp scheduling problem. It has a solution, but the solution is missing 2 constraints that I don't even know how to begin. This post, I just like to tackle one. If someone can point out a direction, or other examples, at least I can read more about it. I did look into itertool, but I don't think that will help because it would require if--elif condition, which i know is not possible with Lineear optimization. here is the code:
import pulp
Days= ["Monday"]
Employees =["Paul", "Beth", "Tom"]
Hours = ["9am - 10am", "10am - 11am", "11am - 12pm", "12pm - 1pm", "1pm - 2pm", "2pm - 3pm", "3pm - 4pm", "4pm - 5pm", "5pm - 6pm", "6pm - 7pm", "7pm - 8pm", "8pm - 9pm" ]
prob=pulp.LpProblem("Hours maximizing problem", pulp.LpMaximize)
avail = pulp.LpVariable.dicts("var", ((employee, day, hour) for employee in Employees for day in Days for hour in Hours), cat="Binary")
# each employee has their desire working # of hours. #
prob += pulp.lpSum(avail['Paul', day, hour] for day in Days for hour in Hours)== 2
prob += pulp.lpSum(avail['Beth', day, hour] for day in Days for hour in Hours)<= 5
prob += pulp.lpSum(avail['Tom', day, hour] for day in Days for hour in Hours)<= 5
#each hour only needs one person
for hour in Hours:
for day in Days:
for employee in Employees:
prob += pulp.lpSum(avail[employee, day, hour] for employee in Employees)==1
prob += 0, "Objective Function"
prob.writeLP("add to 2.lp")
prob.solve()
print (prob)
the constraint that is missing is that all hours worked must be consecutive. as an example: Tom, Monday work 4pm to 9pm, or any combination of 5 hours, but it needs to be together, instead of one hour in the morning(as an example), and 4 other hours in the afternoon.
any help would be appreciated.
You could introduce binary variables to track whether a shift is started/ended in a particular hour, and intorduce a constraint that there can only be one shift start during each day:
import pulp
Days= ["Monday"]
Employees =["Paul", "Beth", "Tom"]
Hours = [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
prob=pulp.LpProblem("Hours maximizing problem", pulp.LpMaximize)
avail = pulp.LpVariable.dicts("var", ((employee, day, hour) for employee in Employees for day in Days for hour in Hours), cat="Binary")
startShift = pulp.LpVariable.dicts("start", ((employee, day, hour) for employee in Employees for day in Days for hour in Hours), cat="Binary")
endShift = pulp.LpVariable.dicts("end", ((employee, day, hour) for employee in Employees for day in Days for hour in Hours), cat="Binary")
# each employee has their desire working # of hours. #
prob += pulp.lpSum(avail['Paul', day, hour] for day in Days for hour in Hours)== 2
prob += pulp.lpSum(avail['Beth', day, hour] for day in Days for hour in Hours)<= 5
prob += pulp.lpSum(avail['Tom', day, hour] for day in Days for hour in Hours)<= 5
#each hour only needs one person
for hour in Hours:
for day in Days:
prob += pulp.lpSum(avail[employee, day, hour] for employee in Employees)==1
for employee in Employees:
if hour == Hours[0]:
# to be working in the first hour of the day, avail==1
# they must have started their shift, startShift==1
prob += avail[employee, day, hour] == startShift[employee, day, hour]
else:
# to be working in any other hour of the day, they either
# have to already be part through their shift; avail[e, d, h-1]
# or they have to have started their shift in this hour; startShift[e, d, h]
# also, if they just ended their shift, they are no longer working; endShift[e, d, h-1]
prob += avail[employee, day, hour] == avail[employee, day, hour-1] + startShift[employee, day, hour] - endShift[employee, day, hour-1]
# each employee must have onlhy a single shift
for employee in Employees:
for day in Days:
prob += pulp.lpSum([startShift[employee, day, hour] for hour in Hours]) == 1
prob += pulp.lpSum([endShift[employee, day, hour] for hour in Hours]) == 1
prob += 0, "Objective Function"
prob.writeLP("add to 2.lp")
prob.solve()
print (prob)
for v in prob.variables():
print (v.name, "=", v.varValue)
print('Status:',pulp.LpStatus[prob.status])