I am using ompr package in R to solve an omptimization problem. The optimization problem in written looks like this:
Min wi * xi
xi ϵ {0,1}
xi ≤ xj , j follower of i
i is a follower of j if in the distance matrix (distmatrix) a value is available. If the value is inf there is no connection possible from i to j
The goal is to analyze a Bill of Material, to make my example a bit easier I have created a more simple example with less materials in it.
vertices_undef <- data.frame(matrix(ncol=3, nrow=5))
vertices_undef$X1 <- c("3","5","9","7","2")
vertices_undef$X3 <- c(12, -8, 8, 3, -9)
rownames(vertices_undef) <- vertices_undef$X1
distMatrix <- data.frame(matrix(ncol=5, nrow=5))
rownames(distMatrix) <- vertices_undef$X1
colnames(distMatrix) <- vertices_undef$X1
distMatrix$`3` <- c("inf", 0.7, "inf", "inf", 0.3)
distMatrix$`5` <- c(3, "inf", "inf", "inf", 0.3)
distMatrix$`9` <- c("inf", 0.7, "inf", 0, 3)
distMatrix$`7` <- c("inf", "inf", "inf", 0.3, "inf")
distMatrix$`2` <- c("inf", 7, "inf", "inf", 0.3)
w <- vertices_undef$X3
w <- t(w)
colnames(w)<- vertices_undef$ID
w <- t(w)
result <- MIPModel() %>%
add_variable(x[i], type = "binary", i = as.integer(as.character(vertices_undef$X1))) %>%
set_objective(sum_expr(x[i]*w[i,1], i = as.integer(as.character(vertices_undef$X1))), "min") %>%
add_constraint(x[i]<=x[j], i = as.integer(as.character(vertices_undef$X1)), j = as.integer(as.character(vertices_undef$X1)), is.finite(distMatrix[i,j])==TRUE)%>%
solve_model(with_ROI(solver = "glpk"))
get_solution(result, x[i])
If I cross out the constraint I am getting the result I would expext (considered that the constraint is not used). How can I adress within the constraint the i and the j separately?
The filter condition in your
add_constraint
call produces an error. Thei
andj
are vectors and indexing a matrix using vectors does not produce a single logical vector as required byadd_constraint
, but another matrix. Also, somei/j
combinations are not part of yourdistMatrix
matrix.What happens internally is essentially this:
The filter condition (i.e. the expression
is.finite(distMatrix[i,j])==TRUE
) needs to return a logical vector with the length ofi/j
that indicates which row should be included in the model and which should not be included.