具有等式和不等式约束的 R 优化 [英] R optimization with equality and inequality constraints

查看:30
本文介绍了具有等式和不等式约束的 R 优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一个函数的局部最小值,并且参数有一个固定的总和.例如,

Fx = 10 - 5x1 + 2x2 - x3

条件如下,

x1 + x2 + x3 = 15

(x1,x2,x3) >= 0

其中 x1、x2 和 x3 的总和具有已知值,并且它们都大于零.在 R 中,它看起来像这样,

Fx = function(x) {10 - (5*x[1] + 2*x[2] + x[3])}opt = optim(c(1,1,1), Fx, method = "L-BFGS-B", lower=c(0,0,0), upper=c(15,15,15))

我还尝试在 constrOptim 中使用不等式来强制求和固定.我仍然认为这可能是一个合理的解决方法,但我无法让它发挥作用.这是实际问题的简化示例,但非常感谢您的帮助.

解决方案

在这种情况下 optim 显然不起作用,因为您有等式约束.由于同样的原因,constrOptim 也不会起作用(我尝试将等式转换为两个不等式,即大于和小于 15,但这对 constrOptim 不起作用).

但是,有一个专门用于解决此类问题的软件包,即 Rsolnp.

您可以通过以下方式使用它:

#指定你的功能opt_func <- 函数(x){10 - 5*x[1] + 2 * x[2] - x[3]}#指定等式函数.数字 15(函数等于)#被指定为附加参数等于 <- 函数(x){x[1] + x[2] + x[3]}#the optimiser - 默认最小化solnp(c(5,5,5), #starting values (random - 显然需要是正数并且总和为15)opt_func, #优化函数eqfun=equal, #equality 函数eqB=15, #等式约束LB=c(0,0,0), #参数的下限,即大于零UB=c(100,100,100)) #参数上限(我只是随机选了100个)

输出:

>解决方案(c(5,5,5),+ opt_func,+ eqfun=相等,+ eqB=15,+ LB=c(0,0,0),+ UB=c(100,100,100))Iter: 1 fn: -65.0000 Pars: 14.99999993134 0.00000002235 0.00000004632Iter: 2 fn: -65.0000 Pars: 14.999999973563 0.000000005745 0.000000020692解决方案-->2次迭代完成$pars[1] 1.500000e+01 5.745236e-09 2.069192e-08$收敛[1] 0$值[1] -10 -65 -65$拉格朗日[,1][1,] -5$黑森州[,1] [,2] [,3][1] 121313076 121313076 121313076[2] 121313076 121313076 121313076[3] 121313076 121313076 121313076$ineqx0空值$nfuneval[1] 126$outer.iter[1] 2$elapsed0.1770101秒的时间差$vscale[1] 6.5e+01 1.0e-08 1.0e+00 1.0e+00 1.0e+00

所以得到的最优值是:

$pars[1] 1.500000e+01 5.745236e-09 2.069192e-08

这意味着第一个参数是 15,其余的零和零.这确实是您函数中的全局最小值,因为 x2 正在添加到函数中,并且 5 * x1 对结果的(负面)影响比 x3 大得多(负面).15, 0, 0的选择是函数根据约束的解和全局最小值.

这个功能很好用!

I am trying to find the local minimum of a function, and the parameters have a fixed sum. For example,

Fx = 10 - 5x1 + 2x2 - x3

and the conditions are as follows,

x1 + x2 + x3 = 15

(x1,x2,x3) >= 0

Where the sum of x1, x2, and x3 have a known value, and they are all greater than zero. In R, it would look something like this,

Fx = function(x) {10 - (5*x[1] + 2*x[2] + x[3])}
opt = optim(c(1,1,1), Fx, method = "L-BFGS-B", lower=c(0,0,0), upper=c(15,15,15))

I also tried to use inequalities with constrOptim to force the sum to be fixed. I still think this may be a plausible work around, but I was unable to make it work. This is a simplified example of the real problem, but any help would be very appreciated.

解决方案

On this occasion optim will not work obviously because you have equality constraints. constrOptim will not work either for the same reason (I tried converting the equality to two inequalities i.e. greater and less than 15 but this didn't work with constrOptim).

However, there is a package dedicated to this kind of problem and that is Rsolnp.

You use it the following way:

#specify your function
opt_func <- function(x) {
  10 - 5*x[1] + 2 * x[2] - x[3]
}

#specify the equality function. The number 15 (to which the function is equal)
#is specified as an additional argument
equal <- function(x) {
  x[1] + x[2] + x[3] 
}

#the optimiser - minimises by default
solnp(c(5,5,5), #starting values (random - obviously need to be positive and sum to 15)
      opt_func, #function to optimise
      eqfun=equal, #equality function 
      eqB=15,   #the equality constraint
      LB=c(0,0,0), #lower bound for parameters i.e. greater than zero
      UB=c(100,100,100)) #upper bound for parameters (I just chose 100 randomly)

Output:

> solnp(c(5,5,5),
+       opt_func,
+       eqfun=equal,
+       eqB=15,
+       LB=c(0,0,0),
+       UB=c(100,100,100))

Iter: 1 fn: -65.0000     Pars:  14.99999993134  0.00000002235  0.00000004632
Iter: 2 fn: -65.0000     Pars:  14.999999973563  0.000000005745  0.000000020692
solnp--> Completed in 2 iterations
$pars
[1] 1.500000e+01 5.745236e-09 2.069192e-08

$convergence
[1] 0

$values
[1] -10 -65 -65

$lagrange
     [,1]
[1,]   -5

$hessian
          [,1]      [,2]      [,3]
[1,] 121313076 121313076 121313076
[2,] 121313076 121313076 121313076
[3,] 121313076 121313076 121313076

$ineqx0
NULL

$nfuneval
[1] 126

$outer.iter
[1] 2

$elapsed
Time difference of 0.1770101 secs

$vscale
[1] 6.5e+01 1.0e-08 1.0e+00 1.0e+00 1.0e+00

So the resulting optimal values are:

$pars
[1] 1.500000e+01 5.745236e-09 2.069192e-08

which means that the first parameter is 15 and the rest zero and zero. This is indeed the global minimum in your function since the x2 is adding to the function and 5 * x1 has a much greater (negative) influence than x3 on the outcome. The choice of 15, 0, 0 is the solution and the global minimum to the function according to the constraints.

The function worked great!

这篇关于具有等式和不等式约束的 R 优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆