I'm currently using the ompr and roi packages in R to solve a IP type problem. I've managed to solve a simple version, however, I'm now trying to extend the problem, and I only want to include an item in 1 knapsack (don't allow it to appear in a knapsack more than once). Below is an example dataset I am using (called KP):
Itemid | ItemType | Value | Weight |
---|---|---|---|
1 | A | 114 | 24 |
2 | B | 557 | 136 |
3 | B | 543 | 136 |
4 | B | 10 | 136 |
5 | B | 4 | 136 |
6 | C | 161 | 152 |
7 | A | 184 | 24 |
8 | A | 751 | 24 |
9 | A | 184 | 24 |
10 | A | 150 | 24 |
My inital version of the knapsack I solved using the following code (and with a knapsack capacity of 240):
library(tidyverse)
library(ROI)
library(ROI.plugin.glpk)
library(ompr)
library(ompr.roi)
# Create variables from data to use in model
n <- nrow(KP)
v <- KP$Value
w <- KP$Weight
c <- 240
solution <- MIPModel() %>%
add_variable(x[i], i = 1:n, type = "binary") %>%
set_objective(sum_expr(v[i] * x[i], i = 1:n), "max") %>%
add_constraint(sum_expr(w[i] * x[i], i = 1:n) <= c) %>%
solve_model(with_ROI(solver = "glpk")) %>%
get_solution(x[i])
#filter(value > 0)
# Now join solution to original dataframe
df <- cbind(KP,capacity=240,solution[,3,drop=FALSE])
ouput <- df %>% filter(value > 0)
I now want to solve an extended version using a vector of capacities (200, 150). Here is the code that I've used, now incorporating an x[i, j] binary variable that is set to 1 if item i is added to c[j]:
# Create variables from data to use in model
n <- nrow(KP)
v <- KP$Value
w <- KP$Weight
c <- c(240,150)
m <- length(c)
# Now solve the model
solution <- MIPModel() %>%
add_variable(x[i, j], i = 1:n,j=1:m, type = "binary") %>%
set_objective(sum_expr(v[i] * x[i, j], i = 1:n, j=1:m), "max") %>%
add_constraint(sum_expr(w[i] * x[i, j], i = 1:n, j=1:m) <= c[j]) %>% #This constraint ensures that the weight of the items must be less than the capacity
add_constraint(sum_expr(x[i, j], i = 1:n, j=1:m) <= 1) %>% #This constraint ensure that an item can only be included in a single knapsack - not across multiple knapsacks
solve_model(with_ROI(solver = "glpk")) %>%
get_solution(x[i, j])
#filter(value > 0)
I've tried debugging the code and it is essentially the constraint that is not generating correctly (this is where the error occurs). Here is the error I'm getting:
Error in check_for_unknown_vars_impl(model, the_ast) : The expression contains a variable that is not part of the model.
I've tried all manner of things to try and get around this but can't seem to work out what is wrong with my constraint.
For anyone that is interested, I had needed to index j on the right hand side. So I managed to get a solution and limit each item to only being added to a knapsack once: