问题描述
我正在尝试用 R 中的 CVXR 解决混合整数问题。以下代码用于解决它:
n <- 6
beta <- Variable(n,n,integer = TRUE)
epsilon <- 0.1*10^-5
objective <- Minimize(1)
constraints <- list(beta >= 1,beta <= 9,abs(diff(beta)) >= epsilon,abs(diff(t(beta))) >= epsilon)
prob <- Problem(objective,constraints)
CVXR_result <- solve(prob)
这会产生以下错误:
Error in construct_intermediate_chain(object,candidate_solvers,gp = gp) :
Problem does not follow DCP rules.
n <- 6
beta <- Variable(n,abs(diff(beta)) <= epsilon,abs(diff(t(beta))) <= epsilon)
prob <- Problem(objective,constraints)
CVXR_result <- solve(prob)
CVXR_result$status
CVXR_result$value
cvxrBeta <- CVXR_result$getValue(beta)
cvxrBeta
它有效,但这些不是我想要的约束。
有人知道如何解决这个问题吗?
解决方法
我们可以通过引入一个布尔矩阵 y
来凸化问题,如果 y[i,j]
上的第 i,j 个不等式大于,则 diff(beta)
为 1,否则为 0。类似地,如果 yy[i,j 个不等式大于,则
diff(t(beta))
为 1,否则为 0。因此我们添加了 2*(n-1)*n 个布尔变量。还要将 M
设置为 9,并且为了避免数值困难,将 epsilon
设置为 0.1。有关详细信息,请参阅:https://math.stackexchange.com/questions/37075/how-can-not-equals-be-expressed-as-an-inequality-for-a-linear-programming-model/1517850
library(CVXR)
n <- 6
epsilon <- 0.1
M <- 9
beta <- Variable(n,n,integer = TRUE)
y <- Variable(n-1,boolean = TRUE)
yy <- Variable(n-1,boolean = TRUE)
objective <- Minimize(1)
constraints <- list(beta >= 1,beta <= M,diff(beta) <= -epsilon + 2*M*y,diff(beta) >= epsilon - (1-y)*2*M,diff(t(beta)) <= -epsilon + 2*M*yy,diff(t(beta)) >= epsilon - (1-yy)*2*M)
prob <- Problem(objective,constraints)
CVXR_result <- solve(prob)
CVXR_result$status
## [1] "optimal"
CVXR_result$getValue(beta)
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1 9 1 9 8 7
## [2,] 9 8 7 6 9 4
## [3,] 3 2 1 9 8 2
## [4,] 7 6 2 1 7 6
## [5,] 3 5 3 2 8 5
## [6,] 5 1 4 3 6 9