如何在每个节点收集scip提供的分支规则的分支过程数据

问题描述

  1. 我想做什么:

    我想在每个节点观察scip提供的分支规则(即strang branch和relpscost)的过程数据,包括LPSolution、分支深度、分支分数、下界等。因此,我需要收集由 scip 提供的规则创建的分支数据。

  2. 我所做的和尝试的:

    我想我可以使用 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;
}
  1. 如何收集我想观察的数据?

解决方法

对于可靠性分支,您实际上可以调用 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?为什么他们似乎使用相同的分支规则,但他们的表现却不同?