问题描述
-
我想做什么:
我想在每个节点观察scip提供的分支规则(即strang branch和relpscost)的过程数据,包括LPSolution、分支深度、分支分数、下界等。因此,我需要收集由 scip 提供的规则创建的分支数据。
-
我所做的和尝试的:
我想我可以使用 How to add branching rules 中描述的方法,我已阅读此页面并尝试使用 c++ 进行编码,过程见下文。在调试这个过程时,我发现我可以找到 relpscost 规则,并且在实现函数
后打印的错误显示为Exception: EXC_BAD_ACCESS (code=1,address=0x28)
branchexeclp(scip,relpscostRule,true,result);
static
SCIP_DECL_BRANCHEXECLP(collectBranchProcessData)
{
SCIP_BRANCHRULE* relpscostRule = SCIPfindBranchrule(scip,"relpscost");
SCIP_RETCODE (*branchexeclp)(SCIP* scip,SCIP_BRANCHRULE* branchrule,SCIP_Bool allowaddcons,SCIP_RESULT* result);
branchexeclp(scip,result);
// Todo: get the data that I want to observe by calling the SCIP APIs.
*result = SCIP_BRANCHED;
return SCIP_OKAY;
}
- 如何收集我想观察的数据?
解决方法
对于可靠性分支,您实际上可以调用 SCIPexecRelpscostBranching
甚至在不执行分支的情况下运行它(这样只会计算您想要的所有内容)。
然后你可以通过调用不同的方法得到你想要的统计信息(比如SCIPvarGetLPSol
得到一个变量的LP解,SCIPgetVarPseudocostScore
等)
如果有找不到的具体方法,请说明。
,出现异常现象:SCIPexecRelpscostBranching
在您@Leon的建议之后的过程(1)中被调用
SCIP_DECL_BRANCHEXECLP(branchExeclpTest)
{
int ncands;
SCIP_VAR** branchcands;
SCIP_Real* branchcandssol;
SCIP_Real* branchcandsfrac;
int npriolpcands;
int nfracimplvars;
SCIP_CALL( SCIPgetLPBranchCands( scip,&branchcands,&branchcandssol,&branchcandsfrac,&ncands,&npriolpcands,&nfracimplvars) );
SCIP_CALL( SCIPexecRelpscostBranching(scip,branchcands,branchcandssol,branchcandsfrac,ncands,FALSE,result) );
*result = SCIP_BRANCHED;
return SCIP_OKAY;
}
同时,为了确保它是正确的代码,我还尝试在主函数(过程(2))中不包含任何分支规则,并使用 shell 中的命令行(过程(3))。因为优先级排在最前面,所以我没有改变(2)和(3)中的优先级。之后,我发现这三个程序的性能是不同的。他们解决了不同数量的节点以解决相同的 MILP 并使用相同的分支规则。
procedure (1)、procedure (2) 和 procedure (3) 的求解过程贴在这里。我是否错误地调用了 SCIPexecRelpscostBranching
?为什么他们似乎使用相同的分支规则,但他们的表现却不同?