在非线性优化函数`nloptr`中传递参数

mm4*_*441 5 r mathematical-optimization nonlinear-optimization

我的初始问题可以在这里找到:R中的任意约束优化

它引发了另一个问题,如何传递参数nloptr.
我需要最小化函数F(x,y,A),其中x和y是向量并且A是矩阵,同时具有约束sum(x * y) >= sum(y/3)sum(x)=1.我试过用nloptr:

F <- function(x,y,A){
   ...
}

Gc <- function(x,y){
  return(sum(y/3) - sum(x*y))
} 

Hc <- function(x){
  retunr(1-sum(x))
}

nloptr(x0=rep(1/3,3), eval_f=F, lb = 0.05, ub = 1, eval_g_ineq = Gc, eval_g_eq = Hc, opts = list(), y=y, A=A)
Run Code Online (Sandbox Code Playgroud)

我收到一个错误: 'A' passed to (...) in 'nloptr' but this is not required in the eval_g_ineq function.

如果我说 nloptr( ... , y, A)

我明白了:eval_f requires argument 'cov.mat' but this has not been passed to the 'nloptr' function.

任何建议都会很棒.谢谢

jlh*_*ard 7

所以这里有几件事情:

首先,目标函数,F等式约束函数Hc和不等式约束函数Gc都必须采用相同的参数.所以传递x, y, A给所有三个,只是忽略它们不需要的地方.

其次,你必须定义yA地方...

第三,您必须指定要使用的算法.这样做opts=list(algoritm=...).事实证明,如果你是(a)使用约束,(b)提供计算雅可比矩阵的函数,那么只有一些算法是合适的.在你的情况下opts=list(algorithm="NLOPT_GN_ISRES")似乎工作.

最后,默认情况maxeval = 100结果还不够.我不得不将其设置为100,000以获得收敛.

把这一切放在一起,虽然有一个弥补的目标函数:

F <- function(x,y,A){  # made-up function
  # minimize scaled distance between points x and y
  sum((A[1]*x-A[2]*y)^2)
}
Gc <- function(x,y,A) return(sum(y/3) - sum(x*y))
Hc <- function(x,y,A) return(1-sum(x))

library(nloptr)
y= c(0,1,0)
A= c(10,1)
opt <- nloptr(x0=rep(1/3,3), eval_f=F, lb = rep(0.05,3), ub = rep(1,3), 
              eval_g_ineq = Gc, eval_g_eq = Hc, 
              opts = list(algorithm="NLOPT_GN_ISRES",maxeval=100000), y=y, A=A)
opt$solution
# [1] 0.2990463 0.4004237 0.3005300
Run Code Online (Sandbox Code Playgroud)