Xander
Xander

Reputation: 97

Optimizing a formula with multiple input variables using nsga2 package mco

I have a formula I want to maximize with 8 input parameters/variables/dimensions/criteria. For the example below I have simplified it to just a 2-part formula. Based on the information here I have been using the mco package calling nsga2.

Here is the setup:

#calculate an s curve for advertising1
Index = (0:250)    
advertising1.sAlpha = .953
advertising1.sBeta = 0.0000000003
advertising1.Max = 53460404
advertising1.Media = Index*advertising1.Max/100
advertising1.scurve = advertising1.sBeta^(advertising1.sAlpha^Index)

advertising1.Beta = 2989.589
advertising1.Cost = .095

#function to convert spend to media, get the response, find the s curve, and return number of sales for advertising1

advertising1.Spend = function(advertising1Spend) {
    monthly.spend = advertising1Spend/12
    Media = monthly.spend/advertising1.Cost
    response.index = findInterval(Media, advertising1.Media)
    scurve = advertising1.scurve[response.index]
    sales = scurve*advertising1.Beta
    return(sales)
}

#calculate an s curve for advertising2
advertising2.sAlpha = .6
advertising2.sBeta = 0.000000001
advertising2.Max = 90
advertising2.Media = Index*advertising2.Max/100
advertising2.scurve = advertising2.sBeta^(advertising2.sAlpha^Index)

advertising2.Beta = 4597.285
advertising2.Cost = 38540.12

#function to convert spend to media, get the response, find the s curve, and return number of sales for advertising2
advertising2.Spend = function(advertising2Spend) {
    monthly.spend = Spend/12
    Media = monthly.spend/advertising2.Cost
    response.index = findInterval(Media, advertising2.Media)
    scurve = advertising2.scurve[response.index]
    sales = scurve*advertising2.Beta
    return(sales)
}

These functions work as desired. I can pass them an annual spending amount and they will return a monthly projected sales figure.

Next: define the function to be optimized.

Optimize.Spend = function(advertising1Spend, advertising2Spend) {
    advertising1.Spend(advertising1Spend) + 
    advertising2.Spend(advertising2Spend)
}

This function also works as expected. I also want to set a budget as a constraint such that advertising1Spend + advertising2Spend <= 50000000 for example.

Budget = function(advertising1Spend, advertising2Spend) {
    advertising1Spend + advertising2Spend <= 50000000
}

Lastly, my attempt to optimize the function is as follows. I have set bounds on the individual variables as well as entered my constraint.

nsga2(Optimize.Spend, 2, 2, lower.bounds = c(0, 0), upper.bounds = 
c(60944860.56, 41623333.92), generations = 100, constraints = Budget, cdim = 1)

In words, I want to find the optimal spending amount per input variable that will yield the most sales given a budget. Firstly, is this kind of optimization even possible in R? And am I using the right package/call?

Currently the code is failing with "Error in advertising2(advertising2Spend): argument 'advertising2Spend' is missing, with no default." I feel the issue may have to do with how the optimization function is written, but I cannot figure out how to improve it. No examples that I've seen take multiple input parameters in the optimization function.

I would also need to "reverse" the formula somehow since nsga2 is a minimization function and I want to maximize. But first thing's first... How do I even get the package to work for me?

Thanks for any help.

Upvotes: 1

Views: 626

Answers (1)

Xander
Xander

Reputation: 97

Here is what I ended up doing with package DEoptimR.

parameters = c(FALSE, FALSE)

Optimize.Spend = function(parameters) {
-Advertising1.Spend(parameters[1]) - Advertising2.Spend(parameters[2])
}

Budget = function(parameters) {-parameters[1] - parameters[2] + 100000000 <= 0
}

JDEoptim(lower = c(0,0), upper = c(60944860.56, 41623333.92), fn = Optimize.Spend, constr = Budget, maxiter = 2000)

Package RccpDE also worked. My primary issue was that I needed a package that would optimize evolutionarily.

Upvotes: 2

Related Questions