From e750b298828658b00a954d7fa6d37a2c04492f88 Mon Sep 17 00:00:00 2001 From: Mark Turner <64978342+Opt-Mucca@users.noreply.github.com> Date: Sat, 4 May 2024 11:43:26 +0200 Subject: [PATCH] Add getnorigconss (#845) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add getnorigconss * Add test for getorigconss * Add an explicit multiplier * Add transformed option to getconss. Fix test * Update CHANGELOG * Update docstring --------- Co-authored-by: João Dionísio <57299939+Joao-Dionisio@users.noreply.github.com> --- CHANGELOG.md | 2 ++ src/pyscipopt/scip.pxd | 4 ++++ src/pyscipopt/scip.pxi | 38 +++++++++++++++++++++++++------------- tests/test_cons.py | 17 ++++++++++++++++- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb671ae5..ca9b38e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ - Added methods for creating expression constraints without adding to problem - Added methods for creating/adding/appending disjunction constraints - Added check for pt_PT locale in test_model.py +- Added SCIPgetOrigConss and SCIPgetNOrigConss Cython bindings. +- Added transformed=False option to getConss, getNConss, and getNVars ### Fixed ### Changed ### Removed diff --git a/src/pyscipopt/scip.pxd b/src/pyscipopt/scip.pxd index 4ccae1a7..73c2227f 100644 --- a/src/pyscipopt/scip.pxd +++ b/src/pyscipopt/scip.pxd @@ -637,6 +637,10 @@ cdef extern from "scip/scip.h": SCIP_RETCODE SCIPdelVar(SCIP* scip, SCIP_VAR* var, SCIP_Bool* deleted) SCIP_RETCODE SCIPaddCons(SCIP* scip, SCIP_CONS* cons) SCIP_RETCODE SCIPdelCons(SCIP* scip, SCIP_CONS* cons) + SCIP_CONS** SCIPgetOrigConss(SCIP* scip) + int SCIPgetNOrigConss(SCIP* scip) + SCIP_CONS* SCIPfindOrigCons(SCIP* scip, const char*) + SCIP_CONS* SCIPfindCons(SCIP* scip, const char*) SCIP_RETCODE SCIPsetObjsense(SCIP* scip, SCIP_OBJSENSE objsense) SCIP_OBJSENSE SCIPgetObjsense(SCIP* scip) SCIP_RETCODE SCIPsetObjlimit(SCIP* scip, SCIP_Real objlimit) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index a1fecdfd..f078428c 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -1774,13 +1774,15 @@ cdef class Model: return vars - def getNVars(self): - """Retrieve number of variables in the problems""" - return SCIPgetNVars(self._scip) - - def getNConss(self): - """Retrieve the number of constraints.""" - return SCIPgetNConss(self._scip) + def getNVars(self, transformed=True): + """Retrieve number of variables in the problems. + + :param transformed: get transformed variables instead of original (Default value = True) + """ + if transformed: + return SCIPgetNVars(self._scip) + else: + return SCIPgetNOrigVars(self._scip) def getNIntVars(self): """gets number of integer active problem variables""" @@ -3366,19 +3368,29 @@ cdef class Model: """sets the value of the given variable in the global relaxation solution""" PY_SCIP_CALL(SCIPsetRelaxSolVal(self._scip, NULL, var.scip_var, val)) - def getConss(self): - """Retrieve all constraints.""" + def getConss(self, transformed=True): + """Retrieve all constraints. + + :param transformed: get transformed variables instead of original (Default value = True) + """ cdef SCIP_CONS** _conss cdef int _nconss conss = [] - _conss = SCIPgetConss(self._scip) - _nconss = SCIPgetNConss(self._scip) + if transformed: + _conss = SCIPgetConss(self._scip) + _nconss = SCIPgetNConss(self._scip) + else: + _conss = SCIPgetOrigConss(self._scip) + _nconss = SCIPgetNOrigConss(self._scip) return [Constraint.create(_conss[i]) for i in range(_nconss)] - def getNConss(self): + def getNConss(self, transformed=True): """Retrieve number of all constraints""" - return SCIPgetNConss(self._scip) + if transformed: + return SCIPgetNConss(self._scip) + else: + return SCIPgetNOrigConss(self._scip) def delCons(self, Constraint cons): """Delete constraint from the model diff --git a/tests/test_cons.py b/tests/test_cons.py index a11b6098..443f8a11 100644 --- a/tests/test_cons.py +++ b/tests/test_cons.py @@ -133,7 +133,6 @@ def test_cons_indicator_fail(): m.setSolVal(sol, binvar, 0) assert m.checkSol(sol) # solution should be feasible - def test_addConsCardinality(): m = Model() x = {} @@ -145,6 +144,22 @@ def test_addConsCardinality(): assert m.isEQ(m.getVal(quicksum(x[i] for i in range(5))), 3) +def test_getOrigConss(): + m = Model() + x = m.addVar("x", lb=0, ub=2, obj=-1) + y = m.addVar("y", lb=0, ub=4, obj=0) + z = m.addVar("z", lb=0, ub=5, obj=2) + m.addCons(x <= y + z) + m.addCons(x <= z + 100) + m.addCons(y >= -100) + m.addCons(x + y <= 1000) + m.addCons(2* x + 2 * y <= 1000) + m.addCons(x + y + z <= 7) + m.optimize() + assert len(m.getConss(transformed=False)) == m.getNConss(transformed=False) + assert m.getNConss(transformed=False) == 6 + assert m.getNConss(transformed=True) < m.getNConss(transformed=False) + def test_printCons(): m = Model()