5.2.2. MILP modeling and optimization in C¶
This topic describes how to use the C API of MindOpt to build a model and solve the problem in Examples of MILP problems.
5.2.2.1. Input by row: MdoMiloEx1¶
First, load the header file.
25#include "Mindopt.h"
Create an optimization model.
54 /*------------------------------------------------------------------*/
55 /* Step 1. Create a model and change the parameters. */
56 /*------------------------------------------------------------------*/
57 /* Create an empty model. */
58 MDO_CHECK_CALL(Mdo_createMdl(&model));
Call Mdo_setIntAttr()
to set the target function to Minimization, call Mdo_addCol()
to add four optimization variables, and define the upper and lower bounds, names, and types of the variables. For more information about how to use Mdo_setIntAttr()
and Mdo_addCol()
, see C API.
60 /*------------------------------------------------------------------*/
61 /* Step 2. Input model. */
62 /*------------------------------------------------------------------*/
63 /* Change to minimization problem. */
64 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
65
66 /* Add variables. */
67 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, 10.0, 1.0, 0, NULL, NULL, "x0", MDO_YES));
68 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x1", MDO_YES));
69 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x2", MDO_YES));
70 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x3", MDO_NO));
Note
In the function Mdo_addCol()
, the last parameter is is_integer
which means the variable is integer when it is set as MDO_YES
.
Then, add non-zero elements and their upper and lower bounds of linear constraints.
49 const int row1_idx[] = { 0, 1, 2, 3 };
50 const double row1_val[] = { 1.0, 1.0, 2.0, 3.0 };
51 const int row2_idx[] = { 0, 2, 3 };
52 const double row2_val[] = { 1.0, -1.0, 6.0 };
Call Mdo_addRow()
to input the constraints.
72 /* Add constraints.
73 * Note that the nonzero elements are inputted in a row-wise order here.
74 */
75 MDO_CHECK_CALL(Mdo_addRow(model, 1.0, MDO_INFINITY, 4, row1_idx, row1_val, "c0"));
76 MDO_CHECK_CALL(Mdo_addRow(model, 1.0, 1.0, 3, row2_idx, row2_val, "c1"));
After the modeling is completed, call Mdo_solveProb()
to solve the optimization problem and call Mdo_displayResults()
to view the optimization result.
78 /*------------------------------------------------------------------*/
79 /* Step 3. Solve the problem and populate the result. */
80 /*------------------------------------------------------------------*/
81 /* Solve the problem. */
82 MDO_CHECK_CALL(Mdo_solveProb(model));
83 Mdo_displayResults(model);
At the end, call Mdo_freeMdl()
to release the memory.
85 /*------------------------------------------------------------------*/
86 /* Step 4. Free the model. */
87 /*------------------------------------------------------------------*/
88 /* Free the model. */
89 Mdo_freeMdl(&model);
The linked file MdoMiloEx1.c provides the complete source code:
1/**
2 * Description
3 * -----------
4 *
5 * Linear optimization (row-wise input).
6 *
7 * Formulation
8 * -----------
9 *
10 * Minimize
11 * obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
12 * Subject To
13 * c0 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
14 * c1 : 1 x0 - 1 x2 + 6 x3 = 1
15 * Bounds
16 * 0 <= x0 <= 10
17 * 0 <= x1
18 * 0 <= x2
19 * 0 <= x3
20 * Integers
21 * x0 x1 x2
22 * End
23 */
24#include <stdio.h>
25#include "Mindopt.h"
26
27/* Macro to check the return code */
28#define MDO_CHECK_CALL(MDO_CALL) \
29 code = MDO_CALL; \
30 if (code != MDO_OKAY) \
31 { \
32 Mdo_explainResult(model, code, str); \
33 Mdo_freeMdl(&model); \
34 fprintf(stderr, "===================================\n"); \
35 fprintf(stderr, "Error : code <%d>\n", code); \
36 fprintf(stderr, "Reason : %s\n", str); \
37 fprintf(stderr, "===================================\n"); \
38 return (int)code; \
39 }
40
41int main(void)
42{
43 /* Variables. */
44 char str[1024] = { "\0" };
45 MdoMdl * model = NULL;
46 MdoResult code = MDO_OKAY;
47 MdoStatus status = MDO_UNKNOWN;
48
49 const int row1_idx[] = { 0, 1, 2, 3 };
50 const double row1_val[] = { 1.0, 1.0, 2.0, 3.0 };
51 const int row2_idx[] = { 0, 2, 3 };
52 const double row2_val[] = { 1.0, -1.0, 6.0 };
53
54 /*------------------------------------------------------------------*/
55 /* Step 1. Create a model and change the parameters. */
56 /*------------------------------------------------------------------*/
57 /* Create an empty model. */
58 MDO_CHECK_CALL(Mdo_createMdl(&model));
59
60 /*------------------------------------------------------------------*/
61 /* Step 2. Input model. */
62 /*------------------------------------------------------------------*/
63 /* Change to minimization problem. */
64 MDO_CHECK_CALL(Mdo_setIntAttr(model, MDO_INT_ATTR_MIN_SENSE, MDO_YES));
65
66 /* Add variables. */
67 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, 10.0, 1.0, 0, NULL, NULL, "x0", MDO_YES));
68 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x1", MDO_YES));
69 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x2", MDO_YES));
70 MDO_CHECK_CALL(Mdo_addCol(model, 0.0, MDO_INFINITY, 1.0, 0, NULL, NULL, "x3", MDO_NO));
71
72 /* Add constraints.
73 * Note that the nonzero elements are inputted in a row-wise order here.
74 */
75 MDO_CHECK_CALL(Mdo_addRow(model, 1.0, MDO_INFINITY, 4, row1_idx, row1_val, "c0"));
76 MDO_CHECK_CALL(Mdo_addRow(model, 1.0, 1.0, 3, row2_idx, row2_val, "c1"));
77
78 /*------------------------------------------------------------------*/
79 /* Step 3. Solve the problem and populate the result. */
80 /*------------------------------------------------------------------*/
81 /* Solve the problem. */
82 MDO_CHECK_CALL(Mdo_solveProb(model));
83 Mdo_displayResults(model);
84
85 /*------------------------------------------------------------------*/
86 /* Step 4. Free the model. */
87 /*------------------------------------------------------------------*/
88 /* Free the model. */
89 Mdo_freeMdl(&model);
90
91 return (int)code;
92}