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

Python/Gurobi优化约束构建求助:灵活适配人员选取规则

Gurobi约束优化与代码简化方案

一、约束逻辑梳理

你需要的约束规则可以拆解为三种适配场景:

  • 若指定地点有足够的对应角色员工,直接从该地点的对应角色员工中选够需求数量
  • 若指定地点对应角色员工不足,但全公司同角色员工数量满足需求,从全公司同角色员工中选够数量
  • 若全公司无该角色员工,从所有员工中选够需求数量(若员工总数仍不足,则取现有所有员工)

二、代码实现步骤

1. 预处理员工属性(简化后续统计)

利用你已有的employeeLondon、employeeAR等字典,先把员工按「地点+角色」「角色」分组,方便后续快速统计可用人数:

from collections import defaultdict

# 从现有字典推导员工的地点
def get_empl_loc(e):
    if employeeLondon.get(e, 0) == 1:
        return "London"
    elif employeeBerlin.get(e, 0) == 1:
        return "Berlin"
    # 有其他地点的话继续补充elif分支
    else:
        return "Other"

# 从现有字典推导员工的角色
def get_empl_role(e):
    if employeeAR.get(e, 0) == 1:
        return "AR"
    elif employeeUL.get(e, 0) == 1:
        return "UL"
    # 有其他角色的话继续补充elif分支
    else:
        return "Other"

# 构建分组字典
loc_role_empls = defaultdict(list)  # 键为(地点,角色),值为对应员工列表
role_empls = defaultdict(list)      # 键为角色,值为全公司该角色的员工列表

for e in lstempls:
    loc = get_empl_loc(e)
    role = get_empl_role(e)
    loc_role_empls[(loc, role)].append(e)
    role_empls[role].append(e)

2. 定义需求清单(避免重复编写约束)

把所有人员需求整理成一个列表,后续只需维护这个列表即可,不用重复写m.addConstr代码:

staff_requirements = [
    ("London", "AR", 1, "c London AR"),
    ("London", "UL", 1, "c London UL"),
    ("Berlin", "UL", 2, "c Berlin UL"),
    # 新增需求直接在这里加一行即可
]

3. 自动生成适配性约束

遍历需求清单,根据实际员工数量动态生成对应约束:

for loc, role, req_num, constr_name in staff_requirements:
    # 获取对应分组的员工列表
    loc_role_list = loc_role_empls.get((loc, role), [])
    global_role_list = role_empls.get(role, [])
    
    # 统计可用员工数
    count_loc_role = len(loc_role_list)
    count_global_role = len(global_role_list)
    
    if count_loc_role >= req_num:
        # 场景1:指定地点员工足够,直接约束从该组选够数量
        m.addConstr(
            sum(empls[e] for e in loc_role_list) == req_num,
            name=constr_name
        )
    elif count_global_role >= req_num:
        # 场景2:指定地点不足,从全公司同角色员工中选够数量
        m.addConstr(
            sum(empls[e] for e in global_role_list) == req_num,
            name=constr_name
        )
    else:
        # 场景3:全公司同角色员工不足,从所有员工中选(若总人数仍不够,取现有全部)
        m.addConstr(
            sum(empls[e] for e in lstempls) >= min(req_num, len(lstempls)),
            name=constr_name
        )

4. 修正目标函数(原函数无实际意义)

你原来的sum([1])是固定值,对Gurobi优化没有实际作用。如果仅需满足约束即可,可设置为:

m.setObjective(0, GRB.MAXIMIZE)

若想在满足约束的前提下最大化选中员工数量,可改为:

m.setObjective(sum(empls.values()), GRB.MAXIMIZE)

三、方案优势

  • 需求集中管理,新增需求只需修改清单,无需重复编写约束代码
  • 提前分组员工,统计效率更高,避免每次遍历全部员工计算乘积
  • 动态适配员工数量,自动调整约束逻辑,避免因实际员工不足导致模型不可行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 23:44:54