GRBCallback#

GRBCallback#

Gurobi 回调类。这是一个抽象类。要实现一个回调,你应该创建这个类的一个子类并实现一个callback()方法。如果你在调用GRBModel.optimizeGRBModel.computeIIS之前将这个子类的对象传递给方法GRBModel.setCallback,该类的callback()方法将会被定期调用。根据回调被调用的位置,你将能够获取关于优化进度的各种信息。

请注意,此类包含一个受保护的int成员变量: where。您可以从callback()方法中查询此变量 以确定回调是从哪里调用的。

Gurobi 回调函数可以用于监控优化的进度,也可以用于修改 Gurobi 优化器的行为。一个简单的用户回调函数可能会调用 GRBCallback.getIntInfoGRBCallback.getDoubleInfo 方法来生成自定义显示,或者可能提前终止优化(使用 GRBCallback.abort)或继续到计算的下一个阶段(使用 GRBCallback.proceed)。更复杂的 MIP 回调函数可能会使用 GRBCallback.getNodeRelGRBCallback.getSolution 从当前节点的解决方案中检索值,然后使用 GRBCallback.addCutGRBCallback.addLazy 添加约束以切断该解决方案,或者使用 GRBCallback.setSolution 导入从该解决方案构建的启发式解决方案。对于多目标问题,您可以使用 GRBCallback.stopOneMultiObj 中断多目标 MIP 问题中某个优化步骤的优化过程,而不会停止分层优化过程。

在使用多线程求解模型时,用户回调只会从单个线程调用,因此您无需担心回调的线程安全性。

一些参数是可回调设置的。这些参数可以在回调调用中使用GRBCallback.set方法进行修改。

您可以查看Callback.java示例,了解如何使用Gurobi回调的详细信息。

GRBCallback GRBCallback()#

回调构造函数。

Return value:

一个回调对象。

void abort()#

中止优化。当优化停止时,状态属性将等于GRB.Status.INTERRUPTED

void addCut(GRBLinExpr lhsExpr, char sense, double rhs)#

在回调函数中向MIP模型添加切割平面。 请注意,此方法只能在where成员变量等于GRB.CB_MIPNODE时调用(有关更多信息,请参阅参考手册中的回调代码部分)。

切割平面可以在分支切割树的任何节点添加。 然而,应该谨慎添加,因为它们会增加在每个节点求解的松弛模型的大小,并可能显著降低节点处理速度。

切割平面通常用于切断当前的松弛解。要检索当前节点的松弛解,您应该首先调用getNodeRel

在添加自己的切割时,您应考虑将参数预粉碎设置为值1。此设置会关闭一些预求解缩减,这些缩减有时会阻止您的切割应用于预求解模型(这会导致您的切割被静默忽略)。

请注意,通过此方法添加的切割平面必须是真正的切割平面——它们可以切断连续解,但不能切断尊重模型原始约束的整数解。忽略此限制将导致错误的解。

Arguments:
  • lhsExpr – 新切割平面的左侧表达式。

  • sense – 新切割平面的方向(GRB.LESS_EQUALGRB.EQUAL,或 GRB.GREATER_EQUAL)。

  • rhs – 新切割平面的右侧值。

void addLazy(GRBLinExpr lhsExpr, char sense, double rhs)#

在回调函数中向MIP模型添加一个惰性约束。 请注意,此方法只能在where成员变量等于GRB.CB_MIPNODEGRB.CB_MIPSOL时调用(更多信息请参见参考手册中的回调代码部分)。

惰性约束通常用于当MIP模型的完整约束集太大而无法显式表示时。通过仅包含在分支切割搜索期间找到的解决方案实际违反的约束,有时可以在仅添加完整约束集的一小部分的情况下找到经过验证的最优解。

通常,您会通过首先查询当前节点解决方案(通过从getSolution回调中调用GRB.CB_MIPSOL,或从getNodeRel回调中调用GRB.CB_MIPNODE),然后调用addLazy()来添加一个约束以切断该解决方案。Gurobi保证您将有机会切断任何原本会被视为可行的解决方案。

MIP 解决方案可能在 MIP 节点之外生成。因此,当回调函数中的 where 值等于 GRB.CB_MIPNODE 时,生成惰性约束是可选的。为了避免这种情况,我们建议始终检查 where 值是否等于 GRB.CB_MIPSOL

您的回调函数应准备好切断违反任何惰性约束的解决方案,包括那些已经添加的约束。节点解决方案通常会尊重先前添加的惰性约束,但并非总是如此。

请注意,如果您想使用惰性约束,必须设置LazyConstraints参数。

Arguments:
  • lhsExpr – 新惰性约束的左侧表达式。

  • sense – 新惰性约束的意义(GRB.LESS_EQUALGRB.EQUAL,或GRB.GREATER_EQUAL)。

  • rhs – 新惰性约束的右侧值。

double getDoubleInfo(int what)#

请求双值回调信息。可用信息取决于where成员的值。有关where的可能值以及可以查询的不同where值的双值信息,请参阅参考手册中的回调代码部分。

Arguments:

what – 请求的信息。请参考参考手册中的 回调代码 列表以获取可能的值。

Return value:

请求的回调信息的价值。

int getIntInfo(int what)#

请求整数值的回调信息。可用的信息取决于where成员的值。有关where的可能值以及可以为不同where值查询的整数值信息,请参阅参考手册中的回调代码部分。

Arguments:

what – 请求的信息。请参考参考手册中的回调代码列表以获取可能的值。

Return value:

请求的回调信息的价值。

double getNodeRel(GRBVar v)#

从当前节点的节点松弛解中检索一个值。 仅在where成员变量等于 GRB.Callback.MIPNODE,且GRB.Callback.MIPNODE_STATUS等于 GRB.Status.OPTIMAL时可用(更多信息请参见回调代码 部分)。

请注意,在节点处检索到的松弛解不一定对用户模型是可行的。

Arguments:

v – 需要获取值的变量。

Return value:

当前节点中指定变量在节点松弛中的值。

double[] getNodeRel(GRBVar[] xvars)#

从当前节点的节点松弛解中检索值。 仅在where成员变量等于 GRB.Callback.MIPNODE,且GRB.Callback.MIPNODE_STATUS等于 GRB.Status.OPTIMAL时可用(更多信息请参见回调代码 部分)。

请注意,在节点处检索到的松弛解不一定对用户模型是可行的。

Arguments:

xvars – 所需值的变量列表。

Return value:

当前节点中指定变量在节点松弛中的值。

double[][] getNodeRel(GRBVar[][] xvars)#

从当前节点的节点松弛解中检索值。 仅在where成员变量等于 GRB.Callback.MIPNODE,且GRB.Callback.MIPNODE_STATUS等于 GRB.Status.OPTIMAL时可用(更多信息请参见回调代码 部分)。

请注意,在节点处检索到的松弛解不一定对用户模型是可行的。

Arguments:

xvars – 所需值的变量数组。

Return value:

当前节点中指定变量在节点松弛中的值。

double getSolution(GRBVar v)#

从当前解向量中检索值。仅当where成员变量等于GRB.CB_MIPSOLGRB.CB_MULTIOBJ时可用。

Arguments:

v – 需要获取值的变量。

Return value:

当前解向量中指定变量的值。

double[] getSolution(GRBVar[] xvars)#

从当前解向量中检索值。仅当where成员变量等于GRB.CB_MIPSOLGRB.CB_MULTIOBJ时可用。

Arguments:

xvars – 所需值的变量列表。

Return value:

当前解决方案中指定变量的值。

double[][] getSolution(GRBVar[][] xvars)#

从当前解向量中检索值。仅在where成员变量等于GRB.CB_MIPSOLGRB.CB_MULTIOBJ时可用。

Arguments:

xvars – 所需值的变量数组。

Return value:

当前解决方案中指定变量的值。

String getStringInfo(int what)#

请求字符串值的回调信息。可用信息取决于where成员的值。有关where的可能值以及可以为不同where值查询的字符串值信息,请参阅参考手册中的回调代码部分。

Arguments:

what – 请求的信息。请参考参考手册中的 回调代码 列表以获取可能的值。

Return value:

请求的回调信息的价值。

void proceed()#

生成一个请求以继续计算的下一个阶段。请注意,该请求仅在算法的几个阶段被接受,并且不会立即执行。

在当前Gurobi版本中,此回调允许您从NoRel启发式算法过渡到标准MIP搜索。您可以使用回调中的MIP_PHASEMIPNODE_PHASEMIPSOL_PHASE查询来确定当前算法阶段。

void set(GRB.DoubleParam param, double newvalue)#

允许在确定性回调期间修改可设置的回调双值参数

也就是说,当where的值为GRB.CB_PRESOLVEDGRB.CB_SIMPLEXGRB.CB_MIPGRB.CB_MIPSOLGRB.CB_MIPNODEGRB.CB_BARRIERGRB.CB_MULTIOBJ时(更多信息请参见 回调代码部分)

在远程服务器的情况下,从回调函数内部更改参数可能不会立即生效。

Arguments:
  • param – 正在修改的参数。

  • newvalue – 参数所需的新值。

void set(GRB.IntParam param, int newvalue)#

允许在确定性回调期间修改可设置的回调整数值参数

也就是说,当where的值为GRB.CB_PRESOLVEDGRB.CB_SIMPLEXGRB.CB_MIPGRB.CB_MIPSOLGRB.CB_MIPNODEGRB.CB_BARRIERGRB.CB_MULTIOBJ时(更多信息请参见 回调代码部分)

在远程服务器的情况下,从回调函数内部更改参数可能不会立即生效。

Arguments:
  • param – 正在修改的参数。

  • newvalue – 参数所需的新值。

void set(GRB.StringParam param, String newvalue)#

允许在确定性回调期间修改可设置的回调字符串值参数

也就是说,当where的值为GRB.CB_PRESOLVEDGRB.CB_SIMPLEXGRB.CB_MIPGRB.CB_MIPSOLGRB.CB_MIPNODEGRB.CB_BARRIERGRB.CB_MULTIOBJ时(更多信息请参见 回调代码部分)

在远程服务器的情况下,从回调函数内部更改参数可能不会立即生效。

Arguments:
  • param – 正在修改的参数。

  • newvalue – 参数所需的新值。

void setSolution(GRBVar v, double val)#

导入启发式解的解决方案值。仅在where成员变量等于GRB.CB_MIPGRB.CB_MIPNODEGRB.CB_MIPSOL时可用(更多信息请参见回调代码部分)。

当您从回调中指定启发式解决方案时,变量最初会取未定义的值。您应该使用此方法来指定变量值。您可以从一次回调调用中多次调用setSolution来为多组变量指定值。回调之后,如果已为任何变量指定了值,Gurobi优化器将尝试从指定的值计算出一个可行的解决方案,可能会为值未定义的变量填充值。您还可以选择在回调函数中调用useSolution,以尝试立即从指定的值计算出一个可行的解决方案。

在计算服务器环境中,出于性能考虑,通过setSolution发送的解决方案不一定立即由计算服务器处理。它们可能在客户端回调发送后稍晚一些出现在求解过程中。在极端情况下,甚至可能在计算服务器优化作业处理用户解决方案之前就终止了。

Arguments:
  • v – 正在设置其值的变量。

  • val – 新解决方案中变量的值。

void setSolution(GRBVar[] xvars, double[] sol)#

导入启发式解的解决方案值。仅在where成员变量等于GRB.CB_MIPGRB.CB_MIPNODEGRB.CB_MIPSOL时可用(更多信息请参见回调代码部分)。

当您从回调中指定启发式解决方案时,变量最初会取未定义的值。您应该使用此方法来指定变量值。您可以从一次回调调用中多次调用setSolution来为多组变量指定值。回调之后,如果已为任何变量指定了值,Gurobi优化器将尝试从指定的值计算可行解,可能会为值未定义的变量填充值。您还可以选择在回调函数中调用useSolution,以尝试立即从指定的值计算可行解。

在计算服务器环境中,出于性能考虑,通过setSolution发送的解决方案不一定立即由计算服务器处理。它们可能在客户端回调发送后稍晚一些出现在求解过程中。在极端情况下,甚至可能计算服务器优化作业在用户解决方案处理之前就终止了。

Arguments:
  • xvars – 正在设置其值的变量。

  • sol – 新解决方案中指定变量的期望值。

void stopOneMultiObj(int objcnt)#

在多目标MIP问题中,中断其中一个优化步骤的优化过程,而不停止分层优化过程。仅适用于多目标MIP模型,并且当where成员变量不等于GRB.CB_MULTIOBJ时(有关更多信息,请参阅回调代码部分)。

通常,您会通过查询最后完成的多目标优化步骤的数量来停止多目标优化步骤,并使用该数量来停止当前步骤并继续下一个层次目标(如果有的话),如下例所示:

import gurobi.*;

public class Callback extends GRBCallback {
  private int objcnt;
  private long starttime;

  protected void callback() {
    try {
      if (where == GRB.CB_MULTIOBJ) {
        /* get current objective number */
        objcnt    = getIntInfo(GRB.CB_MULTIOBJ_OBJCNT);

        /* reset start time to current time */
        starttime = System.currentTimeMillis();

      } else if (System.currentTimeMillis() - starttime > BIG ||
                 /* takes too long or good enough */) {
        /* stop only this optimization step */
        stopOneMultiObj(objcnt);
      }
    }
  }
}

您应该参考 多目标部分,了解如何指定多个目标函数并控制它们之间的权衡。

Arguments:

objnum – 多目标优化步骤的编号,用于中断。对于本地运行的进程,此参数可以具有特殊值-1,表示停止当前步骤。

double useSolution()#

一旦你使用setSolution导入了解决方案值,你可以选择在GRB.CB_MIPNODE回调中调用useSolution,以立即使用这些值尝试计算启发式解决方案。或者,你可以在GRB.CB_MIPGRB.CB_MIPSOL回调中调用useSolution,这将存储解决方案,直到可以在内部处理。

Return value:

从您的解决方案值中获得的解决方案的目标值。如果未找到改进的解决方案或方法是从GRB.CB_MIPNODE以外的回调中调用的,则它等于GRB.INFINITY,因为在这些上下文中,解决方案是存储的,而不是立即处理的。