5.3.4. QP modeling and optimization in Python

This topic describes how to use the Python API of MindOpt to build a model and solve the problem in Examples of quadratic programming problems.

5.3.4.1. Input by row: mdo_qo_ex1

Load the Python package.

25from mindoptpy import *

Create an optimization model.

32    # Step 1. Create a model and change the parameters.
33    model = MdoModel()

Call mindoptpy.MdoModel.set_int_attr() to set the target function to Minimization, call mindoptpy.MdoModel.add_var() to add four optimization variables, and define the upper bound, lower bound, names, and types of the variables. For more information about how to use mindoptpy.MdoModel.set_int_attr() and mindoptpy.MdoModel.add_var(), see Python API.

36        # Step 2. Input model.
37        # Change to minimization problem.
38        model.set_int_attr(MDO_INT_ATTR.MIN_SENSE, 1)
39        
40        # Add variables.
41        x = []
42        x.append(model.add_var(0.0,         10.0, 1.0, None, "x0", False))
43        x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x1", False))
44        x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x2", False))
45        x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x3", False))

Add linear constraints.

46        # Add constraints.
47        # Note that the nonzero elements are inputted in a row-wise order here.
48        model.add_cons(1.0, MDO_INFINITY, 1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3], "c0")
49        model.add_cons(1.0,          1.0, 1.0 * x[0]              - 1.0 * x[2] + 6.0 * x[3], "c1")

Call mindoptpy.MdoModel.set_quadratic_elements() to set the quadratic coefficient \(Q\) for the object. The former two groups of vectors indicate the indexes of the two variables of all non-zero elements in the quadratic term, respectively, and the last group of vectors indicate the corresponding non-zero coefficient values.

Note

To ensure the symmetry of \(Q\), you only need to input the triangle part, which will be multiplied by 1/2 inside the solver.

52        # Add quadratic objective matrix Q.
53        #
54        #  Note.
55        #  1. The objective function is defined as c^Tx + 1/2 x^TQx, where Q is stored with coordinate format.
56        #  2. Q will be scaled by 1/2 internally.
57        #  3. To ensure the symmetricity of Q, user needs to input only the lower triangular part.
58        #
59        # Q = [ 1.0  0.5  0    0   ]
60        #     [ 0.5  1.0  0    0   ]
61        #     [ 0.0  0.0  1.0  0   ]
62        #     [ 0    0    0    1.0 ]
63        model.set_quadratic_elements([ x[0], x[1], x[1], x[2], x[3] ], [ x[0], x[0], x[1], x[2], x[3] ], [  1.0,  0.5,  1.0,  1.0,  1.0 ])

Call mindoptpy.MdoModel.solve_prob() to solve the optimization problem, and call mindoptpy.MdoModel.display_results() to view the optimization result.

65        # Step 3. Solve the problem and populate the result.
66        model.solve_prob()
67        model.display_results()

Call mindoptpy.MdoModel.free_mdl() to release the memory.

78        model.free_mdl()

The linked file mdo_qo_ex1.py provides complete source code:

 1"""
 2/**
 3 *  Description
 4 *  -----------
 5 *
 6 *  Quadratuc optimization (row-wise input).
 7 *
 8 *  Formulation
 9 *  -----------
10 *
11 *  Minimize
12 *    obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
13 *         + 1/2 [ x0^2 + x1^2 + x2^2 + x3^2 + x0 x1]
14 *  Subject To
15 *   c1 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
16 *   c2 : 1 x0 - 1 x2 + 6 x3 = 1
17 *  Bounds
18 *    0 <= x0 <= 10
19 *    0 <= x1
20 *    0 <= x2
21 *    0 <= x3
22 *  End
23 */
24"""
25from mindoptpy import *
26
27
28if __name__ == "__main__":
29
30    MDO_INFINITY = MdoModel.get_infinity()
31
32    # Step 1. Create a model and change the parameters.
33    model = MdoModel()
34
35    try:
36        # Step 2. Input model.
37        # Change to minimization problem.
38        model.set_int_attr(MDO_INT_ATTR.MIN_SENSE, 1)
39        
40        # Add variables.
41        x = []
42        x.append(model.add_var(0.0,         10.0, 1.0, None, "x0", False))
43        x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x1", False))
44        x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x2", False))
45        x.append(model.add_var(0.0, MDO_INFINITY, 1.0, None, "x3", False))
46
47        # Add constraints.
48        # Note that the nonzero elements are inputted in a row-wise order here.
49        model.add_cons(1.0, MDO_INFINITY, 1.0 * x[0] + 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3], "c0")
50        model.add_cons(1.0,          1.0, 1.0 * x[0]              - 1.0 * x[2] + 6.0 * x[3], "c1")
51
52        # Add quadratic objective matrix Q.
53        #
54        #  Note.
55        #  1. The objective function is defined as c^Tx + 1/2 x^TQx, where Q is stored with coordinate format.
56        #  2. Q will be scaled by 1/2 internally.
57        #  3. To ensure the symmetricity of Q, user needs to input only the lower triangular part.
58        #
59        # Q = [ 1.0  0.5  0    0   ]
60        #     [ 0.5  1.0  0    0   ]
61        #     [ 0.0  0.0  1.0  0   ]
62        #     [ 0    0    0    1.0 ]
63        model.set_quadratic_elements([ x[0], x[1], x[1], x[2], x[3] ], [ x[0], x[0], x[1], x[2], x[3] ], [  1.0,  0.5,  1.0,  1.0,  1.0 ])
64
65        # Step 3. Solve the problem and populate the result.
66        model.solve_prob()
67        model.display_results()
68
69    except MdoError as e:
70        print("Received Mindopt exception.")
71        print(" - Code          : {}".format(e.code))
72        print(" - Reason        : {}".format(e.message))
73    except Exception as e:
74        print("Received exception.")
75        print(" - Reason        : {}".format(e))
76    finally:
77        # Step 4. Free the model.
78        model.free_mdl()