使用 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.
我正在尝试将 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.