我有一个 LP/IP 问题,我正在尝试使用 PuLP 来解决。这是员工之间的工作分工。我不明白的是如何限制引擎只计划 1 名员工执行一项操作。事实上,这个问题有更多的限制,但我试图尽可能地减少问题。
假设我有特定的工作量:
import pandas as pd
data = {
"actions": [
"ActionA",
"ActionB",
"ActionC",
"ActionD",
],
"value": [5, 2, 1, 1],
"available_work": [8, 4, 12, 24],
}
work = pd.DataFrame(data=data).set_index("actions")
行动 | 价值 | 可用工作 |
---|---|---|
行动A | 5 | 8 |
行动B | 2 | 4 |
行动C | 1 | 12 |
行动D | 1 | 24 |
还有能够工作的人员名单:
data = {
"ID": [
"01",
"02",
"03",
"04",
"05",
],
"time": [7, 7, 6, 5, 5],
}
employees = pd.DataFrame(data=data).set_index("ID")
身份证 | 时间 |
---|---|
01 | 7 |
02 | 7 |
03 | 6 |
04 | 5 |
05 | 5 |
我想利用 5 名员工的时间实现价值最大化:
prob = pulp.LpProblem('PlanningActions', pulp.LpMaximize)
我创建了一个名为 vars 的字典来包含引用的变量:
vars = pulp.LpVariable.dicts(
"division",
(work.index, employees.index),
lowBound=0
cat=pulp.LpInteger,
)
我不想为一个人计划比可用工作更多的工作:
for details in work.itertuples():
prob += (
pulp.lpSum([vars[details.Index][m] for m in employees.index])
<= details.available_work,
f"Not more than available work {details.Index}",
)
而且我也不想为员工计划比可用时间更多的工作:
for m in employees.index:
prob += (
pulp.lpSum([vars[w][m] for w in work.index])
<= int(employees.loc[m, "time"]),
f"Not more than available time employee {m}",
)
这个功能正常。但是,我无法弄清楚仅计划 1 名员工执行一项操作的限制。我想它会看起来像这样
for action in work.index:
if action == 'ActionA':
prob += (
pulp.lpSum([vars[action][m]>0)
<= 1,
f"Not more than one employee for {action}",
)
但是我似乎无法将变量(vars)与整数进行比较,因为我收到以下错误:
TypeError: '>' not supported between instances of 'LpVariable' and 'int'
您的变量 vars[w][e] 已经代表了工作者 e 到操作 w 的二进制分配(遵循您的代码符号)。如果您要求某个操作上所有变量的总和小于或等于 1,那么您保证每个操作完成 0 或 1 次分配。
for action in work.index:
prob += (
pulp.lpSum([vars[action][emp] for emp in employees.index]) <= 1,
f"Not more than one employee for {action}",
)
或者对于严格赋值,请使用 == 运算符。
for action in work.index:
prob += (
pulp.lpSum([vars[action][emp] for emp in employees.index]) == 1,
f"Stictly one employee for {action}",
)
您的实施的问题是,在纸浆中只有“==”、“">=”、“<=" are allowed and not strict inequalities ">”、“<". 纸浆意义文档。