From 1b45a5aea336bdfe09f7fd723fe32b5491ae7cd8 Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Sun, 17 Dec 2023 20:16:21 +0000 Subject: [PATCH 1/7] Add method for getting Event names --- src/pyscipopt/scip.pxi | 16 ++++++++++++++++ tests/test_event.py | 6 ++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index ba2496361..2095a7bcc 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -165,6 +165,8 @@ cdef class PY_SCIP_HEURTIMING: DURINGPRESOLLOOP = SCIP_HEURTIMING_DURINGPRESOLLOOP AFTERPROPLOOP = SCIP_HEURTIMING_AFTERPROPLOOP +EventNames = {} + cdef class PY_SCIP_EVENTTYPE: DISABLED = SCIP_EVENTTYPE_DISABLED VARADDED = SCIP_EVENTTYPE_VARADDED @@ -221,6 +223,7 @@ cdef class PY_SCIP_EVENTTYPE: ROWCHANGED = SCIP_EVENTTYPE_ROWCHANGED ROWEVENT = SCIP_EVENTTYPE_ROWEVENT + cdef class PY_SCIP_LPSOLSTAT: NOTSOLVED = SCIP_LPSOLSTAT_NOTSOLVED OPTIMAL = SCIP_LPSOLSTAT_OPTIMAL @@ -305,6 +308,19 @@ cdef class Event: """gets type of event""" return SCIPeventGetType(self.event) + def getName(self): + """gets name of event""" + if not EventNames: + self._getEventNames() + return EventNames[self.getType()] + + def _getEventNames(self): + """gets event names""" + for name in dir(PY_SCIP_EVENTTYPE): + attr = getattr(PY_SCIP_EVENTTYPE, name) + if isinstance(attr, int): + EventNames[attr] = name + def __repr__(self): return self.getType() diff --git a/tests/test_event.py b/tests/test_event.py index 92653eab4..c836c78ad 100644 --- a/tests/test_event.py +++ b/tests/test_event.py @@ -14,6 +14,8 @@ def eventinit(self): # self.model.dropEvent(self.event_type, self) def eventexec(self, event): + assert type(event.getName()) == str + calls.append('eventexec') if self.event_type == SCIP_EVENTTYPE.LPEVENT: assert event.getType() in [SCIP_EVENTTYPE.FIRSTLPSOLVED, SCIP_EVENTTYPE.LPSOLVED] @@ -61,10 +63,6 @@ def test_event(): all_events = [SCIP_EVENTTYPE.DISABLED,SCIP_EVENTTYPE.VARADDED,SCIP_EVENTTYPE.VARDELETED,SCIP_EVENTTYPE.VARFIXED,SCIP_EVENTTYPE.VARUNLOCKED,SCIP_EVENTTYPE.OBJCHANGED,SCIP_EVENTTYPE.GLBCHANGED,SCIP_EVENTTYPE.GUBCHANGED,SCIP_EVENTTYPE.LBTIGHTENED,SCIP_EVENTTYPE.LBRELAXED,SCIP_EVENTTYPE.UBTIGHTENED,SCIP_EVENTTYPE.UBRELAXED,SCIP_EVENTTYPE.GHOLEADDED,SCIP_EVENTTYPE.GHOLEREMOVED,SCIP_EVENTTYPE.LHOLEADDED,SCIP_EVENTTYPE.LHOLEREMOVED,SCIP_EVENTTYPE.IMPLADDED,SCIP_EVENTTYPE.PRESOLVEROUND,SCIP_EVENTTYPE.NODEFOCUSED,SCIP_EVENTTYPE.NODEFEASIBLE,SCIP_EVENTTYPE.NODEINFEASIBLE,SCIP_EVENTTYPE.NODEBRANCHED,SCIP_EVENTTYPE.NODEDELETE,SCIP_EVENTTYPE.FIRSTLPSOLVED,SCIP_EVENTTYPE.LPSOLVED,SCIP_EVENTTYPE.POORSOLFOUND,SCIP_EVENTTYPE.BESTSOLFOUND,SCIP_EVENTTYPE.ROWADDEDSEPA,SCIP_EVENTTYPE.ROWDELETEDSEPA,SCIP_EVENTTYPE.ROWADDEDLP,SCIP_EVENTTYPE.ROWDELETEDLP,SCIP_EVENTTYPE.ROWCOEFCHANGED,SCIP_EVENTTYPE.ROWCONSTCHANGED,SCIP_EVENTTYPE.ROWSIDECHANGED,SCIP_EVENTTYPE.SYNC,SCIP_EVENTTYPE.GBDCHANGED,SCIP_EVENTTYPE.LBCHANGED,SCIP_EVENTTYPE.UBCHANGED,SCIP_EVENTTYPE.BOUNDTIGHTENED,SCIP_EVENTTYPE.BOUNDRELAXED,SCIP_EVENTTYPE.BOUNDCHANGED,SCIP_EVENTTYPE.LHOLECHANGED,SCIP_EVENTTYPE.HOLECHANGED,SCIP_EVENTTYPE.DOMCHANGED,SCIP_EVENTTYPE.VARCHANGED,SCIP_EVENTTYPE.VAREVENT,SCIP_EVENTTYPE.NODESOLVED,SCIP_EVENTTYPE.NODEEVENT,SCIP_EVENTTYPE.LPEVENT,SCIP_EVENTTYPE.SOLFOUND,SCIP_EVENTTYPE.SOLEVENT,SCIP_EVENTTYPE.ROWCHANGED,SCIP_EVENTTYPE.ROWEVENT] - - for i in [20]: - print(SCIP_EVENTTYPE.NODEINFEASIBLE) - all_event_hdlrs = [] for event in all_events: s = Model() From 77a95a75a0f1765e30e3f3e1b2862931623a0945 Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Sun, 17 Dec 2023 20:45:39 +0000 Subject: [PATCH 2/7] Add ability to print stage name as string. Add test. --- src/pyscipopt/scip.pxi | 15 +++++++++++++++ tests/test_model.py | 22 ++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 2095a7bcc..70e8ef931 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -110,6 +110,8 @@ cdef class PY_SCIP_STATUS: UNBOUNDED = SCIP_STATUS_UNBOUNDED INFORUNBD = SCIP_STATUS_INFORUNBD +StageNames = {} + cdef class PY_SCIP_STAGE: INIT = SCIP_STAGE_INIT PROBLEM = SCIP_STAGE_PROBLEM @@ -4708,6 +4710,19 @@ cdef class Model: def getStage(self): """Retrieve current SCIP stage""" return SCIPgetStage(self._scip) + + def getStageName(self): + """Returns name of current stage as string""" + if not StageNames: + self._getStageNames() + return StageNames[self.getStage()] + + def _getStageNames(self): + """Gets names of stages""" + for name in dir(PY_SCIP_STAGE): + attr = getattr(PY_SCIP_STAGE, name) + if isinstance(attr, int): + StageNames[attr] = name def getStatus(self): """Retrieve solution status.""" diff --git a/tests/test_model.py b/tests/test_model.py index 14424e108..d5016799e 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -1,6 +1,6 @@ import pytest -from pyscipopt import Model +from pyscipopt import Model, SCIP_STAGE def test_model(): # create solver instance @@ -267,4 +267,22 @@ def test_objLim(): m.setObjlimit(2) m.optimize() assert m.getNLimSolsFound() == 1 - \ No newline at end of file + +def test_getStage(): + m = Model() + + assert m.getStage() == SCIP_STAGE.PROBLEM + assert m.getStageName() == "PROBLEM" + + x = m.addVar() + m.addCons(x >= 1) + + print(m.getStage()) + assert m.getStage() == SCIP_STAGE.PROBLEM + assert m.getStageName() == "PROBLEM" + + m.optimize() + + print(m.getStage()) + assert m.getStage() == SCIP_STAGE.SOLVED + assert m.getStageName() == "SOLVED" From d0104a86adb1a43ea55c2183d16bffd0d09e0f8c Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Sun, 17 Dec 2023 20:46:17 +0000 Subject: [PATCH 3/7] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 845c21d61..f22bf6854 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased ### Added +- Added methods for getting the names of the current stage and of an event - Added all event types and tests for checking them - Added SCIP functions SCIPconsGetNVars, SCIPconsGetVars - Added SCIP functions SCIPchgCoefLinear, SCIPaddCoefLinear and SCIPdelCoefLinear From 9f8689f8b61bb0fc1d346f864ac51205fb7a497d 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: Wed, 27 Dec 2023 13:00:27 +0000 Subject: [PATCH 4/7] Update src/pyscipopt/scip.pxi Co-authored-by: Mohammed Ghannam --- 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 70e8ef931..5ebd0af44 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -324,7 +324,7 @@ cdef class Event: EventNames[attr] = name def __repr__(self): - return self.getType() + return str(self.getType()) def getNewBound(self): """gets new bound for a bound change event""" From 53cafa9bddf96d40554dde7a45466e31955bcac5 Mon Sep 17 00:00:00 2001 From: Joao-Dionisio Date: Wed, 27 Dec 2023 13:25:04 +0000 Subject: [PATCH 5/7] Add __str__ to Event class --- src/pyscipopt/scip.pxi | 5 ++++- tests/test_event.py | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pyscipopt/scip.pxi b/src/pyscipopt/scip.pxi index 70e8ef931..13a29d0cf 100644 --- a/src/pyscipopt/scip.pxi +++ b/src/pyscipopt/scip.pxi @@ -326,6 +326,9 @@ cdef class Event: def __repr__(self): return self.getType() + def __str__(self): + return self.getName() + def getNewBound(self): """gets new bound for a bound change event""" return SCIPeventGetNewbound(self.event) @@ -4716,7 +4719,7 @@ cdef class Model: if not StageNames: self._getStageNames() return StageNames[self.getStage()] - + def _getStageNames(self): """Gets names of stages""" for name in dir(PY_SCIP_STAGE): diff --git a/tests/test_event.py b/tests/test_event.py index c836c78ad..406b6df64 100644 --- a/tests/test_event.py +++ b/tests/test_event.py @@ -14,6 +14,7 @@ def eventinit(self): # self.model.dropEvent(self.event_type, self) def eventexec(self, event): + assert str(event) == event.getName() assert type(event.getName()) == str calls.append('eventexec') From cee32a896ec42fc25e3cf8e1dc1b361f74ea8762 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, 28 Dec 2023 10:21:42 +0000 Subject: [PATCH 6/7] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f22bf6854..e1ecf04d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ ## Unreleased ### Added - Added methods for getting the names of the current stage and of an event +- Add getConshdlrName to class Constraint +### Fixed +### Changed +### Removed + +## 4.4.0 - 2023-12-04 +### Added - Added all event types and tests for checking them - Added SCIP functions SCIPconsGetNVars, SCIPconsGetVars - Added SCIP functions SCIPchgCoefLinear, SCIPaddCoefLinear and SCIPdelCoefLinear From 1c38f3167071ac1407e0599cf2e739f5e7390aa7 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, 28 Dec 2023 10:23:27 +0000 Subject: [PATCH 7/7] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1ecf04d0..4c0723362 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,13 @@ ## Unreleased ### Added - Added methods for getting the names of the current stage and of an event -- Add getConshdlrName to class Constraint ### Fixed ### Changed ### Removed ## 4.4.0 - 2023-12-04 ### Added +- Add getConshdlrName to class Constraint - Added all event types and tests for checking them - Added SCIP functions SCIPconsGetNVars, SCIPconsGetVars - Added SCIP functions SCIPchgCoefLinear, SCIPaddCoefLinear and SCIPdelCoefLinear