The following problem seeks to maximize the weight across any 3 items while being under a cost of 20. I gave group "a" a large weight so that the model will only select the 3 items from group "a". How do I force the model to include at least 2 groups?
library(ompr)
library(ROI.plugin.glpk)
library(ompr.roi)
library(dplyr)
set.seed(1)
d <- data.frame(
id = seq_len(10),
weight = c(rep(100, 3), runif(7, 1, 50)),
cost = runif(10, 1, 10),
group = c(rep("a", 3), rep("b", 3), rep("c", 3), "d")
)
m <- ompr::MIPModel() %>%
ompr::add_variable(x[i],
i = d$id,
type = "binary") %>%
# set objective to maximize the weight
ompr::set_objective(
ompr::sum_over(d$weight[i] * x[i],
i = d$id), "max"
) %>%
# cost must be less than 20
ompr::add_constraint(
ompr::sum_over(d$cost[i] * x[i],
i = d$id) <= 20
) %>%
# can only include 3 items
ompr::add_constraint(
ompr::sum_over(
x[i],
i = d$id
) == 3
)
res <- ompr::solve_model(m, ompr.roi::with_ROI(solver = "glpk"))
res %>%
ompr::get_solution(x[i]) %>%
dplyr::filter(.data$value > 0) %>%
dplyr::inner_join(d, by = c("i" = "id"))
#> variable i value weight cost group
#> 1 x 1 1 100 6.947180 a
#> 2 x 2 1 100 6.662026 a
#> 3 x 3 1 100 1.556076 a
Created on 2023-02-05 with reprex v2.0.2