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

如何为PULP运输问题添加强制选择特定供应商的约束

用PULP强制选择特定供应商解决运输问题

我用PULP求解运输问题,现有供应商列表(supply)和客户列表(demand),供给始终大于需求,部分场景下PULP不会选中所有供应商。但有时需要强制选择特定供应商,无论其是否为最优选项。我知道要添加约束,但不知道怎么修改脚本。

原脚本

prob = LpProblem("transportationproblem", LpMaximize)

routes = [(s,c) for s in suppliers for c in customers]

vars = LpVariable.dicts("Route", (suppliers, customers), 0, None, LpInteger)

prob += (
    lpSum([vars[s][c] * costs[s][c] for (s, c) in routes]),
    "sum_of_transp_cost"
)

for s in suppliers:
    prob += (
        lpSum([vars[s][c] for c in customers]) <= supply[s],
        f"sum_of_products_from_suppliers_{s}",
    )

for c in customers:
    prob += (
        lpSum([vars[s][c] for s in suppliers]) == demand[c],
        f"sum_of_products_to_customers{c}"
    )

错误的约束尝试

我尝试添加以下约束,但求解器无法正常工作:

for s in suppliers:
    if s == "specific supplier": 
        prob += (
            lpSum([vars[s][c] for c in customers]) == supply[s],
            f"sum_of_products_from_suppliers_{s}",
    )

问题原因

  1. 重复约束名冲突:原脚本已经给所有供应商添加了名为sum_of_products_from_suppliers_{s}的约束,再次添加同名约束会导致逻辑冲突。
  2. 约束逻辑不合理:强制特定供应商发完全部供给(== supply[s]),但总供给大于总需求,会导致总发货量超过需求上限,求解器找不到可行解。

正确的修改方案

要强制特定供应商参与运输,只需要求其至少发运一定数量的货物(比如1单位,可根据实际需求调整),同时保留“不超过自身供给”的约束。修改原脚本中的供应商约束部分:

for s in suppliers:
    # 所有供应商的发货量都不能超过自身供给
    prob += (
        lpSum([vars[s][c] for c in customers]) <= supply[s],
        f"max_supply_from_{s}",
    )
    # 强制特定供应商必须发货(至少1单位)
    if s == "specific supplier":
        prob += (
            lpSum([vars[s][c] for c in customers]) >= 1,
            f"min_supply_from_{s}",
        )

说明

  • 给约束设置不同的名称(max_supply_from_xxx和min_supply_from_xxx)避免冲突。
  • 用>= 1保证特定供应商必须参与运输,同时<= supply[s]限制其发货量不超过自身供给,符合总供给大于需求的场景,不会出现无解情况。
  • 如果需要特定供应商发运固定数量,可将>=1改为具体数值(比如>= 50),只要该数值不超过其供给量,且加上其他供应商的可发货量能满足总需求即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:37:12