使用nloptr软件包可以更灵活地定义目标

时间:2019-03-13 16:18:00

标签: r

我正在使用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)
    }

我尝试过,但是有一个错误。

1 个答案:

答案 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

hin的工厂

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