PySCIPOpt 5.2.1__tar.gz → 5.3.0__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.
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/PKG-INFO +4 -2
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/PySCIPOpt.egg-info/PKG-INFO +4 -2
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/PySCIPOpt.egg-info/SOURCES.txt +4 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/pyproject.toml +4 -4
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/setup.py +1 -1
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/__init__.py +1 -0
- pyscipopt-5.3.0/src/pyscipopt/_version.py +1 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/benders.pxi +2 -2
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/conshdlr.pxi +32 -16
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/cutsel.pxi +3 -2
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/lp.pxi +64 -42
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/reader.pxi +4 -2
- pyscipopt-5.3.0/src/pyscipopt/recipes/primal_dual_evolution.py +46 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/scip.c +36089 -31207
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/scip.pxd +34 -1
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/scip.pxi +483 -187
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_cons.py +15 -5
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_copy.py +2 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_event.py +1 -4
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_heur.py +7 -2
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_memory.py +5 -2
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_model.py +43 -2
- pyscipopt-5.3.0/tests/test_nogil.py +23 -0
- pyscipopt-5.3.0/tests/test_recipe_primal_dual_evolution.py +28 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_solution.py +27 -1
- pyscipopt-5.3.0/tests/test_sub_sol.py +58 -0
- pyscipopt-5.2.1/src/pyscipopt/_version.py +0 -1
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/LICENSE +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/PySCIPOpt.egg-info/dependency_links.txt +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/PySCIPOpt.egg-info/top_level.txt +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/README.md +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/setup.cfg +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/Multidict.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/benderscut.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/branchrule.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/event.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/expr.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/heuristic.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/nodesel.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/presol.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/pricer.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/propagator.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/recipes/__init__.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/recipes/infeasibilities.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/recipes/nonlinear.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/recipes/piecewise.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/relax.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/scip.pyx +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/src/pyscipopt/sepa.pxi +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_alldiff.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_benders.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_bipartite.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_branch_mostinfeas.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_branch_probing_lp.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_conshdlr.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_customizedbenders.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_cutsel.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_expr.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_gomory.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_knapsack.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_linexpr.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_logical.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_lp.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_nlrow.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_nodesel.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_nonlinear.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_pricer.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_quadcons.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_quickprod.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_quicksum.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_reader.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_recipe_infeasibilities.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_recipe_nonlinear.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_recipe_piecewise.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_relax.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_reopt.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_short.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_strong_branching.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_tree.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_tsp.py +0 -0
- {pyscipopt-5.2.1 → pyscipopt-5.3.0}/tests/test_vars.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: PySCIPOpt
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.3.0
|
|
4
4
|
Summary: Python interface and modeling environment for SCIP
|
|
5
5
|
Home-page: https://github.com/SCIP-Interfaces/PySCIPOpt
|
|
6
6
|
Author: Zuse Institute Berlin
|
|
@@ -17,6 +17,8 @@ Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
|
17
17
|
Requires-Python: >=3.8
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
|
+
Dynamic: author
|
|
21
|
+
Dynamic: home-page
|
|
20
22
|
|
|
21
23
|
PySCIPOpt
|
|
22
24
|
=========
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: PySCIPOpt
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.3.0
|
|
4
4
|
Summary: Python interface and modeling environment for SCIP
|
|
5
5
|
Home-page: https://github.com/SCIP-Interfaces/PySCIPOpt
|
|
6
6
|
Author: Zuse Institute Berlin
|
|
@@ -17,6 +17,8 @@ Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
|
17
17
|
Requires-Python: >=3.8
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
|
+
Dynamic: author
|
|
21
|
+
Dynamic: home-page
|
|
20
22
|
|
|
21
23
|
PySCIPOpt
|
|
22
24
|
=========
|
|
@@ -34,6 +34,7 @@ src/pyscipopt/recipes/__init__.py
|
|
|
34
34
|
src/pyscipopt/recipes/infeasibilities.py
|
|
35
35
|
src/pyscipopt/recipes/nonlinear.py
|
|
36
36
|
src/pyscipopt/recipes/piecewise.py
|
|
37
|
+
src/pyscipopt/recipes/primal_dual_evolution.py
|
|
37
38
|
tests/test_alldiff.py
|
|
38
39
|
tests/test_benders.py
|
|
39
40
|
tests/test_bipartite.py
|
|
@@ -56,6 +57,7 @@ tests/test_memory.py
|
|
|
56
57
|
tests/test_model.py
|
|
57
58
|
tests/test_nlrow.py
|
|
58
59
|
tests/test_nodesel.py
|
|
60
|
+
tests/test_nogil.py
|
|
59
61
|
tests/test_nonlinear.py
|
|
60
62
|
tests/test_pricer.py
|
|
61
63
|
tests/test_quadcons.py
|
|
@@ -65,11 +67,13 @@ tests/test_reader.py
|
|
|
65
67
|
tests/test_recipe_infeasibilities.py
|
|
66
68
|
tests/test_recipe_nonlinear.py
|
|
67
69
|
tests/test_recipe_piecewise.py
|
|
70
|
+
tests/test_recipe_primal_dual_evolution.py
|
|
68
71
|
tests/test_relax.py
|
|
69
72
|
tests/test_reopt.py
|
|
70
73
|
tests/test_short.py
|
|
71
74
|
tests/test_solution.py
|
|
72
75
|
tests/test_strong_branching.py
|
|
76
|
+
tests/test_sub_sol.py
|
|
73
77
|
tests/test_tree.py
|
|
74
78
|
tests/test_tsp.py
|
|
75
79
|
tests/test_vars.py
|
|
@@ -45,7 +45,7 @@ manylinux-x86_64-image = "manylinux_2_28"
|
|
|
45
45
|
skip="pp* cp36* cp37* *musllinux*"
|
|
46
46
|
before-all = [
|
|
47
47
|
"(apt-get update && apt-get install --yes wget) || yum install -y wget zlib libgfortran || brew install wget",
|
|
48
|
-
"wget https://github.com/scipopt/scipoptsuite-deploy/releases/download/v0.
|
|
48
|
+
"wget https://github.com/scipopt/scipoptsuite-deploy/releases/download/v0.7.0/libscip-linux.zip -O scip.zip",
|
|
49
49
|
"unzip scip.zip",
|
|
50
50
|
"mv scip_install scip"
|
|
51
51
|
]
|
|
@@ -58,10 +58,10 @@ before-all = '''
|
|
|
58
58
|
#!/bin/bash
|
|
59
59
|
brew install wget zlib gcc
|
|
60
60
|
if [[ $CIBW_ARCHS == *"arm"* ]]; then
|
|
61
|
-
wget https://github.com/scipopt/scipoptsuite-deploy/releases/download/v0.
|
|
61
|
+
wget https://github.com/scipopt/scipoptsuite-deploy/releases/download/v0.7.0/libscip-macos-arm.zip -O scip.zip
|
|
62
62
|
export MACOSX_DEPLOYMENT_TARGET=14.0
|
|
63
63
|
else
|
|
64
|
-
wget https://github.com/scipopt/scipoptsuite-deploy/releases/download/v0.
|
|
64
|
+
wget https://github.com/scipopt/scipoptsuite-deploy/releases/download/v0.7.0/libscip-macos-intel.zip -O scip.zip
|
|
65
65
|
export MACOSX_DEPLOYMENT_TARGET=13.0
|
|
66
66
|
fi
|
|
67
67
|
unzip scip.zip
|
|
@@ -87,7 +87,7 @@ repair-wheel-command = '''
|
|
|
87
87
|
skip="pp* cp36* cp37*"
|
|
88
88
|
before-all = [
|
|
89
89
|
"choco install 7zip wget",
|
|
90
|
-
"wget https://github.com/scipopt/scipoptsuite-deploy/releases/download/v0.
|
|
90
|
+
"wget https://github.com/scipopt/scipoptsuite-deploy/releases/download/v0.7.0/libscip-windows.zip -O scip.zip",
|
|
91
91
|
"\"C:\\Program Files\\7-Zip\\7z.exe\" x \"scip.zip\" -o\"scip-test\"",
|
|
92
92
|
"mv .\\scip-test\\scip_install .\\test",
|
|
93
93
|
"mv .\\test .\\scip"
|
|
@@ -109,7 +109,7 @@ with open("README.md") as f:
|
|
|
109
109
|
|
|
110
110
|
setup(
|
|
111
111
|
name="PySCIPOpt",
|
|
112
|
-
version="5.
|
|
112
|
+
version="5.3.0",
|
|
113
113
|
description="Python interface and modeling environment for SCIP",
|
|
114
114
|
long_description=long_description,
|
|
115
115
|
long_description_content_type="text/markdown",
|
|
@@ -46,3 +46,4 @@ from pyscipopt.scip import PY_SCIP_LPSOLSTAT as SCIP_LPSOLSTAT
|
|
|
46
46
|
from pyscipopt.scip import PY_SCIP_BRANCHDIR as SCIP_BRANCHDIR
|
|
47
47
|
from pyscipopt.scip import PY_SCIP_BENDERSENFOTYPE as SCIP_BENDERSENFOTYPE
|
|
48
48
|
from pyscipopt.scip import PY_SCIP_ROWORIGINTYPE as SCIP_ROWORIGINTYPE
|
|
49
|
+
from pyscipopt.scip import PY_SCIP_SOLORIGIN as SCIP_SOLORIGIN
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '5.3.0'
|
|
@@ -175,8 +175,8 @@ cdef SCIP_RETCODE PyBendersSolvesub (SCIP* scip, SCIP_BENDERS* benders, SCIP_SOL
|
|
|
175
175
|
cdef SCIP_RETCODE PyBendersPostsolve (SCIP* scip, SCIP_BENDERS* benders, SCIP_SOL* sol,
|
|
176
176
|
SCIP_BENDERSENFOTYPE type, int* mergecands, int npriomergecands, int nmergecands, SCIP_Bool checkint,
|
|
177
177
|
SCIP_Bool infeasible, SCIP_Bool* merged) noexcept with gil:
|
|
178
|
-
cdef SCIP_BENDERSDATA* bendersdata
|
|
179
|
-
|
|
178
|
+
cdef SCIP_BENDERSDATA* bendersdata = SCIPbendersGetData(benders)
|
|
179
|
+
cdef int i
|
|
180
180
|
PyBenders = <Benders>bendersdata
|
|
181
181
|
if sol == NULL:
|
|
182
182
|
solution = None
|
|
@@ -168,48 +168,54 @@ cdef SCIP_RETCODE PyConsFree (SCIP* scip, SCIP_CONSHDLR* conshdlr) noexcept with
|
|
|
168
168
|
return SCIP_OKAY
|
|
169
169
|
|
|
170
170
|
cdef SCIP_RETCODE PyConsInit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
|
|
171
|
+
cdef int i
|
|
171
172
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
172
|
-
|
|
173
|
+
constraints = []
|
|
173
174
|
for i in range(nconss):
|
|
174
175
|
constraints.append(getPyCons(conss[i]))
|
|
175
176
|
PyConshdlr.consinit(constraints)
|
|
176
177
|
return SCIP_OKAY
|
|
177
178
|
|
|
178
179
|
cdef SCIP_RETCODE PyConsExit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
|
|
180
|
+
cdef int i
|
|
179
181
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
180
|
-
|
|
182
|
+
constraints = []
|
|
181
183
|
for i in range(nconss):
|
|
182
184
|
constraints.append(getPyCons(conss[i]))
|
|
183
185
|
PyConshdlr.consexit(constraints)
|
|
184
186
|
return SCIP_OKAY
|
|
185
187
|
|
|
186
188
|
cdef SCIP_RETCODE PyConsInitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
|
|
189
|
+
cdef int i
|
|
187
190
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
188
|
-
|
|
191
|
+
constraints = []
|
|
189
192
|
for i in range(nconss):
|
|
190
193
|
constraints.append(getPyCons(conss[i]))
|
|
191
194
|
PyConshdlr.consinitpre(constraints)
|
|
192
195
|
return SCIP_OKAY
|
|
193
196
|
|
|
194
197
|
cdef SCIP_RETCODE PyConsExitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
|
|
198
|
+
cdef int i
|
|
195
199
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
196
|
-
|
|
200
|
+
constraints = []
|
|
197
201
|
for i in range(nconss):
|
|
198
202
|
constraints.append(getPyCons(conss[i]))
|
|
199
203
|
PyConshdlr.consexitpre(constraints)
|
|
200
204
|
return SCIP_OKAY
|
|
201
205
|
|
|
202
206
|
cdef SCIP_RETCODE PyConsInitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
|
|
207
|
+
cdef int i
|
|
203
208
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
204
|
-
|
|
209
|
+
constraints = []
|
|
205
210
|
for i in range(nconss):
|
|
206
211
|
constraints.append(getPyCons(conss[i]))
|
|
207
212
|
PyConshdlr.consinitsol(constraints)
|
|
208
213
|
return SCIP_OKAY
|
|
209
214
|
|
|
210
215
|
cdef SCIP_RETCODE PyConsExitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_Bool restart) noexcept with gil:
|
|
216
|
+
cdef int i
|
|
211
217
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
212
|
-
|
|
218
|
+
constraints = []
|
|
213
219
|
for i in range(nconss):
|
|
214
220
|
constraints.append(getPyCons(conss[i]))
|
|
215
221
|
PyConshdlr.consexitsol(constraints, restart)
|
|
@@ -244,8 +250,9 @@ cdef SCIP_RETCODE PyConsTrans (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* s
|
|
|
244
250
|
return SCIP_OKAY
|
|
245
251
|
|
|
246
252
|
cdef SCIP_RETCODE PyConsInitlp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_Bool* infeasible) noexcept with gil:
|
|
253
|
+
cdef int i
|
|
247
254
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
248
|
-
|
|
255
|
+
constraints = []
|
|
249
256
|
for i in range(nconss):
|
|
250
257
|
constraints.append(getPyCons(conss[i]))
|
|
251
258
|
result_dict = PyConshdlr.consinitlp(constraints)
|
|
@@ -253,8 +260,9 @@ cdef SCIP_RETCODE PyConsInitlp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
|
|
|
253
260
|
return SCIP_OKAY
|
|
254
261
|
|
|
255
262
|
cdef SCIP_RETCODE PyConsSepalp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, SCIP_RESULT* result) noexcept with gil:
|
|
263
|
+
cdef int i
|
|
256
264
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
257
|
-
|
|
265
|
+
constraints = []
|
|
258
266
|
for i in range(nconss):
|
|
259
267
|
constraints.append(getPyCons(conss[i]))
|
|
260
268
|
result_dict = PyConshdlr.conssepalp(constraints, nusefulconss)
|
|
@@ -263,8 +271,9 @@ cdef SCIP_RETCODE PyConsSepalp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
|
|
|
263
271
|
|
|
264
272
|
cdef SCIP_RETCODE PyConsSepasol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss,
|
|
265
273
|
SCIP_SOL* sol, SCIP_RESULT* result) noexcept with gil:
|
|
274
|
+
cdef int i
|
|
266
275
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
267
|
-
|
|
276
|
+
constraints = []
|
|
268
277
|
for i in range(nconss):
|
|
269
278
|
constraints.append(getPyCons(conss[i]))
|
|
270
279
|
solution = Solution.create(scip, sol)
|
|
@@ -274,8 +283,9 @@ cdef SCIP_RETCODE PyConsSepasol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS*
|
|
|
274
283
|
|
|
275
284
|
cdef SCIP_RETCODE PyConsEnfolp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss,
|
|
276
285
|
SCIP_Bool solinfeasible, SCIP_RESULT* result) noexcept with gil:
|
|
286
|
+
cdef int i
|
|
277
287
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
278
|
-
|
|
288
|
+
constraints = []
|
|
279
289
|
for i in range(nconss):
|
|
280
290
|
constraints.append(getPyCons(conss[i]))
|
|
281
291
|
result_dict = PyConshdlr.consenfolp(constraints, nusefulconss, solinfeasible)
|
|
@@ -283,8 +293,9 @@ cdef SCIP_RETCODE PyConsEnfolp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
|
|
|
283
293
|
return SCIP_OKAY
|
|
284
294
|
|
|
285
295
|
cdef SCIP_RETCODE PyConsEnforelax (SCIP* scip, SCIP_SOL* sol, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, SCIP_Bool solinfeasible, SCIP_RESULT* result) noexcept with gil:
|
|
296
|
+
cdef int i
|
|
286
297
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
287
|
-
|
|
298
|
+
constraints = []
|
|
288
299
|
for i in range(nconss):
|
|
289
300
|
constraints.append(getPyCons(conss[i]))
|
|
290
301
|
solution = Solution.create(scip, sol)
|
|
@@ -294,8 +305,9 @@ cdef SCIP_RETCODE PyConsEnforelax (SCIP* scip, SCIP_SOL* sol, SCIP_CONSHDLR* con
|
|
|
294
305
|
|
|
295
306
|
cdef SCIP_RETCODE PyConsEnfops (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss,
|
|
296
307
|
SCIP_Bool solinfeasible, SCIP_Bool objinfeasible, SCIP_RESULT* result) noexcept with gil:
|
|
308
|
+
cdef int i
|
|
297
309
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
298
|
-
|
|
310
|
+
constraints = []
|
|
299
311
|
for i in range(nconss):
|
|
300
312
|
constraints.append(getPyCons(conss[i]))
|
|
301
313
|
result_dict = PyConshdlr.consenfops(constraints, nusefulconss, solinfeasible, objinfeasible)
|
|
@@ -304,8 +316,9 @@ cdef SCIP_RETCODE PyConsEnfops (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
|
|
|
304
316
|
|
|
305
317
|
cdef SCIP_RETCODE PyConsCheck (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_SOL* sol, SCIP_Bool checkintegrality,
|
|
306
318
|
SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_Bool completely, SCIP_RESULT* result) noexcept with gil:
|
|
319
|
+
cdef int i
|
|
307
320
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
308
|
-
|
|
321
|
+
constraints = []
|
|
309
322
|
for i in range(nconss):
|
|
310
323
|
constraints.append(getPyCons(conss[i]))
|
|
311
324
|
solution = Solution.create(scip, sol)
|
|
@@ -315,8 +328,9 @@ cdef SCIP_RETCODE PyConsCheck (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
|
|
|
315
328
|
|
|
316
329
|
cdef SCIP_RETCODE PyConsProp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, int nmarkedconss,
|
|
317
330
|
SCIP_PROPTIMING proptiming, SCIP_RESULT* result) noexcept with gil:
|
|
331
|
+
cdef int i
|
|
318
332
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
319
|
-
|
|
333
|
+
constraints = []
|
|
320
334
|
for i in range(nconss):
|
|
321
335
|
constraints.append(getPyCons(conss[i]))
|
|
322
336
|
result_dict = PyConshdlr.consprop(constraints, nusefulconss, nmarkedconss, proptiming)
|
|
@@ -328,8 +342,9 @@ cdef SCIP_RETCODE PyConsPresol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
|
|
|
328
342
|
int nnewdelconss, int nnewaddconss, int nnewupgdconss, int nnewchgcoefs, int nnewchgsides,
|
|
329
343
|
int* nfixedvars, int* naggrvars, int* nchgvartypes, int* nchgbds, int* naddholes,
|
|
330
344
|
int* ndelconss, int* naddconss, int* nupgdconss, int* nchgcoefs, int* nchgsides, SCIP_RESULT* result) noexcept with gil:
|
|
345
|
+
cdef int i
|
|
331
346
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
332
|
-
|
|
347
|
+
constraints = []
|
|
333
348
|
for i in range(nconss):
|
|
334
349
|
constraints.append(getPyCons(conss[i]))
|
|
335
350
|
# dictionary for input/output parameters
|
|
@@ -401,8 +416,9 @@ cdef SCIP_RETCODE PyConsDisable (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS*
|
|
|
401
416
|
return SCIP_OKAY
|
|
402
417
|
|
|
403
418
|
cdef SCIP_RETCODE PyConsDelvars (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
|
|
419
|
+
cdef int i
|
|
404
420
|
PyConshdlr = getPyConshdlr(conshdlr)
|
|
405
|
-
|
|
421
|
+
constraints = []
|
|
406
422
|
for i in range(nconss):
|
|
407
423
|
constraints.append(getPyCons(conss[i]))
|
|
408
424
|
PyConshdlr.consdelvars(constraints)
|
|
@@ -72,9 +72,10 @@ cdef SCIP_RETCODE PyCutselExitsol (SCIP* scip, SCIP_CUTSEL* cutsel) noexcept wit
|
|
|
72
72
|
cdef SCIP_RETCODE PyCutselSelect (SCIP* scip, SCIP_CUTSEL* cutsel, SCIP_ROW** cuts, int ncuts,
|
|
73
73
|
SCIP_ROW** forcedcuts, int nforcedcuts, SCIP_Bool root, int maxnselectedcuts,
|
|
74
74
|
int* nselectedcuts, SCIP_RESULT* result) noexcept with gil:
|
|
75
|
-
cdef SCIP_CUTSELDATA* cutseldata
|
|
75
|
+
cdef SCIP_CUTSELDATA* cutseldata = SCIPcutselGetData(cutsel)
|
|
76
76
|
cdef SCIP_ROW* scip_row
|
|
77
|
-
|
|
77
|
+
cdef int i
|
|
78
|
+
|
|
78
79
|
PyCutsel = <Cutsel>cutseldata
|
|
79
80
|
|
|
80
81
|
# translate cuts to python
|
|
@@ -63,19 +63,14 @@ cdef class LP:
|
|
|
63
63
|
lb -- lower bound (default 0.0)
|
|
64
64
|
ub -- upper bound (default infinity)
|
|
65
65
|
"""
|
|
66
|
-
nnonz = len(entries)
|
|
67
|
-
|
|
66
|
+
cdef int nnonz = len(entries)
|
|
68
67
|
cdef SCIP_Real* c_coefs = <SCIP_Real*> malloc(nnonz * sizeof(SCIP_Real))
|
|
69
68
|
cdef int* c_inds = <int*>malloc(nnonz * sizeof(int))
|
|
70
|
-
cdef SCIP_Real c_obj
|
|
71
|
-
cdef SCIP_Real c_lb
|
|
72
|
-
cdef SCIP_Real c_ub
|
|
73
|
-
cdef int c_beg
|
|
74
|
-
|
|
75
|
-
c_obj = obj
|
|
76
|
-
c_lb = lb
|
|
77
|
-
c_ub = ub if ub != None else self.infinity()
|
|
78
|
-
c_beg = 0
|
|
69
|
+
cdef SCIP_Real c_obj = obj
|
|
70
|
+
cdef SCIP_Real c_lb = lb
|
|
71
|
+
cdef SCIP_Real c_ub = ub if ub != None else self.infinity()
|
|
72
|
+
cdef int c_beg = 0
|
|
73
|
+
cdef int i
|
|
79
74
|
|
|
80
75
|
for i,entry in enumerate(entries):
|
|
81
76
|
c_inds[i] = entry[0]
|
|
@@ -95,17 +90,15 @@ cdef class LP:
|
|
|
95
90
|
lbs -- lower bounds (default 0.0)
|
|
96
91
|
ubs -- upper bounds (default infinity)
|
|
97
92
|
"""
|
|
98
|
-
|
|
99
|
-
ncols = len(entrieslist)
|
|
100
|
-
nnonz = sum(len(entries) for entries in entrieslist)
|
|
101
|
-
|
|
93
|
+
cdef int ncols = len(entrieslist)
|
|
102
94
|
cdef SCIP_Real* c_objs = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
|
|
103
95
|
cdef SCIP_Real* c_lbs = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
|
|
104
96
|
cdef SCIP_Real* c_ubs = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
|
|
105
97
|
cdef SCIP_Real* c_coefs
|
|
106
98
|
cdef int* c_inds
|
|
107
99
|
cdef int* c_beg
|
|
108
|
-
|
|
100
|
+
cdef int nnonz = sum(len(entries) for entries in entrieslist)
|
|
101
|
+
cdef int i
|
|
109
102
|
|
|
110
103
|
if nnonz > 0:
|
|
111
104
|
c_coefs = <SCIP_Real*> malloc(nnonz * sizeof(SCIP_Real))
|
|
@@ -158,18 +151,13 @@ cdef class LP:
|
|
|
158
151
|
lhs -- left-hand side of the row (default 0.0)
|
|
159
152
|
rhs -- right-hand side of the row (default infinity)
|
|
160
153
|
"""
|
|
161
|
-
|
|
162
|
-
nnonz = len(entries)
|
|
163
|
-
|
|
154
|
+
cdef int nnonz = len(entries)
|
|
164
155
|
cdef SCIP_Real* c_coefs = <SCIP_Real*> malloc(nnonz * sizeof(SCIP_Real))
|
|
165
156
|
cdef int* c_inds = <int*>malloc(nnonz * sizeof(int))
|
|
166
|
-
cdef SCIP_Real c_lhs
|
|
167
|
-
cdef SCIP_Real c_rhs
|
|
168
|
-
cdef int c_beg
|
|
169
|
-
|
|
170
|
-
c_lhs = lhs
|
|
171
|
-
c_rhs = rhs if rhs != None else self.infinity()
|
|
172
|
-
c_beg = 0
|
|
157
|
+
cdef SCIP_Real c_lhs = lhs
|
|
158
|
+
cdef SCIP_Real c_rhs = rhs if rhs != None else self.infinity()
|
|
159
|
+
cdef int c_beg = 0
|
|
160
|
+
cdef int i
|
|
173
161
|
|
|
174
162
|
for i,entry in enumerate(entries):
|
|
175
163
|
c_inds[i] = entry[0]
|
|
@@ -188,16 +176,16 @@ cdef class LP:
|
|
|
188
176
|
lhss -- left-hand side of the row (default 0.0)
|
|
189
177
|
rhss -- right-hand side of the row (default infinity)
|
|
190
178
|
"""
|
|
191
|
-
nrows = len(entrieslist)
|
|
192
|
-
nnonz = sum(len(entries) for entries in entrieslist)
|
|
193
|
-
|
|
179
|
+
cdef int nrows = len(entrieslist)
|
|
194
180
|
cdef SCIP_Real* c_lhss = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
|
|
195
181
|
cdef SCIP_Real* c_rhss = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
|
|
182
|
+
cdef int* c_beg = <int*>malloc(nrows * sizeof(int))
|
|
183
|
+
cdef int nnonz = sum(len(entries) for entries in entrieslist)
|
|
196
184
|
cdef SCIP_Real* c_coefs = <SCIP_Real*> malloc(nnonz * sizeof(SCIP_Real))
|
|
197
185
|
cdef int* c_inds = <int*>malloc(nnonz * sizeof(int))
|
|
198
|
-
cdef int
|
|
186
|
+
cdef int tmp = 0
|
|
187
|
+
cdef int i
|
|
199
188
|
|
|
200
|
-
tmp = 0
|
|
201
189
|
for i,entries in enumerate(entrieslist):
|
|
202
190
|
c_lhss[i] = lhss[i] if lhss != None else 0.0
|
|
203
191
|
c_rhss[i] = rhss[i] if rhss != None else self.infinity()
|
|
@@ -232,6 +220,8 @@ cdef class LP:
|
|
|
232
220
|
firstcol -- first column (default 0)
|
|
233
221
|
lastcol -- last column (default ncols - 1)
|
|
234
222
|
"""
|
|
223
|
+
cdef int i
|
|
224
|
+
|
|
235
225
|
lastcol = lastcol if lastcol != None else self.ncols() - 1
|
|
236
226
|
|
|
237
227
|
if firstcol > lastcol:
|
|
@@ -261,6 +251,8 @@ cdef class LP:
|
|
|
261
251
|
firstrow -- first row (default 0)
|
|
262
252
|
lastrow -- last row (default nrows - 1)
|
|
263
253
|
"""
|
|
254
|
+
cdef int i
|
|
255
|
+
|
|
264
256
|
lastrow = lastrow if lastrow != None else self.nrows() - 1
|
|
265
257
|
|
|
266
258
|
if firstrow > lastrow:
|
|
@@ -290,8 +282,9 @@ cdef class LP:
|
|
|
290
282
|
col -- column to change
|
|
291
283
|
obj -- new objective coefficient
|
|
292
284
|
"""
|
|
293
|
-
cdef int c_col = col
|
|
294
285
|
cdef SCIP_Real c_obj = obj
|
|
286
|
+
cdef int c_col = col
|
|
287
|
+
|
|
295
288
|
PY_SCIP_CALL(SCIPlpiChgObj(self.lpi, 1, &c_col, &c_obj))
|
|
296
289
|
|
|
297
290
|
def chgCoef(self, row, col, newval):
|
|
@@ -312,9 +305,10 @@ cdef class LP:
|
|
|
312
305
|
lb -- new lower bound
|
|
313
306
|
ub -- new upper bound
|
|
314
307
|
"""
|
|
315
|
-
cdef int c_col = col
|
|
316
308
|
cdef SCIP_Real c_lb = lb
|
|
317
309
|
cdef SCIP_Real c_ub = ub
|
|
310
|
+
cdef int c_col = col
|
|
311
|
+
|
|
318
312
|
PY_SCIP_CALL(SCIPlpiChgBounds(self.lpi, 1, &c_col, &c_lb, &c_ub))
|
|
319
313
|
|
|
320
314
|
def chgSide(self, row, lhs, rhs):
|
|
@@ -325,9 +319,10 @@ cdef class LP:
|
|
|
325
319
|
lhs -- new left-hand side
|
|
326
320
|
rhs -- new right-hand side
|
|
327
321
|
"""
|
|
328
|
-
cdef int c_row = row
|
|
329
322
|
cdef SCIP_Real c_lhs = lhs
|
|
330
323
|
cdef SCIP_Real c_rhs = rhs
|
|
324
|
+
cdef int c_row = row
|
|
325
|
+
|
|
331
326
|
PY_SCIP_CALL(SCIPlpiChgSides(self.lpi, 1, &c_row, &c_lhs, &c_rhs))
|
|
332
327
|
|
|
333
328
|
def clear(self):
|
|
@@ -337,13 +332,17 @@ cdef class LP:
|
|
|
337
332
|
def nrows(self):
|
|
338
333
|
"""Returns the number of rows."""
|
|
339
334
|
cdef int nrows
|
|
335
|
+
|
|
340
336
|
PY_SCIP_CALL(SCIPlpiGetNRows(self.lpi, &nrows))
|
|
337
|
+
|
|
341
338
|
return nrows
|
|
342
339
|
|
|
343
340
|
def ncols(self):
|
|
344
341
|
"""Returns the number of columns."""
|
|
345
342
|
cdef int ncols
|
|
343
|
+
|
|
346
344
|
PY_SCIP_CALL(SCIPlpiGetNCols(self.lpi, &ncols))
|
|
345
|
+
|
|
347
346
|
return ncols
|
|
348
347
|
|
|
349
348
|
def solve(self, dual=True):
|
|
@@ -359,12 +358,15 @@ cdef class LP:
|
|
|
359
358
|
|
|
360
359
|
cdef SCIP_Real objval
|
|
361
360
|
PY_SCIP_CALL(SCIPlpiGetObjval(self.lpi, &objval))
|
|
361
|
+
|
|
362
362
|
return objval
|
|
363
363
|
|
|
364
364
|
def getPrimal(self):
|
|
365
365
|
"""Returns the primal solution of the last LP solve."""
|
|
366
|
-
ncols = self.ncols()
|
|
366
|
+
cdef int ncols = self.ncols()
|
|
367
367
|
cdef SCIP_Real* c_primalsol = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
|
|
368
|
+
cdef int i
|
|
369
|
+
|
|
368
370
|
PY_SCIP_CALL(SCIPlpiGetSol(self.lpi, NULL, c_primalsol, NULL, NULL, NULL))
|
|
369
371
|
primalsol = [0.0] * ncols
|
|
370
372
|
for i in range(ncols):
|
|
@@ -379,8 +381,10 @@ cdef class LP:
|
|
|
379
381
|
|
|
380
382
|
def getDual(self):
|
|
381
383
|
"""Returns the dual solution of the last LP solve."""
|
|
382
|
-
nrows = self.nrows()
|
|
384
|
+
cdef int nrows = self.nrows()
|
|
383
385
|
cdef SCIP_Real* c_dualsol = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
|
|
386
|
+
cdef int i
|
|
387
|
+
|
|
384
388
|
PY_SCIP_CALL(SCIPlpiGetSol(self.lpi, NULL, NULL, c_dualsol, NULL, NULL))
|
|
385
389
|
dualsol = [0.0] * nrows
|
|
386
390
|
for i in range(nrows):
|
|
@@ -395,10 +399,16 @@ cdef class LP:
|
|
|
395
399
|
|
|
396
400
|
def getPrimalRay(self):
|
|
397
401
|
"""Returns a primal ray if possible, None otherwise."""
|
|
402
|
+
cdef int ncols
|
|
403
|
+
cdef SCIP_Real* c_ray
|
|
404
|
+
cdef int i
|
|
405
|
+
|
|
398
406
|
if not SCIPlpiHasPrimalRay(self.lpi):
|
|
399
407
|
return None
|
|
408
|
+
|
|
400
409
|
ncols = self.ncols()
|
|
401
|
-
|
|
410
|
+
c_ray = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
|
|
411
|
+
|
|
402
412
|
PY_SCIP_CALL(SCIPlpiGetPrimalRay(self.lpi, c_ray))
|
|
403
413
|
ray = [0.0] * ncols
|
|
404
414
|
for i in range(ncols):
|
|
@@ -409,10 +419,16 @@ cdef class LP:
|
|
|
409
419
|
|
|
410
420
|
def getDualRay(self):
|
|
411
421
|
"""Returns a dual ray if possible, None otherwise."""
|
|
422
|
+
cdef int nrows
|
|
423
|
+
cdef SCIP_Real* c_ray
|
|
424
|
+
cdef int i
|
|
425
|
+
|
|
412
426
|
if not SCIPlpiHasDualRay(self.lpi):
|
|
413
427
|
return None
|
|
428
|
+
|
|
414
429
|
nrows = self.nrows()
|
|
415
|
-
|
|
430
|
+
c_ray = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
|
|
431
|
+
|
|
416
432
|
PY_SCIP_CALL(SCIPlpiGetDualfarkas(self.lpi, c_ray))
|
|
417
433
|
ray = [0.0] * nrows
|
|
418
434
|
for i in range(nrows):
|
|
@@ -424,14 +440,17 @@ cdef class LP:
|
|
|
424
440
|
def getNIterations(self):
|
|
425
441
|
"""Returns the number of LP iterations of the last LP solve."""
|
|
426
442
|
cdef int niters
|
|
443
|
+
|
|
427
444
|
PY_SCIP_CALL(SCIPlpiGetIterations(self.lpi, &niters))
|
|
445
|
+
|
|
428
446
|
return niters
|
|
429
447
|
|
|
430
448
|
def getRedcost(self):
|
|
431
449
|
"""Returns the reduced cost vector of the last LP solve."""
|
|
432
|
-
ncols = self.ncols()
|
|
433
|
-
|
|
450
|
+
cdef int ncols = self.ncols()
|
|
434
451
|
cdef SCIP_Real* c_redcost = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
|
|
452
|
+
cdef int i
|
|
453
|
+
|
|
435
454
|
PY_SCIP_CALL(SCIPlpiGetSol(self.lpi, NULL, NULL, NULL, NULL, c_redcost))
|
|
436
455
|
|
|
437
456
|
redcost = []
|
|
@@ -439,12 +458,14 @@ cdef class LP:
|
|
|
439
458
|
redcost[i].append(c_redcost[i])
|
|
440
459
|
|
|
441
460
|
free(c_redcost)
|
|
461
|
+
|
|
442
462
|
return redcost
|
|
443
463
|
|
|
444
464
|
def getBasisInds(self):
|
|
445
465
|
"""Returns the indices of the basic columns and rows; index i >= 0 corresponds to column i, index i < 0 to row -i-1"""
|
|
446
|
-
nrows = self.nrows()
|
|
447
|
-
cdef int* c_binds
|
|
466
|
+
cdef int nrows = self.nrows()
|
|
467
|
+
cdef int* c_binds = <int*> malloc(nrows * sizeof(int))
|
|
468
|
+
cdef int i
|
|
448
469
|
|
|
449
470
|
PY_SCIP_CALL(SCIPlpiGetBasisInd(self.lpi, c_binds))
|
|
450
471
|
|
|
@@ -453,4 +474,5 @@ cdef class LP:
|
|
|
453
474
|
binds.append(c_binds[i])
|
|
454
475
|
|
|
455
476
|
free(c_binds)
|
|
477
|
+
|
|
456
478
|
return binds
|
|
@@ -45,9 +45,10 @@ cdef SCIP_RETCODE PyReaderWrite (SCIP* scip, SCIP_READER* reader, FILE* file,
|
|
|
45
45
|
SCIP_VAR** fixedvars, int nfixedvars, int startnvars,
|
|
46
46
|
SCIP_CONS** conss, int nconss, int maxnconss, int startnconss,
|
|
47
47
|
SCIP_Bool genericnames, SCIP_RESULT* result) noexcept with gil:
|
|
48
|
-
cdef SCIP_READERDATA* readerdata
|
|
49
|
-
readerdata = SCIPreaderGetData(reader)
|
|
48
|
+
cdef SCIP_READERDATA* readerdata = SCIPreaderGetData(reader)
|
|
50
49
|
cdef int fd = fileno(file)
|
|
50
|
+
cdef int i
|
|
51
|
+
|
|
51
52
|
PyFile = os.fdopen(fd, "w", closefd=False)
|
|
52
53
|
PyName = name.decode('utf-8')
|
|
53
54
|
PyBinVars = [Variable.create(vars[i]) for i in range(nbinvars)]
|
|
@@ -61,4 +62,5 @@ cdef SCIP_RETCODE PyReaderWrite (SCIP* scip, SCIP_READER* reader, FILE* file,
|
|
|
61
62
|
PyBinVars, PyIntVars, PyImplVars, PyContVars, PyFixedVars, startnvars,
|
|
62
63
|
PyConss, maxnconss, startnconss, genericnames)
|
|
63
64
|
result[0] = result_dict.get("result", <SCIP_RESULT>result[0])
|
|
65
|
+
|
|
64
66
|
return SCIP_OKAY
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from pyscipopt import Model, Eventhdlr, SCIP_EVENTTYPE, Eventhdlr
|
|
2
|
+
|
|
3
|
+
def attach_primal_dual_evolution_eventhdlr(model: Model):
|
|
4
|
+
"""
|
|
5
|
+
Attaches an event handler to a given SCIP model that collects primal and dual solutions,
|
|
6
|
+
along with the solving time when they were found.
|
|
7
|
+
The data is saved in model.data["primal_log"] and model.data["dual_log"]. They consist of
|
|
8
|
+
a list of tuples, each tuple containing the solving time and the corresponding solution.
|
|
9
|
+
|
|
10
|
+
A usage example can be found in examples/finished/plot_primal_dual_evolution.py. The
|
|
11
|
+
example takes the information provided by this recipe and uses it to plot the evolution
|
|
12
|
+
of the dual and primal bounds over time.
|
|
13
|
+
"""
|
|
14
|
+
class GapEventhdlr(Eventhdlr):
|
|
15
|
+
|
|
16
|
+
def eventinit(self): # we want to collect best primal solutions and best dual solutions
|
|
17
|
+
self.model.catchEvent(SCIP_EVENTTYPE.BESTSOLFOUND, self)
|
|
18
|
+
self.model.catchEvent(SCIP_EVENTTYPE.LPSOLVED, self)
|
|
19
|
+
self.model.catchEvent(SCIP_EVENTTYPE.NODESOLVED, self)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def eventexec(self, event):
|
|
23
|
+
# if a new best primal solution was found, we save when it was found and also its objective
|
|
24
|
+
if event.getType() == SCIP_EVENTTYPE.BESTSOLFOUND:
|
|
25
|
+
self.model.data["primal_log"].append([self.model.getSolvingTime(), self.model.getPrimalbound()])
|
|
26
|
+
|
|
27
|
+
if not self.model.data["dual_log"]:
|
|
28
|
+
self.model.data["dual_log"].append([self.model.getSolvingTime(), self.model.getDualbound()])
|
|
29
|
+
|
|
30
|
+
if self.model.getObjectiveSense() == "minimize":
|
|
31
|
+
if self.model.isGT(self.model.getDualbound(), self.model.data["dual_log"][-1][1]):
|
|
32
|
+
self.model.data["dual_log"].append([self.model.getSolvingTime(), self.model.getDualbound()])
|
|
33
|
+
else:
|
|
34
|
+
if self.model.isLT(self.model.getDualbound(), self.model.data["dual_log"][-1][1]):
|
|
35
|
+
self.model.data["dual_log"].append([self.model.getSolvingTime(), self.model.getDualbound()])
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if not hasattr(model, "data") or model.data==None:
|
|
39
|
+
model.data = {}
|
|
40
|
+
|
|
41
|
+
model.data["primal_log"] = []
|
|
42
|
+
model.data["dual_log"] = []
|
|
43
|
+
hdlr = GapEventhdlr()
|
|
44
|
+
model.includeEventhdlr(hdlr, "gapEventHandler", "Event handler which collects primal and dual solution evolution")
|
|
45
|
+
|
|
46
|
+
return model
|