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

Python Gurobi求解二元决策变量乘积型非线性约束问题

问题解答

可以在Python中调用Gurobi求解这类含二元决策变量乘积的约束,你原代码运行异常有两个核心原因:

  • 语法错误:y_kc[k[, c] 多写了多余的左方括号,会直接触发语法报错
  • 非线性约束问题:直接写两个二元变量的乘积会被Gurobi识别为二次约束,求解效率低,且容易出现误判不可行的情况,建议通过大M法线性化处理后再添加约束

约束逻辑说明

你需要实现的逻辑为:当门店i归属总部k(x_ik[i,k] = 1)、且总部k位于城市街区c(y_kc[k,c] =1)时,门店i到街区c的距离d_ic.at[i,c]必须小于等于300。

正确实现方式

方式1:直接使用二次约束(不推荐)

仅修正语法错误即可运行,但求解效率远低于线性化写法:

for k in K:
    for c in C:
        for i in I:
            modelo.addConstr(x_ik[i, k] * y_kc[k, c] * d_ic.at[i, c] <= 300, name=f"c7_{i}_{k}_{c}")

方式2:大M法线性化实现(推荐)

无需引入额外辅助变量,求解效率更高,其中M取所有d_ic的最大值加1即可:

# 计算大M取值
M = d_ic.max().max() + 1

for k in K:
    for c in C:
        for i in I:
            modelo.addConstr(
                d_ic.at[i, c] <= 300 + M * (1 - x_ik[i, k]) + M * (1 - y_kc[k, c]),
                name=f"c7_{i}_{k}_{c}"
            )

优化写法(适用已约束每个总部仅选址一个街区的场景)

如果你已经为y_kc添加了sum(y_kc[k,c] for c in C) == 1的约束(每个总部仅位于一个街区),可以简化为二重循环,进一步提升性能:

M = d_ic.max().max() + 1

for i in I:
    for k in K:
        modelo.addConstr(
            sum(d_ic.at[i, c] * y_kc[k, c] for c in C) <= 300 + (1 - x_ik[i, k]) * M,
            name=f"c7_{i}_{k}"
        )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 04:54:08