微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 cvxpy 中指定复杂约束会产生严格的不等式错误 方法 A方法 B

如何解决在 cvxpy 中指定复杂约束会产生严格的不等式错误 方法 A方法 B

我正在尝试使用我在 Excel 中概述的 cvxpy 重新创建整数线性优化问题 -

Excel screenshot

。请注意,这是一个虚拟示例,实际数据集将有数千个变量。请忽略电子表格单元格 K5 中的解决方案,因为 Excel Solver 无法提供整数解决方案。

考虑将 9 个变量分成 3 个桶。请注意,我对约束 1-3 的目标是,对于一桶变量,3 个 1 中至少有 2 个,或者所有值都是 0。例如,a,b,c 应该是 1,1,1或 1,0 或 1,1 或 0,0。

import numpy as np
import cvxpy as cp
import cvxopt 

coefs= np.array([0.7,0.95,0.3,2,1.05,2.2,4,3])

dec_vars = cp.Variable(len(coefs),boolean = True)

constr1 = np.array([1,0]) @ dec_vars == 2 * max(dec_vars[0:3]) 
constr2 = np.array([0,0]) @ dec_vars == 2 * max(dec_vars[3:6])
constr3 = np.array([0,1]) @ dec_vars == 2 * max(dec_vars[6:9])
constr4 = np.ones(len(coefs)) @ dec_vars >= 2

当我跑到这里时,我得到一个 NotImplementedError: Strict inequalities are not allowed. 错误

解决方法

核心问题是您对 python 的 max 的使用,它试图在到达 cvxpy 之前进行评估。您不能在 cvxpy-objects 上只使用任何 python 原生函数。不支持 max(cvx_vars)abs(cvx_vars) 等等。

cvxpy 中有 max-function,即:cp.max(...),但我不明白您要做什么或如何通过利用 max 来实现这一点。见下文...

注意我的约束 1-3 的目标是,对于一桶变量,至少有 3 个 1 中的 2 个,或者所有值都是 0。例如,a、b、c 应该是 1, 1,1 或 1,1,0 或 1,1 或 0,0。

一般来说,这需要某种析取推理

方法 A

一般方法是使用二元指示变量和基于big-M的表达式:

is_zero = binary aux-var

sum(dec_vars) <= 3 * is_zero
sum(dec_vars) >= 2 * is_zero

方法 B

或者,也可以通过(不带辅助变量)来对此进行建模:

a -> b || c
b -> a || c
c -> a || b

意思是:如果有一个非零,则至少还需要一个非零。这看起来像:

(1-a) + b + c >= 1
(1-b) + a + c >= 1
(1-c) + a + b >= 1

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。