从R中的nloptr获得中间结果

时间:2015-10-21 01:24:42

标签: r mathematical-optimization

我在nloptr中运行R包,但无法获得算法的中间结果。算法运行正常,但我不想要最终的解决方案和迭代次数,而是希望能够在每次迭代时获得异议函数的当前值。这是我正在使用的代码

library(tgp)
library(nloptr)

#########################################################################################
### 
#########################################################################################

f = function(x){
    ans = cos(pi*(x[1]+x[2]*x[3]+x[4]))+.2*sin(4*pi*(x[5]*x[6]+x[7])/(x[8]+1))
    return(ans)
}

const = function(x){
    ans = numeric(2)
    ans[1] = sin(pi*(x[1]+x[2]*x[3]+x[4]))+.2*cos(4*pi*(x[5]*x[6]+x[7])/(x[8]+1))
    ans[2] = -cos(pi*(x[1]+x[2]*x[3]+x[4]))+.2*cos(4*pi*(x[5]*x[6]+x[7])/(x[8]+1))
    ans[1] = -ans[1]
    ans[2] = -ans[2]
    return(ans)
}

#########################################################################################
###
#########################################################################################

lhs.size = 1
lhs.lower = 0
lhs.upper = 1
x0 = c(lhs(lhs.size,rbind(c(lhs.lower,lhs.upper),c(lhs.lower,lhs.upper),c(lhs.lower,lhs.upper),c(lhs.lower,lhs.upper),c(lhs.lower,lhs.upper),c(lhs.lower,lhs.upper),c(lhs.lower,lhs.upper),c(lhs.lower,lhs.upper))))

COB = cobyla(x0,f,hin=const,lower=rep(0,8),upper=rep(1,8),nl.info = TRUE, control = list(xtol_rel = 1e-16, maxeval = 2000))

所以对象COB给我的是:

> COB
$par
[1] 0.4209398 0.4932406 0.5175745 0.7786042 0.2980017 0.6785051 0.2313283 0.3872766

$value
[1] -0.2828427

$iter
[1] 559

$convergence
[1] 4

$message
[1] "NLOPT_XTOL_REACHED: Optimization stopped because xtol_rel or xtol_abs (above) was reached."

但是我希望每个$value都有$iteration

3 个答案:

答案 0 :(得分:3)

这是一种可能性。在另一个问题上,我定义了一组reap/sow函数,允许您通过不同的函数调用收集值。如果我定义一个名为" sower"

的辅助函数
sower <- function(f,n=deparse(substitute(f))) {
    function(...) {
        x <- f(...)
        do.call("sow", setNames(list(x),n))
        x
    }
}

包装一个函数并通过sow()收集它的输出,我可以在你的调用中使用它

rr <- reap(COB = cobyla(x0, sower(f), hin=sower(const), 
    lower=rep(0,8), upper=rep(1,8), nl.info = TRUE, 
    control = list(xtol_rel = 1e-16, maxeval = 2000)))

然后您可以获得标准返回值仍然在COB,但您也可以调用

rr$f
rr$const

每次调用函数时获取函数的值。 (同样,请确保包含在另一个函数的答案中定义的reap / sow函数。)

答案 1 :(得分:3)

您可以在代码的opts部分添加“print level = 3”。例如:

opts = list("algorithm"="NLOPT_LN_COBYLA",
        "xtol_rel"=1.0e-8, "maxeval"= 5000, 
        "print_level" = 3)

然后在调用算法时使用opts,即

result <- nloptr(my.data.var,eval_f = Error.func,
               lb=lb,ub=ub,
               eval_g_ineq=constraint.func,
               opts = opts) 

除了每次迭代的 参数外,这将为您提供 目标函数值

答案 2 :(得分:0)

我们可以在运行f之前随时发出此声明来跟踪cobyla。每次评估f时,都会显示目标值,后跟参数值。

trace(f, exit = quote(cat(returnValue(), x, "\n")))

删除跟踪:

untrace(f)

这是一个演示:

> f <- function(x) 2*x
> trace(f, exit = quote(cat(returnValue(), x, "\n")))
[1] "f"
> f(3)
Tracing f(3) on exit 
6 3 
[1] 6

> R.version.string
[1] "R version 3.2.2 Patched (2015-10-19 r69550)"

此外,在运行trace语句后运行问题中的COB(...)语句时,这是输出的最后一位:

Tracing f1(x, ...) on exit 
-0.7071068 0.9867454 0.9798806 0.9903225 0.7928568 0.9767687 0.6967606 0.6352815 0.05268439 
Tracing f1(x, ...) on exit 
-0.7071068 0.9867454 0.9798806 0.9903225 0.7928568 0.9767687 0.6967606 0.6352815 0.05268439 
Tracing f1(x, ...) on exit 
-0.7071068 0.9867454 0.9798806 0.9903225 0.7928568 0.9767687 0.6967606 0.6352815 0.05268439 
Tracing f1(x, ...) on exit 
-0.7071068 0.9867454 0.9798806 0.9903225 0.7928568 0.9767687 0.6967606 0.6352815 0.05268439 
Tracing f1(x, ...) on exit 
-0.7071068 0.9867454 0.9798806 0.9903225 0.7928568 0.9767687 0.6967606 0.6352815 0.05268439 

Call:
nloptr(x0 = x0, eval_f = fn, lb = lower, ub = upper, eval_g_ineq = hin,     opts = opts)


Minimization using NLopt version 2.4.0 

NLopt solver status: 5 ( NLOPT_MAXEVAL_REACHED: Optimization stopped because maxeval (above) was reached. )

Number of Iterations....: 2000 
Termination conditions:  stopval: -Inf  xtol_rel: 1e-16 maxeval: 2000   ftol_rel: 0     ftol_abs: 0 
Number of inequality constraints:  2 
Number of equality constraints:    0 
Current value of objective function:  -0.707106791132674 
Current value of controls: 0.9867454 0.9798806 0.9903225 0.7928568 0.9767687 0.6967606 0.6352815 0.05268439