5.6.10. MISOCP Modeling and Optimization in Java¶
In this chapter, we will use MindOpt JAVA API to model and solve the mixed-integer second-order cone program in MIQCP Example II.
Import the MindOpt package:
25 */
Create an optimization environment and model:
29 public static void main(String[] args) {
30 // Create environment and model.
31 MDOEnv env = new MDOEnv();
Next, we set the model name and optimization sense. Then, we call MDOModel.addVar to add five variables. Their lower bounds, upper bounds, types, names, and linear objective coefficients are all passed directly as arguments.
Note
To mark a variable as integer, set its type to 'I' in the call to MDOModel.addVar.
35 // Step 1. Input model.
36 model.set(MDO.StringAttr.ModelName, "MISOCPEx1");
37
38 // Change to minimization problem.
39 model.set(MDO.IntAttr.ModelSense, MDO.MINIMIZE);
40
41 // Add variables. The linear objective coefficients are specified directly.
42 MDOVar[] x = new MDOVar[5];
43 x[0] = model.addVar(0.0, 10.0, 1.0, 'I', "x0");
44 x[1] = model.addVar(0.0, MDO.INFINITY, 2.0, 'I', "x1");
45 x[2] = model.addVar(0.0, MDO.INFINITY, 1.0, 'I', "x2");
46 x[3] = model.addVar(0.0, MDO.INFINITY, 1.0, 'C', "x3");
Note
Since the linear objective coefficients are passed directly during variable creation, there is no separate call to MDOModel.setObjective.
We now add the linear constraints. For the Java API, this involves creating an MDOExpr object for each constraint and adding terms to it.
Constraint c0: \(x_0 + x_1 + 2x_2 + 3x_3 \geq 1\)
Constraint c1: \(x_0 - x_2 + 6x_3 = 1\)
These are added to the model using MDOModel.addConstr:
48 // Add linear constraint c0: 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
49 MDOExpr c0_expr = new MDOExpr();
50 c0_expr.addTerms(new double[] { 1.0, 1.0, 2.0, 3.0 }, new MDOVar[] { x[0], x[1], x[2], x[3] });
51 model.addConstr(c0_expr, MDO.GREATER_EQUAL, 1.0, "c0");
52
53 // Add linear constraint c1: 1 x0 - 1 x2 + 6 x3 = 1
54 MDOExpr c1_expr = new MDOExpr();
55 c1_expr.addTerms(new double[] { 1.0, -1.0, 6.0 }, new MDOVar[] { x[0], x[2], x[3] });
Finally, we add the quadratic (second-order cone) constraint:
c2: \(x_1^2 + x_2^2 - x_4^2 \leq 0\)
This is done by creating an MDOQuadExpr object and adding the quadratic terms. The constraint is then added to the model using MDOModel.addQConstr.
58 // Add second-order cone constraint c2: x_1^2 + x_2^2 - x_4^2 <= 0
59 MDOQuadExpr c2_expr = new MDOQuadExpr();
60 // This constraint has no linear part. We only add the quadratic terms.
61 c2_expr.addTerms(
62 new double[] { 1.0, 1.0, -1.0 }, // values
63 new MDOVar[] { x[1], x[2], x[4] }, // first variable indices
64 new MDOVar[] { x[1], x[2], x[4] } // second variable indices
65 );
Once the model is fully constructed, we solve it by calling MDOModel.optimize:
69 // Step 2. Solve the problem.
After solving, we check the solution status and retrieve the optimal objective value and variable values.
77 // exist, making it necessary to check the SolCount property.
78 if (model.get(MDO.IntAttr.Status) == MDO.OPTIMAL || model.get(MDO.IntAttr.Status) == MDO.SUB_OPTIMAL
79 || model.get(MDO.IntAttr.SolCount) > 0) {
80 System.out.println("Optimal objective value is: " + model.get(MDO.DoubleAttr.ObjVal));
81 System.out.println("Decision variables: ");
82 for (int i = 0; i < 5; i++) {
83 System.out.println("x[" + i + "] = " + x[i].get(MDO.DoubleAttr.X));
84 }
85 } else {
86 System.out.println("No feasible solution.");
Finally, we dispose of the model and environment to free up resources.
95 } finally {
96 // Step 4. Free the model.
97 model.dispose();
The complete example code is shown in MdoMISOCPEx1.java:
1/**
2 * Description
3 * -----------
4 *
5 * Formulation
6 * -----------
7 *
8 Minimize
9 * obj: 1 x0 + 2 x1 + 1 x2 + 1 x3 + 0.5 x_4
10 *
11 *
12 * Subject To
13 * c0 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
14 * c1 : 1 x0 - 1 x2 + 6 x3 = 1
15 * c2 : x_1^2 + x_2^2 - x_4^2 <= 0
16 * Bounds
17 * 0 <= x0 <= 10
18 * 0 <= x1
19 * 0 <= x2
20 * 0 <= x3
21 * 0 <= x4
22 * Integer
23 * x0, x1, x2
24 * End
25 */
26import com.alibaba.damo.mindopt.*;
27
28public class MdoMISOCPEx1 {
29 public static void main(String[] args) {
30 // Create environment and model.
31 MDOEnv env = new MDOEnv();
32 MDOModel model = new MDOModel(env);
33
34 try {
35 // Step 1. Input model.
36 model.set(MDO.StringAttr.ModelName, "MISOCPEx1");
37
38 // Change to minimization problem.
39 model.set(MDO.IntAttr.ModelSense, MDO.MINIMIZE);
40
41 // Add variables. The linear objective coefficients are specified directly.
42 MDOVar[] x = new MDOVar[5];
43 x[0] = model.addVar(0.0, 10.0, 1.0, 'I', "x0");
44 x[1] = model.addVar(0.0, MDO.INFINITY, 2.0, 'I', "x1");
45 x[2] = model.addVar(0.0, MDO.INFINITY, 1.0, 'I', "x2");
46 x[3] = model.addVar(0.0, MDO.INFINITY, 1.0, 'C', "x3");
47 x[4] = model.addVar(0.0, MDO.INFINITY, 0.5, 'C', "x4");
48
49 // Add linear constraint c0: 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
50 MDOExpr c0_expr = new MDOExpr();
51 c0_expr.addTerms(new double[] { 1.0, 1.0, 2.0, 3.0 }, new MDOVar[] { x[0], x[1], x[2], x[3] });
52 model.addConstr(c0_expr, MDO.GREATER_EQUAL, 1.0, "c0");
53
54 // Add linear constraint c1: 1 x0 - 1 x2 + 6 x3 = 1
55 MDOExpr c1_expr = new MDOExpr();
56 c1_expr.addTerms(new double[] { 1.0, -1.0, 6.0 }, new MDOVar[] { x[0], x[2], x[3] });
57 model.addConstr(c1_expr, MDO.EQUAL, 1.0, "c1");
58
59 // Add second-order cone constraint c2: x_1^2 + x_2^2 - x_4^2 <= 0
60 MDOQuadExpr c2_expr = new MDOQuadExpr();
61 // This constraint has no linear part. We only add the quadratic terms.
62 c2_expr.addTerms(
63 new double[] { 1.0, 1.0, -1.0 }, // values
64 new MDOVar[] { x[1], x[2], x[4] }, // first variable indices
65 new MDOVar[] { x[1], x[2], x[4] } // second variable indices
66 );
67 model.addQConstr(c2_expr, MDO.LESS_EQUAL, 0.0, "c2");
68
69 // Step 2. Solve the problem.
70 model.optimize();
71
72 // Step 3. Retrieve model status and solution.
73 // For MIP(MILP,MIQP, MIQCP) problems, if the solving process
74 // terminates early due to reasons such as timeout or interruption,
75 // the model status will indicate termination by timeout (or
76 // interruption, etc.). However, suboptimal solutions may still
77 // exist, making it necessary to check the SolCount property.
78 if (model.get(MDO.IntAttr.Status) == MDO.OPTIMAL || model.get(MDO.IntAttr.Status) == MDO.SUB_OPTIMAL
79 || model.get(MDO.IntAttr.SolCount) > 0) {
80 System.out.println("Optimal objective value is: " + model.get(MDO.DoubleAttr.ObjVal));
81 System.out.println("Decision variables: ");
82 for (int i = 0; i < 5; i++) {
83 System.out.println("x[" + i + "] = " + x[i].get(MDO.DoubleAttr.X));
84 }
85 } else {
86 System.out.println("No feasible solution.");
87 }
88 } catch (MDOException e) {
89 System.out.println("Received Mindopt exception.");
90 System.out.println(" - Code : " + e.getErrorCode());
91 System.out.println(" - Reason : " + e.getMessage());
92 } catch (Exception e) {
93 System.out.println("Received exception.");
94 System.out.println(" - Reason : " + e.getMessage());
95 } finally {
96 // Step 4. Free the model.
97 model.dispose();
98 env.dispose();
99 }
100 }
101}