NLopt与单变量优化

时间:2016-06-09 18:36:26

标签: optimization julia nlopt

任何人都知道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 个答案:

答案 0 :(得分:7)

这里有一些你不想要的东西。

  1. 您需要在函数中指定函数的渐变(即一阶导数)。有关NLopt的github page,请参阅教程和示例。并非所有优化算法都需要这样,但您使用LD_MMA的算法看起来就像这样。有关各种算法的列表以及需要渐变的列表,请参阅here
  2. 您应该在“宣布胜利”之前指定所需条件的容差¹(即确定该功能已充分优化)。这是以下示例中的xtol_rel!(opt,1e-4)。另请参阅ftol_rel!以了解指定不同容差条件的其他方法。例如,根据文档,当优化步骤(或最佳估计值)将每个参数改变小于tol乘以参数的绝对值时,xtol_rel将“停止”。当优化步骤(或最佳估计值)将目标函数值改变小于tol乘以函数值的绝对值时,ftol_rel将“停止”。“请参阅”here下的“{停止标准“部分以获取有关各种选项的更多信息。
  3. 您正在优化的函数应该具有一维输出。在您的示例中,输出是一个向量(尽管长度为1)。 (输出中的x.^2表示向量运算和向量输出)。如果你的“目标函数”最终没有输出一维数,那么你的优化目标是什么就不清楚了(例如,最小化一个向量是什么意思?目前尚不清楚,你可以最小化向量的范数例如,但是整个矢量 - 它不清楚)。
  4. 以下是基于您的代码的工作示例。请注意,我在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。)