PuLP 3.3.0__tar.gz → 3.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pulp-3.3.0 → pulp-3.3.2}/PKG-INFO +24 -25
- {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/PKG-INFO +24 -25
- {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/SOURCES.txt +1 -0
- {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/requires.txt +5 -3
- {pulp-3.3.0 → pulp-3.3.2}/README.rst +18 -20
- {pulp-3.3.0 → pulp-3.3.2}/pulp/__init__.py +26 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/__init__.py +9 -6
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/coin_api.py +76 -58
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/copt_api.py +10 -10
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/core.py +4 -4
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/cplex_api.py +15 -7
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/cuopt_api.py +5 -5
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/glpk_api.py +7 -8
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/gurobi_api.py +6 -6
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/highs_api.py +9 -6
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/mosek_api.py +7 -7
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/scip_api.py +4 -4
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/xpress_api.py +7 -7
- {pulp-3.3.0 → pulp-3.3.2}/pulp/constants.py +2 -1
- {pulp-3.3.0 → pulp-3.3.2}/pulp/mps_lp.py +6 -6
- {pulp-3.3.0 → pulp-3.3.2}/pulp/pulp.py +403 -74
- {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/bin_packing_problem.py +2 -2
- {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/test_gurobipy_env.py +4 -4
- {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/test_lpdot.py +7 -5
- {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/test_pulp.py +420 -292
- pulp-3.3.2/pulp/v4_migration.py +19 -0
- {pulp-3.3.0 → pulp-3.3.2}/pyproject.toml +5 -4
- {pulp-3.3.0 → pulp-3.3.2}/LICENSE +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/dependency_links.txt +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/entry_points.txt +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/top_level.txt +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/choco_api.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/mipcl_api.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/sas_api.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/__init__.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/arm64/__init__.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/arm64/cbc +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/arm64/coin-license.txt +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i32/__init__.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i32/cbc +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i32/coin-license.txt +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i64/__init__.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i64/cbc +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i64/coin-license.txt +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/osx/i64/__init__.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/osx/i64/cbc +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/osx/i64/coin-license.txt +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i32/__init__.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i32/cbc.exe +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i32/coin-license.txt +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i64/__init__.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i64/cbc.exe +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i64/coin-license.txt +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/sparse.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/__init__.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/run_tests.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/test_examples.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/test_sparse.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/pulp/utilities.py +0 -0
- {pulp-3.3.0 → pulp-3.3.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PuLP
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.2
|
|
4
4
|
Summary: PuLP is an LP modeler written in python. PuLP can generate MPS or LP files and call GLPK, COIN CLP/CBC, CPLEX, and GUROBI to solve linear problems.
|
|
5
5
|
Author: J.S. Roy
|
|
6
6
|
Author-email: "S.A. Mitchell" <pulp@stuartmitchell.com>, Franco Peschiera <pchtsp@gmail.com>
|
|
@@ -15,12 +15,13 @@ Classifier: Intended Audience :: Science/Research
|
|
|
15
15
|
Classifier: Natural Language :: English
|
|
16
16
|
Classifier: Programming Language :: Python
|
|
17
17
|
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
18
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
19
|
Description-Content-Type: text/x-rst
|
|
20
20
|
License-File: LICENSE
|
|
21
|
+
Provides-Extra: cbc
|
|
22
|
+
Requires-Dist: cbcbox; extra == "cbc"
|
|
21
23
|
Provides-Extra: open-py
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist: highspy; extra == "open-py"
|
|
24
|
+
Requires-Dist: highspy==1.13; extra == "open-py"
|
|
24
25
|
Requires-Dist: pyscipopt; extra == "open-py"
|
|
25
26
|
Provides-Extra: public-py
|
|
26
27
|
Requires-Dist: gurobipy; extra == "public-py"
|
|
@@ -28,7 +29,7 @@ Requires-Dist: coptpy; extra == "public-py"
|
|
|
28
29
|
Requires-Dist: xpress; extra == "public-py"
|
|
29
30
|
Requires-Dist: cplex; (sys_platform != "darwin" or python_full_version < "3.12") and extra == "public-py"
|
|
30
31
|
Provides-Extra: highs
|
|
31
|
-
Requires-Dist: highspy; extra == "highs"
|
|
32
|
+
Requires-Dist: highspy==1.13; extra == "highs"
|
|
32
33
|
Provides-Extra: scip
|
|
33
34
|
Requires-Dist: pyscipopt; extra == "scip"
|
|
34
35
|
Provides-Extra: gurobi
|
|
@@ -64,7 +65,7 @@ PuLP is part of the `COIN-OR project <https://www.coin-or.org/>`_.
|
|
|
64
65
|
Installation
|
|
65
66
|
================
|
|
66
67
|
|
|
67
|
-
PuLP requires Python 3.
|
|
68
|
+
PuLP requires Python 3.10 or newer.
|
|
68
69
|
|
|
69
70
|
The easiest way to install PuLP is with ``pip``. If ``pip`` is available on your system, type::
|
|
70
71
|
|
|
@@ -75,8 +76,15 @@ Otherwise follow the download instructions on the `PyPi page <https://pypi.pytho
|
|
|
75
76
|
Installing solvers
|
|
76
77
|
----------------------
|
|
77
78
|
|
|
78
|
-
PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver
|
|
79
|
+
PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver via the ``COIN_CMD`` API. Install CBC with::
|
|
79
80
|
|
|
81
|
+
python -m pip install pulp[cbc]
|
|
82
|
+
|
|
83
|
+
If CBC is not available on your system, PuLP falls back to other solvers such as the legacy bundled CBC (``PULP_CBC_CMD``) or GLPK.
|
|
84
|
+
|
|
85
|
+
To install other solvers, PuLP offers a quick way to install most solvers via their pypi package (some require a commercial license for running or for running large models)::
|
|
86
|
+
|
|
87
|
+
python -m pip install pulp[cbc]
|
|
80
88
|
python -m pip install pulp[gurobi]
|
|
81
89
|
python -m pip install pulp[cplex]
|
|
82
90
|
python -m pip install pulp[xpress]
|
|
@@ -84,7 +92,6 @@ PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver,
|
|
|
84
92
|
python -m pip install pulp[highs]
|
|
85
93
|
python -m pip install pulp[copt]
|
|
86
94
|
python -m pip install pulp[mosek]
|
|
87
|
-
python -m pip install pulp[cylp]
|
|
88
95
|
|
|
89
96
|
|
|
90
97
|
If you want to install all open source solvers (scip, highs, cylp), you can use the shortcut::
|
|
@@ -95,18 +102,12 @@ For more information on how to install solvers, see the `guide on configuring so
|
|
|
95
102
|
Quickstart
|
|
96
103
|
===============
|
|
97
104
|
|
|
98
|
-
|
|
105
|
+
Create a problem first, then add variables with ``add_variable`` (variables are owned by the model). To create a variable ``x`` with 0 ≤ x ≤ 3 and a binary variable ``y``::
|
|
99
106
|
|
|
100
107
|
from pulp import *
|
|
101
|
-
x = LpVariable("x", 0, 3)
|
|
102
|
-
|
|
103
|
-
To create a binary variable, y, with values either 0 or 1::
|
|
104
|
-
|
|
105
|
-
y = LpVariable("y", cat="Binary")
|
|
106
|
-
|
|
107
|
-
Use ``LpProblem`` to create new problems. Create a problem called "myProblem" like so::
|
|
108
|
-
|
|
109
108
|
prob = LpProblem("myProblem", LpMinimize)
|
|
109
|
+
x = prob.add_variable("x", 0, 3)
|
|
110
|
+
y = prob.add_variable("y", cat="Binary")
|
|
110
111
|
|
|
111
112
|
Combine variables in order to create expressions and constraints, and then add them to the problem.::
|
|
112
113
|
|
|
@@ -116,10 +117,14 @@ An expression is a constraint without a right-hand side (RHS) sense (one of ``=`
|
|
|
116
117
|
|
|
117
118
|
prob += -4*x + y
|
|
118
119
|
|
|
119
|
-
To solve the problem
|
|
120
|
+
To solve the problem with the default solver (CBC via ``COIN_CMD`` when installed with ``pulp[cbc]``)::
|
|
120
121
|
|
|
121
122
|
status = prob.solve()
|
|
122
123
|
|
|
124
|
+
To solve explicitly with CBC::
|
|
125
|
+
|
|
126
|
+
status = prob.solve(COIN_CMD(msg=0))
|
|
127
|
+
|
|
123
128
|
If you want to try another solver to solve the problem::
|
|
124
129
|
|
|
125
130
|
status = prob.solve(GLPK(msg = 0))
|
|
@@ -159,7 +164,7 @@ More Examples
|
|
|
159
164
|
|
|
160
165
|
Several tutorial are given in `documentation <https://coin-or.github.io/pulp/CaseStudies/index.html>`_ and pure code examples are available in `examples/ directory <https://github.com/coin-or/pulp/tree/master/examples>`_ .
|
|
161
166
|
|
|
162
|
-
The examples use the default solver (CBC). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
|
|
167
|
+
The examples use the default solver (CBC via ``COIN_CMD`` when available). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
|
|
163
168
|
|
|
164
169
|
|
|
165
170
|
For Developers
|
|
@@ -171,12 +176,6 @@ If you want to install the latest version from GitHub you can run::
|
|
|
171
176
|
python -m pip install -U git+https://github.com/coin-or/pulp
|
|
172
177
|
|
|
173
178
|
|
|
174
|
-
On Linux and MacOS systems, you must run the tests to make the default solver executable::
|
|
175
|
-
|
|
176
|
-
sudo pulptest
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
179
|
|
|
181
180
|
Building the documentation
|
|
182
181
|
--------------------------
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PuLP
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.2
|
|
4
4
|
Summary: PuLP is an LP modeler written in python. PuLP can generate MPS or LP files and call GLPK, COIN CLP/CBC, CPLEX, and GUROBI to solve linear problems.
|
|
5
5
|
Author: J.S. Roy
|
|
6
6
|
Author-email: "S.A. Mitchell" <pulp@stuartmitchell.com>, Franco Peschiera <pchtsp@gmail.com>
|
|
@@ -15,12 +15,13 @@ Classifier: Intended Audience :: Science/Research
|
|
|
15
15
|
Classifier: Natural Language :: English
|
|
16
16
|
Classifier: Programming Language :: Python
|
|
17
17
|
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
18
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
19
|
Description-Content-Type: text/x-rst
|
|
20
20
|
License-File: LICENSE
|
|
21
|
+
Provides-Extra: cbc
|
|
22
|
+
Requires-Dist: cbcbox; extra == "cbc"
|
|
21
23
|
Provides-Extra: open-py
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist: highspy; extra == "open-py"
|
|
24
|
+
Requires-Dist: highspy==1.13; extra == "open-py"
|
|
24
25
|
Requires-Dist: pyscipopt; extra == "open-py"
|
|
25
26
|
Provides-Extra: public-py
|
|
26
27
|
Requires-Dist: gurobipy; extra == "public-py"
|
|
@@ -28,7 +29,7 @@ Requires-Dist: coptpy; extra == "public-py"
|
|
|
28
29
|
Requires-Dist: xpress; extra == "public-py"
|
|
29
30
|
Requires-Dist: cplex; (sys_platform != "darwin" or python_full_version < "3.12") and extra == "public-py"
|
|
30
31
|
Provides-Extra: highs
|
|
31
|
-
Requires-Dist: highspy; extra == "highs"
|
|
32
|
+
Requires-Dist: highspy==1.13; extra == "highs"
|
|
32
33
|
Provides-Extra: scip
|
|
33
34
|
Requires-Dist: pyscipopt; extra == "scip"
|
|
34
35
|
Provides-Extra: gurobi
|
|
@@ -64,7 +65,7 @@ PuLP is part of the `COIN-OR project <https://www.coin-or.org/>`_.
|
|
|
64
65
|
Installation
|
|
65
66
|
================
|
|
66
67
|
|
|
67
|
-
PuLP requires Python 3.
|
|
68
|
+
PuLP requires Python 3.10 or newer.
|
|
68
69
|
|
|
69
70
|
The easiest way to install PuLP is with ``pip``. If ``pip`` is available on your system, type::
|
|
70
71
|
|
|
@@ -75,8 +76,15 @@ Otherwise follow the download instructions on the `PyPi page <https://pypi.pytho
|
|
|
75
76
|
Installing solvers
|
|
76
77
|
----------------------
|
|
77
78
|
|
|
78
|
-
PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver
|
|
79
|
+
PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver via the ``COIN_CMD`` API. Install CBC with::
|
|
79
80
|
|
|
81
|
+
python -m pip install pulp[cbc]
|
|
82
|
+
|
|
83
|
+
If CBC is not available on your system, PuLP falls back to other solvers such as the legacy bundled CBC (``PULP_CBC_CMD``) or GLPK.
|
|
84
|
+
|
|
85
|
+
To install other solvers, PuLP offers a quick way to install most solvers via their pypi package (some require a commercial license for running or for running large models)::
|
|
86
|
+
|
|
87
|
+
python -m pip install pulp[cbc]
|
|
80
88
|
python -m pip install pulp[gurobi]
|
|
81
89
|
python -m pip install pulp[cplex]
|
|
82
90
|
python -m pip install pulp[xpress]
|
|
@@ -84,7 +92,6 @@ PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver,
|
|
|
84
92
|
python -m pip install pulp[highs]
|
|
85
93
|
python -m pip install pulp[copt]
|
|
86
94
|
python -m pip install pulp[mosek]
|
|
87
|
-
python -m pip install pulp[cylp]
|
|
88
95
|
|
|
89
96
|
|
|
90
97
|
If you want to install all open source solvers (scip, highs, cylp), you can use the shortcut::
|
|
@@ -95,18 +102,12 @@ For more information on how to install solvers, see the `guide on configuring so
|
|
|
95
102
|
Quickstart
|
|
96
103
|
===============
|
|
97
104
|
|
|
98
|
-
|
|
105
|
+
Create a problem first, then add variables with ``add_variable`` (variables are owned by the model). To create a variable ``x`` with 0 ≤ x ≤ 3 and a binary variable ``y``::
|
|
99
106
|
|
|
100
107
|
from pulp import *
|
|
101
|
-
x = LpVariable("x", 0, 3)
|
|
102
|
-
|
|
103
|
-
To create a binary variable, y, with values either 0 or 1::
|
|
104
|
-
|
|
105
|
-
y = LpVariable("y", cat="Binary")
|
|
106
|
-
|
|
107
|
-
Use ``LpProblem`` to create new problems. Create a problem called "myProblem" like so::
|
|
108
|
-
|
|
109
108
|
prob = LpProblem("myProblem", LpMinimize)
|
|
109
|
+
x = prob.add_variable("x", 0, 3)
|
|
110
|
+
y = prob.add_variable("y", cat="Binary")
|
|
110
111
|
|
|
111
112
|
Combine variables in order to create expressions and constraints, and then add them to the problem.::
|
|
112
113
|
|
|
@@ -116,10 +117,14 @@ An expression is a constraint without a right-hand side (RHS) sense (one of ``=`
|
|
|
116
117
|
|
|
117
118
|
prob += -4*x + y
|
|
118
119
|
|
|
119
|
-
To solve the problem
|
|
120
|
+
To solve the problem with the default solver (CBC via ``COIN_CMD`` when installed with ``pulp[cbc]``)::
|
|
120
121
|
|
|
121
122
|
status = prob.solve()
|
|
122
123
|
|
|
124
|
+
To solve explicitly with CBC::
|
|
125
|
+
|
|
126
|
+
status = prob.solve(COIN_CMD(msg=0))
|
|
127
|
+
|
|
123
128
|
If you want to try another solver to solve the problem::
|
|
124
129
|
|
|
125
130
|
status = prob.solve(GLPK(msg = 0))
|
|
@@ -159,7 +164,7 @@ More Examples
|
|
|
159
164
|
|
|
160
165
|
Several tutorial are given in `documentation <https://coin-or.github.io/pulp/CaseStudies/index.html>`_ and pure code examples are available in `examples/ directory <https://github.com/coin-or/pulp/tree/master/examples>`_ .
|
|
161
166
|
|
|
162
|
-
The examples use the default solver (CBC). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
|
|
167
|
+
The examples use the default solver (CBC via ``COIN_CMD`` when available). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
|
|
163
168
|
|
|
164
169
|
|
|
165
170
|
For Developers
|
|
@@ -171,12 +176,6 @@ If you want to install the latest version from GitHub you can run::
|
|
|
171
176
|
python -m pip install -U git+https://github.com/coin-or/pulp
|
|
172
177
|
|
|
173
178
|
|
|
174
|
-
On Linux and MacOS systems, you must run the tests to make the default solver executable::
|
|
175
|
-
|
|
176
|
-
sudo pulptest
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
179
|
|
|
181
180
|
Building the documentation
|
|
182
181
|
--------------------------
|
|
@@ -19,7 +19,7 @@ PuLP is part of the `COIN-OR project <https://www.coin-or.org/>`_.
|
|
|
19
19
|
Installation
|
|
20
20
|
================
|
|
21
21
|
|
|
22
|
-
PuLP requires Python 3.
|
|
22
|
+
PuLP requires Python 3.10 or newer.
|
|
23
23
|
|
|
24
24
|
The easiest way to install PuLP is with ``pip``. If ``pip`` is available on your system, type::
|
|
25
25
|
|
|
@@ -30,8 +30,15 @@ Otherwise follow the download instructions on the `PyPi page <https://pypi.pytho
|
|
|
30
30
|
Installing solvers
|
|
31
31
|
----------------------
|
|
32
32
|
|
|
33
|
-
PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver
|
|
33
|
+
PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver via the ``COIN_CMD`` API. Install CBC with::
|
|
34
34
|
|
|
35
|
+
python -m pip install pulp[cbc]
|
|
36
|
+
|
|
37
|
+
If CBC is not available on your system, PuLP falls back to other solvers such as the legacy bundled CBC (``PULP_CBC_CMD``) or GLPK.
|
|
38
|
+
|
|
39
|
+
To install other solvers, PuLP offers a quick way to install most solvers via their pypi package (some require a commercial license for running or for running large models)::
|
|
40
|
+
|
|
41
|
+
python -m pip install pulp[cbc]
|
|
35
42
|
python -m pip install pulp[gurobi]
|
|
36
43
|
python -m pip install pulp[cplex]
|
|
37
44
|
python -m pip install pulp[xpress]
|
|
@@ -39,7 +46,6 @@ PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver,
|
|
|
39
46
|
python -m pip install pulp[highs]
|
|
40
47
|
python -m pip install pulp[copt]
|
|
41
48
|
python -m pip install pulp[mosek]
|
|
42
|
-
python -m pip install pulp[cylp]
|
|
43
49
|
|
|
44
50
|
|
|
45
51
|
If you want to install all open source solvers (scip, highs, cylp), you can use the shortcut::
|
|
@@ -50,18 +56,12 @@ For more information on how to install solvers, see the `guide on configuring so
|
|
|
50
56
|
Quickstart
|
|
51
57
|
===============
|
|
52
58
|
|
|
53
|
-
|
|
59
|
+
Create a problem first, then add variables with ``add_variable`` (variables are owned by the model). To create a variable ``x`` with 0 ≤ x ≤ 3 and a binary variable ``y``::
|
|
54
60
|
|
|
55
61
|
from pulp import *
|
|
56
|
-
x = LpVariable("x", 0, 3)
|
|
57
|
-
|
|
58
|
-
To create a binary variable, y, with values either 0 or 1::
|
|
59
|
-
|
|
60
|
-
y = LpVariable("y", cat="Binary")
|
|
61
|
-
|
|
62
|
-
Use ``LpProblem`` to create new problems. Create a problem called "myProblem" like so::
|
|
63
|
-
|
|
64
62
|
prob = LpProblem("myProblem", LpMinimize)
|
|
63
|
+
x = prob.add_variable("x", 0, 3)
|
|
64
|
+
y = prob.add_variable("y", cat="Binary")
|
|
65
65
|
|
|
66
66
|
Combine variables in order to create expressions and constraints, and then add them to the problem.::
|
|
67
67
|
|
|
@@ -71,10 +71,14 @@ An expression is a constraint without a right-hand side (RHS) sense (one of ``=`
|
|
|
71
71
|
|
|
72
72
|
prob += -4*x + y
|
|
73
73
|
|
|
74
|
-
To solve the problem
|
|
74
|
+
To solve the problem with the default solver (CBC via ``COIN_CMD`` when installed with ``pulp[cbc]``)::
|
|
75
75
|
|
|
76
76
|
status = prob.solve()
|
|
77
77
|
|
|
78
|
+
To solve explicitly with CBC::
|
|
79
|
+
|
|
80
|
+
status = prob.solve(COIN_CMD(msg=0))
|
|
81
|
+
|
|
78
82
|
If you want to try another solver to solve the problem::
|
|
79
83
|
|
|
80
84
|
status = prob.solve(GLPK(msg = 0))
|
|
@@ -114,7 +118,7 @@ More Examples
|
|
|
114
118
|
|
|
115
119
|
Several tutorial are given in `documentation <https://coin-or.github.io/pulp/CaseStudies/index.html>`_ and pure code examples are available in `examples/ directory <https://github.com/coin-or/pulp/tree/master/examples>`_ .
|
|
116
120
|
|
|
117
|
-
The examples use the default solver (CBC). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
|
|
121
|
+
The examples use the default solver (CBC via ``COIN_CMD`` when available). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
|
|
118
122
|
|
|
119
123
|
|
|
120
124
|
For Developers
|
|
@@ -126,12 +130,6 @@ If you want to install the latest version from GitHub you can run::
|
|
|
126
130
|
python -m pip install -U git+https://github.com/coin-or/pulp
|
|
127
131
|
|
|
128
132
|
|
|
129
|
-
On Linux and MacOS systems, you must run the tests to make the default solver executable::
|
|
130
|
-
|
|
131
|
-
sudo pulptest
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
133
|
|
|
136
134
|
Building the documentation
|
|
137
135
|
--------------------------
|
|
@@ -29,8 +29,34 @@ Module file that imports all of the pulp functions
|
|
|
29
29
|
|
|
30
30
|
Copyright 2007- Stuart Mitchell (s.mitchell@auckland.ac.nz)
|
|
31
31
|
"""
|
|
32
|
+
|
|
33
|
+
# Pre-load highspy's C extension with RTLD_GLOBAL before any other imports.
|
|
34
|
+
# highspy._core uses C++ exception handling (__cxa_throw etc.) that must be globally
|
|
35
|
+
# visible when pulp._rustcore (a Rust/pyo3 extension) is later loaded into the same
|
|
36
|
+
# process. Without RTLD_GLOBAL, the C++ runtime state gets split across multiple
|
|
37
|
+
# symbol scopes, causing a segfault when highspy.Highs.run() is called.
|
|
38
|
+
# We use find_spec("highspy") (the package) not find_spec("highspy._core") (the
|
|
39
|
+
# submodule) to avoid triggering highspy/__init__.py which would import _core with
|
|
40
|
+
# RTLD_LOCAL before our explicit RTLD_GLOBAL call can take effect.
|
|
41
|
+
try:
|
|
42
|
+
import ctypes as _ctypes
|
|
43
|
+
import glob as _glob
|
|
44
|
+
import importlib.util as _ilu
|
|
45
|
+
|
|
46
|
+
_pkg_spec = _ilu.find_spec("highspy")
|
|
47
|
+
if _pkg_spec is not None and _pkg_spec.submodule_search_locations:
|
|
48
|
+
for _loc in _pkg_spec.submodule_search_locations:
|
|
49
|
+
for _so in _glob.glob(_loc + "/_core*.so"):
|
|
50
|
+
_ctypes.CDLL(_so, _ctypes.RTLD_GLOBAL)
|
|
51
|
+
break
|
|
52
|
+
del _ctypes, _glob, _ilu, _pkg_spec
|
|
53
|
+
except Exception:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
|
|
32
57
|
from .constants import VERSION
|
|
33
58
|
|
|
59
|
+
from .v4_migration import set_v4_migration_warnings
|
|
34
60
|
from .pulp import *
|
|
35
61
|
from .apis import *
|
|
36
62
|
from .utilities import *
|
|
@@ -45,14 +45,14 @@ _all_solvers: List[Type[LpSolver]] = [
|
|
|
45
45
|
CUOPT,
|
|
46
46
|
]
|
|
47
47
|
|
|
48
|
-
LpSolverDefault: Optional[Union[PULP_CBC_CMD, GLPK_CMD
|
|
48
|
+
LpSolverDefault: Optional[Union[COIN_CMD, PULP_CBC_CMD, GLPK_CMD]] = None
|
|
49
49
|
# Default solver selection
|
|
50
|
-
if
|
|
51
|
-
LpSolverDefault =
|
|
50
|
+
if COIN_CMD().available():
|
|
51
|
+
LpSolverDefault = COIN_CMD()
|
|
52
|
+
elif PULP_CBC_CMD(_skip_v4_deprecation=True).available():
|
|
53
|
+
LpSolverDefault = PULP_CBC_CMD(_skip_v4_deprecation=True)
|
|
52
54
|
elif GLPK_CMD().available():
|
|
53
55
|
LpSolverDefault = GLPK_CMD()
|
|
54
|
-
elif COIN_CMD().available():
|
|
55
|
-
LpSolverDefault = COIN_CMD()
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
def getSolver(solver: str, *args, **kwargs) -> LpSolver:
|
|
@@ -116,7 +116,10 @@ def listSolvers(onlyAvailable: bool = False) -> List[str]:
|
|
|
116
116
|
"""
|
|
117
117
|
result = []
|
|
118
118
|
for s in _all_solvers:
|
|
119
|
-
|
|
119
|
+
kwargs: Dict[str, Union[str, bool, float, int]] = {"msg": False}
|
|
120
|
+
if s is PULP_CBC_CMD:
|
|
121
|
+
kwargs["_skip_v4_deprecation"] = True
|
|
122
|
+
solver = s(**kwargs)
|
|
120
123
|
if (not onlyAvailable) or solver.available():
|
|
121
124
|
result.append(solver.name)
|
|
122
125
|
del solver
|
|
@@ -48,9 +48,9 @@ import ctypes
|
|
|
48
48
|
import warnings
|
|
49
49
|
from tempfile import mktemp
|
|
50
50
|
|
|
51
|
+
from ..v4_migration import v4_deprecation
|
|
52
|
+
|
|
51
53
|
cbc_path = "cbc"
|
|
52
|
-
if operating_system == "win":
|
|
53
|
-
cbc_path += ".exe"
|
|
54
54
|
|
|
55
55
|
coinMP_path = ["libCoinMP.so"]
|
|
56
56
|
# workaround for (https://github.com/coin-or/pulp/issues/802)
|
|
@@ -60,6 +60,15 @@ pulp_cbc_path = os.path.join(
|
|
|
60
60
|
os.path.dirname(__file__), f"../solverdir/cbc/{operating_system}/{arch}/{cbc_path}"
|
|
61
61
|
)
|
|
62
62
|
|
|
63
|
+
PULP_CBC_CMD_DEPRECATION_MSG = (
|
|
64
|
+
"PULP_CBC_CMD is deprecated and will be removed in PuLP 4.0. "
|
|
65
|
+
"Install CBC with `pip install pulp[cbc]` and use COIN_CMD instead."
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def warn_pulp_cbc_cmd_deprecated(*, stacklevel: int = 2) -> None:
|
|
70
|
+
v4_deprecation(PULP_CBC_CMD_DEPRECATION_MSG, stacklevel=stacklevel)
|
|
71
|
+
|
|
63
72
|
|
|
64
73
|
class COIN_CMD(LpSolver_CMD):
|
|
65
74
|
"""The COIN CLP/CBC LP solver
|
|
@@ -167,7 +176,7 @@ class COIN_CMD(LpSolver_CMD):
|
|
|
167
176
|
vs = lp.writeLP(tmpLp)
|
|
168
177
|
# In the Lp we do not create new variable or constraint names:
|
|
169
178
|
variablesNames = {v.name: v.name for v in vs}
|
|
170
|
-
constraintsNames = {c: c for c in lp.
|
|
179
|
+
constraintsNames = {c: c for c in lp._constraints}
|
|
171
180
|
cmds = " " + tmpLp + " "
|
|
172
181
|
if self.optionsDict.get("warmStart", False):
|
|
173
182
|
self.writesol(tmpMst, lp, vs, variablesNames, constraintsNames)
|
|
@@ -192,7 +201,7 @@ class COIN_CMD(LpSolver_CMD):
|
|
|
192
201
|
for option in options:
|
|
193
202
|
cmds += "-" + option + " "
|
|
194
203
|
if self.mip:
|
|
195
|
-
cmds += "-
|
|
204
|
+
cmds += "-solve "
|
|
196
205
|
else:
|
|
197
206
|
cmds += "-initialSolve "
|
|
198
207
|
cmds += "-printingOptions all "
|
|
@@ -323,7 +332,7 @@ class COIN_CMD(LpSolver_CMD):
|
|
|
323
332
|
returns status, values, reducedCosts, shadowPrices, slacks, sol_status
|
|
324
333
|
"""
|
|
325
334
|
variablesNames = {v.name: v.name for v in vs}
|
|
326
|
-
constraintsNames = {c: c for c in lp.
|
|
335
|
+
constraintsNames = {c: c for c in lp._constraints}
|
|
327
336
|
return self.readsol_MPS(filename, lp, vs, variablesNames, constraintsNames)
|
|
328
337
|
|
|
329
338
|
def get_status(self, filename):
|
|
@@ -363,11 +372,15 @@ COIN = COIN_CMD
|
|
|
363
372
|
|
|
364
373
|
class PULP_CBC_CMD(COIN_CMD):
|
|
365
374
|
"""
|
|
366
|
-
|
|
375
|
+
Legacy solver that uses a precompiled version of cbc bundled with PuLP.
|
|
376
|
+
|
|
377
|
+
Deprecated: will be removed in PuLP 4.0. Install CBC with
|
|
378
|
+
``pip install pulp[cbc]`` and use :class:`COIN_CMD` instead.
|
|
367
379
|
"""
|
|
368
380
|
|
|
369
381
|
name = "PULP_CBC_CMD"
|
|
370
|
-
pulp_cbc_path = pulp_cbc_path
|
|
382
|
+
pulp_cbc_path = COIN_CMD.executableExtension(pulp_cbc_path)
|
|
383
|
+
_permissions_ok = True
|
|
371
384
|
try:
|
|
372
385
|
if os.name != "nt":
|
|
373
386
|
if not os.access(pulp_cbc_path, os.X_OK):
|
|
@@ -375,61 +388,66 @@ class PULP_CBC_CMD(COIN_CMD):
|
|
|
375
388
|
|
|
376
389
|
os.chmod(pulp_cbc_path, stat.S_IXUSR + stat.S_IXOTH)
|
|
377
390
|
except: # probably due to incorrect permissions
|
|
391
|
+
_permissions_ok = False
|
|
378
392
|
|
|
379
|
-
|
|
380
|
-
|
|
393
|
+
def available(self):
|
|
394
|
+
"""True if the solver is available"""
|
|
395
|
+
if not self._permissions_ok:
|
|
381
396
|
return False
|
|
397
|
+
return super().available()
|
|
382
398
|
|
|
383
|
-
|
|
384
|
-
|
|
399
|
+
def actualSolve(self, lp, **kwargs):
|
|
400
|
+
"""Solve a well formulated lp problem"""
|
|
401
|
+
if not self._permissions_ok:
|
|
385
402
|
raise PulpSolverError(
|
|
386
403
|
"PULP_CBC_CMD: Not Available (check permissions on %s)"
|
|
387
404
|
% self.pulp_cbc_path
|
|
388
405
|
)
|
|
406
|
+
return super().actualSolve(lp, **kwargs)
|
|
389
407
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
408
|
+
def __init__(
|
|
409
|
+
self,
|
|
410
|
+
mip=True,
|
|
411
|
+
msg=True,
|
|
412
|
+
timeLimit=None,
|
|
413
|
+
gapRel=None,
|
|
414
|
+
gapAbs=None,
|
|
415
|
+
presolve=None,
|
|
416
|
+
cuts=None,
|
|
417
|
+
strong=None,
|
|
418
|
+
options=None,
|
|
419
|
+
warmStart=False,
|
|
420
|
+
keepFiles=False,
|
|
421
|
+
path=None,
|
|
422
|
+
threads=None,
|
|
423
|
+
logPath=None,
|
|
424
|
+
timeMode="elapsed",
|
|
425
|
+
maxNodes=None,
|
|
426
|
+
_skip_v4_deprecation: bool = False,
|
|
427
|
+
):
|
|
428
|
+
if not _skip_v4_deprecation:
|
|
429
|
+
warn_pulp_cbc_cmd_deprecated(stacklevel=2)
|
|
430
|
+
if path is not None:
|
|
431
|
+
raise PulpSolverError("Use COIN_CMD if you want to set a path")
|
|
432
|
+
COIN_CMD.__init__(
|
|
393
433
|
self,
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
threads=
|
|
407
|
-
logPath=
|
|
408
|
-
timeMode=
|
|
409
|
-
maxNodes=
|
|
410
|
-
)
|
|
411
|
-
if path is not None:
|
|
412
|
-
raise PulpSolverError("Use COIN_CMD if you want to set a path")
|
|
413
|
-
# check that the file is executable
|
|
414
|
-
COIN_CMD.__init__(
|
|
415
|
-
self,
|
|
416
|
-
path=self.pulp_cbc_path,
|
|
417
|
-
mip=mip,
|
|
418
|
-
msg=msg,
|
|
419
|
-
timeLimit=timeLimit,
|
|
420
|
-
gapRel=gapRel,
|
|
421
|
-
gapAbs=gapAbs,
|
|
422
|
-
presolve=presolve,
|
|
423
|
-
cuts=cuts,
|
|
424
|
-
strong=strong,
|
|
425
|
-
options=options,
|
|
426
|
-
warmStart=warmStart,
|
|
427
|
-
keepFiles=keepFiles,
|
|
428
|
-
threads=threads,
|
|
429
|
-
logPath=logPath,
|
|
430
|
-
timeMode=timeMode,
|
|
431
|
-
maxNodes=maxNodes,
|
|
432
|
-
)
|
|
434
|
+
path=self.pulp_cbc_path,
|
|
435
|
+
mip=mip,
|
|
436
|
+
msg=msg,
|
|
437
|
+
timeLimit=timeLimit,
|
|
438
|
+
gapRel=gapRel,
|
|
439
|
+
gapAbs=gapAbs,
|
|
440
|
+
presolve=presolve,
|
|
441
|
+
cuts=cuts,
|
|
442
|
+
strong=strong,
|
|
443
|
+
options=options,
|
|
444
|
+
warmStart=warmStart,
|
|
445
|
+
keepFiles=keepFiles,
|
|
446
|
+
threads=threads,
|
|
447
|
+
logPath=logPath,
|
|
448
|
+
timeMode=timeMode,
|
|
449
|
+
maxNodes=maxNodes,
|
|
450
|
+
)
|
|
433
451
|
|
|
434
452
|
|
|
435
453
|
def COINMP_DLL_load_dll(path: list[str]):
|
|
@@ -758,7 +776,7 @@ class YAPOSIB(LpSolver):
|
|
|
758
776
|
var.varValue = var.solverVar.solution
|
|
759
777
|
var.dj = var.solverVar.reducedcost
|
|
760
778
|
# put pi and slack variables against the constraints
|
|
761
|
-
for constr in lp.
|
|
779
|
+
for constr in lp._constraints.values():
|
|
762
780
|
constr.pi = constr.solverConstraint.dual
|
|
763
781
|
constr.slack = -constr.constant - constr.solverConstraint.activity
|
|
764
782
|
if self.msg:
|
|
@@ -817,7 +835,7 @@ class YAPOSIB(LpSolver):
|
|
|
817
835
|
prob.obj[col.index] = lp.objective.get(var, 0.0)
|
|
818
836
|
var.solverVar = col
|
|
819
837
|
log.debug("add the Constraints to the problem")
|
|
820
|
-
for name, constraint in lp.
|
|
838
|
+
for name, constraint in lp._constraints.items():
|
|
821
839
|
row = prob.rows.add(
|
|
822
840
|
yaposib.vec(
|
|
823
841
|
[
|
|
@@ -853,7 +871,7 @@ class YAPOSIB(LpSolver):
|
|
|
853
871
|
solutionStatus = self.findSolutionValues(lp)
|
|
854
872
|
for var in lp.variables():
|
|
855
873
|
var.modified = False
|
|
856
|
-
for constraint in lp.
|
|
874
|
+
for constraint in lp._constraints.values():
|
|
857
875
|
constraint.modified = False
|
|
858
876
|
return solutionStatus
|
|
859
877
|
|
|
@@ -865,7 +883,7 @@ class YAPOSIB(LpSolver):
|
|
|
865
883
|
constraints
|
|
866
884
|
"""
|
|
867
885
|
log.debug("Resolve the model using yaposib")
|
|
868
|
-
for constraint in lp.
|
|
886
|
+
for constraint in lp._constraints.values():
|
|
869
887
|
row = constraint.solverConstraint
|
|
870
888
|
if constraint.modified:
|
|
871
889
|
if constraint.sense == constants.LpConstraintLE:
|
|
@@ -882,7 +900,7 @@ class YAPOSIB(LpSolver):
|
|
|
882
900
|
solutionStatus = self.findSolutionValues(lp)
|
|
883
901
|
for var in lp.variables():
|
|
884
902
|
var.modified = False
|
|
885
|
-
for constraint in lp.
|
|
903
|
+
for constraint in lp._constraints.values():
|
|
886
904
|
constraint.modified = False
|
|
887
905
|
return solutionStatus
|
|
888
906
|
|