4.3. 使用 C++ 语言调用 MindOpt 动态库¶
4.3.1. 简要示意¶
// 方法1:从0.19.0版本开始引入新式的创建模型方式
using mindopt::MdoEnv;
MdoEnv env;
MdoModel model(env);
model.readProb(filename);
model.solveProb();
model.displayResults();
// 方法2:旧式的创建模型方式仍然支持
/*
MdoModel model;
model.readProb(filename);
model.solveProb();
model.displayResults();
*/
后文将说明如何使用 C++ 语言编译和链接 MindOpt 动态库,并提供 C++ 语言的编译示例。该示例将读取 MPS 文件中的优化模型并进行优化求解。
Note
由于动态库只在应用程序实际运行时才进行链接,因此,用户必须在环境变量中指定动态库的路径,以便应用程序能够正确地定位到动态库。若环境变量未指定,则用户必须将动态库放置于应用程序旁。关于环境变量的设置说明,请参阅 安装说明。关于 C++ 语言编译器版本的支持,请参阅 支持平台 中的说明。
Warning
mindoptcpp 的 Linux/OSX 动态库将在运行下面的示例时自动生成。换言之,用户在使用 C++ API 之前必须 至少运行一次 这个例子。
4.3.2. Windows¶
MindOpt 已在 Visual Studio 2017/2019 上进行过测试。关于C++ 语言的编译示例,请参考 <MDOHOME>/<VERSION>/examples/CPP
。
如果要用 Visual Studio 来编译, 用户需要进行如下设置:
创建一个空的 Visual Studio 项目。
选用
x64
为解决方案平台。设置 include 目录 (
<MDOHOME>/<VERSION>/win64-x86/include
)。设置 library 目录 (
<MDOHOME>/<VERSION>/win64-x86/lib
)。添加 library 文件 (Release模式:
mindopt_x_x_x.lib
和mindoptcpp_x_x_x.lib
; Debug模式:mindopt_x_x_x.lib
和mindoptcpp_x_x_xd.lib
)。
Note
Visual Studio 在不同编译环境下(Release或Debug)会采用不同的动态库(msvcrt.lib
(multi-threaded DLL)或 msvcrtd.lib
(multi-threaded DLL debug));用户请务必选用正确的 MindOpt 动态库(mindoptcpp_x_x_x.lib
或 mindoptcpp_x_x_xd.lib
)避免运行错误。
Note
使用旧版本的Visual Studio编译器在执行时可能会遇到DLL执行错误,此时可自行编译 mindoptcpp C++ API来避免问题。编译方式如下:
创建一个空的 Visual Studio 项目。
选用
x64
为解决方案平台。设置 include 目录 (
<MDOHOME>/<VERSION>/win64-x86/include
和<MDOHOME>/<VERSION>/win64-x86/src
)。设置 library 目录 (
<MDOHOME>/<VERSION>/win64-x86/lib
)。添加 library 文件 (
mindopt_x_x_x.lib
)。添加 mindoptcpp C++ API 源代码 (
<MDOHOME>/<VERSION>/win64-x86/src/MindoptCppModel.cpp
)。右键单击目节点,然后选择
属性
->C/C++
->预处理器
->预处理器定义
,添增MDO_BUILDING_DLL
。
4.3.3. Linux¶
关于 C++ 语言的编译示例,请参考 <MDOHOME>/<VERSION>/examples/CPP
。以下为编译方法和测试命令:
cd <MDOHOME>/<VERSION>/examples/CPP
make -f Makefile all
make -f Makefile test
Note
用户需要至少运行此示例一次,以生成 mindoptcpp 动态库。
以下编译时用的 makefile
文件:
INCPATHS=-I../../linux64-x86/include -I.
LIBPATHS=-L../../linux64-x86/lib
MINDOPTLIB=-lmindopt -lmindoptcpp
CCOPT=-std=c++11
LDOPT=-Wl,-rpath-link,./../../linux64-x86/lib -Wl,-rpath,'$$ORIGIN/../../linux64-x86/lib' -pthread -lm -lstdc++ -Wl,--no-as-needed -ldl
CC=g++ -m64
LD=g++ -m64
EXAMPLES=mindoptcpp\
MdoMps
mindoptcpp:
make install -C ../../linux64-x86/src
MdoMps: MdoMps.cpp
$(CC) -c $(INCPATHS) $(CCOPT) -o MdoMps.o MdoMps.cpp
$(LD) $(LIBPATHS) MdoMps.o $(MINDOPTLIB) $(LDOPT) -o MdoMps
4.3.4. OSX¶
关于 C++ 语言的编译示例,请参考 <MDOHOME>/<VERSION>/examples/CPP
。以下为编译方法和测试命令:
cd <MDOHOME>/<VERSION>/examples/CPP
make -f Makefile all
make -f Makefile test
Note
用户必须至少运行此例子一次,用来生成 mindoptcpp 动态库。
用来编译的 makefile
文件的内容如下所示:
INCPATHS=-I../../osx64-x86/include
LIBPATHS=-L../../osx64-x86/lib
MINDOPTLIB=-lmindopt.x.x.x -lmindoptcpp.x.x.x -rpath @executable_path/../../osx64-x86/lib/ -lpthread
CCOPT=-std=c++11
LDOPT=-Wl,-headerpad,128
CC=clang++
LD=clang++
%.o: %.cpp
$(CC) -c -g $(INCPATHS) $(CCOPT) -o $@ $<
mindoptcpp:
make install -C ../../osx64-x86/src
MdoMps: MdoMps.o
$(CC) -g $(LIBPATHS) $(LDOPT) -o $@ $< $(MINDOPTLIB)
install_name_tool -change libmindopt.x.x.x.dylib `pwd`/../../osx64-x86/lib/libmindopt.x.x.x.dylib $@
install_name_tool -change libmindoptcpp.x.x.x.dylib `pwd`/../../osx64-x86/lib/libmindoptcpp.x.x.x.dylib $@
4.3.5. C++ 语言编译示例: MdoMps¶
以下,我们将展示如何用 MindOpt C++ API 来读取 MPS/LP 格式的优化问题并进行求解。
首先导入 C++ 头文件:
8#include "MindoptCpp.h"
然后,创建优化模型:
21 /*------------------------------------------------------------------*/
22 /* Step 1. Create a model and change the parameters. */
23 /*------------------------------------------------------------------*/
24 /* Create an empty model. */
25 MdoModel model;
并使用 mindopt::MdoModel::readProb()
来读取 MPS/LP 格式的优化问题:
29 /*------------------------------------------------------------------*/
30 /* Step 2. Input model. */
31 /*------------------------------------------------------------------*/
32 /* Read model from file. */
33 model.readProb(argv[1]);
最后,使用 mindopt::MdoModel::solveProb()
来求解问题,并调用 mindopt::MdoModel::displayResults()
来查看优化结果。
35 /*------------------------------------------------------------------*/
36 /* Step 3. Solve the problem and populate the result. */
37 /*------------------------------------------------------------------*/
38 /* Solve the problem. */
39 model.solveProb();
40 model.displayResults();
以下为完整的源代码文件 MdoMps.cpp。
1/**
2 * Description
3 * -----------
4 *
5 * Read model from an MPS/LP file, and call optimizer to solve the problem.
6 */
7#include <stdio.h>
8#include "MindoptCpp.h"
9
10using namespace mindopt;
11
12int main(
13 int argc,
14 char * argv[])
15{
16 if (argc != 2)
17 {
18 return 0;
19 }
20
21 /*------------------------------------------------------------------*/
22 /* Step 1. Create a model and change the parameters. */
23 /*------------------------------------------------------------------*/
24 /* Create an empty model. */
25 MdoModel model;
26
27 try
28 {
29 /*------------------------------------------------------------------*/
30 /* Step 2. Input model. */
31 /*------------------------------------------------------------------*/
32 /* Read model from file. */
33 model.readProb(argv[1]);
34
35 /*------------------------------------------------------------------*/
36 /* Step 3. Solve the problem and populate the result. */
37 /*------------------------------------------------------------------*/
38 /* Solve the problem. */
39 model.solveProb();
40 model.displayResults();
41 }
42 catch (MdoException & e)
43 {
44 std::cerr << "===================================" << std::endl;
45 std::cerr << "Error : code <" << e.getResult() << ">" << std::endl;
46 std::cerr << "Reason : " << model.explainResult(e.getResult()) << std::endl;
47 std::cerr << "===================================" << std::endl;
48
49 return static_cast<int>(e.getResult());
50 }
51
52 return static_cast<int>(MDO_OKAY);
53}
在安装包的 <MDOHOME>/<VERSION>/examples/CPP
中可以找到更多 C++ 相关示例文件。