NLopt中的无导数算法
(本文所涉及各量皆为C风格,即包含的头文件是
nlopt.h
而非
nlopt.hpp
)
首先说一下NLopt中算法的命名规则,C风格的命名规则为
NLOPT_{G,L}{N,D}_xxxx
,其中
G/L
代表全局最优与局部最优,
N/D
代表无导数与有导数。例如
NLOPT_LN_COBYLA
则表示无导数局部最优的COBYLA算法。
这里的导数是我们算完之后填入
if (grad)
{
/* 各变量的导数 */
}
中的,但是在很多情况下,当问题很复杂时,很难求解出其导数,这个时候就需要使用无导数的算法。
无导数全局最优算法
这种算法的命名为NLOPT_GN_xxxx
。最简单的方法就是在编译器中输入NLOPT_GN_
,然后它会自己弹出来有哪些算法,一个一个试,看哪个满足自己的要求即可:)。
DIRECT和DIRECT-L
DIRECT指的是Dividing Rectangles算法。
首先是基本的NLOPT_GN_DIRECT
和NLOPT_GN_DIRECT_L
。其中NLOPT_GN_DIRECT
将更多的精力放在了全局,而NLOPT_GN_DIRECT_L
算法在局部的表现会更好,其适用于没有过多局部最小值的函数。
其次是NLOPT_GN_DIRECT_L_RAND
,该变体加入了一点随机性以帮助确定将哪个维度二等分。
由于DIRECT算法将各约束缩放为超立方体(与正方体类似,只是正方体为三维,而超立方体为指定维度),因此所有维度的搜索权重是相同的。如果你要搜索的空间与超立方体相差甚远,则更适合用DIRECT的变体NLOPT_GNL_DIRECT_NOSCAL
, NLOPT_GN_DIRECT_L_NOSCAL
和NLOPT_GN_DIRECT_L_RAND_NOSCAL
。
同时,还可以使用基于原始的Fortran语言写的NLopt算法NLOPT_GN_ORIG_DIRECT
, NLOPT_GN_ORIG_DIRECT_L
,在不同的情况下,这两个的表现可能会更好,不过也可能会变差,需要实际尝试。