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

如何在OR-Tools SCIP求解MIP时,每次分支切割后打印目标函数值?

在OR-Tools的SCIP求解器中打印分支切割迭代的目标函数值

要在SCIP每次分支切割迭代后打印目标函数相关值,你可以通过注册回调函数监听求解过程中的中间事件,具体实现步骤如下:

1. 定义回调类

创建继承自pywraplp.Solver.Callback的回调类,重写Callback方法来捕获MIP求解的迭代事件,并打印当前的目标函数边界值:

class MIPIterationCallback(pywraplp.Solver.Callback):
    def __init__(self, solver):
        super().__init__()
        self.solver = solver
        # 可选:设置打印间隔,避免输出过多
        self.iter_count = 0
        self.print_interval = 10

    def Callback(self, where):
        # 仅处理MIP求解的迭代事件
        if where == pywraplp.Solver.Callback.MIP:
            self.iter_count += 1
            # 按间隔打印,可根据需求调整
            if self.iter_count % self.print_interval == 0:
                # 获取松弛问题的下界(当前最优可能的最小值)
                lower_bound = self.solver.BestObjectiveBound()
                # 获取当前找到的最好可行解的目标值(上界)
                upper_bound = self.solver.Objective().Value()
                print(f"迭代次数: {self.iter_count} | 下界: {lower_bound:.4f} | 上界: {upper_bound:.4f}")

2. 在求解流程中注册回调

修改你的原有代码,在调用solver.Solve()之前注册上述回调:

solver = pywraplp.Solver_CreateSolver('SCIP')

"""
Problem Definition Is Omitted Here
"""

solver.Minimize(target_function)

# 实例化回调并注册
iteration_callback = MIPIterationCallback(solver)
solver.SetCallback(iteration_callback)

# 启动求解
status = solver.Solve()

关键说明

  • BestObjectiveBound():返回当前分支切割树中松弛问题的最优目标值,是目标函数的下界,对于最小化问题,下界会随迭代推进逐渐增大。
  • Objective().Value():返回当前找到的所有可行解中的最优目标值,是目标函数的上界,对于最小化问题,上界会随迭代推进逐渐减小。
  • 若不需要间隔打印,可直接去掉iter_count和print_interval相关逻辑,每次迭代都输出。
  • 回调中避免执行耗时操作,防止拖慢大规模问题的求解速度。

内容的提问来源于stack exchange,提问作者Ben Yan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 17:41:24