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.
Files changed (60) hide show
  1. {pulp-3.3.0 → pulp-3.3.2}/PKG-INFO +24 -25
  2. {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/PKG-INFO +24 -25
  3. {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/SOURCES.txt +1 -0
  4. {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/requires.txt +5 -3
  5. {pulp-3.3.0 → pulp-3.3.2}/README.rst +18 -20
  6. {pulp-3.3.0 → pulp-3.3.2}/pulp/__init__.py +26 -0
  7. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/__init__.py +9 -6
  8. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/coin_api.py +76 -58
  9. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/copt_api.py +10 -10
  10. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/core.py +4 -4
  11. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/cplex_api.py +15 -7
  12. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/cuopt_api.py +5 -5
  13. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/glpk_api.py +7 -8
  14. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/gurobi_api.py +6 -6
  15. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/highs_api.py +9 -6
  16. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/mosek_api.py +7 -7
  17. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/scip_api.py +4 -4
  18. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/xpress_api.py +7 -7
  19. {pulp-3.3.0 → pulp-3.3.2}/pulp/constants.py +2 -1
  20. {pulp-3.3.0 → pulp-3.3.2}/pulp/mps_lp.py +6 -6
  21. {pulp-3.3.0 → pulp-3.3.2}/pulp/pulp.py +403 -74
  22. {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/bin_packing_problem.py +2 -2
  23. {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/test_gurobipy_env.py +4 -4
  24. {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/test_lpdot.py +7 -5
  25. {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/test_pulp.py +420 -292
  26. pulp-3.3.2/pulp/v4_migration.py +19 -0
  27. {pulp-3.3.0 → pulp-3.3.2}/pyproject.toml +5 -4
  28. {pulp-3.3.0 → pulp-3.3.2}/LICENSE +0 -0
  29. {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/dependency_links.txt +0 -0
  30. {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/entry_points.txt +0 -0
  31. {pulp-3.3.0 → pulp-3.3.2}/PuLP.egg-info/top_level.txt +0 -0
  32. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/choco_api.py +0 -0
  33. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/mipcl_api.py +0 -0
  34. {pulp-3.3.0 → pulp-3.3.2}/pulp/apis/sas_api.py +0 -0
  35. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/__init__.py +0 -0
  36. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/arm64/__init__.py +0 -0
  37. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/arm64/cbc +0 -0
  38. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/arm64/coin-license.txt +0 -0
  39. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i32/__init__.py +0 -0
  40. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i32/cbc +0 -0
  41. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i32/coin-license.txt +0 -0
  42. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i64/__init__.py +0 -0
  43. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i64/cbc +0 -0
  44. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i64/coin-license.txt +0 -0
  45. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/osx/i64/__init__.py +0 -0
  46. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/osx/i64/cbc +0 -0
  47. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/osx/i64/coin-license.txt +0 -0
  48. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i32/__init__.py +0 -0
  49. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i32/cbc.exe +0 -0
  50. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i32/coin-license.txt +0 -0
  51. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i64/__init__.py +0 -0
  52. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i64/cbc.exe +0 -0
  53. {pulp-3.3.0 → pulp-3.3.2}/pulp/solverdir/cbc/win/i64/coin-license.txt +0 -0
  54. {pulp-3.3.0 → pulp-3.3.2}/pulp/sparse.py +0 -0
  55. {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/__init__.py +0 -0
  56. {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/run_tests.py +0 -0
  57. {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/test_examples.py +0 -0
  58. {pulp-3.3.0 → pulp-3.3.2}/pulp/tests/test_sparse.py +0 -0
  59. {pulp-3.3.0 → pulp-3.3.2}/pulp/utilities.py +0 -0
  60. {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.0
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.9
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: cylp; extra == "open-py"
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.9 or newer.
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, which is included with PuLP. If you want to use 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)::
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
- Use ``LpVariable`` to create new variables. To create a variable x with 0 ≤ x ≤ 3::
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 with the default included solver::
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.0
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.9
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: cylp; extra == "open-py"
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.9 or newer.
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, which is included with PuLP. If you want to use 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)::
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
- Use ``LpVariable`` to create new variables. To create a variable x with 0 ≤ x ≤ 3::
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 with the default included solver::
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
  --------------------------
@@ -13,6 +13,7 @@ pulp/mps_lp.py
13
13
  pulp/pulp.py
14
14
  pulp/sparse.py
15
15
  pulp/utilities.py
16
+ pulp/v4_migration.py
16
17
  pulp/apis/__init__.py
17
18
  pulp/apis/choco_api.py
18
19
  pulp/apis/coin_api.py
@@ -1,4 +1,7 @@
1
1
 
2
+ [cbc]
3
+ cbcbox
4
+
2
5
  [copt]
3
6
  coptpy
4
7
 
@@ -11,14 +14,13 @@ cplex
11
14
  gurobipy
12
15
 
13
16
  [highs]
14
- highspy
17
+ highspy==1.13
15
18
 
16
19
  [mosek]
17
20
  mosek
18
21
 
19
22
  [open_py]
20
- cylp
21
- highspy
23
+ highspy==1.13
22
24
  pyscipopt
23
25
 
24
26
  [public_py]
@@ -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.9 or newer.
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, which is included with PuLP. If you want to use 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)::
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
- Use ``LpVariable`` to create new variables. To create a variable x with 0 ≤ x ≤ 3::
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 with the default included solver::
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, COIN_CMD]] = None
48
+ LpSolverDefault: Optional[Union[COIN_CMD, PULP_CBC_CMD, GLPK_CMD]] = None
49
49
  # Default solver selection
50
- if PULP_CBC_CMD().available():
51
- LpSolverDefault = PULP_CBC_CMD()
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
- solver = s(msg=False)
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.constraints}
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 += "-branch "
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.constraints}
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
- This solver uses a precompiled version of cbc provided with the package
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
- def available(self):
380
- """True if the solver is available"""
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
- def actualSolve(self, lp, callback=None):
384
- """Solve a well formulated lp problem"""
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
- else:
391
-
392
- def __init__(
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
- mip=True,
395
- msg=True,
396
- timeLimit=None,
397
- gapRel=None,
398
- gapAbs=None,
399
- presolve=None,
400
- cuts=None,
401
- strong=None,
402
- options=None,
403
- warmStart=False,
404
- keepFiles=False,
405
- path=None,
406
- threads=None,
407
- logPath=None,
408
- timeMode="elapsed",
409
- maxNodes=None,
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.constraints.values():
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.constraints.items():
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.constraints.values():
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.constraints.values():
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.constraints.values():
903
+ for constraint in lp._constraints.values():
886
904
  constraint.modified = False
887
905
  return solutionStatus
888
906