[SCIP] questions on custom branching
Marc Pfetsch
pfetsch at mathematik.tu-darmstadt.de
Thu Jun 13 21:11:07 CEST 2024
Hi Brannon!
> 1. When I call branchvar from branchexeclp, does the left/right nodes
> returned from that have their relaxed LP computed as part of that
> call?
No, this would be too expensive in general. The nodes are put in the
list of open nodes.
> The instructions on custom branching say that you can call
> updateNodeLowerBound right after branchvar, meaning it did not yet run
> the relaxation for the two new nodes? Can I force it to run the
> relaxation right there?
I don't think you can do so easily. But all of the strong branching rule
implementation do something similar. They tentatively solve relaxations
for candidate branching variables.
> 2. How do I get the dual bound from my newly created nodes inside the
> brancher so that I can propagate my losses?
You would need to perform some strong branching - see above.
> 3. Does it only call one brancher per node (if that brancher returns BRANCHED)?
Yes. If you return something different from BRANCHED it will continue to
the next branching rule.
> 4. Suppose I only want two branching options: my custom brancher and
> strong branching for when the custom brancher can't succeed. With both
> of them, though, I need to update my ML model according to the newly
> found costs. Should I just have one brancher that falls back to strong
> branching inside it?
You can pass the call on - see above.
But if you need to update something you might need to include everything
in the same branching rule.
> Is there sample code for that somewhere in python
> & pyscipopt?
I am not aware for such code.
> What's the best approach here? Would it be better to use
> a MIPNode callback to backpropagate bounds?
See above. If I understood correctly your branching rule wants to update
its own data structures.
> 5. Outside of the branching callback, can I know which variable was
> most-recently fixed in a MIPNode? What decision created that node?
For the first you can have a look at SCIPprintBranchingStatistics(). For
the second you would need to follow the domain changes:
if ( SCIPnodeGetDepth(node) != 0 )
{
SCIP_BOUNDCHG* boundchg;
SCIP_DOMCHG* domchg;
int nboundchgs;
/* get domain changes of current node */
domchg = SCIPnodeGetDomchg(node);
assert( domchg != NULL );
/* loop through all bound changes */
nboundchgs = SCIPdomchgGetNBoundchgs(domchg);
for (int i = 0; i < nboundchgs; ++i)
{
/* get bound change info */
boundchg = SCIPdomchgGetBoundchg(domchg, i);
assert( boundchg != 0 );
/* branching decisions have to be in the beginning of the bound
change array */
if ( SCIPboundchgGetBoundchgtype(boundchg) !=
SCIP_BOUNDCHGTYPE_BRANCHING )
break;
/* get corresponding branching variable */
SCIP_VAR* branchvar = SCIPboundchgGetVar(boundchg);
...
> Thanks for your time. I've got the src/scip/branch_fullstrong.c file
> up, so I'll keep studying that.
Yes, good idea.
Best
Marc
More information about the Scip
mailing list