I am working on the problem in which I am willing to check and test some of the SCIP's event handlers. I see this SCIP document page and have some questions:
SCIPincludeEventhdlr()
and SCIPincludeEventhdlrBasic()
?I tried to call an execute event handler to get the BESTSOLFOUND
thought the solving process, but I got the following error:
class MyEvent(Eventhdlr):
def eventinit(self):
calls.append('eventinit')
self.model.catchEvent(SCIP_EVENTTYPE.BESTSOLFOUND, self)
def eventexit(self):
calls.append('eventexit')
self.model.dropEvent(SCIP_EVENTTYPE.BESTSOLFOUND, self)
def eventexec(self, event):
calls.append('eventexec')
self.model.eventexec(SCIP_EVENTTYPE.BESTSOLFOUND, self)
AttributeError Traceback (most recent call last)
<ipython-input-11-c33e5174ab7e> in eventexec(self, event)
16 def eventexec(self, event):
17 calls.append('eventexec')
---> 18 self.model.eventexec(SCIP_EVENTTYPE.BESTSOLFOUND, self)
19
20
AttributeError: 'pyscipopt.scip.Model' object has no attribute 'eventexec'
Also, an MRE could be found here. I am wondering where am doing wrong and how can I fix that?
Just updated code:
import pytest
from pyscipopt import Model, Eventhdlr, SCIP_RESULT, SCIP_EVENTTYPE, SCIP_PARAMSETTING
calls = []
class MyEvent(Eventhdlr):
def eventinit(self):
calls.append('eventinit')
self.model.catchEvent(SCIP_EVENTTYPE.BESTSOLFOUND, self)
def eventexit(self):
calls.append('eventexit')
self.model.dropEvent(SCIP_EVENTTYPE.BESTSOLFOUND, self)
def eventexec(self, event):
calls.append('eventexec')
def test_event():
# create solver instance
s = Model()
s.redirectOutput()
s.printVersion()
print("--------------------------------------")
s.setPresolve(SCIP_PARAMSETTING.OFF)
s.setSeparating(SCIP_PARAMSETTING.OFF)
s.setHeuristics(SCIP_PARAMSETTING.OFF)
eventhdlr = MyEvent()
s.includeEventhdlr(eventhdlr, "BESTSOLFOUND", "python event handler to catch BESTSOLFOUND")
# add some variables
x = s.addVar("x", vtype="I")
y = s.addVar("y", vtype="I")
# add some constraint
s.setObjective(7*x + 9*y, "maximize")
s.addCons(-x + 3*y <= 6)
s.addCons(7*x + y <= 35)
# solve problem
s.optimize()
# print solution
print("--------------------------------------")
print("x = ", s.getVal(x))
print("y = ", s.getVal(y))
del s
assert 'eventinit' in calls
assert 'eventexit' in calls
assert 'eventexec' in calls
if __name__ == "__main__":
test_event()
SCIP version 8.0.3 [precision: 8 byte] [memory: block] [mode: optimized] [LP solver: Soplex 6.0.3] [GitHash: 62fab8a2e3]
Copyright (C) 2002-2022 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin (ZIB)
--------------------------------------
presolving:
(0.0s) symmetry computation started: requiring (bin +, int +, cont +), (fixed: bin -, int -, cont -)
(0.0s) no symmetry present
presolving (0 rounds: 0 fast, 0 medium, 0 exhaustive):
0 deleted vars, 0 deleted constraints, 0 added constraints, 0 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients
0 implications, 0 cliques
presolved problem has 2 variables (0 bin, 2 int, 0 impl, 0 cont) and 2 constraints
2 constraints of type <linear>
transformed objective value is always integral (scale: 1)
Presolving Time: 0.00
time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl.
0.0s| 1 | 0 | 1 | - | 575k | 0 | 2 | 2 | 2 | 0 | 0 | 0 | 0 | 5.900000e+01 | -- | Inf | unknown
0.0s| 1 | 2 | 1 | - | 575k | 0 | 2 | 2 | 2 | 0 | 1 | 0 | 0 | 5.900000e+01 | -- | Inf | unknown
* 0.0s| 2 | 1 | 1 | 0.0 | LP | 1 | 2 | 2 | 2 | 0 | 1 | 0 | 0 | 5.500000e+01 | 3.500000e+01 | 57.14%| unknown
* 0.0s| 3 | 0 | 2 | 0.5 | LP | 1 | 2 | 1 | 2 | 0 | 1 | 0 | 0 | 5.500000e+01 | 5.500000e+01 | 0.00%| 58.64%
SCIP Status : problem is solved [optimal solution found]
Solving Time (sec) : 0.01
Solving Nodes : 3
Primal Bound : +5.50000000000000e+01 (2 solutions)
Dual Bound : +5.50000000000000e+01
Gap : 0.00 %
I am quite sure you don't need the self.model.eventexec(SCIP_EVENTTYPE.BESTSOLFOUND, self)
line in your exec callback. You just put the code you want to run there