如何在CVXPY中设置(x==0)或(1≤x≤2)约束以最大化目标函数
在CVXPY中实现“每个x分量满足x_i==0 或 1≤x_i≤2”的约束最大化
现有目标函数$y=f(x)$,需在约束条件**每个x的分量$x_i$满足$(x_i==0)$ 或 $(1≤x_i≤2)$**下最大化$y$。以下是无x=0约束时,使用CVXPY实现$x∈[1,2]$下最大化$y$的Python代码及输出:
import cvxpy as cp import numpy as np # 原代码遗漏该导入,补充完整 x = cp.Variable((2,1)) alpha = np.array([-1,1]).reshape(1,-1) y = alpha @ x constraint = [x <= 2, x >= 1] obj = cp.Maximize(y) prob = cp.Problem(obj, constraint) prob.solve() print("optimal", prob.value) print("solution", x.value.ravel())
输出:
optimal 1.0 solution [1.0 2.0]
需求与疑问
能否修改约束,让可行域变为每个$x_i$要么等于0,要么落在[1,2]区间内?用户给出的伪代码示例如下:
constraint = [x <= 2, x >= 1] or [x == 0]
预期输出:
optimal 2.0 solution [0.0 2.0]
解决方案
CVXPY不支持直接用or组合约束,需通过二进制指示变量建模这种“二选一”的逻辑约束。具体实现代码如下:
import cvxpy as cp import numpy as np x = cp.Variable((2, 1)) # 二进制变量,每个z[i]对应x[i]的选择:0表示x[i]=0,1表示x[i]∈[1,2] z = cp.Variable(2, boolean=True) alpha = np.array([-1, 1]).reshape(1, -1) y = alpha @ x # 构建约束:每个x[i]要么为0,要么在[1,2]内 constraints = [] for i in range(2): # z[i]=1时,x[i]≥1;z[i]=0时,x[i]≥0(结合下方x[i]≤0,即x[i]=0) constraints.append(x[i] >= z[i]) # z[i]=1时,x[i]≤2;z[i]=0时,x[i]≤0 constraints.append(x[i] <= 2 * z[i]) # 确保x[i]非负,配合z[i]=0时的约束得到x[i]=0 constraints.append(x[i] >= 0) obj = cp.Maximize(y) prob = cp.Problem(obj, constraints) prob.solve() print("optimal", prob.value) print("solution", x.value.ravel())
代码说明
- 引入二进制变量
z,每个z[i]控制对应x[i]的可行域:- 当
z[i]=0时,x[i]≥0且x[i]≤0,强制x[i]==0; - 当
z[i]=1时,x[i]被约束在[1,2]区间内。
- 当
- 该建模方式符合CVXPY对凸约束的要求,能正确求解出预期结果。
运行上述代码后,输出与预期一致:
optimal 2.0 solution [0.0 2.0]
内容的提问来源于stack exchange,提问作者user3398100
相关产品推荐
相关产品推荐

