You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pulp定义导师-顾问多分配问题的约束条件?

导师-顾问匹配的线性规划约束修正方案

问题背景

我正在解决一个分配问题:导师可根据与顾问的共同语言数量分配给多个顾问(共同语言越多越优)。约束条件如下:

  • 每位导师有固定督导可用工时:14、11、7或0小时
  • 每位顾问有固定所需督导工时:6、3、2、1或0小时
  • 导师可根据可用工时分配多个顾问(导师工时无需用尽,但顾问工时必须全覆盖)
  • 被选中的导师资历需≥对应顾问的资历

现有代码问题

我已编写部分Pulp代码,但在定义工时约束和资历约束时遇到困难,以下是我的代码:

supervisor_h = ... # 每位导师的可用工时列表
consultant_h = ... # 每位顾问的所需工时列表
y = pulp.LpVariable.dicts("pairs", [(i,j) for i in supervisors  for j in consultants], cat='Binary')
prob = pulp.LpProblem("matching", pulp.LpMaximize)

prob += pulp.lpSum([costs[i][m] * y[(i,j)] for i in supervisors for m, j in enumerate(consultants)])

# 每位导师至少分配1位顾问
for i in supervisors:
  prob += pulp.lpSum(y[(i,j)] for j in consultants) >= 1

# 每位顾问最多分配1位导师
for j in consultants:
  prob += pulp.lpSum(y[(i,j)] for i in supervisors) <= 1

# 工时约束:此处定义有问题
for n, i in enumerate(supervisors):
  prob += supervisor_h[n] - pulp.lpSum(qcee_h[m] for m, j in enumerate(consultants))  <= consultant_h[n]

# 资历约束:同样无法正确定义

约束条件修正方案

1. 工时约束修正

当前工时约束逻辑完全错误,正确的约束应该是单个导师分配给所有顾问的总工时,不能超过该导师的可用工时。需要通过二进制变量y[(i,j)]关联导师与顾问,仅当y[(i,j)]=1时,才将顾问j的所需工时计入导师i的消耗。

修正后的代码:

# 遍历每个导师,约束其分配的总工时不超过可用工时
for i in supervisors:
    prob += pulp.lpSum(consultant_h[j] * y[(i,j)] for j in consultants) <= supervisor_h[i]

另外,若要求所有顾问必须被分配(覆盖全部工时需求),需将顾问的分配约束从<=1改为==1:

# 每位顾问必须被分配且仅分配一位导师
for j in consultants:
    prob += pulp.lpSum(y[(i,j)] for i in supervisors) == 1

2. 资历约束修正

首先需要将导师和顾问的资历转化为可比较的数值(比如数字越大资历越高),假设你有supervisor_seniority[i](导师i的资历值)和consultant_seniority[j](顾问j的资历值)两个数据结构。

约束逻辑为:若导师i分配给顾问j(即y[(i,j)]=1),则导师i的资历必须≥顾问j的资历,线性规划中可通过以下方式实现:

# 遍历所有导师-顾问对,添加资历约束
for i in supervisors:
    for j in consultants:
        # 当y[(i,j)]=1时,强制满足资历要求;y=0时约束自动成立
        prob += supervisor_seniority[i] >= consultant_seniority[j] * y[(i,j)]

如果资历是字符串类型(如"初级"/"中级"/"高级"),需先映射为数值:

seniority_map = {"初级": 1, "中级": 2, "高级": 3}
# 假设supervisors_seniority_list是导师资历字符串列表,consultants同理
supervisor_seniority = {i: seniority_map[val] for i, val in enumerate(supervisors_seniority_list)}
consultant_seniority = {j: seniority_map[val] for j, val in enumerate(consultants_seniority_list)}

目标函数修正

原目标函数的索引对应有误,需确保costs[i][j]直接对应导师i与顾问j的共同语言数量:

# 最大化所有匹配对的共同语言总数
prob += pulp.lpSum([costs[i][j] * y[(i,j)] for i in supervisors for j in consultants])

内容的提问来源于stack exchange,提问作者Andrea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:00:54