4.2. 使用 C 语言调用 MindOpt 动态库¶
4.2.1. 简要示意¶
// 方法1:从0.19.0版本开始引入新式的创建模型方式
MdoEnvPtr env;
MdoMdlPtr model;
Mdo_createEnv(&env);
Mdo_createMdlWithEnv(&model, env);
Mdo_readProb(model, filename);
Mdo_solveProb(model);
Mdo_displayResults(model);
Mdo_freeMdl(&model);
// C SDK 需要手动释放 env
Mdo_freeEnv(&env);
// 方法2:旧式的创建模型方式仍然支持
/*
MdoMdlPtr model;
Mdo_createMdl(&model);
Mdo_readProb(model, filename);
Mdo_solveProb(model);
Mdo_displayResults(model);
Mdo_freeMdl(&model);
*/
后文将说明如何使用 C 语言编译和链接 MindOpt 动态库,并提供 C 语言的编译示例。该示例将读取 MPS 文件中的优化模型并进行优化求解。
4.2.2. Windows¶
MindOpt 已在 Visual Studio 2017/2019 上进行过测试。关于C 语言的编译示例,请参考 <MDOHOME>/<VERSION>/examples/C
。
如果要用 Visual Studio 来编译, 用户需要进行如下设置:
创建一个空的 Visual Studio 项目。
选用
x64
为解决方案平台。设置 include 目录 (
<MDOHOME>/<VERSION>/win64-x86/include
)。设置 library 目录 (
<MDOHOME>/<VERSION>/win64-x86/lib
)。添加 library 文件 (
mindopt_x_x_x.lib
)。
4.2.3. Linux¶
关于 C 语言的编译示例,请参考 <MDOHOME>/<VERSION>/examples/C
。以下为编译方法和测试命令:
cd <MDOHOME>/<VERSION>/examples/C
make -f Makefile all
make -f Makefile test
以下编译时用的 makefile
文件:
INCPATHS=-I../../linux64-x86/include -I.
LIBPATHS=-L../../linux64-x86/lib
MINDOPTLIB=-lmindopt
CCOPT=
LDOPT=-Wl,-rpath-link,./../../linux64-x86/lib -Wl,-rpath,'$$ORIGIN/../../linux64-x86/include' -pthread -lc -lm -Wl,--no-as-needed -ldl
CC=cc -m64
LD=cc -m64
MdoMps: MdoMps.c
$(CC) -c $(INCPATHS) $(CCOPT) -o MdoMps.o MdoMps.c
$(LD) $(LIBPATHS) MdoMps.o $(MINDOPTLIB) $(LDOPT) -o MdoMps
4.2.4. OSX¶
关于 C 语言的编译示例,请参考 <MDOHOME>/<VERSION>/examples/C
。以下为编译方法和测试命令:
cd <MDOHOME>/<VERSION>/examples/C
make -f Makefile all
make -f Makefile test
以下编译时用的 makefile
文件:
INCPATHS=-I../../osx64-x86/include
LIBPATHS=-L../../osx64-x86/lib
MINDOPTLIB=-lmindopt.x.x.x -rpath @executable_path/../../osx64-x86/lib/ -lpthread
CCOPT=
LDOPT=-Wl,-headerpad,128
CC=clang
LD=clang
%.o: %.cpp
$(CC) -c -g $(INCPATHS) $(CCOPT) -o $@ $<
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 $@
4.2.5. C 语言编译示例: MdoMps¶
以下,我们将展示如何用 MindOpt C API 来读取 MPS/LP 格式的优化问题并进行求解。
首先导入 C 头文件:
8#include "Mindopt.h"
然后,创建优化模型:
41 /*------------------------------------------------------------------*/
42 /* Step 1. Create a model and change the parameters. */
43 /*------------------------------------------------------------------*/
44 /* Create an empty model. */
45 MDO_CHECK_CALL(Mdo_createMdl(&model));
并使用 Mdo_readProb()
来读取 MPS/LP 格式的优化问题:
47 /*------------------------------------------------------------------*/
48 /* Step 2. Input model. */
49 /*------------------------------------------------------------------*/
50 /* Read model from file. */
51 MDO_CHECK_CALL(Mdo_readProb(model, filename));
再来,使用 Mdo_solveProb()
来求解问题,并调用 Mdo_displayResults()
来查看优化结果。
53 /*------------------------------------------------------------------*/
54 /* Step 3. Solve the problem and populate the result. */
55 /*------------------------------------------------------------------*/
56 /* Solve the problem. */
57 MDO_CHECK_CALL(Mdo_solveProb(model));
58 Mdo_displayResults(model);
最后,使用 Mdo_freeMdl()
来释放内存空间。
60 /*------------------------------------------------------------------*/
61 /* Step 4. Free the model. */
62 /*------------------------------------------------------------------*/
63 /* Free the model. */
64 Mdo_freeMdl(&model);
以下为完整的源代码文件 MdoMps.c 。
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 "Mindopt.h"
9
10/* Macro to check the return code */
11#define MDO_CHECK_CALL(MDO_CALL) \
12 code = MDO_CALL; \
13 if (code != MDO_OKAY) \
14 { \
15 Mdo_explainResult(model, code, str); \
16 Mdo_freeMdl(&model); \
17 fprintf(stderr, "===================================\n"); \
18 fprintf(stderr, "Error : code <%d>\n", code); \
19 fprintf(stderr, "Reason : %s\n", str); \
20 fprintf(stderr, "===================================\n"); \
21 return (int)code; \
22 }
23
24int main(
25 int argc,
26 char * argv[])
27{
28 if (argc != 2)
29 {
30 return 0;
31 }
32
33 /* Variables. */
34 char str[1024] = { "\0" };
35 char * filename = argv[1];
36 double val = 0.0;
37 MdoMdl * model = NULL;
38 MdoResult code = MDO_OKAY;
39 MdoStatus status = MDO_UNKNOWN;
40
41 /*------------------------------------------------------------------*/
42 /* Step 1. Create a model and change the parameters. */
43 /*------------------------------------------------------------------*/
44 /* Create an empty model. */
45 MDO_CHECK_CALL(Mdo_createMdl(&model));
46
47 /*------------------------------------------------------------------*/
48 /* Step 2. Input model. */
49 /*------------------------------------------------------------------*/
50 /* Read model from file. */
51 MDO_CHECK_CALL(Mdo_readProb(model, filename));
52
53 /*------------------------------------------------------------------*/
54 /* Step 3. Solve the problem and populate the result. */
55 /*------------------------------------------------------------------*/
56 /* Solve the problem. */
57 MDO_CHECK_CALL(Mdo_solveProb(model));
58 Mdo_displayResults(model);
59
60 /*------------------------------------------------------------------*/
61 /* Step 4. Free the model. */
62 /*------------------------------------------------------------------*/
63 /* Free the model. */
64 Mdo_freeMdl(&model);
65
66 return (int)code;
67}
在安装包的 <MDOHOME>/<VERSION>/examples/C
中可以找到更多 C 相关示例文件。