【问题标题】:SCIP: How to resolve LP after catching a 'node infeasibility' event,SCIP:捕获“节点不可行”事件后如何解决 LP,
【发布时间】:2019-04-15 15:15:28
【问题描述】:

我在 SCIP 中有一个工作列生成算法。由于我在生成列时包含的特定限制,可能会发生最后一轮定价确定根节点不可行(当然是 Farkas 定价器)。

如果发生这种情况,我想 1) 放宽这些特定限制,2) 解决 LP,以及 3) 重新开始定价列。

所以,我创建了自己的 EventHandler 类,捕捉节点不可行事件:

SCIP_DECL_EVENTINITSOL(EventHandler::scip_initsol)
{
    SCIP_CALL( SCIPcatchEvent(scip_, SCIP_EVENTTYPE_NODEINFEASIBLE, eventhdlr, NULL, NULL));
    return SCIP_OKAY;
}

以及相应的 scip_exec 虚拟方法:

SCIP_DECL_EVENTEXEC(EventHandler::scip_exec)
{
  double cur_rhs = SCIPgetRhsLinear(scip_, *d_varConsInfo).c_primal_obj_cut);
  SCIPchgRhsLinear (scip_, (*d_varConsInfo).c_primal_obj_cut, cur_rhs + DELTA);

  return SCIP_OKAY;     
}

其中(*d_varConsInfo).c_primal_obj_cut 是要更改的特定约束,DELTA 是全局参数,cur_rhs 是特定约束的当前右侧。在节点不可行证明之后巧妙地调用了这个函数,但是,我不知道如何“告诉” scip 应该解决 LP 并且应该包括可能的新列。有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: c++ linear-programming scip


    【解决方案1】:

    当事件处理程序捕获到NODEINFEASIBLE事件时,已经来不及改变不可行的问题,节点处理已经完成。此外,在求解过程中不允许更改约束的 rhs(因为这意味着之前所做的缩减可能无效)。

    我建议如下:如果您的 Farkas 定价无法识别新列以使 LP 再次可行,则该节点将在以下声明为不可行。因此,在 Farkas 定价结束时(如果您位于根节点),您可以只对添加到要放松的约束的辅助变量进行定价,其界限与您的 DELTA 相对应。请注意,您需要在创建约束时将其标记为可修改。然后,由于添加了一个变量,SCIP 将触发另一轮定价。

    【讨论】:

    • 很好的解决方案!
    【解决方案2】:

    也许你应该看看 SCIP 的 PRICERFARKAS 方法 (https://scip.zib.de/doc/html/PRICER.php#PRICER_FUNDAMENTALCALLBACKS)。

    如果当前的 LP 松弛是不可行的,它的任务是 pricer 生成可能呈现的附加变量 LP 再次可行。在标准的分支和价格中,这些是 Farkas 值为正的变量和 PRICERFARKAS 方法 应该识别那些变量。

    【讨论】:

    • 感谢您的回答,但我知道这一点。 Farkas 定价器实际上证明了根节点的不可行性。如果发生这种情况,我希望能够控制更改约束以解决 LP 并重新开始定价。我会稍微澄清一下问题。
    猜你喜欢
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多