淘先锋技术网

首页 1 2 3 4 5 6 7

若目标函数或约束条件中含有自变量的非线性函数,则这样的规划问题就属于非线性规划。这里简单介绍4种情况下非线性规划的R语言实现。

无约束规划

无约束规划中没有约束条件,只需要对目标函数取极值。R语言的nloptr包默认求解的是极小值,因此若要求最大值只需加个负号就行。

以这个目标函数为例,我们求它的极大值
在这里插入图片描述

library(nloptr) 
eval_f = function(x){
  return(list('objective'=-(12*x-3*x^4-2*x^6),   #输入目标函数
              'gradient'=-c(12-12*x^3-12*x^5)))  #一阶导要手动算一下
}
res0 = nloptr(x0 = c(0),  #给x赋一个初值,优化算法会不断迭代
              eval_f = eval_f,
              lb = c(-Inf),  #下界是负无穷
              ub = c(Inf),   #上界是正无穷
              opts = list('algorithm'='NLOPT_LD_LBFGS'))
res0$solution

输出的结果是x的值,为局部最优
在这里插入图片描述
但由于这是一个凸规划,任何局部最优解也是其全局最优解。

只含不等式约束的规划

在这里插入图片描述
在用R语言求解时,需要加上约束条件的方程,默认的不等式约束条件是小于等于0。还要给出雅各比矩阵,即变量的一阶偏导矩阵。

eval_f = function(x){
  return(list('objective'=-(3*x[1]+5*x[2]),
              'gradient'=c(-3,-5)))
}

eval_g = function(x){
  return(list('constraints' = c(8*x[1]-x[1]^2+14*x[2]-x[2]^2-49,x[1]-4),
              'jacobian' = rbind(c(8-2*x[1],14-2*x[2]),c(1,0))))
}

res1 = nloptr(x0 = c(0,0),
              eval_f = eval_f,
              lb = c(0,0),
              ub = c(4,Inf),
              eval_g_ineq = eval_g,
              opts = list('algorithm'='NLOPT_LD_MMA'))
res1$solution  

这样求出来的结果也是局部最优,若改变初始值,结果可能就不一样了。

系数可变的规划

在这种情况下,约束条件中的系数是可变的

题目如下

# min sqrt( x2 )
# s.t. x2 >= 0
#      x2 >= ( a1*x1 + b1 )^3
#      x2 >= ( a2*x1 + b2 )^3
# where
# a1 = 2, b1 = 0, a2 = -1, b2 = 1

求解过程如下

a = c(2,-1)
b = c(0,1)
eval_f = function(x,a,b){
  return(list('objective'=sqrt(x[2]),
              'gradient'=c(0,1/(2*sqrt(x[2])))))
}
eval_g = function(x,a,b){
  return(list('constraints' = c((a[1]*x[1]+b[1])^3-x[2],
                               (a[2]*x[1]+b[2])^3-x[2]),
              'jacobian' = rbind(c(3*a[1]*(a[1]*x[1]+b[1])^2,-1),
                                 c(3*a[2]*(a[2]*x[1]+b[2])^2,-1))))
}
res2 = nloptr(x0 = c(1.234,5.678),
              eval_f = eval_f,
              lb = c(-Inf,0),
              ub = c(Inf,Inf),
              eval_g_ineq = eval_g,
              opts = list('algorithm'='NLOPT_LD_MMA'),
              a = a, b = b)
res2$solution

约束条件含等式的规划

等式约束需单独用一个函数写进去,同样要写出相应的雅各比矩阵

题目如下

#min x1^2 + x2^2 + 8
#s.t. x1^2 - x2 >= 0
#   -x1 - x2^2 + 2 = 0
#   x1, x2 >= 0

求解过程如下

eval_f = function(x){
  return(list('objective'=x[1]^2 + x[2]^2 + 8,
              'gradient'=c(2*x[1],2*x[2])))
}
eval_g = function(x){
  return(list('constraints' = c(x[2]-x[1]^2),
              'jacobian' = rbind(c(-2*x[1],1))))
}
eval_h = function(x){
  return(list('constraints' = c(-x[1]-x[2]^2+2),
              'jacobian' = rbind(c(-1,-2*x[2]))))
}
res3 = nloptr(x0 = c(2,0),
              eval_f = eval_f,
              lb = c(0,0),
              ub = c(Inf,Inf),
              eval_g_ineq = eval_g,
              eval_g_eq = eval_h,
              opts = list('algorithm'='NLOPT_LD_SLSQP'))
res3$solution