dirkschumacher / ompr

R package to model Mixed Integer Linear Programs
https://dirkschumacher.github.io/ompr/
Other
268 stars 35 forks source link

Sparse Matrix Constraints with multi-index #439

Open optimizationnoob opened 1 year ago

optimizationnoob commented 1 year ago

Hello,

I'm working on a modified assignment problem that assigns an individual in an occupation code to a division at a facility. However, not all occupations can be assigned to each division, and not all facilities have each division, so the matrix is sparse. I am attempting to filter while adding in a constraint that sums across divisions and facilities for each occupation code, but am getting the error "Error: You used the variable 'x' with at least one index that does not exists." Below is my code that should reprouce the error. Given the IT system I have access to, I must use R 4.0.2 and ompr 0.8.0. I'm able to add variables and set the objective function, but not add a constraint.

The constraint I am trying to incorporate sums across all divisions and facilities for each occupation code (so there should be 30 constraints of this type, one for each occupation code, and each occupation has a different supply) to ensure that the total assignment of each worker type across all divisions/facilities does not exceed the supply.

library(ompr)
library(dplyr)
set.seed(100)

occupation <- 1:30
division <- 1:20
facility <- 1:10

all_data <- data.frame(as.matrix(expand.grid(occupation, division, facility)))
names(all_data) <- c("occupation","division","facility")

all_data$feasible <- sample(c(0,1),nrow(all_data), replace = TRUE)

supply <- all_data[all_data$feasible == 1,]

supply$supply <- rnorm(nrow(supply), 150, 10)

test_model <- MILPModel() %>%
  add_variable(x[i,j,k], i=occupation, j=division, k=facility, all_data[(all_data$occupation == i)  & (all_data$division == j) & (all_data$facility == k), "feasible"] > 0) %>%

  set_objective(sum_expr(x[i,j,k], i=occupation, j=division, k=facility, all_data[(all_data$occupation == i)  & (all_data$division == j) & (all_data$facility == k), "feasible"] > 0)) %>%

  add_constraint(sum_expr(x[i,j,k], j=division, k=facility, all_data[(all_data$occupation %in% occupation)  & (all_data$division == j) & (all_data$facility == k), "feasible"] > 0) <= sum(supply$supply[supply$occupation == i]), i=occupation,
                 all_data[(all_data$occupation == i)  & (all_data$division %in% division) & (all_data$facility %in% facility), "feasible"] > 0)

What is the proper syntax to filter a sparse matrix in a constraint that sums through only two of the three indices, and then generates one constraint for each value of the third index? Thanks!