1

I am trying to solve an optimization problem by using linear programming. I have a list of products for which I know the content of multiple nutrients. The goal is then to find the combination of products that gives the closest solution to a certain demand of nutrients. In R I wrote a script that is able to solve this.

library(lpSolveAPI)

# Required nutrients
nitrogen = 1500
phosphate = 530

# Product properties (sample dataset, this will later be expanded with more products and nutrients)
products <- data.frame(
  p1 = c(0.2, 0.1),
  p2 = c(0.8, 0),
  p3 = c(0.15, 0.2),
  p4 = c(0.1, 0.25),
  p5 = c(0, 0.4)
)

# Create model
model <- make.lp(nrow = 2, ncol = ncol(products))

# Add the products as decisions
for (p in 1:ncol(products)) {
  set.column(model, p, products[, p])
}

# Set the required amount as constraint 
set.constr.value(model, rhs = c(nitrogen, phosphate))
set.constr.type(model, types = c(2,2))

# Set the objective function
set.objfn(model, rep(1, ncol(products)))
lp.control(model, sense='min')

solve(model)
get.objective(model)

However, I now want to add the contraint that no more than a certain number (e.g. 2) of products can be used. I was thinking about adding a binary constraint, but can't fgure out how to implement that. The only option I was able to spot is to set a decision variable to binary, but this gives not the option to use multiple units of a product.

So how can I add a constraint to not use more than 2 or 3 products?

Sven
  • 133
  • 1
  • 8

1 Answers1

2

Always first write down the mathematical model. This especially the case with low-level input formats. The step from idea to code is just too large.

So you have basically:

min sum(j, x(j))
st  sum(j, a(i,j)*x(j)) >= b(i)  for i=1,2
    x(j) >= 0      

Now you want to count non-zero variables. This requires additional binary variables and some bounds on x(j).

min sum(j, x(j))
st  sum(j, a(i,j)*x(j)) >= b(i)  for i=1,2
    x(j) <= U(j)*y(j)
    sum(j, y(j)) <= 2 (or 3)
    y(j) ∈ {0,1} 
    0 <= x(j) <= U(j)      

I'll leave it to you to transcribe this into code. Note that CVXR or OMPR may be easier to use than LpSolveAPI when the model gets a little bit more complex.

Erwin Kalvelagen
  • 15,677
  • 2
  • 14
  • 39