SCIP:如何在捕获“节点不可行”事件后解决LP,

时间:2019-04-15 15:15:29

标签: c++ linear-programming scip

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

在这种情况下,我想1)放宽那些特定的限制,2)解决价格限制,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是特定约束的当前右侧。在节点不可行证明之后巧妙地调用了此函数,但是,我不知道该如何“告知”应该解决LP并应包括可能的新列。有人可以帮我吗?

2 个答案:

答案 0 :(得分:4)

当事件处理程序捕获到NODEINFEASIBLE事件时,更改有关该问题的不可行性已经为时已晚,节点处理已完成。此外,不允许在求解过程中更改约束的rhs(因为这意味着之前进行的折减可能会无效)。

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

答案 1 :(得分:1)

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

  

如果当前的LP放宽不可行,这是   定价器生成可能呈现的其他变量   LP再次可行。在标准的价格中,这些是   Farkas值为正的变量和PRICERFARKAS方法   应该识别那些变量。