ompr : error message when I add some constraint to my model

322 views Asked by At

I have an error message when I add a constraint to my OMPR model (it works properly like this)

n = dim(note_mpg)[1]
nb_joueurs = 18
perf = scale(note_mpg$performance_beta)
cote = note_mpg$cote_alpha
poste = note_mpg$Poste
note_mpg$Buts[is.na(note_mpg$Buts)] <- 0
buts = scale(note_mpg$Buts)

results = MIPModel() %>%
  add_variable(z[i], i = 1:n, type = "binary") %>%
  set_objective(sum_expr((perf[i] + buts[i]) * z[i], i = 1:n), "max") %>%
  add_constraint(sum_expr(z[i], i = 1:n) == nb_joueurs) %>%
  # add_constraint(sum_expr( (poste[i] == "G") * z[i], i = 1:n) == 2) %>%
  # add_constraint(sum_expr( (poste[i] == "D") * z[i], i = 1:n) == 6) %>%
  # add_constraint(sum_expr( (poste[i] == "M") * z[i], i = 1:n) == 6) %>%
  # add_constraint(sum_expr( (poste[i] == "A") * z[i], i = 1:n) == 4) %>%
  add_constraint(sum_expr(cote[i] * z[i], i = 1:n) <= 500) %>%
  solve_model(with_ROI(solver = "glpk")) %>% 
  get_solution(z[i]) %>% 
  filter(value > 0)

If I add a/some constraint(s) (I remove my # on a comment) on the poste I get the message

Error in check_for_unknown_vars_impl(model, the_ast) : 
  The expression contains a variable that is not part of the model.

Many thanks :)

2

There are 2 answers

3
cookesd On

I've run into a similar problem recently. I was able to fix it using a filter function in the indexing instead of using the comparisons you are in the sum_expr.

# Example to replicate your poste variable
poste = rep(LETTERS[1:5],2)
print(poste)

#  [1] "A" "B" "C" "D" "E" "A" "B" "C" "D" "E"


# function that accepts the indices and the letter you want to filter poste to
# returns a vector of T/F (one for each index in i_indices)
filter_function <- function(i_indices,letter){
  # A list of indices that align to each of the letters in poste
  # Change this for your actual data
  index_list = lapply(unique(poste),function(letter) which(poste==letter))
  names(index_list) = unique(poste)
  
  # Get the T/F value for each index in i_indices
  # T if poste[index] == the provided letter
  # F otherwise
  return(sapply(i_indices,function(index) index %in% index_list[[letter]]))
}


# Build the model
m = MIPModel() %>%
  add_variable(z[i],i=1:10,type='binary') %>%
  # Call the filter function after your indices
  # Passing the index and the letter you want to limit the indices to
  add_constraint(sum_expr(z[i], i = 1:10,
                          filter_function(i,'B')) == 2)

m$constraints

# Only sums the indices of z where poste == 'B'
# (i = 2 and i = 7)
# [[1]]
# $lhs
# expression(z[2L] + z[7L])
# 
# $sense
# [1] "=="
# 
# $rhs
# expression(2)
# 
# attr(,"class")
# [1] "model_constraint"
0
jpetot On

thanks @cookesd for your answer, and sorry for the delay.

I finally find a way, but it is not very clean...

results= MIPModel() %>%
            add_variable(z[i], i = 1:n, type = "binary") %>%
            set_objective(sum_expr((perf[i] + buts[i]) * z[i], i = 1:n), "max") %>%
            add_constraint(sum_expr(z[i], i = 1:n) == nb_joueurs) %>%
            add_constraint(sum_expr(cote[i] * z[i], i = 1:n) <= 500)  %>%
            add_constraint( sum_expr(z[i], i = 1:n, poste[i] == "G") == as.numeric(input$gardiens)) %>%
            add_constraint( sum_expr(z[i], i = 1:n, poste[i] == "D") == as.numeric(input$def)) %>%
            add_constraint( sum_expr(z[i], i = 1:n, poste[i] == "M") == as.numeric(input$mil)) %>%
            add_constraint( sum_expr(z[i], i = 1:n, poste[i] == "A") == as.numeric(input$att))
            
          contraint3 = as.expression(sum_expr(z[i], i = 1:n, poste[i] == "G"))
          contraint4 = as.expression(sum_expr(z[i], i = 1:n, poste[i] == "D"))
          contraint5 = as.expression(sum_expr(z[i], i = 1:n, poste[i] == "M"))
          contraint6 = as.expression(sum_expr(z[i], i = 1:n, poste[i] == "A"))
          
          results$constraints[[3]]$lhs =contraint3
          results$constraints[[4]]$lhs =contraint4
          results$constraints[[5]]$lhs =contraint5
          results$constraints[[6]]$lhs =contraint6

I manually add the value of results$constraints[[k]]$lhs

For your question, I checked and everything is ok when I print the value... i don't understand the bug, Do not hesitate if you have any other idea.