NLopt中ftol_abs和ftol_rel的意外行为

时间:2016-01-12 23:17:21

标签: julia nlopt

更新:对于访问此页面的任何其他人,值得查看this SO question and answer,因为我怀疑解决方案与我在这里遇到的问题有关。

这个问题与我在julia-users mailing list上提出的问题重复,但我没有在那里得到答复(诚然只有4天),所以我想在这里问。

我正在调用Julia的NLopt API,虽然我认为我的问题独立于Julia语言。

我正在尝试使用COBYLA解决优化问题,但在很多情况下我无法触发停止标准。我的问题相当复杂,但我可以通过一个更简单的例子来重现问题行为。

具体来说,我尝试使用COBYLA最小化x1^2 + x2^2 + 1,并将ftol_relftol_abs设置为0.5。我的目标函数包括一个语句,用于将当前值打印到控制台,因此我可以观察收敛。收敛期间打印到控制台的最后五个值是:

1.161
1.074
1.004
1.017
1.038

我的理解是,任何这些步骤都应该触发停止标准。所有步骤都小于0.5,因此应触发ftol_abs。此外,每个值大约为10.5*1 = 0.5,因此所有步骤也应该已触发ftol_rel。事实上,这种行为适用于收敛例程的最后8个步骤。

NLopt已经存在了一段时间,所以我猜测问题在于我对ftol_absftol_rel如何工作的理解,而不是一个错误。

任何人都可以解释为什么停止标准不会更早被触发?

如果有任何用处,可以使用以下Julia代码段重现我刚才所说的所有内容:

using NLopt
function objective_function(param::Vector{Float64}, grad::Vector{Float64})
    obj_func_value = param[1]^2 + param[2]^2 + 1.0
    println("Objective func value = " * string(obj_func_value))
    println("Parameter value = " * string(param))
    return(obj_func_value)
end
opt1 = Opt(:LN_COBYLA, 2)
lower_bounds!(opt1, [-10.0, -10.0])
upper_bounds!(opt1, [10.0, 10.0])
ftol_rel!(opt1, 0.5)
ftol_abs!(opt1, 0.5)
min_objective!(opt1, objective_function)
(fObjOpt, paramOpt, flag) = optimize(opt1, [9.0, 9.0])

1 个答案:

答案 0 :(得分:1)

据推测,android:layout_above="@+id/form" ftol_rel应该提供数字保证错误。较早的值足够接近但算法可能无法保证它。例如,评估点处的梯度或Hessian可能提供这样的数值保证。所以,它会继续下去。

可以肯定的是,最好查看优化算法源。如果我管理这个,我会把它添加到这个答案。

更新:COBYLA算法使用多个评估点以数字方式近似梯度(矢量导数)。如上所述,这用于模拟错误可能是什么。错误实际上可以在数学上保证仅适用于限制在一些不错的家庭中的函数(例如,具有某种程度限制的多项式)。

带回家留言:没关系。不是错误,但算法可以做到最好。让它有那些额外的迭代。