更新:对于访问此页面的其他任何人,值得看看这个 SO 问题和答案,因为我怀疑那里的解决方案与我在这里遇到的问题有关。
这个问题与我在julia-users mailing list上提出的问题重复,但我还没有在那里得到回复(诚然只有 4 天),所以我想我会在这里问。
我从 Julia 调用 NLopt API,尽管我认为我的问题与 Julia 语言无关。
我正在尝试使用 COBYLA 解决优化问题,但在许多情况下我未能触发停止标准。我的问题相当复杂,但我可以用一个更简单的例子重现问题行为。
具体来说,我尝试x1^2 + x2^2 + 1
使用 COBYLA 最小化,并将两者都ftol_rel
设置ftol_abs
为0.5
. 我的目标函数包括一个将当前值打印到控制台的语句,因此我可以观察收敛情况。收敛期间打印到控制台的最后五个值是:
1.161
1.074
1.004
1.017
1.038
我的理解是,这些步骤中的任何一个都应该触发停止标准。所有步骤都小于0.5
,所以应该触发ftol_abs
。此外,每个值大约是1
,并且0.5*1 = 0.5
,因此所有步骤也应该触发ftol_rel
。事实上,收敛例程中的最后 8 个步骤也是如此。
NLopt 已经存在了一段时间,所以我猜问题在于我对如何ftol_abs
和ftol_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])