PuLP 3.2.0__tar.gz → 3.2.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.2.2/PKG-INFO +194 -0
- pulp-3.2.2/PuLP.egg-info/PKG-INFO +194 -0
- {pulp-3.2.0 → pulp-3.2.2}/PuLP.egg-info/requires.txt +3 -1
- {pulp-3.2.0 → pulp-3.2.2}/README.rst +2 -2
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/__init__.py +16 -18
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/cplex_api.py +72 -5
- {pulp-3.2.0 → pulp-3.2.2}/pulp/mps_lp.py +5 -5
- {pulp-3.2.0 → pulp-3.2.2}/pulp/pulp.py +51 -17
- {pulp-3.2.0 → pulp-3.2.2}/pulp/tests/test_examples.py +4 -1
- {pulp-3.2.0 → pulp-3.2.2}/pulp/tests/test_gurobipy_env.py +12 -12
- {pulp-3.2.0 → pulp-3.2.2}/pulp/tests/test_pulp.py +238 -132
- {pulp-3.2.0 → pulp-3.2.2}/pyproject.toml +3 -3
- pulp-3.2.0/PKG-INFO +0 -28
- pulp-3.2.0/PuLP.egg-info/PKG-INFO +0 -28
- {pulp-3.2.0 → pulp-3.2.2}/PuLP.egg-info/SOURCES.txt +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/PuLP.egg-info/dependency_links.txt +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/PuLP.egg-info/entry_points.txt +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/PuLP.egg-info/top_level.txt +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/__init__.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/choco_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/coin_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/copt_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/core.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/cuopt_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/glpk_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/gurobi_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/highs_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/mipcl_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/mosek_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/sas_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/scip_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/apis/xpress_api.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/constants.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/__init__.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/linux/arm64/__init__.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/linux/arm64/cbc +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/linux/arm64/coin-license.txt +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/linux/i32/__init__.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/linux/i32/cbc +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/linux/i32/coin-license.txt +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/linux/i64/__init__.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/linux/i64/cbc +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/linux/i64/coin-license.txt +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/osx/i64/__init__.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/osx/i64/cbc +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/osx/i64/coin-license.txt +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/win/i32/__init__.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/win/i32/cbc.exe +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/win/i32/coin-license.txt +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/win/i64/__init__.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/win/i64/cbc.exe +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/solverdir/cbc/win/i64/coin-license.txt +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/sparse.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/tests/__init__.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/tests/bin_packing_problem.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/tests/run_tests.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/tests/test_lpdot.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/tests/test_sparse.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/pulp/utilities.py +0 -0
- {pulp-3.2.0 → pulp-3.2.2}/setup.cfg +0 -0
pulp-3.2.2/PKG-INFO
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PuLP
|
|
3
|
+
Version: 3.2.2
|
|
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
|
+
Author: J.S. Roy
|
|
6
|
+
Author-email: "S.A. Mitchell" <pulp@stuartmitchell.com>, Franco Peschiera <pchtsp@gmail.com>
|
|
7
|
+
Maintainer-email: Franco Peschiera <pchtsp@gmail.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: source, https://github.com/coin-or/pulp
|
|
10
|
+
Project-URL: download, https://github.com/coin-or/pulp/archive/master.zip
|
|
11
|
+
Keywords: Optimization,Linear Programming,Operations Research
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Natural Language :: English
|
|
17
|
+
Classifier: Programming Language :: Python
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/x-rst
|
|
21
|
+
Provides-Extra: open-py
|
|
22
|
+
Requires-Dist: cylp; sys_platform != "win32" and extra == "open-py"
|
|
23
|
+
Requires-Dist: highspy; extra == "open-py"
|
|
24
|
+
Requires-Dist: pyscipopt; extra == "open-py"
|
|
25
|
+
Provides-Extra: public-py
|
|
26
|
+
Requires-Dist: gurobipy; extra == "public-py"
|
|
27
|
+
Requires-Dist: coptpy; extra == "public-py"
|
|
28
|
+
Requires-Dist: xpress; extra == "public-py"
|
|
29
|
+
|
|
30
|
+
pulp
|
|
31
|
+
**************************
|
|
32
|
+
|
|
33
|
+
.. image:: https://travis-ci.org/coin-or/pulp.svg?branch=master
|
|
34
|
+
:target: https://travis-ci.org/coin-or/pulp
|
|
35
|
+
.. image:: https://img.shields.io/pypi/v/pulp
|
|
36
|
+
:target: https://pypi.org/project/PuLP/
|
|
37
|
+
:alt: PyPI
|
|
38
|
+
.. image:: https://img.shields.io/pypi/dm/pulp
|
|
39
|
+
:target: https://pypi.org/project/PuLP/
|
|
40
|
+
:alt: PyPI - Downloads
|
|
41
|
+
|
|
42
|
+
PuLP is an linear and mixed integer programming modeler written in Python. With PuLP, it is simple to create MILP optimisation problems and solve them with the latest open-source (or proprietary) solvers. PuLP can generate MPS or LP files and call solvers such as GLPK_, COIN-OR CLP/`CBC`_, CPLEX_, GUROBI_, MOSEK_, XPRESS_, CHOCO_, MIPCL_, HiGHS_, SCIP_/FSCIP_.
|
|
43
|
+
|
|
44
|
+
The documentation for PuLP can be `found here <https://coin-or.github.io/pulp/>`_.
|
|
45
|
+
|
|
46
|
+
PuLP is part of the `COIN-OR project <https://www.coin-or.org/>`_.
|
|
47
|
+
|
|
48
|
+
Installation
|
|
49
|
+
================
|
|
50
|
+
|
|
51
|
+
PuLP requires Python 3.9 or newer.
|
|
52
|
+
|
|
53
|
+
The easiest way to install PuLP is with ``pip``. If ``pip`` is available on your system, type::
|
|
54
|
+
|
|
55
|
+
python -m pip install pulp
|
|
56
|
+
|
|
57
|
+
Otherwise follow the download instructions on the `PyPi page <https://pypi.python.org/pypi/PuLP>`_.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
Quickstart
|
|
61
|
+
===============
|
|
62
|
+
|
|
63
|
+
Use ``LpVariable`` to create new variables. To create a variable x with 0 ≤ x ≤ 3::
|
|
64
|
+
|
|
65
|
+
from pulp import *
|
|
66
|
+
x = LpVariable("x", 0, 3)
|
|
67
|
+
|
|
68
|
+
To create a binary variable, y, with values either 0 or 1::
|
|
69
|
+
|
|
70
|
+
y = LpVariable("y", cat="Binary")
|
|
71
|
+
|
|
72
|
+
Use ``LpProblem`` to create new problems. Create a problem called "myProblem" like so::
|
|
73
|
+
|
|
74
|
+
prob = LpProblem("myProblem", LpMinimize)
|
|
75
|
+
|
|
76
|
+
Combine variables in order to create expressions and constraints, and then add them to the problem.::
|
|
77
|
+
|
|
78
|
+
prob += x + y <= 2
|
|
79
|
+
|
|
80
|
+
An expression is a constraint without a right-hand side (RHS) sense (one of ``=``, ``<=`` or ``>=``). If you add an expression to a problem, it will become the objective::
|
|
81
|
+
|
|
82
|
+
prob += -4*x + y
|
|
83
|
+
|
|
84
|
+
To solve the problem with the default included solver::
|
|
85
|
+
|
|
86
|
+
status = prob.solve()
|
|
87
|
+
|
|
88
|
+
If you want to try another solver to solve the problem::
|
|
89
|
+
|
|
90
|
+
status = prob.solve(GLPK(msg = 0))
|
|
91
|
+
|
|
92
|
+
Display the status of the solution::
|
|
93
|
+
|
|
94
|
+
LpStatus[status]
|
|
95
|
+
> 'Optimal'
|
|
96
|
+
|
|
97
|
+
You can get the value of the variables using ``value``. ex::
|
|
98
|
+
|
|
99
|
+
value(x)
|
|
100
|
+
> 2.0
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
Essential Classes
|
|
104
|
+
------------------
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
* ``LpProblem`` -- Container class for a Linear or Integer programming problem
|
|
108
|
+
* ``LpVariable`` -- Variables that are added into constraints in the LP problem
|
|
109
|
+
* ``LpConstraint`` -- Constraints of the general form
|
|
110
|
+
|
|
111
|
+
a1x1 + a2x2 + ... + anxn (<=, =, >=) b
|
|
112
|
+
|
|
113
|
+
* ``LpConstraintVar`` -- A special type of constraint for constructing column of the model in column-wise modelling
|
|
114
|
+
|
|
115
|
+
Useful Functions
|
|
116
|
+
------------------
|
|
117
|
+
|
|
118
|
+
* ``value()`` -- Finds the value of a variable or expression
|
|
119
|
+
* ``lpSum()`` -- Given a list of the form [a1*x1, a2*x2, ..., an*xn] will construct a linear expression to be used as a constraint or variable
|
|
120
|
+
* ``lpDot()`` -- Given two lists of the form [a1, a2, ..., an] and [x1, x2, ..., xn] will construct a linear expression to be used as a constraint or variable
|
|
121
|
+
|
|
122
|
+
More Examples
|
|
123
|
+
================
|
|
124
|
+
|
|
125
|
+
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>`_ .
|
|
126
|
+
|
|
127
|
+
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>`_.
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
For Developers
|
|
131
|
+
================
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
If you want to install the latest version from GitHub you can run::
|
|
135
|
+
|
|
136
|
+
python -m pip install -U git+https://github.com/coin-or/pulp
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
On Linux and MacOS systems, you must run the tests to make the default solver executable::
|
|
140
|
+
|
|
141
|
+
sudo pulptest
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
Building the documentation
|
|
147
|
+
--------------------------
|
|
148
|
+
|
|
149
|
+
The PuLP documentation is built with `Sphinx <https://www.sphinx-doc.org>`_. We recommended using a
|
|
150
|
+
`virtual environment <https://docs.python.org/3/library/venv.html>`_ to build the documentation locally.
|
|
151
|
+
|
|
152
|
+
To build, run the following in a terminal window, in the PuLP root directory
|
|
153
|
+
|
|
154
|
+
::
|
|
155
|
+
|
|
156
|
+
python3 -m pip install --upgrade pip
|
|
157
|
+
pip install --group=dev .
|
|
158
|
+
cd doc
|
|
159
|
+
make html
|
|
160
|
+
|
|
161
|
+
A folder named html will be created inside the ``build/`` directory.
|
|
162
|
+
The home page for the documentation is ``doc/build/html/index.html`` which can be opened in a browser.
|
|
163
|
+
|
|
164
|
+
Contributing to PuLP
|
|
165
|
+
-----------------------
|
|
166
|
+
Instructions for making your first contribution to PuLP are given `here <https://coin-or.github.io/pulp/develop/contribute.html>`_.
|
|
167
|
+
|
|
168
|
+
**Comments, bug reports, patches and suggestions are very welcome!**
|
|
169
|
+
|
|
170
|
+
* Comments and suggestions: https://github.com/coin-or/pulp/discussions
|
|
171
|
+
* Bug reports: https://github.com/coin-or/pulp/issues
|
|
172
|
+
* Patches: https://github.com/coin-or/pulp/pulls
|
|
173
|
+
|
|
174
|
+
Copyright and License
|
|
175
|
+
=======================
|
|
176
|
+
PuLP is distributed under an MIT license.
|
|
177
|
+
|
|
178
|
+
Copyright J.S. Roy, 2003-2005
|
|
179
|
+
Copyright Stuart A. Mitchell
|
|
180
|
+
See the LICENSE file for copyright information.
|
|
181
|
+
|
|
182
|
+
.. _Python: http://www.python.org/
|
|
183
|
+
|
|
184
|
+
.. _GLPK: http://www.gnu.org/software/glpk/glpk.html
|
|
185
|
+
.. _CBC: https://github.com/coin-or/Cbc
|
|
186
|
+
.. _CPLEX: http://www.cplex.com/
|
|
187
|
+
.. _GUROBI: http://www.gurobi.com/
|
|
188
|
+
.. _MOSEK: https://www.mosek.com/
|
|
189
|
+
.. _XPRESS: https://www.fico.com/es/products/fico-xpress-solver
|
|
190
|
+
.. _CHOCO: https://choco-solver.org/
|
|
191
|
+
.. _MIPCL: http://mipcl-cpp.appspot.com/
|
|
192
|
+
.. _SCIP: https://www.scipopt.org/
|
|
193
|
+
.. _HiGHS: https://highs.dev
|
|
194
|
+
.. _FSCIP: https://ug.zib.de
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PuLP
|
|
3
|
+
Version: 3.2.2
|
|
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
|
+
Author: J.S. Roy
|
|
6
|
+
Author-email: "S.A. Mitchell" <pulp@stuartmitchell.com>, Franco Peschiera <pchtsp@gmail.com>
|
|
7
|
+
Maintainer-email: Franco Peschiera <pchtsp@gmail.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: source, https://github.com/coin-or/pulp
|
|
10
|
+
Project-URL: download, https://github.com/coin-or/pulp/archive/master.zip
|
|
11
|
+
Keywords: Optimization,Linear Programming,Operations Research
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Natural Language :: English
|
|
17
|
+
Classifier: Programming Language :: Python
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/x-rst
|
|
21
|
+
Provides-Extra: open-py
|
|
22
|
+
Requires-Dist: cylp; sys_platform != "win32" and extra == "open-py"
|
|
23
|
+
Requires-Dist: highspy; extra == "open-py"
|
|
24
|
+
Requires-Dist: pyscipopt; extra == "open-py"
|
|
25
|
+
Provides-Extra: public-py
|
|
26
|
+
Requires-Dist: gurobipy; extra == "public-py"
|
|
27
|
+
Requires-Dist: coptpy; extra == "public-py"
|
|
28
|
+
Requires-Dist: xpress; extra == "public-py"
|
|
29
|
+
|
|
30
|
+
pulp
|
|
31
|
+
**************************
|
|
32
|
+
|
|
33
|
+
.. image:: https://travis-ci.org/coin-or/pulp.svg?branch=master
|
|
34
|
+
:target: https://travis-ci.org/coin-or/pulp
|
|
35
|
+
.. image:: https://img.shields.io/pypi/v/pulp
|
|
36
|
+
:target: https://pypi.org/project/PuLP/
|
|
37
|
+
:alt: PyPI
|
|
38
|
+
.. image:: https://img.shields.io/pypi/dm/pulp
|
|
39
|
+
:target: https://pypi.org/project/PuLP/
|
|
40
|
+
:alt: PyPI - Downloads
|
|
41
|
+
|
|
42
|
+
PuLP is an linear and mixed integer programming modeler written in Python. With PuLP, it is simple to create MILP optimisation problems and solve them with the latest open-source (or proprietary) solvers. PuLP can generate MPS or LP files and call solvers such as GLPK_, COIN-OR CLP/`CBC`_, CPLEX_, GUROBI_, MOSEK_, XPRESS_, CHOCO_, MIPCL_, HiGHS_, SCIP_/FSCIP_.
|
|
43
|
+
|
|
44
|
+
The documentation for PuLP can be `found here <https://coin-or.github.io/pulp/>`_.
|
|
45
|
+
|
|
46
|
+
PuLP is part of the `COIN-OR project <https://www.coin-or.org/>`_.
|
|
47
|
+
|
|
48
|
+
Installation
|
|
49
|
+
================
|
|
50
|
+
|
|
51
|
+
PuLP requires Python 3.9 or newer.
|
|
52
|
+
|
|
53
|
+
The easiest way to install PuLP is with ``pip``. If ``pip`` is available on your system, type::
|
|
54
|
+
|
|
55
|
+
python -m pip install pulp
|
|
56
|
+
|
|
57
|
+
Otherwise follow the download instructions on the `PyPi page <https://pypi.python.org/pypi/PuLP>`_.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
Quickstart
|
|
61
|
+
===============
|
|
62
|
+
|
|
63
|
+
Use ``LpVariable`` to create new variables. To create a variable x with 0 ≤ x ≤ 3::
|
|
64
|
+
|
|
65
|
+
from pulp import *
|
|
66
|
+
x = LpVariable("x", 0, 3)
|
|
67
|
+
|
|
68
|
+
To create a binary variable, y, with values either 0 or 1::
|
|
69
|
+
|
|
70
|
+
y = LpVariable("y", cat="Binary")
|
|
71
|
+
|
|
72
|
+
Use ``LpProblem`` to create new problems. Create a problem called "myProblem" like so::
|
|
73
|
+
|
|
74
|
+
prob = LpProblem("myProblem", LpMinimize)
|
|
75
|
+
|
|
76
|
+
Combine variables in order to create expressions and constraints, and then add them to the problem.::
|
|
77
|
+
|
|
78
|
+
prob += x + y <= 2
|
|
79
|
+
|
|
80
|
+
An expression is a constraint without a right-hand side (RHS) sense (one of ``=``, ``<=`` or ``>=``). If you add an expression to a problem, it will become the objective::
|
|
81
|
+
|
|
82
|
+
prob += -4*x + y
|
|
83
|
+
|
|
84
|
+
To solve the problem with the default included solver::
|
|
85
|
+
|
|
86
|
+
status = prob.solve()
|
|
87
|
+
|
|
88
|
+
If you want to try another solver to solve the problem::
|
|
89
|
+
|
|
90
|
+
status = prob.solve(GLPK(msg = 0))
|
|
91
|
+
|
|
92
|
+
Display the status of the solution::
|
|
93
|
+
|
|
94
|
+
LpStatus[status]
|
|
95
|
+
> 'Optimal'
|
|
96
|
+
|
|
97
|
+
You can get the value of the variables using ``value``. ex::
|
|
98
|
+
|
|
99
|
+
value(x)
|
|
100
|
+
> 2.0
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
Essential Classes
|
|
104
|
+
------------------
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
* ``LpProblem`` -- Container class for a Linear or Integer programming problem
|
|
108
|
+
* ``LpVariable`` -- Variables that are added into constraints in the LP problem
|
|
109
|
+
* ``LpConstraint`` -- Constraints of the general form
|
|
110
|
+
|
|
111
|
+
a1x1 + a2x2 + ... + anxn (<=, =, >=) b
|
|
112
|
+
|
|
113
|
+
* ``LpConstraintVar`` -- A special type of constraint for constructing column of the model in column-wise modelling
|
|
114
|
+
|
|
115
|
+
Useful Functions
|
|
116
|
+
------------------
|
|
117
|
+
|
|
118
|
+
* ``value()`` -- Finds the value of a variable or expression
|
|
119
|
+
* ``lpSum()`` -- Given a list of the form [a1*x1, a2*x2, ..., an*xn] will construct a linear expression to be used as a constraint or variable
|
|
120
|
+
* ``lpDot()`` -- Given two lists of the form [a1, a2, ..., an] and [x1, x2, ..., xn] will construct a linear expression to be used as a constraint or variable
|
|
121
|
+
|
|
122
|
+
More Examples
|
|
123
|
+
================
|
|
124
|
+
|
|
125
|
+
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>`_ .
|
|
126
|
+
|
|
127
|
+
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>`_.
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
For Developers
|
|
131
|
+
================
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
If you want to install the latest version from GitHub you can run::
|
|
135
|
+
|
|
136
|
+
python -m pip install -U git+https://github.com/coin-or/pulp
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
On Linux and MacOS systems, you must run the tests to make the default solver executable::
|
|
140
|
+
|
|
141
|
+
sudo pulptest
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
Building the documentation
|
|
147
|
+
--------------------------
|
|
148
|
+
|
|
149
|
+
The PuLP documentation is built with `Sphinx <https://www.sphinx-doc.org>`_. We recommended using a
|
|
150
|
+
`virtual environment <https://docs.python.org/3/library/venv.html>`_ to build the documentation locally.
|
|
151
|
+
|
|
152
|
+
To build, run the following in a terminal window, in the PuLP root directory
|
|
153
|
+
|
|
154
|
+
::
|
|
155
|
+
|
|
156
|
+
python3 -m pip install --upgrade pip
|
|
157
|
+
pip install --group=dev .
|
|
158
|
+
cd doc
|
|
159
|
+
make html
|
|
160
|
+
|
|
161
|
+
A folder named html will be created inside the ``build/`` directory.
|
|
162
|
+
The home page for the documentation is ``doc/build/html/index.html`` which can be opened in a browser.
|
|
163
|
+
|
|
164
|
+
Contributing to PuLP
|
|
165
|
+
-----------------------
|
|
166
|
+
Instructions for making your first contribution to PuLP are given `here <https://coin-or.github.io/pulp/develop/contribute.html>`_.
|
|
167
|
+
|
|
168
|
+
**Comments, bug reports, patches and suggestions are very welcome!**
|
|
169
|
+
|
|
170
|
+
* Comments and suggestions: https://github.com/coin-or/pulp/discussions
|
|
171
|
+
* Bug reports: https://github.com/coin-or/pulp/issues
|
|
172
|
+
* Patches: https://github.com/coin-or/pulp/pulls
|
|
173
|
+
|
|
174
|
+
Copyright and License
|
|
175
|
+
=======================
|
|
176
|
+
PuLP is distributed under an MIT license.
|
|
177
|
+
|
|
178
|
+
Copyright J.S. Roy, 2003-2005
|
|
179
|
+
Copyright Stuart A. Mitchell
|
|
180
|
+
See the LICENSE file for copyright information.
|
|
181
|
+
|
|
182
|
+
.. _Python: http://www.python.org/
|
|
183
|
+
|
|
184
|
+
.. _GLPK: http://www.gnu.org/software/glpk/glpk.html
|
|
185
|
+
.. _CBC: https://github.com/coin-or/Cbc
|
|
186
|
+
.. _CPLEX: http://www.cplex.com/
|
|
187
|
+
.. _GUROBI: http://www.gurobi.com/
|
|
188
|
+
.. _MOSEK: https://www.mosek.com/
|
|
189
|
+
.. _XPRESS: https://www.fico.com/es/products/fico-xpress-solver
|
|
190
|
+
.. _CHOCO: https://choco-solver.org/
|
|
191
|
+
.. _MIPCL: http://mipcl-cpp.appspot.com/
|
|
192
|
+
.. _SCIP: https://www.scipopt.org/
|
|
193
|
+
.. _HiGHS: https://highs.dev
|
|
194
|
+
.. _FSCIP: https://ug.zib.de
|
|
@@ -124,8 +124,8 @@ To build, run the following in a terminal window, in the PuLP root directory
|
|
|
124
124
|
|
|
125
125
|
::
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
python3 -m pip install --upgrade pip
|
|
128
|
+
pip install --group=dev .
|
|
129
129
|
cd doc
|
|
130
130
|
make html
|
|
131
131
|
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
from typing import Dict, Optional, Type, Union
|
|
2
|
-
|
|
3
|
-
from .choco_api import
|
|
4
|
-
from .coin_api import
|
|
5
|
-
from .copt_api import
|
|
6
|
-
from .core import
|
|
7
|
-
from .cplex_api import
|
|
8
|
-
from .glpk_api import
|
|
9
|
-
from .gurobi_api import
|
|
10
|
-
from .highs_api import
|
|
11
|
-
from .mipcl_api import
|
|
12
|
-
from .mosek_api import
|
|
13
|
-
from .sas_api import
|
|
14
|
-
from .scip_api import
|
|
15
|
-
from .xpress_api import
|
|
16
|
-
from .cuopt_api import
|
|
1
|
+
from typing import Dict, Optional, Type, Union, List
|
|
2
|
+
import json
|
|
3
|
+
from .choco_api import CHOCO_CMD
|
|
4
|
+
from .coin_api import CYLP, PULP_CBC_CMD, COIN_CMD, COINMP_DLL, YAPOSIB
|
|
5
|
+
from .copt_api import COPT, COPT_DLL, COPT_CMD
|
|
6
|
+
from .core import LpSolver, LpSolver_CMD, PulpSolverError
|
|
7
|
+
from .cplex_api import CPLEX_PY, CPLEX_CMD, CPLEX
|
|
8
|
+
from .glpk_api import GLPK_CMD, PYGLPK, GLPK
|
|
9
|
+
from .gurobi_api import GUROBI, GUROBI_CMD
|
|
10
|
+
from .highs_api import HiGHS, HiGHS_CMD
|
|
11
|
+
from .mipcl_api import MIPCL_CMD
|
|
12
|
+
from .mosek_api import MOSEK
|
|
13
|
+
from .sas_api import SAS94, SASCAS, SASsolver
|
|
14
|
+
from .scip_api import SCIP, SCIP_CMD, SCIP_PY, FSCIP_CMD, FSCIP
|
|
15
|
+
from .xpress_api import XPRESS_CMD, XPRESS_PY, XPRESS
|
|
16
|
+
from .cuopt_api import CUOPT
|
|
17
17
|
|
|
18
18
|
_all_solvers: List[Type[LpSolver]] = [
|
|
19
19
|
CYLP,
|
|
@@ -45,8 +45,6 @@ _all_solvers: List[Type[LpSolver]] = [
|
|
|
45
45
|
CUOPT,
|
|
46
46
|
]
|
|
47
47
|
|
|
48
|
-
import json
|
|
49
|
-
|
|
50
48
|
LpSolverDefault: Optional[Union[PULP_CBC_CMD, GLPK_CMD, COIN_CMD]] = None
|
|
51
49
|
# Default solver selection
|
|
52
50
|
if PULP_CBC_CMD().available():
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import warnings
|
|
3
|
+
from typing import Iterable, Optional
|
|
3
4
|
|
|
4
5
|
from .. import constants
|
|
5
6
|
from .core import LpSolver, LpSolver_CMD, PulpSolverError, clock, log, subprocess
|
|
@@ -252,7 +253,7 @@ class CPLEX_PY(LpSolver):
|
|
|
252
253
|
name = "CPLEX_PY"
|
|
253
254
|
try:
|
|
254
255
|
global cplex
|
|
255
|
-
import cplex # type: ignore[import-not-found]
|
|
256
|
+
import cplex # type: ignore[import-not-found, import-untyped, unused-ignore]
|
|
256
257
|
except Exception as e:
|
|
257
258
|
err = e
|
|
258
259
|
"""The CPLEX LP/MIP solver from python. Something went wrong!!!!"""
|
|
@@ -276,6 +277,7 @@ class CPLEX_PY(LpSolver):
|
|
|
276
277
|
warmStart=False,
|
|
277
278
|
logPath=None,
|
|
278
279
|
threads=None,
|
|
280
|
+
**solverParams,
|
|
279
281
|
):
|
|
280
282
|
"""
|
|
281
283
|
:param bool mip: if False, assume LP even if integer variables
|
|
@@ -285,6 +287,15 @@ class CPLEX_PY(LpSolver):
|
|
|
285
287
|
:param bool warmStart: if True, the solver will use the current value of variables as a start
|
|
286
288
|
:param str logPath: path to the log file
|
|
287
289
|
:param int threads: number of threads to be used by CPLEX to solve a problem (default None uses all available)
|
|
290
|
+
|
|
291
|
+
:param dict solverParams: Additional parameters to set in the CPLEX solver.
|
|
292
|
+
|
|
293
|
+
Parameters should use dot notation as specified in the CPLEX documentation.
|
|
294
|
+
The 'parameters.' prefix is optional. For example:
|
|
295
|
+
|
|
296
|
+
* parameters.advance (or advance)
|
|
297
|
+
* parameters.barrier.algorithm (or barrier.algorithm)
|
|
298
|
+
* parameters.mip.strategy.probe (or mip.strategy.probe)
|
|
288
299
|
"""
|
|
289
300
|
|
|
290
301
|
LpSolver.__init__(
|
|
@@ -297,22 +308,25 @@ class CPLEX_PY(LpSolver):
|
|
|
297
308
|
logPath=logPath,
|
|
298
309
|
threads=threads,
|
|
299
310
|
)
|
|
311
|
+
self.solverParams = solverParams
|
|
300
312
|
|
|
301
313
|
def available(self):
|
|
302
314
|
"""True if the solver is available"""
|
|
303
315
|
return True
|
|
304
316
|
|
|
305
|
-
def actualSolve(self, lp, callback=None): # type: ignore[misc]
|
|
317
|
+
def actualSolve(self, lp, callback: Optional[Iterable[type[cplex.callbacks.Callback]]] = None): # type: ignore[misc]
|
|
306
318
|
"""
|
|
307
319
|
Solve a well formulated lp problem
|
|
308
320
|
|
|
309
321
|
creates a cplex model, variables and constraints and attaches
|
|
310
322
|
them to the lp model which it then solves
|
|
323
|
+
|
|
324
|
+
:param callback: Optional list of CPLEX callback classes to register during solve
|
|
311
325
|
"""
|
|
312
326
|
self.buildSolverModel(lp)
|
|
313
327
|
# set the initial solution
|
|
314
328
|
log.debug("Solve the Model using cplex")
|
|
315
|
-
self.callSolver(lp)
|
|
329
|
+
self.callSolver(lp, callback=callback)
|
|
316
330
|
# get the solution information
|
|
317
331
|
solutionStatus = self.findSolutionValues(lp)
|
|
318
332
|
for var in lp._variables:
|
|
@@ -430,6 +444,47 @@ class CPLEX_PY(LpSolver):
|
|
|
430
444
|
self.solverModel.MIP_starts.add(
|
|
431
445
|
cplex.SparsePair(ind=ind, val=val), effort, "1"
|
|
432
446
|
)
|
|
447
|
+
for param, value in self.solverParams.items():
|
|
448
|
+
self.set_param(param, value)
|
|
449
|
+
|
|
450
|
+
def set_param(self, name: str, value):
|
|
451
|
+
"""
|
|
452
|
+
Sets a parameter value using its name.
|
|
453
|
+
"""
|
|
454
|
+
param = self.search_param(name=name)
|
|
455
|
+
param.set(value)
|
|
456
|
+
|
|
457
|
+
def get_param(self, name: str):
|
|
458
|
+
"""
|
|
459
|
+
Returns the value of a named parameter by searching within the instance's parameters.
|
|
460
|
+
"""
|
|
461
|
+
param = self.search_param(name=name)
|
|
462
|
+
return param.get()
|
|
463
|
+
|
|
464
|
+
def search_param(self, name: str):
|
|
465
|
+
"""
|
|
466
|
+
Searches for a solver model parameter by its name and returns the corresponding attribute.
|
|
467
|
+
|
|
468
|
+
The method takes a parameter name string, processes it to remove the "parameters." prefix
|
|
469
|
+
and splits it by periods to traverse the attribute hierarchy of the solver model's parameters.
|
|
470
|
+
"""
|
|
471
|
+
name = name.replace("parameters.", "")
|
|
472
|
+
param = self.solverModel.parameters
|
|
473
|
+
for attr in name.split("."):
|
|
474
|
+
param = getattr(param, attr)
|
|
475
|
+
return param
|
|
476
|
+
|
|
477
|
+
def get_all_params(self):
|
|
478
|
+
"""
|
|
479
|
+
Returns all parameters from the solver model.
|
|
480
|
+
"""
|
|
481
|
+
return self.solverModel.parameters.get_all()
|
|
482
|
+
|
|
483
|
+
def get_changed_params(self):
|
|
484
|
+
"""
|
|
485
|
+
Returns the parameters that have been changed in the solver model.
|
|
486
|
+
"""
|
|
487
|
+
return self.solverModel.parameters.get_changed()
|
|
433
488
|
|
|
434
489
|
def setlogfile(self, fileobj):
|
|
435
490
|
"""
|
|
@@ -458,9 +513,21 @@ class CPLEX_PY(LpSolver):
|
|
|
458
513
|
"""
|
|
459
514
|
self.solverModel.parameters.timelimit.set(timeLimit)
|
|
460
515
|
|
|
461
|
-
def callSolver(
|
|
462
|
-
|
|
516
|
+
def callSolver(
|
|
517
|
+
self,
|
|
518
|
+
isMIP,
|
|
519
|
+
callback: Optional[Iterable[type[cplex.callbacks.Callback]]] = None,
|
|
520
|
+
):
|
|
521
|
+
"""
|
|
522
|
+
Solves the problem with cplex
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
:param callback: Optional list of CPLEX callback classes to register during solve
|
|
526
|
+
"""
|
|
463
527
|
# solve the problem
|
|
528
|
+
if callback is not None:
|
|
529
|
+
for call in callback:
|
|
530
|
+
self.solverModel.register_callback(call)
|
|
464
531
|
self.solveTime = -clock()
|
|
465
532
|
self.solverModel.solve()
|
|
466
533
|
self.solveTime += clock()
|
|
@@ -312,9 +312,9 @@ def writeMPS(
|
|
|
312
312
|
if mpsSense != lp.sense:
|
|
313
313
|
n = cobj.name
|
|
314
314
|
cobj = -cobj
|
|
315
|
-
cobj.name = n
|
|
315
|
+
cobj.name = n
|
|
316
316
|
if rename:
|
|
317
|
-
constrNames, varNames, cobj.name = lp.normalisedNames()
|
|
317
|
+
constrNames, varNames, cobj.name = lp.normalisedNames()
|
|
318
318
|
# No need to call self.variables() again, we have just filled self._variables:
|
|
319
319
|
vs = lp._variables
|
|
320
320
|
else:
|
|
@@ -324,7 +324,7 @@ def writeMPS(
|
|
|
324
324
|
model_name = lp.name
|
|
325
325
|
if rename:
|
|
326
326
|
model_name = "MODEL"
|
|
327
|
-
objName = cobj.name
|
|
327
|
+
objName = cobj.name
|
|
328
328
|
if not objName:
|
|
329
329
|
objName = "OBJ"
|
|
330
330
|
|
|
@@ -346,7 +346,7 @@ def writeMPS(
|
|
|
346
346
|
for v in vs:
|
|
347
347
|
name = varNames[v.name]
|
|
348
348
|
columns_lines.extend(
|
|
349
|
-
writeMPSColumnLines(coefs[name], v, mip, name, cobj, objName)
|
|
349
|
+
writeMPSColumnLines(coefs[name], v, mip, name, cobj, objName)
|
|
350
350
|
)
|
|
351
351
|
|
|
352
352
|
# right hand side
|
|
@@ -382,7 +382,7 @@ def writeMPS(
|
|
|
382
382
|
if not rename:
|
|
383
383
|
return vs
|
|
384
384
|
else:
|
|
385
|
-
return vs, varNames, constrNames, cobj.name
|
|
385
|
+
return vs, varNames, constrNames, cobj.name
|
|
386
386
|
|
|
387
387
|
|
|
388
388
|
def writeMPSColumnLines(
|