I have the following matrix of suppliers who are able to make a certain product, against all products in my portfolio.
What is the best way of finding the solution to "the least suppliers necessary to deliver the whole portfolio" - and "which suppliers are necessary to deliver the whole portfolio"?
Ideally looking for a solution in R, since I have manipulated the data beforehand in order to get to this one-hot coded matrix. But generally I'm trying to understand first how to approach this.
The full dataset is obviously larger - I can see myself that in this case only Sup1 and Sup7 would be required :-)
I received some great answers below. Unfortunately I cannot install the "pulp" module for python on my laptop (restrictions from work - I know it doesn't seem to make sense). I am trying to convert the below python script into R (ompr by @dirks user:2798441). However I struggle with the syntax. I receive an error message with below code:
require(ompr)
require(ompr.roi)
require(dplyr)
require(ROI)
require(ROI.plugin.glpk)
test <-rbind(c(),
c("Prd1", 1, NA, NA, NA, NA, NA, NA, 1, NA, NA, NA),
c("Prd2",1, NA, NA, NA, NA, 1, NA, NA, NA, 1, NA),
c("Prd3",NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
c("Prd4",1, 1, 1, 1, NA, NA, NA, NA, NA, NA, NA),
c("Prd5",NA, NA, NA, NA, NA, NA, 1, NA, NA, NA, NA),
c("Prd6",1, NA, NA, NA, NA, 1, NA, NA, NA, 1, NA),
c("Prd7",1, NA, NA, NA, 1, NA, NA, NA, 1, NA, NA),
c("Prd8",NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
c("Prd9",NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA))
dims <- dim(test)
test <- as.numeric(test)
dim(test) <- dims
test.df <- data.frame(test)
colnames(test.df) <- c("Product","Sup1", "Sup2", "Sup3", "Sup4", "Sup5", "Sup6", "Sup7", "Sup8", "Sup9", "Sup10", "Sup11")
test.df[,1] <- c("Prd1","Prd2","Prd3","Prd4","Prd5","Prd6","Prd7","Prd8","Prd9")
n <- nrow(test.df)
m <- ncol(test.df)
M <- 100
set_n <- range(0,n)
set_m <- range(0,m)
model <- MIPModel() %>%
add_variable(b[i,j], i = set_n, j = set_m, type = "binary") %>%
add_variable(x[j], j = set_m, type = "binary") %>%
set_objective(sum_expr(b[i,j] * 2, i = set_n, j = set_m) - sum_expr(x[j], j = set_m)) %>%
add_constraint((sum_expr(b[i,j], j = set_m)) <= 1) %>%
add_constraint(M * x[j] >= sum_expr(b[i,j], i = set_n) - 1 + 0.001) %>%
add_constraint(M * ( 1- x[j]) >= ( 1 - sum_expr(b[i,j], i = set_n) - 0.001)) %>%
solve_model(with_ROI(solver = "symphony", verbosity = 1)) %>%
get_solution(x[i, j]) %>%
filter(value > 0) %>%
arrange(i)
If someone has some kind of experience with ompr I would appreciate a nudge in the right direction.