7.4. PuLP¶
Pulp is a third-party open source modeling language developed based on Python. It supports modeling and analysis of problems such as linear programming, mixed integer programming, and nonlinear programming, and calls other commercial or open source solvers to solve them.
Currently, MindOpt can solve linear programming models built with Pulp on Windows/Linux/macOS platforms. For more details about Pulp, please refer to Pulp official documentation.
In this section, we describe how to use the PuLP API to formulate the optimization problem in Example of Linear Programming and call MindOpt to solve it.
7.4.1. Install PuLP¶
Users must first install MindOpt. For installation and configuration of MindOpt, please refer to Software Installation. After MindOpt is installed, users can install PuLP in the following two ways:
Use
pip
command to install:pip install pulp
Use
git
command to install:pip install -U git+https://github.com/coin-or/pulp
For the detailed installation method of PuLP, please refer to PuLP official website or PyPi.
7.4.2. PuLP Interface¶
MindOpt defines the necessary interfaces for PuLP to call MindOpt in the PuLP interface file (mindopt_pulp.py
). This interface inherits from PuLP’s LpSolver
class. Implementation details can be found in the interface file within the installation package:
<MDOHOME>/<VERSION>/<PLATFORM>/lib/pulp/mindopt_pulp.py
When users want to use it, they first need to move this interface file to the current working directory and load the MINDOPT
class defined in this module in the Python code:
25from mindopt_pulp import MINDOPT
Next, we call the PuLP API to set up the optimization problem in Example of Linear Programming. For detailed information about the PuLP API, please refer to the PuLP official documentation.
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")
Before solving, we specify using the MindOpt solver and set the relevant parameters for solving (for solver parameters, please refer to 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}
Finally, we call PuLP’s solve()
function to solve and obtain the relevant results:
75 prob.solve(MINDOPT(options=options))
7.4.3. Modeling Example: mdo_pulp_lo_ex1¶
The complete code is provided in the file link mdo_pulp_lo_ex1.py:
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))