概述
由于NLopt非线性优化库网评非常好,作为编程小白,课题组程序用的C++,编译器是VS,为了找到好用且依赖项不多,引用简单的优化库,觉得这个还可以。但是好的库都是基于Linux或者使用CMake跨平台编译,为了使用这玩意浪费一周时间,终于搞好了。特此想记录下来,希望对那些编程小白,希望使用VS引用的人会有帮助。
文章结构如下:
-
本人电脑系统及软件配置
-
下载文件
-
文件介绍
-
生成lib链接库
-
CMake编译
-
引用配置及测试算例
看了很多博客,最后的测试程序是使用别人的,忘了是谁的了,有时间把链接放上,侵权了麻烦联系,写完已经废了,懒得动了。
这是编译完成后的压缩包,包裹所有过程以及最终版本,欢迎下载。CSDN不能免费,那就TB吧。
(有网友反映不能直接用,可能是因为环境变量没有设置,或者我的文件目录是绝对路径,最好自己做一遍,按照教程最多一晚上就可以了,不建议直接下载)
https://download.csdn.net/download/xingdu_/11889148
本人电脑系统及软件配置
本人电脑配置:Win10+VS2019+CMake(电脑版本win10,win7没验证过。VS使用的VS2019,使用你自己的VS版本就可以。我的VS安装在D盘,但是安装在C盘是最好的,找东西方便。CMake安装很简单就不介绍了)
下载文件
下载:NLopt+官方为C++编译的dll文件+pexports
(网址https://nlopt.readthedocs.io/en/latest/ + https://nlopt.readthedocs.io/en/latest/NLopt_on_Windows/ +
https://sourceforge.net/projects/mingw/files/MinGW/Extension/pexports/pexports-0.47/)
如图所示:
下载完成之后,以我的电脑为例,在F盘下新建文件夹NLopt,将压缩包放进去,如图
按照顺序解压
1:多层压缩文件解压后文件夹F:NLoptpexports-0.47-mingw32-bin.tarpexports-0.47-mingw32-binbin,最后得到pexports.exe文件
2:解压后得到nlopt-2.6.1子文件夹和pax_global_header文件,把nlopt-2.6.1子文件夹内的文件移动到跟目录下,将nlopt-2.6.1根目录命名为nlopt
3:解压
最终文件如下
最终的目录文件如下图所示:
文件介绍
生成lib链接库
所需文件:libnlopt.dll+pexports.exe
把pexports.exe文件放在bin下面,我的是:VSvs2019VCToolsMSVC14.22.27905binHostx64x64,同时在环境变量中添加路径(我的电脑->属性->高级系统设置->高级->环境变量->系统变量->path->新建)。
32位还是64位根据编译时x64/x86决定下载哪个版本
CMD
这三个都可以应该是,找到dll的文件夹
命令:
进入dll文件夹
cd F:NLopttestnloptbin
生成def文件
pexports F:NLopttestnloptbinlibnlopt.dll > F:NLopttestnloptbinlibnlopt.def
生成exp和lib文件
lib /out:F:NLopttestnloptbinlibnlopt.lib /MACHINE:IX86 /DEF:F:NLopttestnloptbinlibnlopt.def
/out:是.lib文件生成的位置,/MACHINE:IX86:表示机器类型,32位机器,/DEF:表示的是.def存放的位置。
https://blog.csdn.net/u010141928/article/details/100515091
https://blog.csdn.net/qq_37043191/article/details/78473386
https://blog.csdn.net/u014571489/article/details/79344676
接下来继续移动文件,将.lib文件移动到lib文件夹,如nlopt文件说明图所示。
移动完成后如图所示
CMake编译
上面准备动作已经差不多了,接下来编译NLopt。
nlopt文件夹下新建bulid文件夹。
打开根目录下的CMakeLists.txt文件(用notepad++等打开方便看行数,记事本打开下面有行数,但是不太方便)。
40行:
option (NLOPT_CXX "enable cxx routines" ON)
option (NLOPT_FORTRAN "enable fortran tests" OFF)
option (BUILD_SHARED_LIBS "Build NLopt as a shared library" ON)
option (NLOPT_PYTHON "build python bindings" ON)
option (NLOPT_OCTAVE "build octave bindings" ON)
option (NLOPT_MATLAB "build matlab bindings" ON)
option (NLOPT_GUILE "build guile bindings" ON)
option (NLOPT_SWIG "use SWIG to build bindings" ON)
第一行CXX表示C++,后面的ON全部改为OFF
option (NLOPT_CXX "enable cxx routines" ON)
option (NLOPT_FORTRAN "enable fortran tests" OFF)
option (BUILD_SHARED_LIBS "Build NLopt as a shared library" OFF)
option (NLOPT_PYTHON "build python bindings" OFF)
option (NLOPT_OCTAVE "build octave bindings" OFF)
option (NLOPT_MATLAB "build matlab bindings" OFF)
option (NLOPT_GUILE "build guile bindings" OFF)
option (NLOPT_SWIG "use SWIG to build bindings" OFF)
296行
if (NLOPT_PYTHON)
find_package (PythonInterp)
find_package (PythonLibs)
find_package (NumPy)
endif ()
使用#屏蔽代码
#if (NLOPT_PYTHON)
# find_package (PythonInterp)
# find_package (PythonLibs)
# find_package (NumPy)
#endif ()
314行:
if (NLOPT_GUILE)
find_package (Guile)
endif ()
if (NLOPT_SWIG)
find_package (SWIG)
if (SWIG_FOUND)
add_subdirectory (src/swig)
endif ()
endif ()
if (NLOPT_OCTAVE)
find_package (Octave)
endif ()
if (NLOPT_MATLAB)
find_package (Matlab COMPONENTS MX_LIBRARY)
endif ()
使用#屏蔽代码
#if (NLOPT_GUILE)
# find_package (Guile)
#endif ()
#if (NLOPT_SWIG)
# find_package (SWIG)
# if (SWIG_FOUND)
# add_subdirectory (src/swig)
# endif ()
#endif ()
#if (NLOPT_OCTAVE)
# find_package (Octave)
#endif ()
#if (NLOPT_MATLAB)
# find_package (Matlab COMPONENTS MX_LIBRARY)
#endif ()
377行
configure_file (cmake/NLoptConfig.cmake.in NLoptConfig.cmake @ONLY)
configure_file (cmake/NLoptConfigVersion.cmake.in NLoptConfigVersion.cmake @ONLY)
使用#屏蔽代码
#configure_file (cmake/NLoptConfig.cmake.in NLoptConfig.cmake @ONLY)
#configure_file (cmake/NLoptConfigVersion.cmake.in NLoptConfigVersion.cmake @ONLY)
如果不修改CMakeLists.txt文件,编译时会提示错误,找到错误中提示的行数屏蔽相应语句即可。
打开CMake,
点击3后如图配置
红色就不用管了
好了,NLopt编译完成,接下来就是配置我们自己的程序了。
引用配置及测试算例
在F:NLopttestnloptbulid打开nlopt.vcxproj,保留方框中的文件,并将tests设为启动项。
运行后如图所示
说明正常,没有问题。并且在F:NLopttestnloptbulid下会生成Release文件,里面有nlopt.lib。
test下新建test_1文件夹,在test_1中新建C++项目。
添加代码
#include<nlopt.h>
#include<nlopt.hpp>
typedef struct
{
double a, b;
}my_constraint_data;
double myconstraint(unsigned n, const double *x, double *grad, void *data)
{
my_constraint_data *d = (my_constraint_data *)data;
double a = d->a, b = d->b;
if (grad)
{
grad[0] = 3 * a*(a*x[0] + b)*(a*x[0] + b);
grad[1] = -1.0;
}
return ((a*x[0] + b)*(a*x[0] + b)*(a*x[0] + b) - x[1]);
}
int count = 0;
double myfunc(unsigned n, const double *x, double *grad, void *my_func_data)
{
++count;
if (grad)
{
grad[0] = 0.0;
grad[1] = 0.5 / sqrt(x[1]);
}
return sqrt(x[1]);
}
int main()
{
double lb[2] = { -HUGE_VAL, 0 };
nlopt_opt opt;
opt = nlopt_create(NLOPT_LD_MMA, 2);
nlopt_set_lower_bounds(opt, lb);
nlopt_set_min_objective(opt, myfunc, NULL);
my_constraint_data data[2] = { { 2, 0 }, { -1, 1 } };
nlopt_add_inequality_constraint(opt, myconstraint, &data[0], 1e-8);
nlopt_add_inequality_constraint(opt, myconstraint, &data[1], 1e-8);
nlopt_set_xtol_rel(opt, 1e-4);
double x[2] = { 1.234, 5.678 };
double minf;
if (nlopt_optimize(opt, x, &minf) < 0)
{
printf("nlopt faild!n");
}
else
{
printf("found minimum after %d evaluationsn",count);
printf("found minimum at f(%g,%g)=&0.10gn", x[0], x[1], minf);
}
nlopt_destroy(opt);
system("pause");
return 0;
}
并且头文件中添加F:NLopttestnloptbulidsrcapi中的nlopt.h,nlopt.hpp文件。(到目前为止,我们只需要bulid文件夹里卖弄的东西。在bulid中找到这两个文件位置添加进去,或者拿出来放到自己程序的目录下也可以,记得include这两个文件的路径就行)
release+x64模式
在项目属性中
C++->常规->附加包含目录->bulid文件夹和头文件的位置
链接器->常规->附加库目录->添加路径F:NLopttestnloptbulidRelease;
链接器->输入->附加依赖项->添加路径F:NLopttestnloptbulidRelease里面的lib文件名nlopt.lib;
完成了,
如下图所示,完成。
最后
以上就是调皮大白为你收集整理的NLopt在C 和Windows平台VS编译器上的配置与使用(超详细教程)的全部内容,希望文章能够帮你解决NLopt在C 和Windows平台VS编译器上的配置与使用(超详细教程)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复