-1

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

CS.py
  • 43
  • 6

2 Answers2

3

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
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
  • Hello @Ben, thanks for your reply. Is this what you meant, because its not working either:max_obj <- function(x){ -1 * x } MaxClicks_optim.parms <- nlminb(objective = max_obj(TotalSpend), start = startValVec, lower = minValVec, upper = maxValVec, control = list(iter.max=100000,eval.max=20000), Budget = 10000) – CS.py Apr 26 '20 at 20:08
  • no, that's not what I meant. The first line (objective function definition) should be entered *exactly as written here* – Ben Bolker Apr 26 '20 at 20:29
  • I'm not sure i understand, can you give an example please? – CS.py Apr 26 '20 at 20:30
  • Can you please share an example with optim() – CS.py Apr 26 '20 at 20:45
  • Hi Ben thank you for your answer. Is there a way using optim() to add constraints. So the sum of the maxValVec parameters will not exceed 1, say. Basically distributing the budget variable between the three parameters so the parameters equal 1. – CS.py Apr 28 '20 at 13:16
0

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

tpetzoldt
  • 5,338
  • 2
  • 12
  • 29