使用 optimx 进行非线性约束优化

Nonlinear constrained optimization with optimx

我正在尝试将 optimx 用于受约束的非线性问题,但我无法在网上找到可以调整的示例(我不是 R 程序员)。我发现我应该使用下面的来测试一些算法

optimx(par, fn, lower=low, upper=up, method=c("CG", "L-BFGS-B", "spg", "nlm"))

我明白par只是一个可行方案的例子。所以,如果我有两个变量并且 (0,3) 是可行的,我可以只做 par <- c(0,3)。如果我想最小化

2x+3y 

受制于

2x^2 + 3y^2 <= 100
x<=3
-x<=0
-y<=-3

我想我可以像这样设置 fn

fn <- function(x){return 2*x[0]+3*x[1]}

但是如何为我的约束设置下限和上限?

非常感谢!

1) 我们可以将约束合并到 objective 函数中,方法是在违反任何约束时返回一个大数字。

对于大多数方法(但 Nelder Mead 除外),要求 objective 函数是连续的和可微的,并且需要在可行区域的内部而不是边界的起始值。下面的 f 不满足这些要求,但我们还是会尝试的。

library(optimx)

f <- function(z, x = z[1], y = z[2]) {
  if (2*x^2 + 3*y^2 <= 100 && x<=3 && -x<=0 && -y<=-3) 2*x+3*y else 1e10
}

optimx(c(0, 3), f, method = c("Nelder", "CG", "L-BFGS-B", "spg", "nlm"))
##             p1 p2 value fevals gevals niter convcode  kkt1  kkt2 xtime
## Nelder-Mead  0  3     9    187     NA    NA        0 FALSE FALSE  0.00
## CG           0  3     9     41      1    NA        0 FALSE FALSE  0.00
## L-BFGS-B     0  3     9     21     21    NA       52 FALSE FALSE  0.00
## spg          0  3     9   1077     NA     1        0 FALSE FALSE  0.05
## nlm          0  3     9     NA     NA     1        0 FALSE FALSE  0.00

1a) 这也适用于 optim,其中 Nelder Mead 是默认设置(或者您可以尝试明确支持不等式约束的 constrOptim)。

optim(c(0, 3), f)
## $par
## [1] 0 3
## 
## $value
## [1] 9
##
## $counts
## function gradient 
##      187       NA 

$convergence
[1] 0

$message
NULL

2) 上面我们注意到 2x^2 + 3y^2 <= 100 约束不活跃所以我们可以放下它。现在,由于 objective 函数在 x 和 y 中独立增加,很明显我们想将它们都设置为它们的下限,所以 c(0, 3) 就是答案。

如果我们无论如何都想使用 optimx,那么我们只需为那些使用它们的方法使用 upper= 和 lower= 参数。

f2 <- function(z, x = z[1], y = z[2]) 2*x+3*y
optimx(c(0, 3), f2, lower = c(0, 3), upper = c(3, Inf), 
  method = c("L-BFGS-B", "spg", "nlm"))
##          p1 p2 value fevals gevals niter convcode  kkt1 kkt2 xtime
## L-BFGS-B  0  3     9      1      1    NA        0 FALSE   NA  0.00
## spg       0  3     9      1     NA     0        0 FALSE   NA  0.01
## nlminb    0  3     9      1      2     1        0 FALSE   NA  0.00
## Warning message:
## In BB::spg(par = par, fn = ufn, gr = ugr, lower = lower, upper = upper,  :
##   convergence tolerance satisified at intial parameter values.