问题描述
我正在尝试解决一个非常简单的 TSP 问题,但 SCIP 的 TSP 示例有点吓人。
我只想像 GuRoBi 那样添加简单的 Lazy 约束。
我可能需要一些帮助来了解某些地方正在发生的事情。
我假设我不必实现 SCIP_DECL_CONSSEPALP
SCIP_DECL_CONSENFOLP
和 SCIP_DECL_CONSENFOPS
。我只需要实现一个简单的循环检测功能并将其添加为一个剪辑。
如果我理解正确,我可以在 SCIP_DECL_CONSCHECK
中编写执行循环检测的函数,但我不确定它实际上是如何工作的。
assert(result != NULL);
*result = SCIP_FEASIBLE;
for( int i = 0; i < nconss; ++i )
{
SCIP_CONSDATA* consdata;
GRAPH* graph;
SCIP_Bool found;
assert(conss != NULL);
assert(conss[i] != NULL);
consdata = SCIPconsGetData(conss[i]);
assert(consdata != NULL);
graph = consdata->graph;
assert(graph != NULL);
// if a subtour is found,the solution must be infeasible
found = findSubtour(scip,graph,sol);
if( found )
{
*result = SCIP_INFEASIBLE;
if( printreason )
{
SCIP_CALL( SCIpprintCons(scip,conss[i],NULL) );
SCIPinfoMessage(scip,NULL,"violation: graph has a subtour\n");
}
}
}
return SCIP_OKAY;
如果我只有一个约束处理程序,我还应该使用 nconss
吗?
找到子旅行后究竟会发生什么?将 *result
设置为 SCIP_INFEASIBLE
后调用哪个函数?
我如何将在 SCIP_DECL_CONSCHECK
中找到的子环(环中的顶点)传递给该函数,以便我不必再次查找循环并添加实际切割?
解决方法
您实际上需要实现两个回调。 SCIP_DECL_CONSCHECK
和 SCIP_DECL_CONSENFOLP
。
在检查回调中,您只需要检测是否找到了子游览,如果是,则将结果设置为 SCIP_INFEASIBLE
(正如您所做的那样)。
您不必使用 nconss
,因为您的 subtour 约束处理程序没有任何约束。
在执行回调 SCIP_DECL_CONSENFOLP
中,您必须通过添加新的子巡回消除约束来实际解决这些不可行性。
如果您想了解更多关于这些 SCIP 回调如何工作的信息,您可以听听我在去年 CO@Work 暑期学校的演讲(运行示例是 TSP)on youtube。 同一天的编程插件练习也是在 PySCIPopt 中实现 TSP,您可以在 Co@Work 网页上找到解决方案。