nlopt非线性优化算法整理

最近做项目想引入NLopt到C++里进行非线性优化,但是好像C++的文档不是很详细,官网关于C的文档介绍得更多一些,关于具体的例程也所讲甚少,这篇博客介绍例程介绍得比较详细:

Nlopt优化函数库,用法举例

另外一些例子可以在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;

注释里讲得很清楚:

  1. NLOPT_{G/L}{D/N}_* = global/local derivative/no-derivative optimization,
    respectively

算法的命名,G/L表示全局/局部优化,D/N表示有导数和无导数优化)

  1. *_RAND algorithms involve some randomization.

*_RAND 为随机算法

  1. *_NOSCAL algorithms are not scaled to a unit hypercube
    (i.e. they are sensitive to the units of x)

*_NOSCAL不对问题进行标准化或缩放到单位超立方体(unit hypercube)。标准化或缩放是一种常见的预处理步骤,用于将优化问题的变量范围映射到单位超立方体(每个变量的范围为[0, 1])。这种标准化可以使不同变量的范围保持一致,从而更容易进行优化。但有的问题并不适合进行这种缩放。

简单做了一个表总结吧(按照文档梳理的):

在这里插入图片描述

下面都是从文档里面摘录出来的,个人觉得有用的信息保留了下来,具体的算法参考的哪个参考文献还是建议读者去官网的文档查看:
NLopt Algorithms

1. 全局优化

NLopt所有全局优化算法都要求对所有优化参数指定边界约束。

  • 支持非线性不等式约束的算法NLOPT_GN_ISRESNLOPT_GN_AGSNLOPT_GN_ORIG_DIRECT
  • 支持非线性等式约束的算法NLOPT_GN_ISRES
  • 可以通过将它们与增广Lagrange方法相结合,可以将任何算法应用于非线性约束问题。
  • tips: 在运行全局优化之后,可以使用全局最优解作为局部优化的起点,以将最优解“打磨”到更高的精度。(许多全局优化算法更注重搜索全局参数空间,而不是精确找到局部最优解的位置。)

1.1 Direct算法

  • Direct算法实现了多个版本,在NLopt里实现的版本主要有:
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方法只处理边界约束,并且实际上需要有限的边界约束(它们不适用于无约束问题)。它们不处理任意的非线性约束。它们的思想都是基于将搜索区域系统地划分为越来越小的超矩形来进行确定性确定性搜索

  • Direct_L版本的算法“更偏向于局部搜索”,因此对于没有太多局部最小值的函数来说,它更有效。作者推荐优先使用NLOPT_GN_DIRECT_L
  • NLOPT_GN_DIRECT_L_RAND_NOSCAL是Direct_L版本算法的随机化变体,使用随机化来帮助决定近似平局的情况下使用一些随机化来决定下一个要分割的维度。
  • Direct和Direct_L算法首先将边界约束重新缩放为超立方体,这样在搜索过程中所有维度都具有相等的权重。这里又分为有缩放和无缩放版本,默认的是使用有缩放版本,使用无缩放版本的情况在于:
    • 如果你的维度权重不相等,例如如果你的搜索空间是“长而狭窄”的,并且你的函数在所有方向上的变化速度大致相同,那么最好使用这些算法的无缩放变体,包括NLOPT_GNL_DIRECT_NOSCALNLOPT_GN_DIRECT_L_NOSCALNLOPT_GN_DIRECT_L_RAND_NOSCAL指定。对于无缩放变体最适合原始的Direct算法,因为Direct_L的设计在某种程度上依赖于搜索区域是一个超立方体(这导致被分割的超矩形只有一小部分边长)

1.2 CRS(Controlled Random Search)算法

NLopt的CRS算法(尤其是CRS2变体)进行了“局部突变”修改。

  • CRS算法和遗传算法相似,因为它们都从随机的点“总体”开始,然后通过启发式规则随机“演化”这些点。在这种情况下,“进化”有点类似于随机的Nelder-Mead算法。相关论文里的CRS结果似乎很大程度上是经验性的。此算法仅支持边界约束问题。它在NLopt实现的版本是:
NLOPT_GN_CRS2_LM
  • CRS算法的初始总体大小在 n 个维度中默认为 10×(n+1),初始总体大小可以通过 nlopt_set_population 函数进行更改;初始总体必须至少为 n+1。

1.3 MLSL(Multi-Level Single-Linkage)算法

MLSL算法通过一系列从随机起始点开始的局部优化(使用其他一些局部优化算法)来进行全局优化,它是一种“多起点”算法。该算法仅支持有边界约束的问题。在NLopt里实现的版本主要有:

NLOPT_GN_MLSL,
NLOPT_GD_MLSL,
NLOPT_GN_MLSL_LDS,
NLOPT_GD_MLSL_LDS,

...

NLOPT_G_MLSL,
NLOPT_G_MLSL_LDS,
  • 后缀有LDS的算法为修改的MLSL算法,它使用Sobol’低差异序列(LDS)代替伪随机数,据称可以提高收敛速度。基于LDS的MLSL为NLOPT_G_MLSL_LDS,而无LDS的MLSL(使用伪随机数,目前通过Mersenne twister算法)使用NLOPT_G_MLSL表示。
  • MLSL的局部搜索部分可以使用NLopt中的任何其他算法,特别是可以使用基于梯度的算法(D)或无导数的算法(N)。局部搜索使用由nlopt_opt_set_local_optimizer设置的导数/非导数算法。
  • MLSL的区别在于“聚类”启发式方法,这有助于它避免重复搜索相同的局部最优值,并且在理论上可以保证在有限数量的局部最小化中找到所有局部最优值
  • 默认情况下,如果没有为局部优化算法设置停止容差,MLSL的默认设置为ftol_rel= 1 0 − 15 10^{-15} 1015和xtol_rel= 1 0 − 7 10^{-7} 107用于局部搜索。请注意,为这些局部搜索设置相对较大的容差是完全合理的。
  • 默认情况下,MLSL的每次迭代会采样4个随机的新试验点,但可以使用nlopt_set_population函数进行更改。
  • 可以先运行MLSL进行全局优化,然后在最后使用更低的容差使用MLSL的结果作为起始点运行另一个局部优化,实现高精度"优化"最优解。

1.4 StoGO算法

StoGO是一种全局优化算法,通过系统地将搜索空间(必须有边界约束)通过分支定界技术划分为较小的超矩形,并使用基于梯度的局部搜索算法(一种BFGS变体)对其进行搜索,可选择包含一些随机性(因此有"Sto",代表"stochastic")。该算法仅支持有边界约束的问题。在NLopt里实现的版本主要有:

NLOPT_GD_STOGO,
NLOPT_GD_STOGO_RAND,
  • NLOPT_GD_STOGO是StoGO的标准算法,NLOPT_GD_STOGO_RAND是算法的随机变体。
  • StoGO是用C++编写的,这意味着只有在启用C++算法时才会包含它,使用的时候必须使用-lnlopt_cxx而不是-lnlopt

1.5 AGS算法

NLopt使用的AGS算法改编自ags_nlp_solverAGS算法可以处理任意的目标函数和非线性不等式约束,此外,边界约束也是需要被包含的。为了保证收敛性,目标函数和约束条件应满足指定超矩形上的Lipschitz条件。AGS是一种无导数算法,它使用希尔伯特曲线将源问题转化为一元问题。该算法将一元空间划分为区间,通过使用后验概率生成新的点。在每次试验中,AGS依次尝试评估约束条件。如果某个约束在该点处被违反,后续的约束将不会被评估。如果所有约束条件都得到满足,即试验点是可行的,AGS将评估目标函数。因此,一些约束条件(除了第一个)和目标函数可以在搜索超矩形中部分未定义。在NLopt里实现的版本主要有:

NLOPT_GN_AGS
  • AGS 在 NLopt 中由 NLOPT_GN_AGS指定。AGS 的其他参数无法从公共 NLOpt 接口进行调整,它在ags.h中声明和描述。此外,AGS 源文件中还给出了解决约束问题的示例。
  • 当空间维数大于 5 时,机器算术的局限性不允许为 Hilbert 构建紧密近似,因此 AGS 的这种实现在这个意义上受到限制。它最多支持 10 个维度,但在 6 个或更多维度的情况下,该方法可以提前停止
  • AGS 和 StoGO 一样,是用 C++ 编写的,但它需要 C++11。如果库是使用 C++ 构建的,并且编译器支持 C++11,则也会构建 AGS。
  • 目前NLOpt里的AGS不支持向量约束

1.6 ISRES(Improved Stochastic Ranking Evolution Strategy)算法

ISRES算法用于非线性约束的全局优化(至少是半全局优化;虽然它具有逃离局部最优解的启发式方法,但目前是否存在收敛证明还不知道),该方法支持任意的非线性不等式和等式约束以及边界约束。在NLopt里实现的版本主要有:

NLOPT_GN_ISRES,

该进化策略基于突变规则(对数正态步长更新和指数平滑)和差分变异(一种类似Nelder-Mead的更新规则)的组合,对于没有非线性约束的问题,适应度排序仅通过目标函数进行,当包含非线性约束时,采用了Runarsson和Yao提出的随机排序方法。

  • ISRES的种群大小在n维中默认为20×(n+1),可以使用nlopt_set_population函数进行更改。

1.7 ESCH(evolutionary algorithm)算法

ESCH是用于全局优化的改进进化算法,该方法仅支持边界约束(无非线性约束)。在NLopt里实现的版本主要有:

NLOPT_GN_ESCH

2. 局部无导数优化

目前只有 NLOPT_LN_COBYLA原生地支持任意非线性不等式和相等约束;其余的仅支持有约束或无约束的问题。但是,可以通过将它们与增强拉格朗日方法相结合,它们中的任何一个都可以应用于非线性约束问题。

使用局部无导数算法时,必须考虑优化器以何种方式决定初始步长。默认情况下,NLopt 会启发式地选择此初始步长,但这可能并不总是最佳选择。如果遇到问题,可以修改初始步长。

2.1 COBYLA(Constrained Optimization BY Linear Approximations)算法

COBYLA算法可以用于具有非线性不等式和相等约束的无导数优化。它通过 n+1 个点的单纯形(以 n 维为单位)构造目标函数和约束的连续线性近似,并在每一步的信任区域中优化这些近似值。在NLopt里实现的版本主要有:

NLOPT_LN_COBYLA
  • NLopt对COBYLA算法进行了一些修改:首先,纳入了所有 NLopt 终止标准。其次,添加了对边界约束的显式支持(尽管原始的 COBYLA 可以将绑定约束作为线性约束进行处理,但有时它会采取违反绑定约束的步骤)。第三,如果预测的更新大致正确且单纯形正常,则允许增加信任区域半径,该建议似乎可以提高收敛速度。第四,在COBYLA算法中伪随机化单纯形步骤,通过避免意外采取不改善条件反射的步骤来提高鲁棒性(这似乎有时会发生在主动约束下);但是,该算法仍然是确定性的(使用确定性种子)。此外,支持不同参数中的初始步长不相等(通过内部重新缩放与初始步长成比例的参数的简单方法),当不同参数具有非常不同的尺度时,这一点很重要。
  • 底层 COBYLA 代码仅支持不等式约束。相等约束会自动转换为成对的不等式约束,在这种情况下,似乎不会引起问题。

2.2 BOBYQA算法

BOBYQA算法从 M. J. D. Powell 的 BOBYQA 子程序派生的算法,转换为 C 语言并针对 NLopt 停止标准进行了修改。它使用迭代构造的目标函数二次近似执行无导数边界约束优化(由于 BOBYQA 构造了目标的二次近似,因此对于不可两次微分的目标函数,它可能表现不佳)。在NLopt里实现的版本主要有:

NLOPT_LN_BOBYQA
  • BOBYQA 接口支持不同参数中不相等的初始步长(通过内部重新缩放与初始步长成比例的参数的简单方法),这在不同参数具有非常不同的尺度时非常重要。

2.3 NEWUOA算法

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提供的一个变体,它允许有效处理边界约束。
  • 在最初的 NEWUOA 算法中,Powell 通过截断共轭梯度算法求解了球形信任区域中的二次子问题(在例程 TRSAPP 和 BIGLAG 中)。在NLopt的边界约束变体中则对这些子问题使用 MMA 算法来求解它们,同时使用边界约束和球形信任区域。原则上,也应该以类似的方式更改 BIGDEN 子程序(因为 BIGDEN 也近似地求解了一个信任区域子问题),但Nlopt的算法只是将其结果截断到边界(这可能会给出次优收敛,但 BIGDEN 在实践中很少被调用)。
  • NEWUOA 算法要求参数空间的维数 n ≥ 2,即实现不处理一维优化问题。

2.4 PRAXIS(PRincipal AXIS)算法

PRAXIS算法最初是为无约束优化而设计的,它使用Richard Brent 的“主轴方法”进行“PRAXIS”无梯度局部优化。在NLopt里实现的版本主要有:

NLOPT_LN_PRAXIS,
  • 在 NLopt 中,边界约束在 PRAXIS 中通过违反约束时返回无穷大 (Inf) 的简单方式“实现”(这是自动完成的,不必在自己的函数中执行此操作)。这似乎有效,但似乎大大减慢了收敛速度。所以如果有边界约束,则最好使用 COBYLA 或 BOBYQA

2.5 Nelder-Mead Simplex算法

NLopt实现了原始的 Nelder-Mead 单纯形算法,在NLopt里实现的版本主要有:

NLOPT_LN_NELDERMEAD
  • NLopt实现了对边界约束的显式支持
  • 每当一个新点位于约束约束之外时,Box 主张将其“刚好在”约束内移动一些固定的小距离 1 0 − 8 10^{−8} 108左右。在约束内使用固定距离有什么好处,特别是当最优值就位于约束上时,所以在这种情况下,NLopt选择可以将点精确地移动到约束上。这种方式(或通过 Box 的方法)实现边界约束的危险在于,可能会将单纯形折叠成低维子空间。无论如何,通过重新启动,单纯形的这种崩溃在某种程度上得到了改善,例如在下面的 Subplex 算法中使用 Nelder-Mead 时。

2.6 Sbplx (based on Subplex)算法

Subplex(Nelder-Mead 的变体,在一系列子空间上使用 Nelder-Mead)据称比原来的 Nelder-Mead 更有效、更强大,同时保留了后者具有不连续目标的设置(然而还不知道有任何证据表明 Subplex 是全局收敛的,也许它可能会在某些目标上失败)。在NLopt里实现的版本主要有:

NLOPT_LN_SBPLX
  • NLopt实现了对边界约束的显式支持

3. 基于局部梯度的优化

算法概览:

  • 支持任意非线性不等式约束:只有 MMA 和 SLSQP 。
  • 支持非线性等式约束:只有 SLSQP。
  • 支持边界约束或无约束的问题:其余算法。
  • 但是,通过将它们与下面的增强拉格朗日方法相结合,它们中的任何一个都可以应用于非线性约束问题。

3.1 MMA (Method of Moving Asymptotes) 和CCSA算法

全局收敛的移动渐近线方法 (MMA) 算法被用于基于梯度的局部优化,包括非线性不等式约束(但不是相等约束),注意:“全局收敛”并不意味着该算法收敛到全局最优;它意味着它保证从任何可行的起点收敛到某个局部最小值。在NLopt里实现的版本主要有:

NLOPT_LD_MMA
NLOPT_LD_CCSAQ
  • MMA 算法在每个点 x 处,使用 f 的梯度和约束函数形成局部近似,加上二次“惩罚”项,使近似“保守”(精确函数的上限)。精确的近似MMA形式很难用几句话来描述,因为它包括非线性项,由距离x一定距离的极点组成(在当前信任区域之外),几乎是一种Padé近似。主要的一点是,近似既是凸的,又是可分离的,因此用对偶方法求解近似优化变得微不足道。优化近似值会导致新的候选点 x。在候选点评估目标和约束。如果近似值确实是保守的(候选点处实际函数的上限),则该过程将在新的 x 处重新启动。否则,近似值将变得更加保守(通过增加惩罚项)并重新优化。
  • CCSA 算法,它不是构造局部 MMA 近似,而是构造简单的二次近似(或者更确切地说,仿射近似加上二次惩罚项以保持保守)。对于大多数问题,它似乎与 MMA 具有相似的收敛率。对于二次变量,NLopt实现了预处理的可能性:在局部模型中包括用户提供的 Hessian 近似。全局收敛仍然是有保证的,并且如果预处理器是真实Hessian的良好近似(至少对于最大特征值的特征向量),则可以大大提高收敛性。
  • 上述的两个算法支持使用 nlopt_set_param设置内部参数:
    • inner_maxeval:如果 ≥ 0,则给出算法的最大“内部”迭代次数,其中它试图确保其近似值是“保守的”;默认值为0(无限制)。如果梯度或目标函数的不准确性阻碍了算法的进展,可以为该参数指定一个有限的数值(如5或10)
    • dual_algorithm(默认值为 NLOPT_LD_MMA)、dual_ftol_rel(默认值为 1 0 − 14 10^{-14} 1014)、dual_ftol_abs(默认值为0 )、dual_xtol_rel(默认值为0 )、dual_xtol_abs(默认值为0 ):这些参数用于指定算法在内部求解其近似目标的“对偶”优化问题。由于这个辅助求解不需要对用户的目标函数进行评估,通常它足够快,可以在不太关心细节的情况下以高精度解决它。然而,在高维问题中,您可能会注意到MMA/CCSA在优化步骤之间花费了很长时间,在这种情况下,您可能希望增加或进行其他更改。如果未指定这些参数,NLopt将使用子优化器算法中的参数(如果已指定),否则使用这里指定的默认值。
    • verbosity:如果大于0,则导致算法在每次迭代时打印内部状态信息。

3.2 SLSQP算法

SLSQP算法是用于**非线性约束梯度优化(支持不等式和等式约束)**的顺序二次规划(SQP)。该问题被视为一系列受约束的最小二乘问题,但是这样的最小二乘问题等价于二次规划问题。该算法通过BFGS更新优化目标函数的连续二阶(二次/最小二乘)近似,并使用约束的一阶(仿射)近似。在NLopt里实现的版本主要有:

NLOPT_LD_SLSQP
  • NLopt中对该算法进行了以下更改:
    • 将代码转换为C语言并进行手动清理。修改为可重入(保留了反向通信接口,但在数据结构中显式保存状态)。
    • 使用NLopt风格的接口包装了反向通信接口,并添加了NLopt的停止条件。修正了不精确的线搜索,以便在第一步中计算函数和梯度,因为这样可以避免在不精确的线搜索在单步后结束时为相同点再次计算函数+梯度。
    • 由于舍入误差有时会使SLSQP的参数略微超出边界约束(NLopt不允许此情况),添加了检查以将参数强制限制在边界内。
    • 对于等式约束数等于问题维度的情况,修复了LSEI子程序中的一个错误(未初始化变量的使用)。
    • 对于具有无限下界/上界的情况,修改了LSQ子程序以处理这些约束(在这种情况下,这些约束将被省略)。
  • 由于SLSQP代码使用了密集矩阵方法(普通BFGS,而不是低存储BFGS),在n维空间中,它需要 O ( n 2 ) O(n^2) O(n2)的存储空间和 O ( n 3 ) O(n^3) O(n3)的时间,这使得它在优化超过几千个参数时变得不太实用。

3.3 Low-storage BFGS算法

原始的L-BFGS算法基于通过Strang递归进行变量度量更新。在NLopt里实现的版本主要有:

NLOPT_LD_LBFGS_NOCEDAL,

NLOPT_LD_LBFGS,
  • 该算法的一个参数是梯度数量M(用来记住先前优化的步骤step)。增加M会增加内存要求,但可能加快收敛速度。NLopt默认情况下将M设置为启发式值,但可以通过nlopt_set_vector_storage函数进行更改。

3.4 Preconditioned truncated Newton算法

预条件截断牛顿(Preconditioned truncated Newton)算法在NLopt里实现的版本主要有:

NLOPT_LD_TNEWTON,
NLOPT_LD_TNEWTON_RESTART,
NLOPT_LD_TNEWTON_PRECOND,
NLOPT_LD_TNEWTON_PRECOND_RESTART,
  • NLopt包含了预条件截断牛顿(Preconditioned truncated Newton)算法的几种变体:
    • 首先是通过低存储BFGS算法进行预条件的变体,其中包括最陡下降法重新启动,指定为NLOPT_LD_TNEWTON_PRECOND_RESTART
    • 其次是简化版本(没有重新启动的算法),分别是NLOPT_LD_TNEWTON_PRECOND(没有重新启动)、NLOPT_LD_TNEWTON_RESTART(没有预条件)和 NLOPT_LD_TNEWTON(没有重新启动或预条件的最简化版本)。
  • 该算法的一个参数是梯度数量M(用来记住先前优化的步骤step)。增加M会增加内存要求,但可能加快收敛速度。NLopt默认情况下将M设置为启发式值,但可以通过nlopt_set_vector_storage函数进行更改。

3.5 Shifted limited-memory variable-metric算法

移位有限存储变量度量(Shifted limited-memory variable-metric)算法在NLopt里实现的版本主要有:

NLOPT_LD_VAR1,
NLOPT_LD_VAR2,
  • NLOPT_LD_VAR2使用二阶方法,而NLOPT_LD_VAR1使用一阶方法。
  • 该算法的一个参数是梯度数量M(用来记住先前优化的步骤step)。增加M会增加内存要求,但可能加快收敛速度。NLopt默认情况下将M设置为启发式值,但可以通过nlopt_set_vector_storage函数进行更改。

4. Augmented Lagrangian算法

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中,增广拉格朗日方法被定义为NLOPT_AUGLAG。另一个变体NLOPT_AUGLAG_EQ只对等式约束使用惩罚函数,而将不等式约束直接传递给辅助算法处理;在这种情况下,辅助算法必须处理不等式约束(例如MMA算法或COBYLA算法)。
  • 34
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NLopt是一个用于非线性优化的开源软件库,可以用于求解各种类型的优化问题,包括定日镜场优化。定日镜场优化是指通过调整镜面形状以最大程度地聚焦太阳光线到焦点,从而实现太阳能的收集。在NLopt中,可以使用不同的优化算法来求解这个问题,如COBYLA、SLSQP、Nelder-Mead等。具体的使用方法如下: 1. 安装NLopt库:首先需要在您的计算机上安装NLopt库。您可以在NLopt官方网站(https://nlopt.readthedocs.io)上找到详细的安装说明。 2. 定义目标函数:在定日镜场优化中,目标函数通常是一个关于镜面形状参数的函数,该函数的值表示聚焦太阳光线的效果。您需要根据具体的问题定义目标函数。 3. 设置约束条件:根据定日镜场优化的具体要求,您可能需要设置一些约束条件,例如镜面形状的范围限制等。 4. 调用NLopt进行优化:利用NLopt提供的API,将目标函数和约束条件传入优化器中,并选择合适的优化算法和参数进行求解。具体使用方法可以参考NLopt库的文档和示例代码。 需要注意的是,定日镜场优化是一个复杂的问题,涉及到光学原理和数值计算等方面的知识。在实际应用中,还需要根据具体的要求和约束条件进行问题的建模和求解。以上只是一个简要的介绍,希望能对您有所帮助。如果您有更具体的问题或疑问,欢迎继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值