-1

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:

  • Do the event handlers callbacks return with something that may be printable? or just for assertation?
  • What exactly is the difference between SCIPincludeEventhdlr() and SCIPincludeEventhdlrBasic()?
  • When we really need to use an additional callback besides an event handler?

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 %
A.Omidi
  • 113
  • 7

1 Answers1

1

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

Leon
  • 1,588
  • 1
  • 7
  • 16
  • Dear @Leon, thanks for answering. I am not sure to understand what you proposed as I am pretty new to call SCIP advanced methods. As I can see in the SCIP doc, every event handler needs to be initiated, executed, and also dropped. This is why I write this. If I am wrong please, correct me. However, by turning this line off the SCIP shows `python error in eventexec: this method needs to be implemented`. Would you please, take a look at the code and modify that if needed? – A.Omidi Jul 04 '23 at 07:56
  • I am not saying delete the `eventexec` just the line I explicitly typed in my answer. I modified your code, not sure if you can see that? – Leon Jul 04 '23 at 08:30
  • Dear @Leon, thanks for replaying. I just updated my question by the last code I can see and I hope it was what you modified. (you allow to modify code). I expected the solver to print some lines between the B&B lines, but it seems the solver continues as the usual paradigm. Is it normal? – A.Omidi Jul 04 '23 at 08:53
  • Dear @Leon, I check the template of the SCIP for the event handler and see that in this case, the log is the same as the original problem. I will manage to ask some questions w.r.t that asap. Thanks once again. – A.Omidi Jul 04 '23 at 11:42
  • Why should the solver print something? Your event exec method does nothing. If you would print something in it, then you would see it in the log. – Leon Jul 05 '23 at 06:00
  • Dear @Leon, thanks for the clarification. Would you please, take a look at [this](https://stackoverflow.com/q/76612707/7414813)? – A.Omidi Jul 05 '23 at 09:27