Reputation: 23
I am trying to solve an mixed integer problem with CVXR in R. Following code is used to solve it:
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)
This gives the following error:
Error in construct_intermediate_chain(object, candidate_solvers, gp = gp) :
Problem does not follow DCP rules.
When I change the code into following code:
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)
CVXR_result$status
CVXR_result$value
cvxrBeta <- CVXR_result$getValue(beta)
cvxrBeta
It works, but these are not the constraints that I want.
Does anyone know how to solve this?
Upvotes: 1
Views: 713
Reputation: 269556
We can convexivy the problem by introducing a boolean matrix y
such that y[i,j]
is 1 if the i,jth inequality on diff(beta)
is greater-than and 0 otherwise. Similarly yy[i,j]
is 1 if the i,jth inequality on diff(t(beta))
is greater-than and 0 otherwise. Thus we have added 2*(n-1)*n boolean variables. Also set M
to 9 and to avoid numerical difficulties set epsilon
to 0.1. For more information see: 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, n, boolean = TRUE)
yy <- Variable(n-1, n, 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
Upvotes: 1