Solving a non-linear optimization problem by using R with the nloptr package

108 views Asked by At

My problem is that a bakery is selling three different products (apple pie, croissant, and donut). The profits from selling them are $12, $8, and $5, respectively. An apple pie costs 30 minutes labour_mins and 3 eggs. A croissant costs 15 minutes labour_mins and 2 eggs. And a donut costs 10 minutes labour_mins and an egg. The total available labour minutes and eggs are 500 mins and 60 eggs. The production volumme of each item needs to be greater than or equal to 0.

Here are my R codes:

 library(nloptr)
# Define the objective function
    objective <- function(x) {
      profit <- c(12, 8, 5)  # Profits for apple pie, croissant, and donut
      total_profit <- sum(profit * x)
      return(total_profit) 
    }

# Define the constraint function
    constraint <- function(x) {
      labor_mins <- c(30, 15, 10)  # Labor minutes for apple pie, croissant, and donut
      eggs <- c(3, 2, 1)  # Eggs for apple pie, croissant, and donut
  
  # Labor hours constraint
# Available Labor Hours - sum(labor_mins * x) >= 0
      labor_hours_constraint <- 500 - sum(labor_mins * x)  
  
  # Egg units constraint
# Available Eggs - sum(eggs * x) >= 0
      egg_units_constraint <- 60 - sum(eggs * x)  
      return(c(labor_hours_constraint, egg_units_constraint))
    }

# Set optimization options
    opts <- list(
      "algorithm" = "NLOPT_GN_ISRES",
      "xtol_rel" = 1e-8
    )

# Define the optimization problem
    res <- nloptr(
      x0 = rep(0, 3),  # Initial values (assuming 3 products)
      eval_f = objective,  # Objective function
      lb = rep(0, 3),  # Lower bounds (non-negative constraint)
      ub = rep(Inf, 3),  # Upper bounds
      eval_g_ineq = constraint,# Inequality constraint function
      opts = opts
    )

#Print the result
    print(res) 

But the result I got is (0,0,0), it seems wrong. Does anyone know how to solve it and get a reasonable answer? Or I should redefine the problem?

Thank you

2

There are 2 answers

2
Emmanuel Hamel On

You can consider the following approach which is not with the nloptr package :

library(DEoptim)

objective_Function <- function(param)
{
  param <- round(param)
  nb_Pie <- param[1]
  nb_Croissant <- param[2]
  nb_Donut <- param[3]
  time <- nb_Pie * 30 + nb_Croissant * 15 + nb_Donut * 10
  eggs <- nb_Pie * 3 + nb_Croissant * 2 + nb_Donut * 1
  
  if((time > 500) | (eggs > 60) | (nb_Pie < 0) | (nb_Croissant < 0) | (nb_Donut < 0))
  {
    return(10 ^ 10)
    
  }else
  {
    profit <- nb_Pie * 12 + nb_Croissant * 8 + nb_Donut * 5
    return(-profit)
  }  
}

obj_DEoptim <- DEoptim(fn = objective_Function, 
                       lower = c(0, 0, 0),
                       upper = c(100, 100, 100),
                       control = list(itermax = 1000))


round(obj_DEoptim$optim$bestmem)

par1 par2 par3 
   0   20   20 

-obj_DEoptim$optim$bestval
260
1
Emmanuel Hamel On

I have been able with the following code :

library(nloptr)

objective <- function(x)
{
  profit <- c(12, 8, 5)  
  total_profit <- -sum(profit * x)
  return(total_profit) 
}

constraint <- function(x)
{
  labor_mins <- c(30, 15, 10) 
  eggs <- c(3, 2, 1) 
  labor_hours_constraint <- sum(labor_mins * x) - 500   
  egg_units_constraint <- sum(eggs * x) - 60 
  return(c(labor_hours_constraint, egg_units_constraint))
}

opts <- list(
  algorithm = "NLOPT_LN_COBYLA",
  xtol_rel = 1e-8
)

res <- nloptr(
  x0 = rep(0, 3),
  eval_f = objective,  
  lb = rep(0, 3),  
  ub = rep(1000, 3),  
  eval_g_ineq = constraint,
  opts = opts)

print(res)

Call:
nloptr(x0 = rep(0, 3), eval_f = objective, lb = rep(0, 3), ub = rep(1000, 
    3), eval_g_ineq = constraint, opts = opts)


Minimization using NLopt version 2.7.1 

NLopt solver status: 4 ( NLOPT_XTOL_REACHED: Optimization stopped because xtol_rel or xtol_abs (above) was 
reached. )

Number of Iterations....: 70 
Termination conditions:  xtol_rel: 1e-08 
Number of inequality constraints:  2 
Number of equality constraints:    0 
Optimal value of objective function:  -260 
Optimal value of controls: 0 20 20