Nlopt优化包在Windows上的安装配置及应用案例

时间:2021-09-03 21:11:32

​​​1.Nlopt优化包介绍

​        NLopt是一个用于非线性优化的免费/开源库,提供了多种局部优化全局优化算法的原始实现及通用接口,类似于MATLAB中的 fmincon ,其简单粗暴,方便好用,支持C++,但是其安装配置稍显麻烦。现有的帖子中多多少少不够全面或者有些许问题,因此特作此文作为总结,So,废话少说,进入正题。

2.下载Nlopt优化包

Nlopt下载地址:https://nlopt.readthedocs.io/en/latest/NLopt_on_Windows

选择多少位取决于编译器的设置若用win32平台编译则下载32-bit版本,用X64平台编译则下载64-bit版本。本文以32-bit版本为例。

Nlopt优化包在Windows上的安装配置及应用案例Nlopt下载网页截图

​下载后解压,能看见libnlopt-0.def文件,最关键的步骤就是用.def文件生成.lib库文件,有这个文件后就能在VS中配置环境然后直接调用了。

Nlopt优化包在Windows上的安装配置及应用案例Nlopt压缩包解压截图

​3..def生成.lib静态链接库

根据以往的帖子有两种方法

方法一参照博客:

http://blog.csdn.net/qq_37043191/article/details/78473386

但是根据实验,发现会报错:

Nlopt优化包在Windows上的安装配置及应用案例方法一报错截图

​方法二:

  • 先找到lib.exe:E:\Microsoft Visual Studio 14.0\VC\bin
  • 运行>cmd;并切换到lib.exe所在的目录下: 

Nlopt优化包在Windows上的安装配置及应用案例在CMD中切换至lib.exe所在的目录

  • 输入命令:lib /out:G:\nlopt-2.4.2-dll32\libnlopt-0.lib /MACHINE:IX86 /DEF:G:\nlopt-2.4.2-dll32\libnlopt-0.def

/out:是.lib文件生成的位置,/MACHINE:IX86:表示机器类型,32位机器,/DEF:表示的是.def存放的位置。 

运行完后就会在G:\nlopt-2.4.2-dll32目录下生成对应的.lib文件和.exp文件: 

Nlopt优化包在Windows上的安装配置及应用案例在CMD中输入命令

Nlopt优化包在Windows上的安装配置及应用案例生成.lib和.exp文件

  • libnlopt-0.dll文件复制到vs2015的的目录下,找到vc文件夹下的bin文件夹:

Nlopt优化包在Windows上的安装配置及应用案例将libnlopt-0.dll复制到VS的安装目录下

​4.在VS2015进行配置环境并优化案例

  • 有了以上步骤,就得到了如下图所示的所有文件:G:\NonlinearOptimization\nlopt-2.4.2-dll32

Nlopt优化包在Windows上的安装配置及应用案例生成.lib后的所有文件截图

  • 打开vs2015,新建一个空项目,然后对其项目属性进行配置

Nlopt优化包在Windows上的安装配置及应用案例VC++目录设置

Nlopt优化包在Windows上的安装配置及应用案例链接器输入设置

  • ​包含头文件nlopt.h和nlopt.hpp,并添加nonlinearoptimization.cpp文件(数学模型及代码附在本文后面)

Nlopt优化包在Windows上的安装配置及应用案例头文件及代码截图

  • ​数学模型:

Nlopt优化包在Windows上的安装配置及应用案例数学模型

​ 上述中有一个等式约束和一个不等式约束。使用Sequential Least-Squares Quadratic Programming (SLSQP) 算法来求解这个优化问题。

  • C++代码(nonlinearoptimization.cpp文件中的代码):

#include <stdio.h>

#include <math.h>

#include "nlopt.h"

#define INF (1000000)


double utility(unsigned n, const double *x, double *grad, void *data) 

{

grad[0] = 1.0 / x[0];

grad[1] = 1.0 / x[1];

printf("%f, %f, %f ", x[0], x[1], log(x[0]) + log(x[1]));

return log(x[0]) + log(x[1]);

}


double constraint(unsigned n, const double *x, double *grad, void *data) 

{

double *p = (double *)data;

grad[0] = *p;

grad[1] = *(p + 1);

printf("Constraint: %f\n", x[0] * (*p) + x[1] * (*(p + 1)) - 5);

return x[0] * (*p) + x[1] * (*(p + 1)) - 5;

}


double inconstraint(unsigned n, const double *x, double *grad, void *data)

{

grad[0] = 1;

grad[1] = -1;

return x[0] - x[1];

}


int main(int argc, char const *argv[]) {

double p[2] = { 1,2 };

double tol = 1e-8;

double lb[2] = { 0,0 };

double ub[2] = { INF,INF };

double x[2] = { 1,1 };

double f_max = -INF;

// set up optimizer

nlopt_opt opter = nlopt_create(NLOPT_LD_SLSQP, 2);

// lower and upper bound

nlopt_set_lower_bounds(opter, lb);

nlopt_set_upper_bounds(opter, ub);

// objective function

nlopt_set_max_objective(opter, utility, NULL);

// equality constraint

nlopt_add_equality_constraint(opter, constraint, p, tol);

// inequality constraint

nlopt_add_inequality_constraint(opter, inconstraint, NULL, tol);

// stopping criterion

nlopt_set_xtol_rel(opter, tol);

nlopt_set_ftol_abs(opter, tol);

nlopt_set_force_stop(opter, tol);

// optimize

nlopt_result result = nlopt_optimize(opter, x, &f_max);

if (result)

printf("Maximum utility=%f, x=(%f,%f)\n", f_max, x[0], x[1]);

// free

nlopt_destroy(opter);

return 0;

}

  • 程序非常快速的收敛到了正确的结果:

Nlopt优化包在Windows上的安装配置及应用案例优化结果

5.总结

        关于nlopt的入门应用,上述内容已经非常的详细。还有一些稍微高深的用法需要读者自己根据实际情况变通。

        比如实际应用中,可能会需要更进一步的用C++语法的继承、派生等写出基于此文叙述基础上的代码框架,可以将等式约束,不等式约束,目标函数集中在一个函数中形成类似于MATLAB中fmincon函数类似的形式。

        还有关于步骤【 将libnlopt-0.dll文件复制到vs2015的的目录下 】在实际项目研发中并不适用,可移植性很差,进一步涉及到dll文件调用方法,这部分的帖子将会陆续发布。

参考链接:

https://zhuanlan.zhihu.com/econcode/24350637

http://nlopt.readthedocs.io/en/latest/NLopt_on_Windows

http://blog.csdn.net/qq_37043191/article/details/78473386

http://blog.csdn.net/yunfeiyang62/article/details/45949701