使用 R 对分组变量进行非线性优化

Nonlinear optimization with R for grouped variables

我正在尝试为以下 objective 函数找到最大值:

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)
}

受制于

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)
}

我的价值观如下:

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)

我正在使用 R 的 nloptr 库

图书馆(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)

使用上面的代码,我可以找到最大化我的 objective 函数的出价,但我想根据 "cluster" 对我的值进行分组,并为每个集群找到最大化的 "bid" 值以上 objective 具有相同约束的函数。

你能帮我解决这个问题吗?

我找到了一个不是最好的解决方案,但拯救了我的一天。简而言之,我为 objective 函数和约束

编写了循环

objective 函数的新形式变成了这样。

   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)
    }

约束变成这样:

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)
}

作为最后一步,我向优化算法添加了 "cluster" 参数:

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)