【问题标题】:Optimizing a combination of curves with constraints in R在 R 中优化带有约束的曲线组合
【发布时间】:2015-03-07 04:44:33
【问题描述】:

我不熟悉求解器(优化),我想找到使非线性函数最大化的 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 软件包,但无法正常工作。 如果您能提供任何帮助,我将不胜感激。

【问题讨论】:

  • 你的约束是线性的,你可以通过提供梯度来使用 constrOptim。

标签: r optimization nonlinear-optimization


【解决方案1】:

使用 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

【讨论】:

    【解决方案2】:

    我认为您需要在该表达式中使用另一个右括号才能最大化。不清楚你是要 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
    

    您可以看到,对于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)
    

    【讨论】:

    • 感谢 BondedDust 的帮助,右括号不见了。
    • 所以你希望的是fn2? (那是我用的那个。)
    • 在上述解决方案中,将 x1 和 x2 替换为值 2215.306、17784.694 为 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(5695,14305) = [1] 86.22543。
    猜你喜欢
    • 2020-01-11
    • 2021-08-07
    • 1970-01-01
    • 2011-07-23
    • 2012-12-08
    • 2014-07-28
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多