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

基于Python Pulp的组间元素频次约束优化问题

修正多约束组得分最大化问题的目标函数与模型构建

核心问题分析

原代码的问题集中在变量定义偏差和目标函数逻辑错误:

  • 变量命名冲突(person变量误用"group"前缀),且无法体现“人员-组”的关联关系,忽略了同一人员在不同组的得分差异
  • 约束条件表述错误(比如lpSum(group) ==2不符合“每组2人”的实际要求)
  • 目标函数仅简单累加人员的单一得分,未结合人员所在组的实际得分,完全偏离需求

修正后的完整模型

步骤1:重新定义决策变量

创建二元变量x[(g, p)],表示人员p是否被分配到组g,精准对应每个人员在不同组的得分差异。

步骤2:明确约束条件

  • 每个人员最多被分配到1个组(只能被选中1次):对每个人员p,所有包含p的组g对应的x[(g,p)]之和 ≤1
  • 每个被使用的组必须恰好包含2名人员:对每个组g,所有属于g的人员p对应的x[(g,p)]之和只能是0或2(要么不选该组,要么选满2人)
  • 可选:若需固定选择组的数量,可额外添加对应约束(比如强制选2个组)

步骤3:正确构建目标函数

总得分是所有被选中的(g,p)组合对应的得分之和,即对每个(g,p),若x[(g,p)]=1,则累加该组合的score值。

完整代码实现

import pandas as pd
import pulp

# 示例数据
data = pd.DataFrame({
    'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C'],
    'person': [1, 2, 3, 4, 1, 2, 5, 6, 1, 4, 7],
    'score': [3, 1, 0.5, 1, 0.7, 0.8, 1.5, 2, 1.5, 2, 1.1]
})

# 创建最大化问题
prob = pulp.LpProblem("group_scores", sense=pulp.LpMaximize)

# 定义决策变量:x[(g,p)] = 1表示人员p被分配到组g
valid_pairs = list(zip(data['group'], data['person']))
x = pulp.LpVariable.dicts("assignment", valid_pairs, cat=pulp.LpBinary)

# 约束1:每个人员最多被分配到1个组
for p in data['person'].unique():
    relevant_pairs = [pair for pair in valid_pairs if pair[1] == p]
    prob += pulp.lpSum([x[pair] for pair in relevant_pairs]) <= 1, f"person_limit_{p}"

# 约束2:每个组要么不选,要么恰好选2人
for g in data['group'].unique():
    group_pairs = [pair for pair in valid_pairs if pair[0] == g]
    prob += pulp.lpSum([x[pair] for pair in group_pairs]).isin([0, 2]), f"group_size_{g}"

# 可选约束:如果需要固定选择的组数量(比如选2个组)
# selected_groups = pulp.LpVariable.dicts("selected_group", data['group'].unique(), cat=pulp.LpBinary)
# for g in data['group'].unique():
#     group_pairs = [pair for pair in valid_pairs if pair[0] == g]
#     prob += pulp.lpSum([x[pair] for pair in group_pairs]) == 2 * selected_groups[g]
# prob += pulp.lpSum(selected_groups.values()) == 2

# 目标函数:最大化所有选中组合的得分之和
prob += pulp.lpSum([x[pair] * data[(data['group'] == pair[0]) & (data['person'] == pair[1])]['score'].values[0] 
                    for pair in valid_pairs]), "total_score"

# 求解问题
prob.solve()

# 整理结果
results = []
for pair in valid_pairs:
    if x[pair].varValue == 1:
        results.append({
            'group': pair[0],
            'person': pair[1],
            'score': data[(data['group'] == pair[0]) & (data['person'] == pair[1])]['score'].values[0]
        })
results_df = pd.DataFrame(results)
print("选中的人员-组分配:")
print(results_df)
print(f"总得分:{pulp.value(prob.objective)}")

关键说明

  • 决策变量x[(g,p)]精准捕捉了人员与组的关联,解决了同一人员在不同组得分不同的问题
  • 约束条件严格贴合需求:人员唯一分配、组人数合规
  • 目标函数直接累加所有有效分配的得分,完全匹配“最大化总组得分”的需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 18:27:48