lpsugar is an AML (Algebraic Modeling Language) inspired in R’s vectorized syntax, used to define and solve Mixed Integer Linear Programs (MILP).
This package is in development, and being made by a solo student. For a safer choice, I recommend using ompr.
Installation
You can install the development version of lpsugar from GitHub with:
# install.packages("pak")
pak::pak("benet1one/lpsugar")Quick Example
Start with a simple problem to show the basic syntax.
Let’s write the problem in lpsugar and solve it!
library(lpsugar)
library(ROI.plugin.highs) # Use any ROI solver you like!
my_problem <- lp_problem() |>
lp_variable(x) |>
lp_variable(y) |>
lp_maximize(x + y) |>
lp_constraint(
2*x + y <= 8,
2*x + 3*y <= 12
)
my_solution <- lp_solve(my_problem)
my_solution$variables
#> $x
#> [1] 3
#>
#> $y
#> [1] 2
my_solution$objective
#> [1] 5Production Problem
Given a set of limited resources, we can make products. Each product takes a certain amount of resources and sells at a price. We wish to maximize earnings.
available <- c(Material = 20, Labour = 10)
price <- c(A = 150, B = 220, C = 160)
resources <- names(available)
products <- names(price)
required <- c(
# A, B, C
6, 3, 4, # Material
2, 3, 1 # Labour
) |> parameter(resources, products)
# parameter() sets the dimensions and names
required
#> products
#> resources A B C
#> Material 6 3 4
#> Labour 2 3 1
production_problem <- lp_problem() |>
lp_var(units[products], integer = TRUE, lower = 0) |>
lp_max(sum(price * units)) |>
lp_con(
for (r in resources) {
sum_over(p=products, units[p] * required[r,p]) <= available[r]
}
)
production_solution <- lp_solve(production_problem)
production_solution$objective
#> [1] 920
production_solution$variables
#> $units
#> products
#> A B C
#> 0 2 3Transportation Problem
Here’s an example solving the classic transportation problem. We shall transport u[f, w] units from factory f to warehousse w, subject to a supply[f] and a demand[w]. We will minimize the total cost.
factory <- paste0("fct", 1:3)
warehouse <- c("A", "B", "C", "D")
supply <- c(20, 25, 15) |> parameter(factory)
demand <- c(8, 10, 12, 10) |> parameter(warehouse)
cost <- c(
# A, B, C, D
2, 7, 3, 1,
6, 2, 9, 2,
4, 6, 2, 8
) |> parameter(factory, warehouse)
cost
#> warehouse
#> factory A B C D
#> fct1 2 7 3 1
#> fct2 6 2 9 2
#> fct3 4 6 2 8
transportation_problem <- lp_problem() |>
lp_variable(u[factory, warehouse], integer = TRUE, lower = 0) |>
lp_minimize(sum(u * cost)) |>
lp_constraint(
for (f in factory) sum(u[f, ]) <= supply[f],
for (w in warehouse) sum(u[, w]) >= demand[w]
# Alternatively, using vectorization:
# rowSums(u) <= supply,
# colSums(u) >= demand
)
transportation_solution <- lp_solve(transportation_problem)
transportation_solution$objective
#> [1] 70
transportation_solution$variables
#> $u
#> warehouse
#> factory A B C D
#> fct1 8 0 0 10
#> fct2 0 10 0 0
#> fct3 0 0 12 0