dirkschumacher / ompr

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

Object not found #430

Closed justlebeau closed 2 years ago

justlebeau commented 2 years ago

Hi,

I am new to the package but it seems the choice of anyone looking at OR problems.

I have the following allocation/scheduling problem:

df<-data.frame(
  Week.1 = c(10000L,120000L,120000L,10000L,120000L,
             120000L,10000L,10000L,10000L,80000L,10000L,120000L,
             120000L,20000L,120000L),
  Week.2 = c(10000L,120000L,120000L,10000L,120000L,
             120000L,10000L,10000L,10000L,80000L,10000L,120000L,
             120000L,20000L,120000L),
  Week.3 = c(10000L,120000L,120000L,10000L,120000L,
             120000L,10000L,10000L,10000L,80000L,10000L,120000L,
             120000L,20000L,120000L),
  Week.4 = c(10000L,120000L,120000L,10000L,120000L,
             120000L,10000L,10000L,10000L,80000L,10000L,120000L,
             120000L,20000L,120000L),
  Week.5 = c(10000L,120000L,120000L,10000L,120000L,
             120000L,10000L,10000L,10000L,80000L,10000L,120000L,
             120000L,20000L,120000L),
  Week.6 = c(10000L,120000L,120000L,10000L,120000L,
             120000L,10000L,10000L,10000L,80000L,10000L,120000L,
             120000L,20000L,120000L),
  Week.7 = c(10000L,120000L,120000L,10000L,120000L,
             120000L,10000L,10000L,10000L,80000L,10000L,120000L,
             120000L,20000L,120000L),
  Week.8 = c(10000L,120000L,120000L,10000L,120000L,
             120000L,10000L,10000L,10000L,80000L,10000L,120000L,
             120000L,20000L,120000L),
  Week.9 = c(10000L,120000L,120000L,10000L,120000L,
             120000L,10000L,10000L,10000L,80000L,10000L,120000L,
             120000L,20000L,120000L),
  Week.10 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.11 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.12 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.13 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.14 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.15 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.16 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.17 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.18 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.19 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.20 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.21 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.22 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.23 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.24 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.25 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.26 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.27 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.28 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.29 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.30 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.31 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.32 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.33 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.34 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.35 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.36 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.37 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.38 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.39 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.40 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.41 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.42 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.43 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.44 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.45 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.46 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.47 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.48 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.49 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.50 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.51 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L),
  Week.52 = c(10000L,120000L,120000L,10000L,120000L,
              120000L,10000L,10000L,10000L,80000L,10000L,120000L,
              120000L,20000L,120000L)
)

nmodels<-ncol(df)
nproducts<-nrow(df)

capacity<-c(50000,  50000, 325000, 100000, 150000, 100000, 100000,  25000,  50000, 250000, 100000, 275000,  75000,  75000,  50000)

totalcost<-function(i){
  sum(df[i,],x[i,],y[i,],na.rm=TRUE)
}

model <- MIPModel() %>%
  ##Allocation matrix
  add_variable(x[i,j], i = 1:nmodels,j=1:nproducts,  type = "continuous") %>% 
  ##Schedule matrix
  add_variable(y[i,j],i = 1:nmodels,j=1:nproducts, type="binary") %>% 

  set_objective(sum(y[i,j],i = 1:nmodels,j=1:nproducts),sense="max") %>% 
  add_constraint(totalcost(i)<=capacity[i],i=1:nmodels) %>% 
  add_constraint(y[i]==1,i=1:nnmodels) %>% 
  solve_model(with_ROI(solver = "glpk")) 

Error in `[.OmprLinearVariableCollection`(y, i, j) : object 'i' not found

I'm wanting to allocate the values in df as percentages and then have a schedule associated with the allocation. This seems relatively straight forward but I am new to setting these up so any help/direction is appreciated.

sbmack commented 2 years ago

Error in[.OmprLinearVariableCollection(y, i, j) : object 'i' not found

Given the error in i reported, I am guessing that it doesn't like the totalcost(i) term in: add_constraint(totalcost(i)<=capacity[i],i=1:nmodels)

Without knowing exactly what your intended constraint intent is, suggest substituting the totalcost term with the ompr sum_over function and explicitly indexing over j. The ompr documentation has 2 dimensional examples of sum_over.

BTW, also suggest installing and using the latest development version of ompr:

remotes::install_github("dirkschumacher/ompr")
remotes::install_github("dirkschumacher/ompr.roi")

It has better performance, additional functionality and behaves properly. Note the ompr documentation has not yet been updated to reflect Dirk's package updates. The sum_expr term has been deprecated and replaced by sum_over.

justlebeau commented 2 years ago

Thanks for the tips!

The intent is to have 2 matrices: x and y. X providing the allocation amount for df and y the schedule (1,0) allowing only 1 per week. I'm wanting to constrain the sum of the product of the rows of df, x, and y to each capacity[I]

dirkschumacher commented 2 years ago

The problem is in the objective function:

# this uses the base R sum function
set_objective(sum(y[i,j],i = 1:nmodels,j=1:nproducts),sense="max") 
# but you have to use sum_over
set_objective(sum_over(y[i,j],i = 1:nmodels,j=1:nproducts),sense="max") 

Also checkout reprex. this helps creating reproducible examples. But nothing wrong with your code, just a suggestion 😊

BTW, also suggest installing and using the latest development version of ompr:

CRAN and development should be nearly identical ATM. At least I hope 😅

For tips/help on modelling please use the Discussion section.