You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySCIPopt中BESTSOLFOUND事件处理器问题咨询与报错排查

关于SCIP事件处理器的疑问与代码修复

核心疑问解答

1. 事件处理器的回调函数是否会返回可打印内容,还是仅用于断言?

事件处理器的回调函数(如eventexec)本身不会主动返回可打印内容,但你可以在函数内部添加打印语句输出信息;它的核心作用是响应特定事件执行自定义逻辑,也可用于测试中的断言验证(例如通过记录函数调用情况来验证事件是否触发)。

2. SCIPincludeEventhdlr()与SCIPincludeEventhdlrBasic()的具体区别是什么?

  • SCIPincludeEventhdlrBasic():仅初始化事件处理器的基础结构,需要手动绑定eventinit、eventexit等回调函数,适合需要精细控制回调绑定的场景。
  • SCIPincludeEventhdlr():完整封装版,会一次性注册所有必要的回调函数,使用更简洁,适合大多数常规场景。

3. 何时需要在事件处理器之外使用额外的回调函数?

当事件处理器的逻辑需要与SCIP其他组件(如启发式算法、约束处理器)交互,或者需要在事件触发之外的时机(如求解开始/结束、节点创建/销毁)执行自定义操作时,就需要在事件处理器之外注册额外的回调函数。


BESTSOLFOUND事件处理器报错修复

报错原因

在eventexec方法中错误调用了self.model.eventexec(),但pyscipopt的Model类并不提供该方法。eventexec是事件处理器的回调函数,当BESTSOLFOUND事件触发时,SCIP会自动调用该方法,无需手动触发。

修复方法

删除self.model.eventexec(SCIP_EVENTTYPE.BESTSOLFOUND, self)这一行,保留自定义逻辑即可。

更新后的完整代码

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():
    # 创建求解器实例
    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", "捕获BESTSOLFOUND事件的Python事件处理器")

    # 添加变量
    x = s.addVar("x", vtype="I")
    y = s.addVar("y", vtype="I")

    # 添加约束
    s.setObjective(7*x + 9*y, "maximize")
    s.addCons(-x + 3*y <=  6)
    s.addCons(7*x +  y <=  35)

    # 求解问题
    s.optimize()

    # 打印解
    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 %

内容的提问来源于stack exchange,提问作者A.Omidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:40:41