为了解决运输问题或网络建模问题,线性编程就足够了。
但是,根据当前的主题,在考虑非线性的其他约束或目标时,非线性编程可能会变得很重要。
R提供了一个解决非线性问题的程序包:nloptr
在这篇文章中,我将应用nloptr包来解决下面的非线性优化问题,应用梯度下降方法。梯度下降算法寻找最陡变化的方向,即最大或最小一阶导数的方向。逻辑是,如果我继续朝着最陡的下降方向前进,那么我将迅速朝着自己的最优方向发展。
手头的问题:
重要说明:当使用nloptr建模非线性问题时,必须将问题陈述为最小化问题,并且所有不等式约束的类型都必须小于等于0(小于)。该函数可以处理相等约束,因此您不必通过重叠不相等约束来替换它们。允许对变量进行框约束,这可以由nloptr求解器考虑。但是,应该选择一个起点。
我使用R中的nloptr包(带有nloptr函数!)对梯度下降建模并解决了这个问题:
#加载包
library(nloptr)
#定义要优化的功能
eval_f <- function(x){
return(
list(
"objective"=x[1]^2+x[2]^2,
"gradient"=c(2*x[1],
2*x[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....: 102
## Termination conditions: xtol_rel: 1e-07 maxeval: 1000
## Number of inequality constraints: 1
## Number of equality constraints: 0
## Optimal value of objective function: 1.09462903864043e-94
## Optimal value of controls: -7.398071e-48 -7.398071e-48
专业领域为优化和仿真的工业工程师(R,Python,SQL,VBA)
Leave a Reply