dirkschumacher / ompr

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

Error in `multiply.LinearTerm()`: ! Quadratic expression are not supported #414

Closed Patrikios closed 2 years ago

Patrikios commented 2 years ago

Got the following modelling situation

model <- MIPModel() %>%
add_variable(x[i], i = 1:188, type = 'continuous') %>%
add_variable(b[i], i = 1:188, type = 'binary') %>%
set_objective(sum_expr(x[i], i = 1:188), sense = 'min') %>%
set_bounds(x[i], lb = 4.780000, i = 1) %>%
set_bounds(x[i], lb = 0.140000, i = 2) %>%
set_bounds(x[i], lb = 0.020000, i = 3) %>%
set_bounds(x[i], lb = 0.630000, i = 4) %>%
set_bounds(x[i], lb = 0.110000, i = 5) %>%
set_bounds(x[i], lb = 0.160000, i = 6) %>%
set_bounds(x[i], lb = 2.270000, i = 7) %>%
set_bounds(x[i], lb = 0.960000, i = 8) %>%
set_bounds(x[i], lb = 0.430000, i = 9) %>%
...an other up to 188 lower bounds on x

After, I want to add few constraints like

model %>% 
  add_constraint(sum_expr(x[i]*b[i], i = 5:46) <= 45)

However get the error Error in multiply.LinearTerm(): ! Quadratic expression are not supported

As I am multiplying binary with numeric I don't think this should be an issue for the optimisation procedure. Am I missing a transform?

dirkschumacher commented 2 years ago

Thanks for taking the time to write issue. As the error message suggests, quadratic terms are not supported ... yet. Multiplying two variables x and b would make that constraint quadratic. It does not matter if it is a binary or continuous variable.

PS: you can also do set_bounds(x[i] >= lower_bounds[i], i = 1:188) assuming your bounds are in some vector lower_bounds.

Patrikios commented 2 years ago

Cheers for answer. I guess I have to look elsewhere (I guess something like ROI, lpsolve) to solve the problem. Keep it up!

sbmack commented 2 years ago

Got the following modelling situation

model <- MIPModel() %>%
add_variable(x[i], i = 1:188, type = 'continuous') %>%
add_variable(b[i], i = 1:188, type = 'binary') %>%
set_objective(sum_expr(x[i], i = 1:188), sense = 'min') %>%
set_bounds(x[i], lb = 4.780000, i = 1) %>%
set_bounds(x[i], lb = 0.140000, i = 2) %>%
set_bounds(x[i], lb = 0.020000, i = 3) %>%
set_bounds(x[i], lb = 0.630000, i = 4) %>%
set_bounds(x[i], lb = 0.110000, i = 5) %>%
set_bounds(x[i], lb = 0.160000, i = 6) %>%
set_bounds(x[i], lb = 2.270000, i = 7) %>%
set_bounds(x[i], lb = 0.960000, i = 8) %>%
set_bounds(x[i], lb = 0.430000, i = 9) 

As an FYI, note that you can add multiple bounds statements using a for loop and the Assignment operator %<>%:

lbs <- c(4.78, 0.14, 0.02, 0.63, 0.11, 0.16, 2.27, 0.96, 0.43)
nlbs <- length(lbs)

model2 <- MIPModel() %>%
  add_variable(x[i], i = 1:188, type = 'continuous') %>%
  add_variable(b[i], i = 1:188, type = 'binary') %>%
  set_objective(sum_expr(x[i], i = 1:188), sense = 'min')
  for (z in 1:nlbs) {
    model2 %<>% set_bounds(x[z], lb = lbs[z]) 
  }

> identical(variable_bounds(model), variable_bounds(model2))
[1] TRUE
sbmack commented 2 years ago

model %>% add_constraint(sum_expr(x[i]*b[i], i = 5:46) <= 45)



However get the error `Error in multiply.LinearTerm(): ! Quadratic expression are not supported`

As I am multiplying binary with numeric I don't think this should be an issue for the optimisation procedure. Am I missing a transform?

Also note that you can often use linear relationships between binary auxiliary variables and continuous variables to bound your problem.

So in your case something like this:

lbs <- c(4.78, 0.14, 0.02, 0.63, 0.11, 0.16, 2.27, 0.96, 0.43) #out to 188 lb values
nlbs <- length(lbs)

model3 <- MIPModel() %>%
  add_variable(x[i], i = 1:188, type = 'continuous') %>%
  add_variable(b[i], i = 1:188, type = 'binary') %>%
  set_objective(sum_expr(x[i], i = 1:188), sense = 'min') %>% 
  add_constraint(lbs[i] * b[i] <= x[i], i = 1:188) %>%
  add_constraint(sum_expr(b[i], i = 1:188) <= 45)

That is the standard method for formulating project portfolio models. The simple bounds are removed and replaced by constraints containing the lower bound values * binary variables <= continuous variables. The constraint on the number of continuous variables is imputed by constraining the sum of non-zero binary variables <= 45 in this case.

Patrikios commented 2 years ago

I figured it out, unbalanced transportation problem with additional constraints and elastic filter. ompr helped to formulate the problem. Thnx for the package!