Nonlinear optimization with R for grouped variable

2019-05-20 09:51发布

问题:

I am trying to find maximum values for below objective function:

objective <-function(bid,revenue,click,cost) {

    revenue_2 <- sum((revenue / cost)*                                                      
                    (bid*click*bid*(cost/click) / cost)^(-0.2*revenue/cost)*              
                    (bid*click)*bid*(cost/click))

  return(-revenue_2)
}

subject to

roas_2 <- function(bid, revenue,click,cost) {

  revenue_2 <- ((revenue / cost)*                                                      
               (bid*click*bid*(cost/click) / cost)^(-0.2*revenue/cost))*              
               (bid*click)*bid*(cost/click)

  cost_2 <- (bid*click)*bid*(cost/click)

  roas_2 <- (sum(revenue_2)/sum(cost_2)) -1.2

  return(-roas_2)
}

where my values are as follows:

click <- c(123565, 94434, 79345, 152944, 83657, 67872, 80534, 48726, 107977, 138871, 116918, 41024, 63143)
revenue <- c(117251, 91806, 75356, 105787, 84419, 44139 , 57942 ,36283, 110902 ,130689, 116093, 36541, 37718)
cost <- c(93031,74764,73168,87510,66791,37637,50043,29209,90300,103276,93972,27228,32556)
cluster <- c(1,1,1,1,1,1,1,1,1,2,2,2,2)
bid <- c(1.2,1,1.6,1,1,1.2,1.2,1,1,1,1,1,1)

I am using nloptr library of R

library(nloptr)

res <- nloptr(x0=bid,
              eval_f=objective, 
              lb=c(0,0,0,0,0,0,0,0,0,0,0,0,0),
              ub=c(2,2,2,2,2,2,2,2,2,2,2,2,2),
              eval_g_ineq  = roas_2,
              # opts = list(algorithm="NLOPT_LN_COBYLA",maxeval=1000000),
              opts = list(algorithm="NLOPT_GN_ISRES",maxeval=105000),
              revenue=revenue,
              click=click,
              cost=cost)

With above code I can find bid values which maximizes my objective function but I would like to group my values according to "cluster" and find "bid" values for each cluster which maximizes above objective function with same constraints.

Could you please help me to overcome that problem?

回答1:

I found a solution which is not best but saved my day. Briefly, I wrote loop for objective function and constraint

And new form of objective function became like.

   objective <-function(bid,revenue,click,cost, cluster) {

      revenue_2 <- 0

      for (i in 1:13) {

        t <- cluster[i]

          revenue_2[i] <- (revenue[i]/cost[i])*
                          ((bid[t]*click[i]*bid[t]*(cost[i]/click[i]) / cost[i])^(-0.2*revenue[i]/cost[i]))*
                          (bid[t]*click[i])*bid[t]*(cost[i]/click[i])

      } 

      revenue_2 <- sum(revenue_2)

      return(-revenue_2)
    }

Constraint became like:

roas_2 <- function(bid, revenue,click,cost,cluster) {

  revenue_2 <- 0
  cost_2 <- 0

  for(i in 1:13) {

    t <- cluster[i]

    revenue_2[i] <- ((revenue[i] / cost[i])*                                                     
                            (bid[t]*click[i]*bid[t]*(cost[i]/click[i]) / cost[i])^(-0.2*revenue[i]/cost[i]))*              #new cost / old cost
                            (bid[t]*click[i])*bid[t]*(cost[i]/click[i])

    cost_2[i] <- (bid[t]*click[i])*bid[t]*(cost[i]/click[i])

    roas_2 <- (sum(revenue_2)/sum(cost_2)) - 1.2 

  }

  return(-roas_2)
}

As last step I added "cluster" parameter to optimization algorithm:

res <- nloptr(x0=bid,
              eval_f=objective, 
              lb=rep_len(0, 13),
              ub=rep_len(2, 13),
              eval_g_ineq  = roas_2,
              # opts = list(algorithm="NLOPT_LN_COBYLA",maxeval=1000000),
              opts = list(algorithm="NLOPT_GN_ISRES",maxeval=100000),
              revenue=revenue,
              click=click,
              cost=cost,
              cluster=cluster)