前言
最近在做的课题需要用到NLopt库来优化,然而配置环境困住了我至少四天。上网搜索了很多相关内容,根据这篇博客成功配合命令行使用,但是想要运行在vs上还是有困难。参考Gabriel Domingos的博客,我成功在VS2022上面配置了NLopt,现在记录一下整个过程。原博客指路
准备工具
- Git Bash,如果需要下载,点击这里
- CMake, 如果需要下载,点击这里
- Visual Studio, 如果需要下载,点击这里 。作者使用的是2022版本。下载完成VS后,记得下载C++开发工具,具体配置C++环境,可参考这里。
现在准备好了这些,开始安装吧!
开始安装
使用Git Bash下载NLopt
- 在你想要安装的文件夹(我这里安装的文件夹位置是D:\OpenSource\nlopt)下打开Git Bash(在文件夹中右键可以看到Open Git Bash here),然后键入以下命令:
git clone https://github.com/stevengj/nlopt
- 之后你会在当前选择的文件夹下得到一个nlopt文件夹,其中包含的是GitHub上最新版本的NLopt。于是我当前的文件结构为D:\OpenSource\nlopt\nlopt.
使用CMake为Visual Studio构建工程
-
打开CMake GUI(可以在安装的CMake文件夹中找到),在 “Where is source code” 中输入你的nlopt文件夹位置,在我的例子中是 D:\OpenSource\nlopt\nlopt
-
在 “Where to build the binaries” 选择文件夹放CMake构建的二进制文件。我在当前文件夹下创建了新的build文件夹,该文件夹的路径为 D:\OpenSource\nlopt\nlopt\build
-
点击 Generate 并确认你的Visual Studio 版本,我的选择是 Visual Studio 17 2022。点击 Finish。
-
之后点击 Generate 然后等待,出现 Generating done 说明创建成功。
-
点击 Open Project,这会自动打开一个Visual Studio界面,如下图
- 在这个界面中,在右侧,确保你有 ALL_BUILD
- 选择编译模式为 Release
- 选择你适合的x86或者x64格式
- 在上方菜单栏,点击 生成 中的 生成解决方案
以上步骤将为所选的配置和平台构建库。在完成 Release 模式后,你可以选择 Debug 再重复第四个步骤。
在Visual Studio中创建一个简单的例子
- 打开 Visual Studio,创建新空白项目。
- 新建一个 main.cpp 文件,复制以下代码:
#include <iomanip> #include <iostream> #include <vector> #include <nlopt.hpp> typedef struct { double a, b; } my_constraint_data; double myvfunc(const std::vector<double>& x, std::vector<double>& grad, void* my_func_data) { if (!grad.empty()) { grad[0] = 0.0; grad[1] = 0.5 / sqrt(x[1]); } return sqrt(x[1]); } double myvconstraint(const std::vector<double>& x, std::vector<double>& grad, void* data) { my_constraint_data* d = reinterpret_cast<my_constraint_data*>(data); double a = d->a, b = d->b; if (!grad.empty()) { 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 main() { nlopt::opt opt(nlopt::LD_MMA, 2); std::vector<double> lb(2); lb[0] = -HUGE_VAL; lb[1] = 0; opt.set_lower_bounds(lb); opt.set_min_objective(myvfunc, NULL); my_constraint_data data[2] = { {2,0}, {-1,1} }; opt.add_inequality_constraint(myvconstraint, &data[0], 1e-8); opt.add_inequality_constraint(myvconstraint, &data[1], 1e-8); opt.set_xtol_rel(1e-4); std::vector<double> x(2); x[0] = 1.234; x[1] = 5.678; double minf; try { nlopt::result result = opt.optimize(x, minf); std::cout << "found minimum at f(" << x[0] << "," << x[1] << ") = " << std::setprecision(10) << minf << std::endl; } catch (std::exception& e) { std::cout << "nlopt failed: " << e.what() << std::endl; } }
这与 NLopt 教程中的代码几乎相同 - NLopt 文档的 C++ 选项卡中的示例,但从原始代码中更正了一些拼写错误。
当你粘贴并保存以上代码到main.cpp文件中时,可以看到Visual Studio提示这份代码有些问题,但是先别着急,后面让我们来配置Visual Studio项目解决这个情况。
配置Visual Studio项目
- 在右侧 解决方案,点击鼠标右键,选择 属性,进入到 属性页。
- 将配置改为 所有配置, 平台改为 所有平台。
- 在左侧的标签菜单上,选择 配置属性 ->调试 ->环境, 编辑上以下内容:
这个地址是nlopt.dll所在的位置, 如果你的nlopt文件夹位置和我不一样,请找到相应的位置键入。PATH=%PATH%;D:\OpenSource\nlopt\nlopt\build\$(Configuration)
- 选择 VC++目录 ->库目录, 编辑上以下内容:
这个地址是nlopt.lib所在的位置D:\OpenSource\nlopt\nlopt\build\$(Configuration)
- 选择 C/C++ -> 通用 -> 附加包含目录,编辑以下内容:
第一行为nlopt.h文件的位置,第二行为nlopt.hpp文件的位置D:\OpenSource\nlopt\nlopt\src\api D:\OpenSource\nlopt\nlopt\build
- 选择 链接器 -> 输入 -> 附加依赖项,编辑以下内容:
nlopt.lib
- 应用并保存以上所有配置。
- 现在你可以看到,之前提示的错误全部解决了。
配置成功
代码运行成功的结果为:
found minimum at f(0.333333,0.296296) = 0.5443310474
如果你跟我一样配置成功了,会有相同的结果。
—2024.08.24 更新 —
找不到nlopt.dll文件可能的解决办法
如果你是运行已有的项目,修改好配置后依旧显示找不到nlopt.dll文件,另外一种可以尝试的方法:直接找到你的nlopt.dll文件,将其复制到项目的debug或release文件夹下(一般和项目在同一个文件夹,或在同一个文件夹的x64文件夹内)随后即可解决。