使用R中的约束优化曲线组合

时间:2015-01-08 22:37:07

标签: r optimization nonlinear-optimization

我不熟悉求解器(优化),我想找到最大化非线性函数的x1和x2的最佳值。

a1 = 0.000176
b1 = 26.51410219
a2 = 0.0000403
b2 = 158.4966186
max
   fn = (b1*(1-exp(-a1*x1))+(b2*(1-exp(-a2*x2)))
Subject to
x1 + x2 <=20000
x1 <=15000
x2 >= 9000

如果我要在excel中这样做(我想在这种情况下使用R),我得到以下值; fn = 152,x1 = 5695,x2 = 14305。 我查看了quadprog软件包,但是我无法正常工作。 我真的很感激你能提供的任何帮助。

2 个答案:

答案 0 :(得分:2)

我认为你需要另一个关闭表达式才能最大化。目前还不清楚你是否想要f​​n或fn2:

fn = function(x1,x2){  (b1*(1-exp(-a1*x1))) + (b2*(1-exp(-a2*x2)))  }
fn2 = function(x1,x2){ (b1*(1-exp(-a1*x1)) + (b2*(1-exp(-a2*x2)))) }

施加约束的一种方法是在边界处减去大值:

optim(par=list(10000, 10000), fn=function(x){ 
              # starting values inside constraint boundaries
          ( b1*(1-exp(-a1*x[1]))+(b2*(1-exp(-a2*x[2]))) - 
               200000*( ( x[1]+x[2])> 20000) -
               200000*(x[1]>15000) - 
               200000*(x[2] < 9000) )},
           control=list(fnscale=-1) #  to make max
       )

#---------

$par
[1]  2215.306 17784.694

$value
[1] 89.65546

$counts
function gradient 
     197       NA 

$convergence
[1] 0

$message
NULL

> 2215.306 + 17784.694
[1] 20000

你可以看到fn2我建议的R方法优于Excel结果:

> fn2( x1 = 5695 , x2 = 14305)
[1] 86.22543
> fn2(2215.306 , 17784.694)
[1] 89.65546

也可以对敏感度进行图形检查,将值设置在边界之外会抑制图中的外观:

vals <- outer(X=seq(5000,20000,by=1000), Y=seq(5000,20000,by=1000), FUN=function(x,y) ( b1*(1-exp(-a1*x))+(b2*(1-exp(-a2*y))) ) )
 constr1 <- outer(X=seq(5000,20000,by=1000), Y=seq(5000,20000,by=1000), FUN=function(x,y) ( x+y >20000 ) )
 constr2 <- outer(X=seq(5000,20000,by=1000), Y=seq(5000,20000,by=1000), FUN=function(x,y) ( x >15000 ) )
 constr3 <- outer(X=seq(5000,20000,by=1000), Y=seq(5000,20000,by=1000), FUN=function(x,y) ( y < 9000 ) )
 vals[constr1] <- NA
 vals[constr2] <- NA
 vals[constr3] <- NA
 persp(x=seq(5000,20000,by=1000), y=seq(5000,20000,by=1000),z=vals,ticktype="detailed", las=3,ylab="",theta=-45)

enter image description here

答案 1 :(得分:0)

使用constrOptim可以获得类似的结果,但是约束应该具有Ax&gt; = b的形式。

fn = function(x){
  (26.51410219*(1-exp(-0.000176*x[1]))) + (158.4966186*(1-exp(-0.0000403*x[2])))
  }

将约束重写为

 x1 +x2 <=20000 --> -x1 –x2 >= -20000
 x1 <= 15000 --> -x1 >= -15000
 x2 >= 9000
 A = matrix(c(-1,-1,-1,0,0,1),nrow=3,byrow=T)
 b = c(-20000,-15000,9000)

 constrOptim(c(5000,10000),fn,NULL,A,b,control=list(fnscale=-1))
$par
[1]  2275.632 17724.367
$value
[1] 89.65666