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

如何在Python版Gurobi中实现向量乘法并解决线性约束维度报错问题

问题排查与解决

错误原因

  • 变量类型混用:同时使用了addMVar()创建的矩阵型变量x和addVars()创建的元组字典型变量y/w/gamma,两类变量的运算逻辑、返回结果维度不匹配,直接混合运算会触发维度错误
  • 错误使用numpy运算处理Gurobi变量:w.select(j,'*')返回的是Gurobi变量对象列表,直接转numpy矩阵做dot运算时,numpy无法正确识别Gurobi变量的维度和运算规则,返回的结果维度不符合约束要求
  • 约束符号不规范:Gurobi线性约束仅支持非严格不等号>=/<=,使用严格大于>虽然不会直接触发报错,但不符合求解器规范
  • 约束逻辑符号错误:原数学表达式中为w_j a_i - γ_j,代码中写成了-w_j a_i + γ_j,符号完全相反,会导致约束逻辑不符合预期

修正方案

把所有变量类型统一,内积直接通过Gurobi内置的线性表达式构造,避免用numpy做变量运算,修改后的代码如下:

import numpy as np 
import gurobipy as gp
from gurobipy import GRB

A=np.array([[ 7.6 , 8 ],
            [ 3  , 2.7],
            [ 0 , 0 ],
            [ 0.8 , 0.5],
            [ 6.6,  7.4],
            [ 6.7,  7.8],
            [ 1.9 , 2.6],
            [ 3.2 , 4.6],
            [ 6.4,  6.3],
            [10 , 10]])

m = A.shape[0] # A的行数
n = A.shape[1] # A的列数
M = 100000
k=2 # 将数据点聚为k个簇
# 创建模型
model = gp.Model('hyperplane clustering')
# 统一使用addVars创建变量,避免类型混用
x = model.addVars(m, k, vtype=GRB.BINARY, name="x")
y = model.addVars(m, lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="y")
w = model.addVars(k, n, lb=0.0, ub=1.0, vtype=GRB.CONTINUOUS, name='w')
gamma = model.addVars(k, vtype=GRB.CONTINUOUS, name="gamma")

# 构造约束
for i in range(m):
    for j in range(k):
        # 直接计算w_j和a_i的内积,不用numpy运算
        w_dot_a = gp.quicksum(w[j, t] * A[i, t] for t in range(n))
        model.addConstr(y[i] >= (w_dot_a - gamma[j]) - M * (1 - x[i,j]))
# 后续可自行添加目标函数、调用solve()求解
model.update()

如果你偏好矩阵变量的写法,可以把所有变量都改成addMVar()类型,直接用矩阵乘法构造约束,运算效率更高:

# 矩阵变量版本实现
import numpy as np 
import gurobipy as gp
from gurobipy import GRB

A=np.array([[ 7.6 , 8 ],
            [ 3  , 2.7],
            [ 0 , 0 ],
            [ 0.8 , 0.5],
            [ 6.6,  7.4],
            [ 6.7,  7.8],
            [ 1.9 , 2.6],
            [ 3.2 , 4.6],
            [ 6.4,  6.3],
            [10 , 10]])

m = A.shape[0] # A的行数
n = A.shape[1] # A的列数
M = 100000
k=2 # 将数据点聚为k个簇
# 创建模型
model = gp.Model('hyperplane clustering')
# 统一使用addMVar创建矩阵变量
x = model.addMVar((m,k), vtype=GRB.BINARY,name="x")
y = model.addMVar(m, lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="y")
w = model.addMVar((k,n), lb=0.0, ub=1.0, vtype=GRB.CONTINUOUS, name='w')
gamma = model.addMVar(k, vtype=GRB.CONTINUOUS, name="gamma")

# 批量构造约束,无需循环i
for j in range(k):
    model.addConstr(y >= (A @ w[j,:] - gamma[j]) - M * (1 - x[:,j]))

model.update()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 04:15:01