5.2.4. Java 的MILP建模与优化

在本节中,我们将使用 MindOpt JAVA API,以按行输入的形式来建模以及求解 混合整数线性规划问题示例 中的问题。

首先,引入 Java 包:

24 */

并创建优化模型:

30        // Create model
31        MDOEnv env = new MDOEnv();
32        MDOModel model = new MDOModel(env);

接下来,我们通过 MDOModel.set 设置模型属性 ModelSense,将目标函数设置为 最小化,并调用 MDOModel.addVar 来添加四个优化变量,定义其下界、上界、类型和名称(有关模型属性内容及其设置可参考 属性, 其他API请参考 JAVA API):

35        try {
36            // Change to minimization problem.
37            model.set(MDO.IntAttr.ModelSense, MDO.MINIMIZE);
38
39            // Add variables.
40            MDOVar[] x = new MDOVar[4];
41            x[0] = model.addVar(0.0, 10.0, 1.0, 'I', "x0");
42            x[1] = model.addVar(0.0, MDO.INFINITY, 2.0, 'I', "x1");
43            x[2] = model.addVar(0.0, MDO.INFINITY, 1.0, 'I', "x2");

接着,我们开始添加线性约束:

45            // Add constraints.
46            double[][] consV = new double[][] {
47                    { 1.0, 1.0, 2.0, 3.0 },
48                    { 1.0, 0, -1.0, 6.0 }
49            };
50
51            MDOLinExpr tempLinExpr1 = new MDOLinExpr();
52            tempLinExpr1.addTerms(consV[0], x);
53            model.addConstr(tempLinExpr1, MDO.GREATER_EQUAL, 1.0, "c0");
54
55            MDOLinExpr tempLinExpr2 = new MDOLinExpr();
56            tempLinExpr2.addTerms(consV[1], x);

问题输入完成后,再调用 MDOModel.optimize 求解优化问题:

60            // Step 3. Solve the problem and populate the result.

最后用 MDOModel.get 和模型属性值 ObjVal 来查看优化结果和最优目标值,以及 MDOVar.get 和变量属性值 X 来查看优化解的目标值。 其他的属性值请查看 属性 章节。

62            // Step 4. Retrive model status and objective. 
63            // For MIP(MILP,MIQP, MIQCP) problems, if the solving process
64            // terminates early due to reasons such as timeout or interruption,
65            // the model status will indicate termination by timeout (or
66            // interruption, etc.). However, suboptimal solutions may still
67            // exist, making it necessary to check the SolCount property.
68            if (model.get(MDO.IntAttr.Status) == MDO.OPTIMAL || model.get(MDO.IntAttr.Status) == MDO.SUB_OPTIMAL ||
69                model.get(MDO.IntAttr.SolCount) != 0) {
70                System.out.println("Optimal objective value is: " + model.get(MDO.DoubleAttr.ObjVal));

示例 MdoMiloEx1.java 提供了完整源代码:

 1/*
 2 *  Description
 3 *  -----------
 4 *
 5 *  Mixed Integer Linear optimization (row-wise input).
 6 *
 7 *  Formulation
 8 *  -----------
 9 *
10 *  Minimize
11 *    obj: 1 x0 + 2 x1 + 1 x2 + 1 x3
12 *  Subject To
13 *   c1 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
14 *   c2 : 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 */
24import com.alibaba.damo.mindopt.*;
25import java.util.*;
26
27public class MdoMiloEx1 {
28    public static void main(String[] args) throws MDOException {
29        // Create model
30        MDOEnv env = new MDOEnv();
31        MDOModel model = new MDOModel(env);
32        model.set(MDO.StringAttr.ModelName, "MILP_01");
33
34        try {
35            // Change to minimization problem.
36            model.set(MDO.IntAttr.ModelSense, MDO.MINIMIZE);
37
38            // Add variables.
39            MDOVar[] x = new MDOVar[4];
40            x[0] = model.addVar(0.0, 10.0, 1.0, 'I', "x0");
41            x[1] = model.addVar(0.0, MDO.INFINITY, 2.0, 'I', "x1");
42            x[2] = model.addVar(0.0, MDO.INFINITY, 1.0, 'I', "x2");
43            x[3] = model.addVar(0.0, MDO.INFINITY, 1.0, 'C', "x3");
44
45            // Add constraints.
46            double[][] consV = new double[][] {
47                    { 1.0, 1.0, 2.0, 3.0 },
48                    { 1.0, 0, -1.0, 6.0 }
49            };
50
51            MDOLinExpr tempLinExpr1 = new MDOLinExpr();
52            tempLinExpr1.addTerms(consV[0], x);
53            model.addConstr(tempLinExpr1, MDO.GREATER_EQUAL, 1.0, "c0");
54
55            MDOLinExpr tempLinExpr2 = new MDOLinExpr();
56            tempLinExpr2.addTerms(consV[1], x);
57            model.addConstr(tempLinExpr2, MDO.EQUAL, 1.0, "c1");
58
59            // Step 3. Solve the problem and populate the result.
60            model.optimize();
61
62            // Step 4. Retrive model status and objective. 
63            // For MIP(MILP,MIQP, MIQCP) problems, if the solving process
64            // terminates early due to reasons such as timeout or interruption,
65            // the model status will indicate termination by timeout (or
66            // interruption, etc.). However, suboptimal solutions may still
67            // exist, making it necessary to check the SolCount property.
68            if (model.get(MDO.IntAttr.Status) == MDO.OPTIMAL || model.get(MDO.IntAttr.Status) == MDO.SUB_OPTIMAL ||
69                model.get(MDO.IntAttr.SolCount) != 0) {
70                System.out.println("Optimal objective value is: " + model.get(MDO.DoubleAttr.ObjVal));
71                System.out.println("Decision variables: ");
72                for (int i = 0; i < 4; i++) {
73                    System.out.println("x[" + i + "] = " + x[i].get(MDO.DoubleAttr.X));
74                }
75            } else {
76                System.out.println("No feasible solution.");
77            }
78        } catch (Exception e) {
79            System.out.println("Exception during optimization");
80            e.printStackTrace();
81        } finally {
82            model.dispose();
83            env.dispose();
84        }
85    }
86}