CVXPY二维数组三维索引约束报错:Atoms must be at most 2D 如何修复?
解决CVXPY中"Atoms must be at most 2D"的错误:约束中的3D变量问题
这个报错的根源很明确:你用np.meshgrid生成了三维索引数组u, v, w,当用这些索引去访问你的2D变量arr时,得到的是一个3D的表达式集合——而CVXPY的核心原子(表达式)最多只支持2D维度,所以直接抛出了这个错误。
解决思路
我们需要把这个针对所有(u, v, w)三元组的约束,转化为CVXPY能处理的1D/2D约束集合,有两种常用的实现方式:
方式1:直观的三重循环(适合小规模V)
直接遍历所有可能的u、v、w组合,逐个添加标量约束,完全避开维度问题:
import numpy as np import cvxpy as cp def ILP_example(scores): V = scores.shape[0] # 注意:如果是整数线性规划,记得加上boolean=True(根据你的实际需求调整) arr = cp.Variable(scores.shape, boolean=True) objective = cp.Maximize(cp.sum(cp.multiply(scores, arr))) constraints = [] # 遍历所有三元组(u, v, w) for u in range(V): for v in range(V): for w in range(V): constraints.append(arr[u, v] + arr[v, w] - arr[u, w] <= 1) prob = cp.Problem(objective, constraints) prob.solve() return arr.value
方式2:向量化扁平化(适合大规模V,效率更高)
利用numpy广播生成所有三元组的约束表达式,再通过flatten()把3D的约束数组转成1D列表,让CVXPY可以正常处理:
import numpy as np import cvxpy as cp def ILP_example(scores): V = scores.shape[0] arr = cp.Variable(scores.shape, boolean=True) objective = cp.Maximize(cp.sum(cp.multiply(scores, arr))) # 用广播生成所有u、v、w的索引矩阵 u = np.arange(V)[:, None, None] v = np.arange(V)[None, :, None] w = np.arange(V)[None, None, :] # 生成3D约束表达式,再扁平化为1D约束列表 constraint_expr = arr[u, v] + arr[v, w] - arr[u, w] <= 1 constraints = constraint_expr.flatten() prob = cp.Problem(objective, constraints) prob.solve() return arr.value
额外注意
如果你的问题不是整数线性规划(比如是普通线性规划),记得去掉Variable的boolean=True参数,让变量默认使用连续值。
现在运行ILP_example(np.random.rand(5, 5))就不会再触发维度错误了。
内容的提问来源于stack exchange,提问作者Sandeep Dcunha
相关产品推荐
相关产品推荐

