在 cvxpy 中指定复杂的约束会产生严格的不等式错误
Specifying complex constraints in cvxpy yields strict inequalities error
我正在尝试使用我在 Excel - 中概述的 cvxpy 重新创建整数线性优化问题。请注意,这是一个虚拟示例,实际数据集将包含数千个变量。请忽略电子表格单元格 K5 中的解决方案,因为 Excel 规划求解无法提供整数解决方案。
考虑将 9 个变量分成 3 个桶。请注意,我对约束 1-3 的目标是,对于一桶变量,3 个 1 中至少有 2 个,或者所有值都是 0。例如,a、b、c 应该是 1、1、1或 1, 1, 0 或 1,0,1 或 0, 1, 1 或 0, 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, 1, 3])
dec_vars = cp.Variable(len(coefs), boolean = True)
constr1 = np.array([1,1,1,0,0,0,0,0,0]) @ dec_vars == 2 * max(dec_vars[0:3])
constr2 = np.array([0,0,0,1,1,1,0,0,0]) @ dec_vars == 2 * max(dec_vars[3:6])
constr3 = np.array([0,0,0,0,0,0,1,1,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 对象上只使用任何 python-native 函数。 max(cvx_vars)
不支持 abs(cvx_vars)
等等。
cvxpy 中有 max-function,即:cp.max(...)
,但我不明白你想要做什么,也不知道你将如何通过最大利用见下文...
Note my goal with constraints 1-3 is that either there are at least 2 out of 3 1's for a bucket of variables, or all of the values are 0. For example, a,b,c should be either 1,1,1 or 1, 1, 0 or 1,0,1 or 0, 1, 1, or 0, 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
我正在尝试使用我在 Excel -
考虑将 9 个变量分成 3 个桶。请注意,我对约束 1-3 的目标是,对于一桶变量,3 个 1 中至少有 2 个,或者所有值都是 0。例如,a、b、c 应该是 1、1、1或 1, 1, 0 或 1,0,1 或 0, 1, 1 或 0, 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, 1, 3])
dec_vars = cp.Variable(len(coefs), boolean = True)
constr1 = np.array([1,1,1,0,0,0,0,0,0]) @ dec_vars == 2 * max(dec_vars[0:3])
constr2 = np.array([0,0,0,1,1,1,0,0,0]) @ dec_vars == 2 * max(dec_vars[3:6])
constr3 = np.array([0,0,0,0,0,0,1,1,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 对象上只使用任何 python-native 函数。 max(cvx_vars)
不支持 abs(cvx_vars)
等等。
cvxpy 中有 max-function,即:cp.max(...)
,但我不明白你想要做什么,也不知道你将如何通过最大利用见下文...
Note my goal with constraints 1-3 is that either there are at least 2 out of 3 1's for a bucket of variables, or all of the values are 0. For example, a,b,c should be either 1,1,1 or 1, 1, 0 or 1,0,1 or 0, 1, 1, or 0, 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