我正在使用nloptr
软件包,并且一切正常。但是我需要一种更快地定义目标函数和约束的方法。我不能每次都手动写所有设置。
例如,我要解决此问题:
library(nloptr)
eval_f <- function(x){
return(x[4]^2+x[7]^2+x[9]^2)
}
x0 = c(1,1,1,1,0.5,0,0.5,1,0)
hin <- function(x){
h <- numeric(6)
h[1] = x[1]+x[4]-x[2]-x[5]-0.01
h[2] = x[1]+x[4]-x[3]-x[6]-0.01
h[3] = x[2]+x[5]-x[3]-x[6]-0.01
h[4] = x[2]+x[8]-x[1]-x[7]-0.01
h[5] = x[2]+x[8]-x[3]-x[9]-0.01
h[6] = x[1]+x[7]-x[3]-x[9]-0.01
return(h)
}
heq <- function(x){
h <- numeric(1)
h[1] <- x[1]+x[2]+x[3]-3
return(h)
}
res <- slsqp(x0=x0,fn=eval_f,hin = hin,heq = heq)
一切正常。 但是我想以更快的方式定义目标函数。我可以自动将另一个参数(索引)传递给函数吗?例如:
eval_f <- function(x,indices){
return(x[indices]^2)
}
我尝试过,但是有一个错误。
答案 0 :(得分:1)
...
的{{1}}参数允许您将任意参数传递给目标函数。因此,定义一个以slsqp
作为参数的新目标函数:
indices
...并包括eval_f2 <- function(x,indices){
return(sum(x[indices]^2))
}
(以匹配先前目标函数的定义):
indices=c(4,7,9)
检查解决方案:
res2 <- slsqp(x0=x0,fn=eval_f2, hin = hin,heq = heq, indices=c(4,7,9))
更一般地,您可以定义 factory -返回函数的函数。之所以行之有效,是因为函数具有关联的环境,其中可以存储变量(例如索引)。即使在顶层函数不允许传递任意参数的情况下,这也将起作用(例如,如果要为目标函数和约束函数使用不同个索引集,则可能很重要) ...)
all.equal(res$par,res2$par) ## TRUE
eval_factory <- function(indices) {
fun <- function(x) {
return(sum(x[indices]^2))
}
return(fun)
}
res3 <- slsqp(x0=x0, fn=eval_factory(indices=c(4,7,9)),
hin = hin,heq = heq)
all.equal(res$par,res3$par) ## TRUE