Using nlminb to maximize functions

2.4k Views Asked by At

I have the following function and i need it to be maximized instead of minimized.

adbudgReturn = function(Spend,a,b,c,d){
adbudgReturn = sum(b+(a-b)*((Spend^c)/(d+(Spend^c))))
return(adbudgReturn)
}

FP_param <- c(95000,0,1.15,700000)
FB_param <- c(23111.55,0,1.15,20000)
GA_param <- c(115004,1409,1.457,2000000)

y = c(0.333333,0.333333,0.333333)

TotalSpend <- function(Budget,y){
                   FP_clicks = adbudgReturn(Budget * y[1], FP_param[1], FP_param[2],  FP_param[3], FP_param[4])
                   FB_clicks = adbudgReturn(Budget * y[2], FB_param[1], FB_param[2],  FB_param[3], FB_param[4])
                   GA_clicks = adbudgReturn(Budget * y[3], GA_param[1], GA_param[2],  GA_param[3], GA_param[4])
                   return(total = FP_clicks + FB_clicks + GA_clicks)
}




startValVec = c(0.33333,0.333333,0.3333333)
minValVec = c(0,0.2,0)
maxValVec = c(0.8,1,08)


MaxClicks_optim.parms <- nlminb(objective = TotalSpend,start = startValVec,
                     lower = minValVec,
                     upper = maxValVec,
                     control = list(iter.max=100000,eval.max=20000),
                     Budget = 10000)

I have tried adding the minus sign in front of the nlminb function i.e:

-nlminb(..)

but without any success. Any help will be appreciated.

Also i would like to add constraints so the sum of the maxValVec = 1

2

There are 2 best solutions below

5
Ben Bolker On

Other optimization functions in R such as optim() have a built-in fnscale control parameter you can use to switch from minimization to maximization (i.e. optim(..., control=list(fnscale=-1)), but nlminb doesn't appear to. So you either need to flip the sign in your original objective function, or (possibly more transparently) make a wrapper function that inverts the sign, e.g.

max_obj <- function(...) -1*TotalSpend(...)
MaxClicks_optim.parms <- nlminb(objective = max_obj, 
           [ .... everything else as before ... ] )

Note that the ... in the max_obj() definition are literal. The only part of the solution above that needs to be filled in is the [.... everything else as a before ...] part. To be absolutely explicit:

max_obj <- function(...) -1*TotalSpend(...)
MaxClicks_optim.parms <- nlminb(objective = max_obj,
                 start = startValVec,
                 lower = minValVec,
                 upper = maxValVec,
                 control = list(iter.max=100000,eval.max=20000),
                 Budget = 1e4)

If you were using a user-specified gradient argument you'd have to wrap that too.

This CV question points out that you can maximize by minimizing the negative of a function, but doesn't go into the nuts and bolts.

An optim()-based solution would look something like:

optim(fn = TotalSpend,
      par = startValVec,
      lower = minValVec,
      upper = maxValVec,
      method = "L-BFGS-B",
      control = list(maxit=100000, fnscale=-1),
      Budget = 1e4)
  • L-BFGS-B is the only method built into to optim() that does box-constrained optimization
  • optim() doesn't have separate controls for max iterations and max function evaluations
0
tpetzoldt On

Here is an example with a simple parabolic function, It works the same with nlminband optim:

## ==== Some preliminaries ========================
par(mfrow=c(1,2))
a <- b <- seq(-10, 10, 0.1)

## ==== Search for a minimum ======================

# function has minimum
f1 <- function(a, b) {
  (a - 1)^2 + (b - 2)^2
}
## show function, blue color is low
image(a, b, outer(a,  b, f1), col=topo.colors(16))

## wrapper: combine parameters
g1 <- function(p) f1(p["a"], p["b"])

## minimization
(ret <- nlminb(c(a=0, b=0), g1))
## show minimum
points(t(ret$par), pch="+", cex=2)


## ==== Search for a maximum =======================

## function has a maximum
f2 <- function(a, b) {
  - (a - 1)^2 - (b + 2)^2
}
## brown color is high
image(a, b, outer(a,  b, f2), col=topo.colors(16))

## wrapper:  combine parameters, invert sign
g2 <- function(p) -f2(p["a"], p["b"])

## minimization of negative objective = maximization
(ret <- nlminb(c(a=0, b=0), g2))
## show maximum
points(t(ret$par), pch="+", cex=2)

optimization landscape