最近做项目想引入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
算法)。文章浏览阅读3.4k次,点赞8次,收藏42次。一、什么是内部类?or 内部类的概念内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。public class TestA{ class TestB {}}二、 为什么需要内部类?or 内部类有什么作用?1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。2、内部类可以对同一个包中的其他类隐藏起来。3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类成员内部_成员内部类和局部内部类的区别
文章浏览阅读118次。分布式系统要求拆分分布式思想的实质搭配要求分布式系统要求按照某些特定的规则将项目进行拆分。如果将一个项目的所有模板功能都写到一起,当某个模块出现问题时将直接导致整个服务器出现问题。拆分按照业务拆分为不同的服务器,有效的降低系统架构的耦合性在业务拆分的基础上可按照代码层级进行拆分(view、controller、service、pojo)分布式思想的实质分布式思想的实质是为了系统的..._分布式系统运维工具
文章浏览阅读174次。1.数据源准备2.数据处理step1:数据表处理应用函数:①VLOOKUP函数; ② CONCATENATE函数终表:step2:数据透视表统计分析(1) 透视表汇总不同渠道用户数, 金额(2)透视表汇总不同日期购买用户数,金额(3)透视表汇总不同用户购买订单数,金额step3:讲第二步结果可视化, 比如, 柱形图(1)不同渠道用户数, 金额(2)不同日期..._exce l趋势分析数据量
文章浏览阅读3.3k次。堡垒机可以为企业实现服务器、网络设备、数据库、安全设备等的集中管控和安全可靠运行,帮助IT运维人员提高工作效率。通俗来说,就是用来控制哪些人可以登录哪些资产(事先防范和事中控制),以及录像记录登录资产后做了什么事情(事后溯源)。由于堡垒机内部保存着企业所有的设备资产和权限关系,是企业内部信息安全的重要一环。但目前出现的以下问题产生了很大安全隐患:密码设置过于简单,容易被暴力破解;为方便记忆,设置统一的密码,一旦单点被破,极易引发全面危机。在单一的静态密码验证机制下,登录密码是堡垒机安全的唯一_horizon宁盾双因素配置
文章浏览阅读7.7k次,点赞4次,收藏16次。Chrome作为一款挺不错的浏览器,其有着诸多的优良特性,并且支持跨平台。其支持(Windows、Linux、Mac OS X、BSD、Android),在绝大多数情况下,其的安装都很简单,但有时会由于网络原因,无法安装,所以在这里总结下Chrome的安装。Windows下的安装:在线安装:离线安装:Linux下的安装:在线安装:离线安装:..._chrome linux debian离线安装依赖
文章浏览阅读153次。中国发达城市榜单每天都在刷新,但无非是北上广轮流坐庄。北京拥有最顶尖的文化资源,上海是“摩登”的国际化大都市,广州是活力四射的千年商都。GDP和发展潜力是衡量城市的数字指...
文章浏览阅读3.3k次。前言spark在java使用比较少,多是scala的用法,我这里介绍一下我在项目中使用的代码配置详细算法的使用请点击我主页列表查看版本jar版本说明spark3.0.1scala2.12这个版本注意和spark版本对应,只是为了引jar包springboot版本2.3.2.RELEASEmaven<!-- spark --> <dependency> <gro_使用java调用spark注册进去的程序
文章浏览阅读4.8k次。汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用,代码精简高效,大厂出品有量产保证。:139800617636213023darcy169_uds协议栈 源代码
文章浏览阅读4.6k次,点赞20次,收藏148次。AUTOSAR基础篇之OS(下)前言首先,请问大家几个小小的问题,你清楚:你知道多核OS在什么场景下使用吗?多核系统OS又是如何协同启动或者关闭的呢?AUTOSAR OS存在哪些功能安全等方面的要求呢?多核OS之间的启动关闭与单核相比又存在哪些异同呢?。。。。。。今天,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCXrdI0k-1636287756923)(https://gite_autosar 定义了 5 种多核支持类型
文章浏览阅读2.2k次,点赞6次,收藏14次。原因:自己写的头文件没有被加入到方案的包含目录中去,无法被检索到,也就无法打开。将自己写的头文件都放入header files。然后在VS界面上,右键方案名,点击属性。将自己头文件夹的目录添加进去。_vs2013打不开自己定义的头文件
文章浏览阅读3.3w次,点赞80次,收藏342次。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。_redis命令
文章浏览阅读449次,点赞3次,收藏3次。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。_urp渲染管线