From b12dabdf08ec9bd0df9919a241c0472ae9806ac1 Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Wed, 23 Jul 2025 21:32:58 +0100 Subject: [PATCH 01/13] Add getConsVals --- CHANGELOG.md | 1 + src/pyscipopt/scip.pxd | 1 + src/pyscipopt/scip.pxi | 27 +++++++++++++++++++++++++++ tests/test_cons.py | 17 +++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b55ccad09..aac85aecf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Added addMatrixConsIndicator(), and tests - Added SCIPvarMarkRelaxationOnly, SCIPvarIsRelaxationOnly, SCIPvarMarkDeletable, SCIPvarIsDeletable, and tests - Wrapped SCIPgetNLPBranchCands +- Added getConsVals, generalized getRhs, and tests ### Fixed - Raised an error when an expression is used when a variable is required ### Changed diff --git a/src/pyscipopt/scip.pxd b/src/pyscipopt/scip.pxd index 2d20d5ff3..bcc57a487 100644 --- a/src/pyscipopt/scip.pxd +++ b/src/pyscipopt/scip.pxd @@ -858,6 +858,7 @@ cdef extern from "scip/scip.h": SCIP_RETCODE SCIPtransformCons(SCIP* scip, SCIP_CONS* cons, SCIP_CONS** transcons) SCIP_RETCODE SCIPgetTransformedCons(SCIP* scip, SCIP_CONS* cons, SCIP_CONS** transcons) SCIP_RETCODE SCIPgetConsVars(SCIP* scip, SCIP_CONS* cons, SCIP_VAR** vars, int varssize, SCIP_Bool* success) + SCIP_RETCODE SCIPgetConsVals(SCIP* scip, SCIP_CONS* cons, SCIP_Real* vals, int valssize, SCIP_Bool* success) SCIP_RETCODE SCIPgetConsNVars(SCIP* scip, SCIP_CONS* cons, int* nvars, SCIP_Bool* success) SCIP_CONS** SCIPgetConss(SCIP* scip) const char* SCIPconsGetName(SCIP_CONS* cons) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index b615f96f2..1700dede9 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -6035,6 +6035,31 @@ cdef class Model: vars.append(var) return vars + + def getConsVals(self, Constraint constraint): + """ + Returns the value array of an arbitrary SCIP constraint that can be represented as a single linear constraint. + + Parameters + ---------- + constraint : Constraint + Constraint to get the values from. + + Returns + ------- + list of float + + """ + cdef SCIP_Real* vals + cdef int nvars + cdef SCIP_Bool success + cdef int i + + nvars = self.getConsNVars(constraint) + vals = malloc(nvars * sizeof(SCIP_Real)) + PY_SCIP_CALL(SCIPgetConsVals(self._scip, constraint.scip_cons, vals, nvars*sizeof(SCIP_Real), &success)) + + return [vals[i] for i in range(nvars)] def getNVarsAnd(self, Constraint and_cons): """ @@ -7275,6 +7300,8 @@ cdef class Model: return SCIPgetRhsLinear(self._scip, cons.scip_cons) elif constype == 'nonlinear': return SCIPgetRhsNonlinear(cons.scip_cons) + elif constype == 'knapsack': + return SCIPgetCapacityKnapsack(self._scip, cons.scip_cons) else: raise Warning("method cannot be called for constraints of type " + constype) diff --git a/tests/test_cons.py b/tests/test_cons.py index 188095b23..381d5ffbd 100644 --- a/tests/test_cons.py +++ b/tests/test_cons.py @@ -27,6 +27,22 @@ def test_getConsVars(): c = m.addCons(quicksum(x[i] for i in x) <= 1) assert m.getConsVars(c) == [x[i] for i in x] +def test_getConsVals(): + n_vars = 100 + m = Model() + x = {} + for i in range(n_vars): + x[i] = m.addVar("%i" % i, vtype="B") + + c1 = m.addCons(quicksum(x[i] for i in x) <= 1) + c2 = m.addConsKnapsack([x[i] for i in x], [1]*n_vars, 10) + vals1 = m.getConsVals(c1) + vals2 = m.getConsVals(c2) + + assert len(vals1) == n_vars + assert all(isinstance(v, float) for v in vals1) + assert len(vals2) == n_vars + assert all(isinstance(v, float) for v in vals2) def test_constraint_option_setting(): m = Model() @@ -266,6 +282,7 @@ def test_cons_knapsack(): m.chgCapacityKnapsack(knapsack_cons, 5) assert m.getCapacityKnapsack(knapsack_cons) == 5 + assert m.getRhs(knapsack_cons) == 5 m.addCoefKnapsack(knapsack_cons, z, 3) weights = m.getWeightsKnapsack(knapsack_cons) From cf35ff36b927b2722c781d1e24716255b5a67884 Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Wed, 23 Jul 2025 21:50:53 +0100 Subject: [PATCH 02/13] fix memleak --- src/pyscipopt/scip.pxi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 1700dede9..d2a9793b1 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -6059,7 +6059,9 @@ cdef class Model: vals = malloc(nvars * sizeof(SCIP_Real)) PY_SCIP_CALL(SCIPgetConsVals(self._scip, constraint.scip_cons, vals, nvars*sizeof(SCIP_Real), &success)) - return [vals[i] for i in range(nvars)] + result = [vals[i] for i in range(nvars)] + free(vals) + return result def getNVarsAnd(self, Constraint and_cons): """ From 6a26d783fa78c12d81be3970fb8af7c4ad86165d Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Wed, 23 Jul 2025 21:52:58 +0100 Subject: [PATCH 03/13] remove useless declarations --- src/pyscipopt/scip.pxi | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index d2a9793b1..9e394b295 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -6077,8 +6077,6 @@ cdef class Model: int """ - cdef int nvars - cdef SCIP_Bool success return SCIPgetNVarsAnd(self._scip, and_cons.scip_cons) @@ -6096,9 +6094,9 @@ cdef class Model: list of Variable """ + cdef SCIP_VAR** _vars cdef int nvars - cdef SCIP_Bool success cdef int i constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(and_cons.scip_cons))).decode('UTF-8') @@ -6136,8 +6134,8 @@ cdef class Model: Variable """ + cdef SCIP_VAR* _resultant - cdef SCIP_Bool success _resultant = SCIPgetResultantAnd(self._scip, and_cons.scip_cons) @@ -6167,8 +6165,7 @@ cdef class Model: bool """ - cdef SCIP_Bool success - + return SCIPisAndConsSorted(self._scip, and_cons.scip_cons) def sortAndCons(self, Constraint and_cons): @@ -6181,7 +6178,6 @@ cdef class Model: Constraint to sort. """ - cdef SCIP_Bool success PY_SCIP_CALL(SCIPsortAndCons(self._scip, and_cons.scip_cons)) From 42c184523b1dbb8255a0fe3ecd30c44a882824a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dion=C3=ADsio?= <57299939+Joao-Dionisio@users.noreply.github.com> Date: Thu, 24 Jul 2025 10:53:56 +0100 Subject: [PATCH 04/13] Update src/pyscipopt/scip.pxi Co-authored-by: DominikKamp <130753997+DominikKamp@users.noreply.github.com> --- src/pyscipopt/scip.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 9e394b295..7e86fd994 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -6057,7 +6057,7 @@ cdef class Model: nvars = self.getConsNVars(constraint) vals = malloc(nvars * sizeof(SCIP_Real)) - PY_SCIP_CALL(SCIPgetConsVals(self._scip, constraint.scip_cons, vals, nvars*sizeof(SCIP_Real), &success)) + PY_SCIP_CALL(SCIPgetConsVals(self._scip, constraint.scip_cons, vals, nvars, &success)) result = [vals[i] for i in range(nvars)] free(vals) From 51a1d75530e10843a47e8b8bbd3282e35566c147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dion=C3=ADsio?= <57299939+Joao-Dionisio@users.noreply.github.com> Date: Thu, 24 Jul 2025 14:12:13 +0100 Subject: [PATCH 05/13] Update CHANGELOG.md Co-authored-by: DominikKamp <130753997+DominikKamp@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aac85aecf..38113debf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ - Added addMatrixConsIndicator(), and tests - Added SCIPvarMarkRelaxationOnly, SCIPvarIsRelaxationOnly, SCIPvarMarkDeletable, SCIPvarIsDeletable, and tests - Wrapped SCIPgetNLPBranchCands -- Added getConsVals, generalized getRhs, and tests +- Added getConsVals() and generalized getLhs() as well as getRhs() for linear type constraints ### Fixed - Raised an error when an expression is used when a variable is required ### Changed From d6febca5ca111ca0b9564b8c2e953928c5a92cba Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Thu, 24 Jul 2025 16:15:15 +0100 Subject: [PATCH 06/13] generalize getRhs, getLhs --- CHANGELOG.md | 1 + src/pyscipopt/scip.pxd | 2 ++ src/pyscipopt/scip.pxi | 26 ++++++++++++++++++++------ tests/test_cons.py | 1 + 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38113debf..a83f37f2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Added SCIPvarMarkRelaxationOnly, SCIPvarIsRelaxationOnly, SCIPvarMarkDeletable, SCIPvarIsDeletable, and tests - Wrapped SCIPgetNLPBranchCands - Added getConsVals() and generalized getLhs() as well as getRhs() for linear type constraints +- Generalized getRhs() to use SCIPconsGetRhs(), same for getLhs(). ### Fixed - Raised an error when an expression is used when a variable is required ### Changed diff --git a/src/pyscipopt/scip.pxd b/src/pyscipopt/scip.pxd index bcc57a487..cd523d880 100644 --- a/src/pyscipopt/scip.pxd +++ b/src/pyscipopt/scip.pxd @@ -1478,6 +1478,8 @@ cdef extern from "scip/cons_linear.h": SCIP_RETCODE SCIPchgRhsLinear(SCIP* scip, SCIP_CONS* cons, SCIP_Real rhs) SCIP_Real SCIPgetLhsLinear(SCIP* scip, SCIP_CONS* cons) SCIP_Real SCIPgetRhsLinear(SCIP* scip, SCIP_CONS* cons) + SCIP_Real SCIPconsGetRhs(SCIP* scip, SCIP_CONS* cons, SCIP_Bool* success) + SCIP_Real SCIPconsGetLhs(SCIP* scip, SCIP_CONS* cons, SCIP_Bool* success) SCIP_RETCODE SCIPchgCoefLinear(SCIP* scip, SCIP_CONS* cons, SCIP_VAR* var, SCIP_Real newval) SCIP_RETCODE SCIPdelCoefLinear(SCIP* scip, SCIP_CONS* cons, SCIP_VAR*) SCIP_RETCODE SCIPaddCoefLinear(SCIP* scip, SCIP_CONS* cons, SCIP_VAR*, SCIP_Real val) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 7e86fd994..ec96a69b5 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -2196,6 +2196,18 @@ cdef class Constraint: constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(self.scip_cons))).decode('UTF-8') return constype == 'knapsack' + def isLinearRepresentable(self): + """ + Returns True if constraint can be represented as a linear constraint. + + Returns + ------- + bool + + """ + constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(self.scip_cons))).decode('UTF-8') + return constype in ('linear', 'knapsack', 'setppc') + def isNonlinear(self): """ Returns True if constraint is nonlinear. @@ -7293,13 +7305,13 @@ cdef class Model: float """ + cdef SCIP_Bool success constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.scip_cons))).decode('UTF-8') - if constype == 'linear': - return SCIPgetRhsLinear(self._scip, cons.scip_cons) + + if cons.isLinearRepresentable(): + return SCIPconsGetRhs(self._scip, cons.scip_cons, &success) elif constype == 'nonlinear': return SCIPgetRhsNonlinear(cons.scip_cons) - elif constype == 'knapsack': - return SCIPgetCapacityKnapsack(self._scip, cons.scip_cons) else: raise Warning("method cannot be called for constraints of type " + constype) @@ -7336,9 +7348,11 @@ cdef class Model: float """ + cdef SCIP_Bool success constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.scip_cons))).decode('UTF-8') - if constype == 'linear': - return SCIPgetLhsLinear(self._scip, cons.scip_cons) + + if cons.isLinearRepresentable(): + return SCIPconsGetLhs(self._scip, cons.scip_cons, &success) elif constype == 'nonlinear': return SCIPgetLhsNonlinear(cons.scip_cons) else: diff --git a/tests/test_cons.py b/tests/test_cons.py index 381d5ffbd..678c0ee3d 100644 --- a/tests/test_cons.py +++ b/tests/test_cons.py @@ -283,6 +283,7 @@ def test_cons_knapsack(): assert m.getCapacityKnapsack(knapsack_cons) == 5 assert m.getRhs(knapsack_cons) == 5 + assert m.getLhs(knapsack_cons) == -m.infinity() m.addCoefKnapsack(knapsack_cons, z, 3) weights = m.getWeightsKnapsack(knapsack_cons) From 600c67abfbc37bacb6615040707737047c767398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dion=C3=ADsio?= <57299939+Joao-Dionisio@users.noreply.github.com> Date: Thu, 24 Jul 2025 16:49:14 +0100 Subject: [PATCH 07/13] Apply suggestions from code review Co-authored-by: DominikKamp <130753997+DominikKamp@users.noreply.github.com> --- CHANGELOG.md | 4 ++-- src/pyscipopt/scip.pxi | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a83f37f2f..c35102ae4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,8 @@ - Added addMatrixConsIndicator(), and tests - Added SCIPvarMarkRelaxationOnly, SCIPvarIsRelaxationOnly, SCIPvarMarkDeletable, SCIPvarIsDeletable, and tests - Wrapped SCIPgetNLPBranchCands -- Added getConsVals() and generalized getLhs() as well as getRhs() for linear type constraints -- Generalized getRhs() to use SCIPconsGetRhs(), same for getLhs(). +- Added getConsVals() to get coefficients of any linear type constraint +- Generalized getLhs() and getRhs() to additionally support any linear type constraint ### Fixed - Raised an error when an expression is used when a variable is required ### Changed diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index ec96a69b5..5b22b6df3 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -2206,7 +2206,7 @@ cdef class Constraint: """ constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(self.scip_cons))).decode('UTF-8') - return constype in ('linear', 'knapsack', 'setppc') + return constype in ('linear', 'knapsack', 'setppc', 'logicor', 'varbound') def isNonlinear(self): """ From dadff0ee56937b88b22d78665fb510c4e58ca0c2 Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Thu, 24 Jul 2025 16:59:22 +0100 Subject: [PATCH 08/13] Change name and better test --- src/pyscipopt/scip.pxi | 6 +++--- tests/test_cons.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 5b22b6df3..3e18d73c3 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -2196,7 +2196,7 @@ cdef class Constraint: constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(self.scip_cons))).decode('UTF-8') return constype == 'knapsack' - def isLinearRepresentable(self): + def isLinearType(self): """ Returns True if constraint can be represented as a linear constraint. @@ -7308,7 +7308,7 @@ cdef class Model: cdef SCIP_Bool success constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.scip_cons))).decode('UTF-8') - if cons.isLinearRepresentable(): + if cons.isLinearType(): return SCIPconsGetRhs(self._scip, cons.scip_cons, &success) elif constype == 'nonlinear': return SCIPgetRhsNonlinear(cons.scip_cons) @@ -7351,7 +7351,7 @@ cdef class Model: cdef SCIP_Bool success constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.scip_cons))).decode('UTF-8') - if cons.isLinearRepresentable(): + if cons.isLinearType(): return SCIPconsGetLhs(self._scip, cons.scip_cons, &success) elif constype == 'nonlinear': return SCIPgetLhsNonlinear(cons.scip_cons) diff --git a/tests/test_cons.py b/tests/test_cons.py index 678c0ee3d..36a0dfcec 100644 --- a/tests/test_cons.py +++ b/tests/test_cons.py @@ -35,7 +35,7 @@ def test_getConsVals(): x[i] = m.addVar("%i" % i, vtype="B") c1 = m.addCons(quicksum(x[i] for i in x) <= 1) - c2 = m.addConsKnapsack([x[i] for i in x], [1]*n_vars, 10) + c2 = m.addConsKnapsack([x[i] for i in x], [i for i in range(1, n_vars+1)], 10) vals1 = m.getConsVals(c1) vals2 = m.getConsVals(c2) @@ -43,6 +43,7 @@ def test_getConsVals(): assert all(isinstance(v, float) for v in vals1) assert len(vals2) == n_vars assert all(isinstance(v, float) for v in vals2) + assert m.getConsVals(c2) == [i for i in range(1, n_vars+1)] def test_constraint_option_setting(): m = Model() From 4b2e48a8c80efa5071e539d524a84a6a17d4ebb3 Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Thu, 24 Jul 2025 17:05:29 +0100 Subject: [PATCH 09/13] Correct memory allocation in getConsVars --- src/pyscipopt/scip.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 3e18d73c3..6540057e2 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -6031,7 +6031,7 @@ cdef class Model: SCIPgetConsNVars(self._scip, constraint.scip_cons, &nvars, &success) _vars = malloc(nvars * sizeof(SCIP_VAR*)) - SCIPgetConsVars(self._scip, constraint.scip_cons, _vars, nvars*sizeof(SCIP_VAR*), &success) + SCIPgetConsVars(self._scip, constraint.scip_cons, _vars, nvars, &success) vars = [] for i in range(nvars): From 2bc0ab8be1f0226c1d71ac8ef70743a26526acfe Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Thu, 24 Jul 2025 17:15:06 +0100 Subject: [PATCH 10/13] return None at not success --- src/pyscipopt/scip.pxi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 6540057e2..e39b3c2c8 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -6033,6 +6033,10 @@ cdef class Model: _vars = malloc(nvars * sizeof(SCIP_VAR*)) SCIPgetConsVars(self._scip, constraint.scip_cons, _vars, nvars, &success) + if not success: + free(_vars) + return None + vars = [] for i in range(nvars): ptr = (_vars[i]) @@ -6046,6 +6050,7 @@ cdef class Model: self._modelvars[ptr] = var vars.append(var) + free(_vars) return vars def getConsVals(self, Constraint constraint): @@ -6071,6 +6076,10 @@ cdef class Model: vals = malloc(nvars * sizeof(SCIP_Real)) PY_SCIP_CALL(SCIPgetConsVals(self._scip, constraint.scip_cons, vals, nvars, &success)) + if not success: + free(vals) + return None + result = [vals[i] for i in range(nvars)] free(vals) return result From 4d511391254757a476a637a8be6b04324bd6e2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dion=C3=ADsio?= <57299939+Joao-Dionisio@users.noreply.github.com> Date: Thu, 24 Jul 2025 17:53:31 +0100 Subject: [PATCH 11/13] Apply suggestions from code review Co-authored-by: DominikKamp <130753997+DominikKamp@users.noreply.github.com> --- src/pyscipopt/scip.pxd | 2 +- src/pyscipopt/scip.pxi | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pyscipopt/scip.pxd b/src/pyscipopt/scip.pxd index cd523d880..36ab1c53b 100644 --- a/src/pyscipopt/scip.pxd +++ b/src/pyscipopt/scip.pxd @@ -1478,8 +1478,8 @@ cdef extern from "scip/cons_linear.h": SCIP_RETCODE SCIPchgRhsLinear(SCIP* scip, SCIP_CONS* cons, SCIP_Real rhs) SCIP_Real SCIPgetLhsLinear(SCIP* scip, SCIP_CONS* cons) SCIP_Real SCIPgetRhsLinear(SCIP* scip, SCIP_CONS* cons) - SCIP_Real SCIPconsGetRhs(SCIP* scip, SCIP_CONS* cons, SCIP_Bool* success) SCIP_Real SCIPconsGetLhs(SCIP* scip, SCIP_CONS* cons, SCIP_Bool* success) + SCIP_Real SCIPconsGetRhs(SCIP* scip, SCIP_CONS* cons, SCIP_Bool* success) SCIP_RETCODE SCIPchgCoefLinear(SCIP* scip, SCIP_CONS* cons, SCIP_VAR* var, SCIP_Real newval) SCIP_RETCODE SCIPdelCoefLinear(SCIP* scip, SCIP_CONS* cons, SCIP_VAR*) SCIP_RETCODE SCIPaddCoefLinear(SCIP* scip, SCIP_CONS* cons, SCIP_VAR*, SCIP_Real val) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index e39b3c2c8..7a0047248 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -6067,22 +6067,22 @@ cdef class Model: list of float """ - cdef SCIP_Real* vals + cdef SCIP_Real* _vals cdef int nvars cdef SCIP_Bool success cdef int i nvars = self.getConsNVars(constraint) - vals = malloc(nvars * sizeof(SCIP_Real)) - PY_SCIP_CALL(SCIPgetConsVals(self._scip, constraint.scip_cons, vals, nvars, &success)) + _vals = malloc(nvars * sizeof(SCIP_Real)) + PY_SCIP_CALL(SCIPgetConsVals(self._scip, constraint.scip_cons, _vals, nvars, &success)) if not success: - free(vals) + free(_vals) return None - result = [vals[i] for i in range(nvars)] - free(vals) - return result + vals = [_vals[i] for i in range(nvars)] + free(_vals) + return vals def getNVarsAnd(self, Constraint and_cons): """ From b24ee4d2676e94c2361bca0144c95b61e32667f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dion=C3=ADsio?= <57299939+Joao-Dionisio@users.noreply.github.com> Date: Thu, 24 Jul 2025 19:10:57 +0100 Subject: [PATCH 12/13] Update src/pyscipopt/scip.pxi Co-authored-by: DominikKamp <130753997+DominikKamp@users.noreply.github.com> --- src/pyscipopt/scip.pxi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 7a0047248..6403262f3 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -7361,7 +7361,9 @@ cdef class Model: constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.scip_cons))).decode('UTF-8') if cons.isLinearType(): - return SCIPconsGetLhs(self._scip, cons.scip_cons, &success) + lhs = SCIPconsGetLhs(self._scip, cons.scip_cons, &success) + assert(success) + return lhs elif constype == 'nonlinear': return SCIPgetLhsNonlinear(cons.scip_cons) else: From a9b71b5795addba1e2ffce21ce4db710a716158d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dion=C3=ADsio?= <57299939+Joao-Dionisio@users.noreply.github.com> Date: Thu, 24 Jul 2025 19:11:13 +0100 Subject: [PATCH 13/13] Update src/pyscipopt/scip.pxi Co-authored-by: DominikKamp <130753997+DominikKamp@users.noreply.github.com> --- src/pyscipopt/scip.pxi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 6403262f3..ad9af85b8 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -7318,7 +7318,9 @@ cdef class Model: constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.scip_cons))).decode('UTF-8') if cons.isLinearType(): - return SCIPconsGetRhs(self._scip, cons.scip_cons, &success) + rhs = SCIPconsGetRhs(self._scip, cons.scip_cons, &success) + assert(success) + return rhs elif constype == 'nonlinear': return SCIPgetRhsNonlinear(cons.scip_cons) else: