具有单变量优化的 NLopt

NLopt with univariate optimization

任何人都知道 NLopt 是否适用于单变量优化。尝试 运行 以下代码:

using NLopt

function myfunc(x, grad)
    x.^2
end

opt = Opt(:LD_MMA, 1)
min_objective!(opt, myfunc)
(minf,minx,ret) = optimize(opt, [1.234])
println("got $minf at $minx (returned $ret)")

但是得到以下错误信息:

> Error evaluating untitled
LoadError: BoundsError: attempt to access 1-element Array{Float64,1}:
1.234
at index [2]
in myfunc at untitled:8
in nlopt_callback_wrapper at /Users/davidzentlermunro/.julia/v0.4/NLopt/src/NLopt.jl:415
in optimize! at /Users/davidzentlermunro/.julia/v0.4/NLopt/src/NLopt.jl:514
in optimize at /Users/davidzentlermunro/.julia/v0.4/NLopt/src/NLopt.jl:520
in include_string at loading.jl:282
in include_string at /Users/davidzentlermunro/.julia/v0.4/CodeTools/src/eval.jl:32
in anonymous at /Users/davidzentlermunro/.julia/v0.4/Atom/src/eval.jl:84
in withpath at /Users/davidzentlermunro/.julia/v0.4/Requires/src/require.jl:37
in withpath at /Users/davidzentlermunro/.julia/v0.4/Atom/src/eval.jl:53
[inlined code] from /Users/davidzentlermunro/.julia/v0.4/Atom/src/eval.jl:83
in anonymous at task.jl:58
while loading untitled, in expression starting on line 13

如果这不可能,有人知道我是否可以在其中指定边界和初始条件的单变量优化器吗?

您在这里遗漏了几件事。

  1. 您需要在函数内指定函数的梯度(即一阶导数)。请参阅 github page for NLopt. Not all optimization algorithms require this, but the one that you are using LD_MMA looks like it does. See here 上的教程和示例以获取各种算法的列表并且需要梯度。
  2. 您应该在 "declare victory" ¹ 之前指定您需要的条件容差(即确定函数已充分优化)。这是下面示例中的 xtol_rel!(opt,1e-4)。另请参阅 ftol_rel! 以了解另一种指定不同容差条件的方法。根据文档,例如,xtol_rel 将 "stop when an optimization step (or an estimate of the optimum) changes every parameter by less than tol multiplied by the absolute value of the parameter." 和 ftol_rel 将 "stop when an optimization step (or an estimate of the optimum) changes the objective function value by less than tol multiplied by the absolute value of the function value. " 请参阅 "Stopping Criteria" 部分下的 here 以获取有关各种信息的更多信息选项在这里。
  3. 您正在优化的函数应该具有一维输出。在您的示例中,您的输出是一个向量(尽管长度为 1)。 (输出中的 x.^2 表示向量运算和向量输出)。如果你"objective function"最终没有输出一维数,那么你的优化objective是什么就不清楚了(比如最小化一个向量是什么意思?不清楚,你可以最小化例如,一个向量的范数,但是一个完整的向量——目前还不清楚)。

下面是一个基于您的代码的工作示例。请注意,我在 github 页面上包含了示例的打印输出,这有助于您诊断问题。

using NLopt    

count = 0 # keep track of # function evaluations    

function myfunc(x::Vector, grad::Vector)
    if length(grad) > 0
        grad[1] = 2*x[1]
    end    

    global count
    count::Int += 1
    println("f_$count($x)")    

    x[1]^2
end    

opt = Opt(:LD_MMA, 1)    

xtol_rel!(opt,1e-4)    

min_objective!(opt, myfunc)
(minf,minx,ret) = optimize(opt, [1.234])    

println("got $minf at $minx (returned $ret)")

¹(用优化大神Yinyu Ye的话来说。)