dirkschumacher / ompr

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

the cannery problem - vignette enhancement #436

Open brilstl opened 1 year ago

brilstl commented 1 year ago

Hi Dirk,

First off, very cool package and a great contribution to the R community :)

I was trying out ompr with some examples from the JuMP documentation and got stuck working out the cannery problem. I thought it could be a nice enhancement for the vignette section of the ompr package, so I share the code here - without a working model - which hopefully can be converted quite easily into a vignette:

# packages ----
library(ompr)
library(ompr.roi)
library(tidyverse)

# json ----
x <- '
{
    "plants": {
        "Seattle": {"capacity": 350},
        "San-Diego": {"capacity": 600}
    },
    "markets": {
        "New-York": {"demand": 300},
        "Chicago": {"demand": 300},
        "Topeka": {"demand": 300}
    },
    "distances": {
        "Seattle => New-York": 2.5,
        "Seattle => Chicago": 1.7,
        "Seattle => Topeka": 1.8,
        "San-Diego => New-York": 2.5,
        "San-Diego => Chicago": 1.8,
        "San-Diego => Topeka": 1.4
    }
}
'
# transform data ----
data <- jsonlite::parse_json(x)

# get plants ----
P <- data[['plants']] %>% names

# get markets ----
M <- data[["markets"]] %>% names

# create function for dinstances between plants and markets ----
distance <- \(p,m) data[["distances"]][[glue::glue("{p} => {m}")]] 
## check if it works ----
distance(P[1], M[1])

# start model (copy-paste from JuMP documentation) ----
MIPModel() %>% 
  # Our decision variables are indexed over the set of plants and markets:
  add_variable(x[p, m] >= 0, p = P, m = M) %>% 
  # We need a constraint that each plant can ship no more than its capacity:
  add_constraint(sum_expr(x[p] <= data[["plants"]][[p]][["capacity"]], p = P)) %>%
  # and each market must receive at least its demand:
  add_constraint(sum_expr(x[m] <= data[["markets"]][[m]][["demand"]], m = M)) %>% 
  # Finally, our objective is to minimize the transportation distance:
  set_objective(sum_over(distance(p, m) * x[p, m], p = P, m = M))