dirkschumacher / ompr

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

mymodel not found #346

Closed Lotte10 closed 2 years ago

Lotte10 commented 2 years ago

I'm an ompr beginner, new also to MIP in general, so this may be trivial. I want to run the maximum expected covering location problem. But if I run it with in the end "solution <- solve_model(mymodel, withROI(solver="glpk",verbose=TRUE))", it always gives an error "object 'mymodel' not found" and if I run it with in the end "solution <-solve_model(withROI(solver="glpk",verbose=TRUE))", it gives an error "no applicable method for 'solve_model' applied to an object of class "function"". I wonder what is wrong with my code. Thanks! Lotte

mymodel <- MILPModel() %>% add_variable(x[p], p=1:185,type="integer") %>% add_variable(y[p,r], p=1:185,r=1:12, type="binary") %>% set_objective(sum_expr(sum_expr((demand[p](1-0.45)0.45^(r-1))y[p,r],r = 1:12),p=1:185)) %>% add_constraint(sum_expr(as.numeric(covers[q,p])x[p],p=1:185) >= sum_expr(y[q,r], r=1:12),q=1:185) %>% add_constraint(sum_expr(x[p],p=1:185) <= 12) %>% solution <- solve_model(mymodel, with_ROI(solver="glpk",verbose=TRUE))

sbmack commented 2 years ago

I don't think you need the last %>% pipe since solution <- breaks the piping. So:

add_constraint(sum_expr(x[p],p=1:185) <= 12)
solution <- solve_model(mymodel, with_ROI(solver="glpk",verbose=TRUE))
Lotte10 commented 2 years ago

Thanks! I tried that, but then I get the error: Error in MILPModel() %>% add_variable(x[p], p = 1:185, type = "integer") %>% : could not find function "%>%". So that doesn't work..

sbmack commented 2 years ago

You have to load in a library that contains the piping function, e.g., require(tidyverse) or require(magrittr)

You could also create a .Rprofile file in an R Project folder for your optimization models:

require(tidyverse)
require(ROI)
require(ROI.plugin.symphony)
require(ROI.plugin.glpk)
require(ompr)
require(ompr.roi)
Lotte10 commented 2 years ago

Thanks! Now it runs, but the solver just gives the first answer that it can find (far from optimal). I don't know why it doesn't find the optimal answer. Does somebody know how to solve this?

The updated code is:

mymodel <- MILPModel() %>% add_variable(x[p], p=1:185,type="integer") %>% add_variable(y[p,r],type="binary",p=1:185,r=1:12) %>% add_constraint(sum_expr(x[p],p=1:185) == 12) %>% add_constraint(sum_expr(as.numeric(cover[q,i])x[i],i=1:185) >= sum_expr(y[q,]),q=1:185) %>% set_objective(sum_expr(as.numeric(demand[p])(1-0.45)0.45^(r-1)y[p,r], r=1:12,p=1:185),"max") k <- solve_model(mymodel, with_ROI(solver="glpk",verbose=TRUE))

sbmack commented 2 years ago

First examine the verbose outputs to see if the column and row dimensions are what you expect. You can then write out your model in standard form and visually inspect it to see if your formulation is giving you what you want:

wd <- getwd()
file_out <- paste(wd, "model.txt", sep = "/")
ROI_write(as_ROI_model(model), file_out, "lp_lpsolve")   

You can add that code block after the formulation and before the solve function. The code will write out your model to a model.txt file in your working directory. The file will be accessible in the Files tab of the Files, Plots... pane of RStudio. Click on the model.txt file and it will open in a tab in the Source pane. View the tab to see the contents. The variable names are fixed and only linearly indexed, but you should be able to figure out if you are getting what you want. You can then iterate by adjusting your model and re-creating the model.txt file.

Lotte10 commented 2 years ago

I know where it goes wrong. I get the message "non-numeric argument to binary operator" for my first constraint. There is a matrix multiplication in there (matrix*vector) and I already read that this gives problems. I do not know how to solve this. Can anybody help me? Propose a way to do this multiplication while the package accepts this? I would really appreciate it!

code: mymodel <- MILPModel() %>% add_variable(x[p], p=1:185,type="integer") %>% set_bounds(x[p],lb=0,p=1:185) %>% add_variable(y[p,r],p=1:185,r=1:12,type="binary")%>% add_variable(l[p],p=1:185,type="binary")%>% add_variable(covering[p],p=1:185, type="integer")%>% add_constraint(covering[i]==sum_expr(covers[i,s] x[s],s=1:185),i=1:185) %>% add_constraint(sum_expr(x[p],p=1:185) == 12) %>% add_constraint(l[i]-(x[i]/12) >= 0,i=1:185) %>% add_constraint(sum_expr(l[i], i=1:185) <=10) %>% add_constraint(covering[s]-sum_expr(y[s,r], r=1:12) >= 0,s=1:185) %>% set_objective(sum_expr(as.numeric(demand[p])(1-0.45)0.45^(r-1)y[p,r], r=1:12,p=1:185),"max")

sbmack commented 2 years ago

Doing matrix operations with the MILPModel function is a not intuitive. See the section Vectorized semantics revisited and the colwise function at this link: https://dirkschumacher.github.io/ompr/articles/milp-modelling.html

I and others have not figured out a way to formulate sparse constraint matrices using colwise. You should also try replacing the MILPModel function with the old MIPModel function. Just swap out the function names. MIPModel will accept standard matrix representations of constraints. If that works, you'll know your formulation is correct. Then you'll have to figure out the colwise equivalent if you want to refactor with MILPModel.

dirkschumacher commented 2 years ago

I convert that to discussions.