【发布时间】:2016-03-25 17:13:14
【问题描述】:
我需要针对目标函数优化一组变量。我有函数的分析梯度,并想在优化例程中使用它。目标和梯度有一些共同的计算,我想以最有效的方式定义函数。下面的例子演示了这个问题。
让f_obj、f_grad 和f_common 分别是目标、梯度和普通计算的函数。优化在向量x 上。下面的代码找到多项式y^3 - 3*y^2 + 6*y + 1 的根,其中y 是c(x[1], x[2]) 的函数。请注意,函数f_common 在f_obj 和f_grad 中都被调用。在我的实际问题中,常见的计算要长得多,所以我正在寻找一种方法来定义f_obj 和f_grad,以便最大限度地减少对f_common 的调用次数。
f_common <- function(x) x[1]^3*x[2]^3 - x[2]
f_obj <- function(x) {
y <- f_common(x)
return ( (y^3 - 3*y^2 + 6*y + 1)^2 )
}
f_grad <- function(x) {
y <- f_common(x)
return ( 2 * (y^3 - 3*y^2 + 6*y + 1) * (3*y^2 - 6*y + 6)* c(3*x[1]^2*x[2]^3, 3*x[1]^3*x[2]^2 - 1) )
}
optim(par = c(100,100), fn = f_obj, gr = f_grad, method = "BFGS")
更新
我发现包nloptr 提供了将目标函数及其梯度作为列表输入的功能。有没有办法以类似的方式定义其他优化器(optim、optimx、nlminb 等)?
谢谢。
【问题讨论】:
-
你想要什么>?该代码有效。如果你想最小化 f_common 的调用,你不应该调用它,而是在函数中硬编码 y。
-
硬编码两个函数中的公共计算相当于调用 f_common(就执行时间而言)。我正在寻找一种消除冗余计算的方法。使用我的代码,如果优化例程是在
x点计算f_obj并在该点找到它的梯度,则需要调用f_common两次,但我们只需要计算一次y。 -
也许你可以使用像memoise这样的包来缓存
f_common的结果。
标签: r optimization