如何使用 nloptr 在 R 中构造一个具有 n 项优化的 objective 函数?

How to construct an objective function with n terms for optimisation in R using nloptr?

我已经更新了这个问题以更清楚地说明问题。

我有以下形式的数据集:

#sample dataset
dt <- read.table(text = 'Plant Type Ownership Capacity VC TargetPLF
1      T Base       Pub 1000 1.50 0.80  
2      S Base       Pub 500  1.62 0.80
3      Y Base       Pub 500  2.43 0.75
4      K Base       Pub 500  1.93 0.80
5      J Base       Pub 500  3.40 0.80', header =T)

demand <- c(1500,2000,2200,3000,2800)

我的 objective 函数如下所示:

eval_f <- function(x)   #objective function
{
    return((1.50*1000*x[1] + 1.62*500*x[2] + 2.43*500*x[3] + 1.93*500*x[4] + 3.40*500*x[5]) / (1000*x[1] + 500*x[2] + 500*x[3] + 500*x[4] + 500*x[5]))
}

其他参数:

x0 <- rep(0.45,5) #initialisation values

local_opts <- list( "algorithm" = "NLOPT_LD_MMA", "xtol_rel" = 1.0e-15 )  #options for optimisation
opts = list( "algorithm"= "NLOPT_GN_ISRES","xtol_rel"= 1.0e-15,"maxeval"= 160000,"local_opts" = local_opts,"print_level" = 0 ) #optimisation algorithm

# constraint function
eval_g0_eq <- function(x) {
return(1000*x[1] + 500*x[2] + 500*x[3] + 500*x[4] + 500*x[5] - 1500)
}

lb = c(rep(0.40,5))   #lower bounds of controls
ub = dt$Target        #upper bounds of controls

nloptr(x0,eval_f,lb=lb,ub=ub,eval_g_eq = eval_g0_eq,opts=opts)  #optimisation

如何进行 5 次优化,每次使用不同的约束函数?

所以在第二次迭代中,约束函数应该从向量 'demand' 中取出第二个元素,变成这样:

# constraint function for second iteration
eval_g0_eq <- function(x) {
return(1000*x[1] + 500*x[2] + 500*x[3] + 500*x[4] + 500*x[5] - 2000)
}
nloptr(x0,eval_f,lb=lb,ub=ub,eval_g_eq = eval_g0_eq,opts=opts)  #optimisation

此外,有没有一种方法可以使用 dt 中的值构造 eval_f 和 eval_g0_eq,而不是像现在这样手动完成?

我不知道这个 nlopt 函数或库来自哪里,但我认为您不需要重复创建 objective functionconstraint function。您可以使用 R 的矢量化计算潜力来执行此操作。

dt <- read.table(text = 'Plant Type Ownership Capacity VC TargetPLF
1      T Base       Pub 1000 1.50 0.80  
2      S Base       Pub 500  1.62 0.80
3      Y Base       Pub 500  2.43 0.75
4      K Base       Pub 500  1.93 0.80
5      J Base       Pub 500  3.40 0.80', header =T)

demand <- c(1500,2000,2200,3000,2800)

library(nloptr)
dt
#>   Plant Type Ownership Capacity   VC TargetPLF
#> 1     T Base       Pub     1000 1.50      0.80
#> 2     S Base       Pub      500 1.62      0.80
#> 3     Y Base       Pub      500 2.43      0.75
#> 4     K Base       Pub      500 1.93      0.80
#> 5     J Base       Pub      500 3.40      0.80

下面的代码将执行等于 dt

中的行数的迭代
lapply(seq(nrow(dt)), function(.x) nloptr(x0 = rep(0.45,5), 
                                      eval_f = function(x) sum(dt$VC * dt$Capacity * x)/sum(dt$Capacity * x), 
                                      lb=c(rep(0.40,5)), 
                                      ub = dt$Target, 
                                      eval_g_eq = function(x) sum(dt$Capacity * x) - demand[.x] , 
                                      opts = list( "algorithm"= "NLOPT_GN_ISRES",
                                                   "xtol_rel"= 1.0e-15,
                                                   "maxeval"= 160000,
                                                   "local_opts" = list("algorithm" = "NLOPT_LD_MMA", 
                                                                       "xtol_rel" = 1.0e-15 ),
                                                   "print_level" = 0 ) 
                                      )
       )

它的输出将是

#> [[1]]
#> 
#> Call:
#> nloptr(x0 = rep(0.45, 5), eval_f = function(x) sum(dt$VC * dt$Capacity * 
#>     x)/sum(dt$Capacity * x), lb = c(rep(0.4, 5)), ub = dt$Target, 
#>     eval_g_eq = function(x) sum(dt$Capacity * x) - demand[.x], 
#>     opts = list(algorithm = "NLOPT_GN_ISRES", xtol_rel = 1e-15, 
#>         maxeval = 160000, local_opts = list(algorithm = "NLOPT_LD_MMA", 
#>             xtol_rel = 1e-15), print_level = 0))
#> 
#> 
#> Minimization using NLopt version 2.4.2 
#> 
#> NLopt solver status: 5 ( NLOPT_MAXEVAL_REACHED: Optimization stopped because 
#> maxeval (above) was reached. )
#> 
#> Number of Iterations....: 160000 
#> Termination conditions:  xtol_rel: 1e-15 maxeval: 160000 
#> Number of inequality constraints:  0 
#> Number of equality constraints:    1 
#> Current value of objective function:  1.9506666666645 
#> Current value of controls: 0.7 0.4 0.4 0.4 0.4
#> 
#> 
#> 
#> [[2]]
#> 
#> Call:
#> nloptr(x0 = rep(0.45, 5), eval_f = function(x) sum(dt$VC * dt$Capacity * 
#>     x)/sum(dt$Capacity * x), lb = c(rep(0.4, 5)), ub = dt$Target, 
#>     eval_g_eq = function(x) sum(dt$Capacity * x) - demand[.x], 
#>     opts = list(algorithm = "NLOPT_GN_ISRES", xtol_rel = 1e-15, 
#>         maxeval = 160000, local_opts = list(algorithm = "NLOPT_LD_MMA", 
#>             xtol_rel = 1e-15), print_level = 0))
#> 
#> 
#> Minimization using NLopt version 2.4.2 
#> 
#> NLopt solver status: 5 ( NLOPT_MAXEVAL_REACHED: Optimization stopped because 
#> maxeval (above) was reached. )
#> 
#> Number of Iterations....: 160000 
#> Termination conditions:  xtol_rel: 1e-15 maxeval: 160000 
#> Number of inequality constraints:  0 
#> Number of equality constraints:    1 
#> Current value of objective function:  1.893 
#> Current value of controls: 0.8 0.8 0.4 0.8 0.4
#> 
#> 
#> 
#> [[3]]
#> 
#> Call:
#> nloptr(x0 = rep(0.45, 5), eval_f = function(x) sum(dt$VC * dt$Capacity * 
#>     x)/sum(dt$Capacity * x), lb = c(rep(0.4, 5)), ub = dt$Target, 
#>     eval_g_eq = function(x) sum(dt$Capacity * x) - demand[.x], 
#>     opts = list(algorithm = "NLOPT_GN_ISRES", xtol_rel = 1e-15, 
#>         maxeval = 160000, local_opts = list(algorithm = "NLOPT_LD_MMA", 
#>             xtol_rel = 1e-15), print_level = 0))
#> 
#> 
#> Minimization using NLopt version 2.4.2 
#> 
#> NLopt solver status: 5 ( NLOPT_MAXEVAL_REACHED: Optimization stopped because 
#> maxeval (above) was reached. )
#> 
#> Number of Iterations....: 160000 
#> Termination conditions:  xtol_rel: 1e-15 maxeval: 160000 
#> Number of inequality constraints:  0 
#> Number of equality constraints:    1 
#> Current value of objective function:  1.92181376479112 
#> Current value of controls: 0.7883007 0.7815353 0.583928 0.7845948 0.4043761
#> 
#> 
#> 
#> [[4]]
#> 
#> Call:
#> nloptr(x0 = rep(0.45, 5), eval_f = function(x) sum(dt$VC * dt$Capacity * 
#>     x)/sum(dt$Capacity * x), lb = c(rep(0.4, 5)), ub = dt$Target, 
#>     eval_g_eq = function(x) sum(dt$Capacity * x) - demand[.x], 
#>     opts = list(algorithm = "NLOPT_GN_ISRES", xtol_rel = 1e-15, 
#>         maxeval = 160000, local_opts = list(algorithm = "NLOPT_LD_MMA", 
#>             xtol_rel = 1e-15), print_level = 0))
#> 
#> 
#> Minimization using NLopt version 2.4.2 
#> 
#> NLopt solver status: 5 ( NLOPT_MAXEVAL_REACHED: Optimization stopped because 
#> maxeval (above) was reached. )
#> 
#> Number of Iterations....: 160000 
#> Termination conditions:  xtol_rel: 1e-15 maxeval: 160000 
#> Number of inequality constraints:  0 
#> Number of equality constraints:    1 
#> Current value of objective function:  1.93672658072513 
#> Current value of controls: 0.7870349 0.7534322 0.6660887 0.770566 0.4118776
#> 
#> 
#> 
#> [[5]]
#> 
#> Call:
#> nloptr(x0 = rep(0.45, 5), eval_f = function(x) sum(dt$VC * dt$Capacity * 
#>     x)/sum(dt$Capacity * x), lb = c(rep(0.4, 5)), ub = dt$Target, 
#>     eval_g_eq = function(x) sum(dt$Capacity * x) - demand[.x], 
#>     opts = list(algorithm = "NLOPT_GN_ISRES", xtol_rel = 1e-15, 
#>         maxeval = 160000, local_opts = list(algorithm = "NLOPT_LD_MMA", 
#>             xtol_rel = 1e-15), print_level = 0))
#> 
#> 
#> Minimization using NLopt version 2.4.2 
#> 
#> NLopt solver status: 5 ( NLOPT_MAXEVAL_REACHED: Optimization stopped because 
#> maxeval (above) was reached. )
#> 
#> Number of Iterations....: 160000 
#> Termination conditions:  xtol_rel: 1e-15 maxeval: 160000 
#> Number of inequality constraints:  0 
#> Number of equality constraints:    1 
#> Current value of objective function:  1.93152444911471 
#> Current value of controls: 0.795248 0.7687759 0.6712354 0.7692782 0.4034175