optimization - 具有单变量优化的 NLopt

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

下面是一个基于您的代码的工作示例。请注意,我在 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的话来说。)

关于optimization - 具有单变量优化的 NLopt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37733740/

相关文章:

php - 将 MySQLi 结果传递给 PHP 中的函数有哪些内存影响?

java - 使用 Android 处理 Firebase 引用的最佳方式

arrays - Julia:使用自定义比较器按行对矩阵进行排序

plot - IJulia 情节 One Liner

c++ - 将 void 函数作为参数传递给 c++ 中的 double 函数

r - 无法在没有 root 权限的集群上安装 nloptr/nlopt

javascript - 页面加载前白色闪烁

java - 生成 AES 和 HMAC key 需要太多时间

julia - 如何在 julia 中展平二维数组?