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

Gurobi gurobipy实现嵌套求和乘积约束报QuadExpr不可迭代错误

报错原因
  • 类型错误直接原因:grb.quicksum() 只接受可迭代的变量/表达式序列作为输入,你的代码中外层grb.quicksum直接传入了两个quicksum相乘得到的单个QuadExpr二次对象,不是可迭代结构,因此触发报错。
  • 求和逻辑错误:原公式是遍历每个a∈A,单独计算i、j在该a下b维度的x求和项,两者相乘后再对所有a求和,你写的迭代逻辑把b也放到了跨a的求和层,维度和公式完全不匹配。
  • 模型阶数错误:原约束中0-1变量y_{i,j}与两个x求和项的乘积(二次项)继续相乘,会生成三次项,Gurobi原生不支持三次及以上的非线性规划,必须通过辅助变量加大M法线性化三次乘积部分才能求解。
修复方案
  1. 修正求和逻辑:遍历每个a单独计算b维度的x求和,相乘后累加得到括号内的二次表达式,避免错误嵌套quicksum。
  2. 引入辅助变量aux[i,j]表示y[i,j]和括号内二次表达式的乘积,用大M法对三次乘积做线性化。大M取括号内表达式的理论上界:x是0-1变量,单个b维度求和最大值为len(set_B),两个求和相乘最大值为len(set_B)**2,对a求和后最大值为len(set_A)*len(set_B)**2,加1后得到M = len(set_A)*len(set_B)**2 + 1。
  3. 线性化约束规则:
  • 当y[i,j] = 0时,强制aux[i,j] = 0
  • 当y[i,j] = 1时,强制aux[i,j] = 括号内的表达式值
修复后可运行代码
import gurobipy as grb

m = grb.Model()

set_I = range(2)
set_J = range(2)
set_A = range(2)
set_B = range(2)

# 计算大M上界
M = len(set_A) * (len(set_B) ** 2) + 1

x_vars = {(i,a,b):m.addVar(vtype=grb.GRB.BINARY, name=f"x_{i}_{a}_{b}") for i in set_I for a in set_A for b in set_B}
y_vars = {(i,j): m.addVar(vtype=grb.GRB.BINARY, name=f"y_{i}_{j}") for i in set_I for j in set_J}
c_vars = {(i,j): m.addVar(vtype=grb.GRB.CONTINUOUS, name=f"c_{i}_{j}") for i in set_I for j in set_J}
# 三次乘积的线性化辅助变量
aux_vars = {(i,j): m.addVar(vtype=grb.GRB.CONTINUOUS, name=f"aux_{i}_{j}") for i in set_I for j in set_J}

for i in set_I:
    for j in set_J:
        # 按公式正确计算括号内的二次表达式
        sum_a = 0
        for a in set_A:
            sum_b_i = grb.quicksum(x_vars[i,a,b] for b in set_B)
            sum_b_j = grb.quicksum(x_vars[j,a,b] for b in set_B)
            sum_a += sum_b_i * sum_b_j
        inner_expr = sum_a + 1

        # 大M法线性化乘积项 y * inner_expr = aux
        m.addConstr(aux_vars[i,j] >= 0)
        m.addConstr(aux_vars[i,j] <= M * y_vars[i,j])
        m.addConstr(aux_vars[i,j] <= inner_expr)
        m.addConstr(aux_vars[i,j] >= inner_expr - M * (1 - y_vars[i,j]))

        # 原约束:如果需要严格匹配公式的等号,把sense改为grb.GRB.EQUAL即可
        m.addConstr(
            lhs=aux_vars[i,j],
            sense=grb.GRB.GREATER_EQUAL,
            rhs=c_vars[i,j]
        )

# 测试求解
m.optimize()

修复后的模型最高阶数为2,属于Gurobi支持的混合整数二次约束规划(MIQCP)类型,运行不会触发类型错误,求和逻辑完全匹配给出的公式,线性化处理后可以被Gurobi正常求解。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:09:18