优化R中带约束的曲线组合

优化R中带约束的曲线组合,r,optimization,nonlinear-optimization,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 a1=0.000176 b1=26.51410219 a2=0.0000403

我不熟悉解算器(优化),我想找到使非线性函数最大化的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
a1=0.000176
b1=26.51410219
a2=0.0000403
b2=158.4966186
最大值
fn=(b1*(1-exp(-a1*x1))+(b2*(1-exp(-a2*x2)))
从属于

x1+x2我认为你需要在表达式中使用另一个闭包来最大化。不清楚你想要的是fn还是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
也可以对灵敏度进行图形检查,设置边界外的值会抑制绘图中的外观:

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)

vals使用constrOptim可以获得类似的结果,但是约束的形式应为Ax>=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
x1+x2-x1-x2>=-20000
x1-x1>=-15000
x2>=9000
A=矩阵(c(-1,-1,-1,0,0,1),nrow=3,byrow=T)
b=c(-20000,-150009000)
constrOptim(c(500010000),fn,NULL,A,b,control=list(fnscale=-1))
$par
[1]  2275.632 17724.367
美元价值
[1] 89.65666

您的约束是线性的,您可以通过提供梯度来使用constrOptim。感谢BondedDust的帮助,关闭参数丢失了。因此,您希望的是fn2?(这就是我使用的)。在上面的解决方案中,用值2215.306、17784.694替换x1和x2为fn=(b1*(1-exp(-a1*x1))+(b2*(1-exp(-a2*x2)))最大值为136。使用excel中的解算器,我能够得到fn=152,其中x1=5695,x2=14305。我希望R在最大化fn时会给出更好或类似的结果。我在这里遗漏了一些东西。抱歉,BondedDust,我是在寻找fn(不是fn2),但是我在代码中将fn2替换为fn时仍然得到了相同的结果。我得到了fn(569514305) = [1] 86.22543.
 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