运筹系列27:Cplex中的callback function

博客介绍了callback函数的定义,它是应用以参数形式传入API的函数,cplex的callback分3种。还进行了MIP control callback案例分析,以location问题为例给出数学模型。最后说明了可将主问题中第3条约束作为自定义UserCutCallback,并给出代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. callback函数的定义

所谓callback函数,即应用以参数的形式传入API的函数。cplex的callback分为3种:

  1. Informational callbacks:不干涉优化过程,仅获取信息。
  2. Query callbacks(也叫diagnostic callbacks):与优化过程相互交涉的获取信息过程。
  3. Control callbacks:会改变优化过程的函数。

下面是
在这里插入图片描述

2. MIP control callback案例分析

本文案例是一个location问题,有4个备选仓库,9个客户,x1x_1x1~x4x_4x4表示是否选择这4个仓库,启用仓库有启动成本。yijy_{ij}yij表示仓库与客户之间的距离,运输有成本。每个客户只能从一个仓库供货;每个仓库的库存量有限。
数学模型如下:

# Given a set of locations J and a set of clients C
# Minimize
#   sum(j in J) fixedCost[j]*used[j] + sum(j in J)sum(c in C)cost[c][j]*supply[c][j]
# Subject to
#   sum(j in J) supply[c][j] == 1                    for all c in C
#   sum(c in C) supply[c][j] <= Capacity[j]* used[j] for all j in J
#               supply[c][j] <= used[j]              for all c in C, j in J
#               supply[c][j] in { 0, 1 }             for all c in C, j in J
#                    used[j] in { 0, 1 }             for all j in J

3. 自定义UserCutCallback

我们可以在主问题中不添加第3条约束,而把它作为UserCutCallback。代码如下:

import sys
from cplex.callbacks import UserCutCallback
from docplex.mp.callbacks.cb_mixin import *
from docplex.mp.model import Model
class MyCutCallback(ConstraintCallbackMixin, UserCutCallback):
    # Callback constructor. Model object is set after registration.
    def __init__(self, env):
        UserCutCallback.__init__(self, env)
        ConstraintCallbackMixin.__init__(self)
        self.eps = 1e-6
        self.nb_cuts = 0

    def add_cut_constraint(self, ct):
        self.register_constraint(ct)

    @print_called("--> custom cut callback called: #{0}")
    def __call__(self):
        # fetch variable solution values at this point.
        sol = self.make_solution()
        # fetch those constraints which are not satisfied.
        unsats = self.get_cpx_unsatisfied_cts(self.cts, sol, self.eps)
        for ct, cut, sense, rhs in unsats:
            # Method add() here is CPLEX's CutCallback.add()
            self.add(cut, sense, rhs)
            self.nb_cuts += 1
            print('-- add new cut[{0}]: [{1!s}]'.format(self.nb_cuts, ct))

在主代码中如下:

cut_cb = m.register_callback(MyCutCallback)
for l in range_locations:
    location_used = used[l]
    for c in range_clients:
        cut_cb.add_cut_constraint(supply[c, l] <= location_used)
print('* add cut constraints callback with {0} cuts'.format(len(cut_cb.cts)))

m.cut_callback = cut_cb
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值