我的初步问题可以在这里找到:Optimization in R with arbitrary constraints
它引发了另一个问题,即如何将参数传递给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)
我收到一个错误:
'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.
任何建议都会很棒。感谢
答案 0 :(得分:7)
所以这里有几件事情发生了:
首先,目标函数F
,等式约束函数Hc
和不等式约束函数Gc
都必须采用相同的参数。所以将x, y, A
传递给所有三个,并在不需要的地方忽略它们。
其次,你必须在某处定义y
和A
......
第三,您必须指定要使用的算法。使用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