在 PuLP 问题中设置最大每日小时数的要求
Setup the requirement for max daily hours in PuLP problem
我正在尝试配置我的 PuLP 问题以确保员工每天的工作时间不超过 10 小时。
我设置的员工变量是:
cost = []
vars_by_shift = defaultdict(list)
for employee, info in employees.iterrows():
for shift in info['availability']:
employee_var = pl.LpVariable("%s_%s" % (employee, shift), 0, 1, pl.LpInteger)
vars_by_shift[shift].append(employee_var)
cost.append(employee_var * info['base_rate'])
我的objective是为了最小化成本:
prob = pl.LpProblem("scheduling", pl.LpMinimize)
prob += sum(cost)
我的班次数据示例是:
"76749": {
"start_date": "2019-08-14",
"start_time": "08:00",
"end_date": "2019-08-14",
"end_time": "12:00",
"duration": 4,
"number_positions": 1
},
"76750": {
"start_date": "2019-08-14",
"start_time": "13:00",
"end_date": "2019-08-14",
"end_time": "20:00",
"duration": 7,
"number_positions": 1
}
一名员工有时可以在同一天分配两个短班。我想确保员工在任何一天的排班总时数不超过 10 小时。如何为该约束建模?
好吧,您需要一个时间分组变量,是否将 start_date 视为您不想分配超过 10 小时的那一天?
如果答案是肯定的
那么你需要这样的……
emp in employees.iterrows():
for d in dates:
prob.addConstrain(pl.lpSum([ employee_var*vars_by_shift[s][hours] if vars_by_shift[s]==d else 0 for s in shifts]) < 10)
如果我理解你的实现,你有一组二元决策变量:
pl[e, s]
employees
中的每个 e
和 shifts
中的每个 s
有一个变量
我还假设有(或者您可以轻松创建)一个列表 days
,其中包含轮班所涵盖的天数列表,并且您可以轻松编写一个函数 return s 特定日期轮班的小时数。
然后您想要添加约束:
for e in employees:
for d in days:
lpSum([pl[e, s]*n_hours_of_shift_in_day(s, d) for s in shifts]) <= 10.0
函数 n_hours_of_shift_in_day(s, d)
是 return 天 d
轮班小时数 s
的函数,例如,如果您的班次是:
"76749": {
"start_date": "2019-08-14",
"start_time": "18:00",
"end_date": "2019-08-15",
"end_time": "19:00",
"duration": 25,
"number_positions": 1
}
那么n_hours_of_shift_in_day("76749", "2019-08-14")
会return5.0
,n_hours_of_shift_in_day("76749", "2019-08-15")
会return19.0
.
此外,您的班次示例似乎使用了 12 小时时钟格式,没有指示上午或下午,这可能会给您带来一些问题。
我正在尝试配置我的 PuLP 问题以确保员工每天的工作时间不超过 10 小时。
我设置的员工变量是:
cost = []
vars_by_shift = defaultdict(list)
for employee, info in employees.iterrows():
for shift in info['availability']:
employee_var = pl.LpVariable("%s_%s" % (employee, shift), 0, 1, pl.LpInteger)
vars_by_shift[shift].append(employee_var)
cost.append(employee_var * info['base_rate'])
我的objective是为了最小化成本:
prob = pl.LpProblem("scheduling", pl.LpMinimize)
prob += sum(cost)
我的班次数据示例是:
"76749": {
"start_date": "2019-08-14",
"start_time": "08:00",
"end_date": "2019-08-14",
"end_time": "12:00",
"duration": 4,
"number_positions": 1
},
"76750": {
"start_date": "2019-08-14",
"start_time": "13:00",
"end_date": "2019-08-14",
"end_time": "20:00",
"duration": 7,
"number_positions": 1
}
一名员工有时可以在同一天分配两个短班。我想确保员工在任何一天的排班总时数不超过 10 小时。如何为该约束建模?
好吧,您需要一个时间分组变量,是否将 start_date 视为您不想分配超过 10 小时的那一天?
如果答案是肯定的
那么你需要这样的……
emp in employees.iterrows():
for d in dates:
prob.addConstrain(pl.lpSum([ employee_var*vars_by_shift[s][hours] if vars_by_shift[s]==d else 0 for s in shifts]) < 10)
如果我理解你的实现,你有一组二元决策变量:
pl[e, s]
employees
中的每个 e
和 shifts
s
有一个变量
我还假设有(或者您可以轻松创建)一个列表 days
,其中包含轮班所涵盖的天数列表,并且您可以轻松编写一个函数 return s 特定日期轮班的小时数。
然后您想要添加约束:
for e in employees:
for d in days:
lpSum([pl[e, s]*n_hours_of_shift_in_day(s, d) for s in shifts]) <= 10.0
函数 n_hours_of_shift_in_day(s, d)
是 return 天 d
轮班小时数 s
的函数,例如,如果您的班次是:
"76749": {
"start_date": "2019-08-14",
"start_time": "18:00",
"end_date": "2019-08-15",
"end_time": "19:00",
"duration": 25,
"number_positions": 1
}
那么n_hours_of_shift_in_day("76749", "2019-08-14")
会return5.0
,n_hours_of_shift_in_day("76749", "2019-08-15")
会return19.0
.
此外,您的班次示例似乎使用了 12 小时时钟格式,没有指示上午或下午,这可能会给您带来一些问题。