最近做项目想引入NLopt到C++里进行非线性优化,但是好像C++的文档不是很详细,官网关于C的文档介绍得更多一些,关于具体的例程也所讲甚少,这篇博客介绍例程介绍得比较详细:
另外一些例子可以在nlopt目录下的nlopt\test
找到相关的测试文件:
有py、c++、c、matlab的文件。
但是具体要使用什么算法呢?感觉官网的博客写得比较繁杂,这里自己做一下整理(如果有错误和遗漏的话欢迎指出),首先所有的算法都是放在nlopt.h头文件里的:
typedef enum {
/* Naming conventions:
NLOPT_{G/L}{D/N}_*
= global/local derivative/no-derivative optimization,
respectively
*_RAND algorithms involve some randomization.
*_NOSCAL algorithms are *not* scaled to a unit hypercube
(i.e. they are sensitive to the units of x)
*/
NLOPT_GN_DIRECT = 0,
NLOPT_GN_DIRECT_L,
NLOPT_GN_DIRECT_L_RAND,
NLOPT_GN_DIRECT_NOSCAL,
NLOPT_GN_DIRECT_L_NOSCAL,
NLOPT_GN_DIRECT_L_RAND_NOSCAL,
NLOPT_GN_ORIG_DIRECT,
NLOPT_GN_ORIG_DIRECT_L,
NLOPT_GD_STOGO,
NLOPT_GD_STOGO_RAND,
NLOPT_LD_LBFGS_NOCEDAL,
NLOPT_LD_LBFGS,
NLOPT_LN_PRAXIS,
NLOPT_LD_VAR1,
NLOPT_LD_VAR2,
NLOPT_LD_TNEWTON,
NLOPT_LD_TNEWTON_RESTART,
NLOPT_LD_TNEWTON_PRECOND,
NLOPT_LD_TNEWTON_PRECOND_RESTART,
NLOPT_GN_CRS2_LM,
NLOPT_GN_MLSL,
NLOPT_GD_MLSL,
NLOPT_GN_MLSL_LDS,
NLOPT_GD_MLSL_LDS,
NLOPT_LD_MMA,
NLOPT_LN_COBYLA,
NLOPT_LN_NEWUOA,
NLOPT_LN_NEWUOA_BOUND,
NLOPT_LN_NELDERMEAD,
NLOPT_LN_SBPLX,
NLOPT_LN_AUGLAG,
NLOPT_LD_AUGLAG,
NLOPT_LN_AUGLAG_EQ,
NLOPT_LD_AUGLAG_EQ,
NLOPT_LN_BOBYQA,
NLOPT_GN_ISRES,
/* new variants that require local_optimizer to be set,
not with older constants for backwards compatibility */
NLOPT_AUGLAG,
NLOPT_AUGLAG_EQ,
NLOPT_G_MLSL,
NLOPT_G_MLSL_LDS,
NLOPT_LD_SLSQP,
NLOPT_LD_CCSAQ,
NLOPT_GN_ESCH,
NLOPT_GN_AGS,
NLOPT_NUM_ALGORITHMS /* not an algorithm, just the number of them */
} nlopt_algorithm;
注释里讲得很清楚:
算法的命名,G/L表示全局/局部优化,D/N表示有导数和无导数优化)
*_RAND 为随机算法
*_NOSCAL不对问题进行标准化或缩放到单位超立方体(unit hypercube)。标准化或缩放是一种常见的预处理步骤,用于将优化问题的变量范围映射到单位超立方体(每个变量的范围为[0, 1])。这种标准化可以使不同变量的范围保持一致,从而更容易进行优化。但有的问题并不适合进行这种缩放。
简单做了一个表总结吧(按照文档梳理的):
下面都是从文档里面摘录出来的,个人觉得有用的信息保留了下来,具体的算法参考的哪个参考文献还是建议读者去官网的文档查看:
NLopt Algorithms
NLopt所有全局优化算法都要求对所有优化参数指定边界约束。
NLOPT_GN_ISRES
、NLOPT_GN_AGS
和NLOPT_GN_ORIG_DIRECT
NLOPT_GN_ISRES
。NLOPT_GN_DIRECT = 0,
NLOPT_GN_DIRECT_L,
NLOPT_GN_DIRECT_L_RAND,
NLOPT_GN_DIRECT_NOSCAL,
NLOPT_GN_DIRECT_L_NOSCAL,
NLOPT_GN_DIRECT_L_RAND_NOSCAL,
Direct方法只处理边界约束,并且实际上需要有限的边界约束(它们不适用于无约束问题)。它们不处理任意的非线性约束。它们的思想都是基于将搜索区域系统地划分为越来越小的超矩形来进行确定性确定性搜索。
NLOPT_GN_DIRECT_L
。NLOPT_GN_DIRECT_L_RAND_NOSCAL
是Direct_L版本算法的随机化变体,使用随机化来帮助决定近似平局的情况下使用一些随机化来决定下一个要分割的维度。NLOPT_GNL_DIRECT_NOSCAL
、NLOPT_GN_DIRECT_L_NOSCAL
和NLOPT_GN_DIRECT_L_RAND_NOSCAL
指定。对于无缩放变体最适合原始的Direct算法,因为Direct_L的设计在某种程度上依赖于搜索区域是一个超立方体(这导致被分割的超矩形只有一小部分边长)NLopt的CRS算法(尤其是CRS2变体)进行了“局部突变”修改。
NLOPT_GN_CRS2_LM
nlopt_set_population
函数进行更改;初始总体必须至少为 n+1。MLSL算法通过一系列从随机起始点开始的局部优化(使用其他一些局部优化算法)来进行全局优化,它是一种“多起点”算法。该算法仅支持有边界约束的问题。在NLopt里实现的版本主要有:
NLOPT_GN_MLSL,
NLOPT_GD_MLSL,
NLOPT_GN_MLSL_LDS,
NLOPT_GD_MLSL_LDS,
...
NLOPT_G_MLSL,
NLOPT_G_MLSL_LDS,
NLOPT_G_MLSL_LDS
,而无LDS的MLSL(使用伪随机数,目前通过Mersenne twister算法)使用NLOPT_G_MLSL
表示。nlopt_opt_set_local_optimizer
设置的导数/非导数算法。nlopt_set_population
函数进行更改。StoGO是一种全局优化算法,通过系统地将搜索空间(必须有边界约束)通过分支定界技术划分为较小的超矩形,并使用基于梯度的局部搜索算法(一种BFGS变体)对其进行搜索,可选择包含一些随机性(因此有"Sto",代表"stochastic")。该算法仅支持有边界约束的问题。在NLopt里实现的版本主要有:
NLOPT_GD_STOGO,
NLOPT_GD_STOGO_RAND,
NLOPT_GD_STOGO
是StoGO的标准算法,NLOPT_GD_STOGO_RAND
是算法的随机变体。-lnlopt_cxx
而不是-lnlopt
NLopt使用的AGS算法改编自ags_nlp_solver,AGS算法可以处理任意的目标函数和非线性不等式约束,此外,边界约束也是需要被包含的。为了保证收敛性,目标函数和约束条件应满足指定超矩形上的Lipschitz条件。AGS是一种无导数算法,它使用希尔伯特曲线将源问题转化为一元问题。该算法将一元空间划分为区间,通过使用后验概率生成新的点。在每次试验中,AGS依次尝试评估约束条件。如果某个约束在该点处被违反,后续的约束将不会被评估。如果所有约束条件都得到满足,即试验点是可行的,AGS将评估目标函数。因此,一些约束条件(除了第一个)和目标函数可以在搜索超矩形中部分未定义。在NLopt里实现的版本主要有:
NLOPT_GN_AGS
NLOPT_GN_AGS
指定。AGS 的其他参数无法从公共 NLOpt 接口进行调整,它在ags.h
中声明和描述。此外,AGS 源文件中还给出了解决约束问题的示例。ISRES算法用于非线性约束的全局优化(至少是半全局优化;虽然它具有逃离局部最优解的启发式方法,但目前是否存在收敛证明还不知道),该方法支持任意的非线性不等式和等式约束以及边界约束。在NLopt里实现的版本主要有:
NLOPT_GN_ISRES,
该进化策略基于突变规则(对数正态步长更新和指数平滑)和差分变异(一种类似Nelder-Mead的更新规则)的组合,对于没有非线性约束的问题,适应度排序仅通过目标函数进行,当包含非线性约束时,采用了Runarsson和Yao提出的随机排序方法。
nlopt_set_population
函数进行更改。ESCH是用于全局优化的改进进化算法,该方法仅支持边界约束(无非线性约束)。在NLopt里实现的版本主要有:
NLOPT_GN_ESCH
目前只有 NLOPT_LN_COBYLA
原生地支持任意非线性不等式和相等约束;其余的仅支持有约束或无约束的问题。但是,可以通过将它们与增强拉格朗日方法相结合,它们中的任何一个都可以应用于非线性约束问题。
使用局部无导数算法时,必须考虑优化器以何种方式决定初始步长。默认情况下,NLopt 会启发式地选择此初始步长,但这可能并不总是最佳选择。如果遇到问题,可以修改初始步长。
COBYLA算法可以用于具有非线性不等式和相等约束的无导数优化。它通过 n+1 个点的单纯形(以 n 维为单位)构造目标函数和约束的连续线性近似,并在每一步的信任区域中优化这些近似值。在NLopt里实现的版本主要有:
NLOPT_LN_COBYLA
BOBYQA算法从 M. J. D. Powell 的 BOBYQA 子程序派生的算法,转换为 C 语言并针对 NLopt 停止标准进行了修改。它使用迭代构造的目标函数二次近似执行无导数边界约束优化(由于 BOBYQA 构造了目标的二次近似,因此对于不可两次微分的目标函数,它可能表现不佳)。在NLopt里实现的版本主要有:
NLOPT_LN_BOBYQA
NEWUOA 算法是从 M. J. D. Powell 的 NEWUOA 子程序派生的算法,转换为 C 并针对 NLopt 停止标准进行了修改。原始 NEWUOA 使用迭代构造的目标函数二次近似执行无导数无约束优化。该算法在很大程度上被 2.2所述的BOBYQA算法所取代(它针对边界约束以及一些数值稳定性和收敛增强功能进行了修改)。在NLopt里实现的版本主要有:
NLOPT_LN_NEWUOA,
NLOPT_LN_NEWUOA_BOUND,
NLOPT_LN_NEWUOA
为原始算法 ,并且仅支持无约束问题。NLOPT_LN_NEWUOA_BOUND
为NLopt提供的一个变体,它允许有效处理边界约束。PRAXIS算法最初是为无约束优化而设计的,它使用Richard Brent 的“主轴方法”进行“PRAXIS”无梯度局部优化。在NLopt里实现的版本主要有:
NLOPT_LN_PRAXIS,
NLopt实现了原始的 Nelder-Mead 单纯形算法,在NLopt里实现的版本主要有:
NLOPT_LN_NELDERMEAD
Subplex(Nelder-Mead 的变体,在一系列子空间上使用 Nelder-Mead)据称比原来的 Nelder-Mead 更有效、更强大,同时保留了后者具有不连续目标的设置(然而还不知道有任何证据表明 Subplex 是全局收敛的,也许它可能会在某些目标上失败)。在NLopt里实现的版本主要有:
NLOPT_LN_SBPLX
算法概览:
全局收敛的移动渐近线方法 (MMA) 算法被用于基于梯度的局部优化,包括非线性不等式约束(但不是相等约束),注意:“全局收敛”并不意味着该算法收敛到全局最优;它意味着它保证从任何可行的起点收敛到某个局部最小值。在NLopt里实现的版本主要有:
NLOPT_LD_MMA
NLOPT_LD_CCSAQ
nlopt_set_param
设置内部参数:
inner_maxeval
:如果 ≥ 0,则给出算法的最大“内部”迭代次数,其中它试图确保其近似值是“保守的”;默认值为0(无限制)。如果梯度或目标函数的不准确性阻碍了算法的进展,可以为该参数指定一个有限的数值(如5或10)dual_algorithm
(默认值为 NLOPT_LD_MMA
)、dual_ftol_rel
(默认值为 1 0 − 14 10^{-14} 10−14)、dual_ftol_abs
(默认值为0 )、dual_xtol_rel
(默认值为0 )、dual_xtol_abs
(默认值为0 ):这些参数用于指定算法在内部求解其近似目标的“对偶”优化问题。由于这个辅助求解不需要对用户的目标函数进行评估,通常它足够快,可以在不太关心细节的情况下以高精度解决它。然而,在高维问题中,您可能会注意到MMA/CCSA在优化步骤之间花费了很长时间,在这种情况下,您可能希望增加或进行其他更改。如果未指定这些参数,NLopt将使用子优化器算法中的参数(如果已指定),否则使用这里指定的默认值。verbosity
:如果大于0,则导致算法在每次迭代时打印内部状态信息。SLSQP算法是用于**非线性约束梯度优化(支持不等式和等式约束)**的顺序二次规划(SQP)。该问题被视为一系列受约束的最小二乘问题,但是这样的最小二乘问题等价于二次规划问题。该算法通过BFGS更新优化目标函数的连续二阶(二次/最小二乘)近似,并使用约束的一阶(仿射)近似。在NLopt里实现的版本主要有:
NLOPT_LD_SLSQP
原始的L-BFGS算法基于通过Strang递归进行变量度量更新。在NLopt里实现的版本主要有:
NLOPT_LD_LBFGS_NOCEDAL,
NLOPT_LD_LBFGS,
nlopt_set_vector_storage
函数进行更改。预条件截断牛顿(Preconditioned truncated Newton)算法在NLopt里实现的版本主要有:
NLOPT_LD_TNEWTON,
NLOPT_LD_TNEWTON_RESTART,
NLOPT_LD_TNEWTON_PRECOND,
NLOPT_LD_TNEWTON_PRECOND_RESTART,
NLOPT_LD_TNEWTON_PRECOND_RESTART
。NLOPT_LD_TNEWTON_PRECOND
(没有重新启动)、NLOPT_LD_TNEWTON_RESTART
(没有预条件)和 NLOPT_LD_TNEWTON
(没有重新启动或预条件的最简化版本)。nlopt_set_vector_storage
函数进行更改。移位有限存储变量度量(Shifted limited-memory variable-metric)算法在NLopt里实现的版本主要有:
NLOPT_LD_VAR1,
NLOPT_LD_VAR2,
NLOPT_LD_VAR2
使用二阶方法,而NLOPT_LD_VAR1
使用一阶方法。nlopt_set_vector_storage
函数进行更改。NLopt中有一个算法可以适用于上述所有类别,具体取决于指定的辅助优化算法,即增广拉格朗日方法(Augmented Lagrangian algorithm)。它的思路是将目标函数和非线性不等式/等式约束(如果有)组合成一个单一的函数:基本上是目标函数加上对任何违反约束的“惩罚”。然后,将这个修改后的目标函数传递给另一个没有非线性约束的优化算法。如果这个子问题的解违反了约束条件,那么惩罚的大小就会增加,然后重复这个过程;最终,该过程必须收敛到所需的解(如果存在)。它在NLopt里实现的版本主要有:
NLOPT_LN_AUGLAG,
NLOPT_LD_AUGLAG,
NLOPT_LN_AUGLAG_EQ,
NLOPT_LD_AUGLAG_EQ,
NLOPT_AUGLAG,
NLOPT_AUGLAG_EQ,
nlopt_set_local_optimizer
指定(不要忘记为这个辅助优化器设置一个停止容差!)由于所有实际的优化都在这个辅助优化器中进行,指定的辅助算法决定了优化是基于梯度还是无导数。实际上,甚至可以为辅助优化器指定一个全局优化算法,以进行全局非线性约束优化(尽管为该辅助全局优化器指定一个良好的停止准则比较困难)。NLOPT_AUGLAG
。另一个变体NLOPT_AUGLAG_EQ
只对等式约束使用惩罚函数,而将不等式约束直接传递给辅助算法处理;在这种情况下,辅助算法必须处理不等式约束(例如MMA
算法或COBYLA
算法)。文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文
文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作 导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释: cwy_init/init_123..._达梦数据库导入导出
文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js
文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6
文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输
文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...
文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure
文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割
文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答
文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。
文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入
文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf