6.3. Modeling and optimization in PuLP¶
PuLP is a third-party open-source modeling language developed based on Python. It supports modeling and analysis for linear programming, mixed-integer programming, and nonlinear programming problems, and it calls other commercial or open-source solvers to solve the problems.
At present, MindOpt allows you to build a linear programming model by using PuLP on Windows, Linux, or OSX and call MindOpt to solve problems. For more information about PuLP, see the official document.
This topic describes how to use PuLP API to build a model for the optimization problem in Examples of linear programming problems and call MindOpt to solve the problem.
6.3.1. Install PuLP¶
To use PuLP, you need to install MindOpt first. For more information about how to install and configure MindOpt, see Installation. After installing MindOpt, install PuLP in the following two ways:
Use the
pip
commandpip install pulp
Use the
git
commandpip install -U git+https://github.com/coin-or/pulp
For more information about how to install PuLP, visit the official website of PuLP.
6.3.2. Call the PuLP API¶
The PuLP API document (mindopt_pulp.py
) of MindOpt defines the API required for PuLP to call MindOpt. This API document is inherited from the LpSolver
category of PuLP and the implementation code is included in the installation package.
<MDOHOME>\<VERSION>\<PLATFORM>\lib\pulp\mindopt_pulp.py
Move this API document to the current directory and load it in the code of Python.
25from mindopt_pulp import MINDOPT
Call the PuLP API to build a model for the optimization problem in Examples of linear programming problems. For more information about the PuLP API, see the official document.
29 # A new LP problem
30 prob = LpProblem("lo_ex1", LpMinimize)
31
32 # Variables
33 # 0 <= x0 <= 10
34 x0 = LpVariable("x0", 0, 10)
35 # 0 <= x1
36 x1 = LpVariable("x1", 0)
37 # 0 <= x2
38 x2 = LpVariable("x2", 0)
39 # 0 <= x3
40 x3 = LpVariable("x3", 0)
41 # Use None for +/- Infinity, i.e. x <= 0 -> LpVariable("x", None, 0)
42
43 # Objective
44 prob += x0 + 1 * x1 + 1 * x2 + 1 * x3, "obj"
45 # (the name at the end is facultative)
46
47 # Constraints
48 """
49 c1 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
50 c2 : 1 x0 - 1 x2 + 6 x3 = 1
51 """
52 prob += x0 + x1 + 2 * x2 + 3 * x3 >= 1, "c1"
53 prob += x0 - x2 + 6 * x3 == 1, "c2"
54 # (the names at the end are facultative)
55
56 # Write the problem as an MPS file
57 prob.writeMPS("lo_ex1.mps")
Specify the solver to MindOpt and set the related parameters. For more information about parameters, see Optional input parameters.
61 options = {
62 "Method": -1,
63 "NumThreads": 0,
64 "Presolve": 1,
65 "Dualization": -1,
66 "SPX/MaxIterations": 2147483647,
67 "SPX/ColumnGeneration": -1,
68 "IPM/MaxIterations": 400,
69 "MaxTime": 1.7976931348623158e+308,
70 "SPX/PrimalTolerance": 1.E-6,
71 "SPX/DualTolerance": 1.E-6,
72 "IPM/PrimalTolerance": 1.E-8,
73 "IPM/DualTolerance": 1.E-8,
74 "IPM/GapTolerance": 1.E-8}
Call the solve()
function of PuLP and obtain related results.
75 prob.solve(MINDOPT(options=options))
6.3.3. Modeling example: mdo_pulp_lo_ex1¶
The linked file mdo_pulp_lo_ex1.py provides complete code.
1"""
2/**
3 * Description
4 * -----------
5 *
6 * Linear optimization (row-wise input).
7 *
8 * Formulation
9 * -----------
10 *
11 * Minimize
12 * obj: 1 x0 + 1 x1 + 1 x2 + 1 x3
13 * Subject To
14 * c1 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
15 * c2 : 1 x0 - 1 x2 + 6 x3 = 1
16 * Bounds
17 * 0 <= x0 <= 10
18 * 0 <= x1
19 * 0 <= x2
20 * 0 <= x3
21 * End
22 */
23"""
24from pulp import LpProblem, LpMinimize, LpVariable, LpStatus, value
25from mindopt_pulp import MINDOPT
26
27if __name__ == "__main__":
28
29 # A new LP problem
30 prob = LpProblem("lo_ex1", LpMinimize)
31
32 # Variables
33 # 0 <= x0 <= 10
34 x0 = LpVariable("x0", 0, 10)
35 # 0 <= x1
36 x1 = LpVariable("x1", 0)
37 # 0 <= x2
38 x2 = LpVariable("x2", 0)
39 # 0 <= x3
40 x3 = LpVariable("x3", 0)
41 # Use None for +/- Infinity, i.e. x <= 0 -> LpVariable("x", None, 0)
42
43 # Objective
44 prob += x0 + 1 * x1 + 1 * x2 + 1 * x3, "obj"
45 # (the name at the end is facultative)
46
47 # Constraints
48 """
49 c1 : 1 x0 + 1 x1 + 2 x2 + 3 x3 >= 1
50 c2 : 1 x0 - 1 x2 + 6 x3 = 1
51 """
52 prob += x0 + x1 + 2 * x2 + 3 * x3 >= 1, "c1"
53 prob += x0 - x2 + 6 * x3 == 1, "c2"
54 # (the names at the end are facultative)
55
56 # Write the problem as an MPS file
57 prob.writeMPS("lo_ex1.mps")
58
59 # Solve the problem using the MINDOPT solver
60 # prob.solve(MINDOPT()) # use default options
61 options = {
62 "Method": -1,
63 "NumThreads": 0,
64 "Presolve": 1,
65 "Dualization": -1,
66 "SPX/MaxIterations": 2147483647,
67 "SPX/ColumnGeneration": -1,
68 "IPM/MaxIterations": 400,
69 "MaxTime": 1.7976931348623158e+308,
70 "SPX/PrimalTolerance": 1.E-6,
71 "SPX/DualTolerance": 1.E-6,
72 "IPM/PrimalTolerance": 1.E-8,
73 "IPM/DualTolerance": 1.E-8,
74 "IPM/GapTolerance": 1.E-8}
75 prob.solve(MINDOPT(options=options))
76
77 # Print the status of the solved LP
78 print("Status:", LpStatus[prob.status])
79
80 # Print the value of the variables at the optimum
81 for v in prob.variables():
82 print(v.name, "=", v.varValue)
83
84 # Print the value of the objective
85 print("objective=", value(prob.objective))