R中的梯度下降,用于非线性优化(nloptr程序包)

为了解决运输问题或网络建模问题,线性编程就足够了。

但是,根据当前的主题,在考虑非线性的其他约束或目标时,非线性编程可能会变得很重要。

R提供了一个解决非线性问题的程序包:nloptr

在这篇文章中,我将应用nloptr包来解决下面的非线性优化问题,应用梯度下降方法。梯度下降算法寻找最陡变化的方向,即最大或最小一阶导数的方向。逻辑是,如果我继续朝着最陡的下降方向前进,那么我将迅速朝着自己的最优方向发展。

手头的问题:

重要说明:当使用nloptr建模非线性问题时,必须将问题陈述为最小化问题,并且所有不等式约束的类型都必须小于等于0(小于)。该函数可以处理相等约束,因此您不必通过重叠不相等约束来替换它们。允许对变量进行框约束,这可以由nloptr求解器考虑。但是,应该选择一个起点。

我使用R中的nloptr包(带有nloptr函数!)对梯度下降建模并解决了这个问题:

#加载包
library(nloptr)

#定义要优化的功能
eval_f <- function(x){
  return(
    list(
      "objective"=x[1]*x[2] - 2*x[1] - 2*x[2]+4,
      "gradient"=c(x[2]-2,
                   x[1]-2)
       )
  )
}

#定义表示不等式约束“ <= 0”的函数
eval_g_ineq <- function(x){
  return(
    list(
      "constraints"=x[1]+x[2]-100,
      "jacobian"=c(1,
                   1)
    )
  )
}

#定义起点
x_0 <- c(0,0)

#nloptr文档文件建议的其他设置
#这些设置,例如定义精确的优化算法
local_opts <- list( "algorithm" = "NLOPT_LD_MMA",
                    "xtol_rel"  = 1.0e-7 )

opts <- list( "algorithm" = "NLOPT_LD_AUGLAG",
              "xtol_rel"  = 1.0e-7,
              "maxeval"   = 1000,
              "local_opts" = local_opts )

#建模并解决问题
solution <- nloptr(x0=x_0,
                   eval_f=eval_f,
                   lb=NULL,
                   ub=NULL,
                   eval_g_ineq = eval_g_ineq,
                   eval_g_eq = NULL,
                   opts=opts)

现在让我们回顾一下优化结果:

print(solution)
## 
## Call:
## 
## nloptr(x0 = x_0, eval_f = eval_f, lb = NULL, ub = NULL, eval_g_ineq = eval_g_ineq, 
##     eval_g_eq = NULL, opts = opts)
## 
## 
## Minimization using NLopt version 2.4.2 
## 
## NLopt solver status: 3 ( NLOPT_FTOL_REACHED: Optimization stopped because 
## ftol_rel or ftol_abs (above) was reached. )
## 
## Number of Iterations....: 45 
## Termination conditions:  xtol_rel: 1e-07 maxeval: 1000 
## Number of inequality constraints:  1 
## Number of equality constraints:    0 
## Optimal value of objective function:  0 
## Optimal value of controls: 2 2

Leave a Reply

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Close

功能