I am trying to run a nonlinear optimization with bounded constraints in R.
I have got to know NlcOptim
& roptim
can be used to optimize a nonlinear objective function, and I have gone through examples [https://cran.r-project.org/web/packages/NlcOptim/NlcOptim.pdf] like one (ex1) as I have mentioned below;
require(NlcOptim)
require(MASS)
objfun=function(x){
return(exp(x[1]*x[2]*x[3]*x[4]*x[5]))
}
#constraint function
confun=function(x){
f=NULL
f=rbind(f,x[1]^2+x[2]^2+x[3]^2+x[4]^2+x[5]^2-10)
f=rbind(f,x[2]*x[3]-5*x[4]*x[5])
f=rbind(f,x[1]^3+x[2]^3+1)
#return(list(ceq=f,c=NULL))
return(list(ceq=f,c=NULL))
}
x0=c(-2,2,2,-1,-1)
solnl(x0,objfun=objfun,confun=confun)
Understanding: x used in both objfun & confun, is a vector containing x(i), i=1(1)5 x0 is the starting values (In this case, I am bit confused as we are not defining here the bounds of x1,..,x5, rather only the initial values)
I have tried to replicate this example for my actual problem, the objective function I framed is as below;
Maximize P= (x*y*z)-(cost1 + cost2 + cost3 + cost4 + cost5 + cost6)
where
cost1 = 5000
cost2 = (0.23*cost1) + (0.67*x*y)
cost3 = 0.2* cost1+ (0.138*x*y)
cost4 = 0.62*cost1
cost5 = 0.12* cost1
cost6 = 0.354*x
Boundaries for the variables are as follow;
200<=x=>350
17<=y=>60
964<=z=>3000
Having this problem in hand, I tried to formulate this as code;
x <- runif(2037,200,350)
y <- runif(2037,17,60)
z <- seq(964,3000,1) # z is having highest length of 2037. But not sure if this the way to define bounds!!
data_comb <- cbind(x,y,z)
mat <- as.matrix(data_comb)
cost1 <- 5000
cost2 <- (0.23*cost1) + (0.67* mat[,1])* (mat[,2])
cost3 <- 0.2* cost1+ (0.138* mat[,1])* (mat[,2])
cost4 <- rep(0.62*cost1, dim(mat)[1])
cost5 <- rep(0.12* cost1, dim(mat)[1])
cost6 <- 0.354* mat[,1]
#Objective function
objfun <- function(mat){
return((mat[,1]*mat[,2]*mat[,3]) - (cost1 + cost2 + cost3 + cost4 + cost5 + cost6))
}
#Constraints
confun=function(mat){
f=NULL
f=rbind(f,(0.23*cos1) + (0.67*mat[,1])* (mat[,2]))
f=rbind(f,(0.2*cost1) + (0.138*mat[,1])*(mat[,2]))
f=rbind(f,0.354*mat[,1])
return(list(ceq=f,c=NULL))
}
x0 <- c(200,17,964)
solnl(x0,objfun=objfun,confun=confun)
This is giving me an error
Error in mat[, 2] : subscript out of bounds
I am having a feel somehow I am not replicating the example properly for my problem, but at the same time not able to understand what I am missing. I don’t know if I have defined the bounds properly or how to include multivariate bounds in the function. Please help me in solving this optimization problem.
TIA
There are no nonlinear constraints, only box constraints, therefore no reason to apply a specialized package or function.
obj <- function(v) {
x <- v[1]; y <- v[2]; z <- v[3]
cost1 <- 5000
cost2 <- (0.23*cost1) + (0.67*x*y)
cost3 <- 0.2* cost1+ (0.138*x*y)
cost4 <- 0.62*cost1
cost5 <- 0.12* cost1
cost6 <- 0.354*x
w <- (x*y*z) - (cost1 + cost2 + cost3 + cost4 + cost5 + cost6)
return(-w)
}
o <- optim(c(200,17,964), obj, method = "L-BFGS-B",
lower = c(200,17,964), upper = c(350,60,3000))
o$par; -o$value
## [1] 350 60 3000
## [1] 62972058
For using NlcOptim:solnl()
you can define the box constraints with the lb
and ub
option arguments, just the same as above.
NlcOptim::solnl(c(200,17,964), obj,
lb = c(200,17,964), ub = c(350,60,3000))
with the same result, showing that your function does not have a real, inner maximum. Or you can integrate the bounds into the constraint function