/** creates a new node entry in the VBC output file */ SCIP_RETCODE SCIPvbcNewChild( SCIP_VBC* vbc, /**< VBC information */ SCIP_STAT* stat, /**< problem statistics */ SCIP_NODE* node /**< new node, that was created */ ) { SCIP_VAR* branchvar; SCIP_BOUNDTYPE branchtype; SCIP_Real branchbound; size_t parentnodenum; size_t nodenum; assert(vbc != NULL); assert(stat != NULL); assert(node != NULL); /* check, if VBC output should be created */ if( vbc->file == NULL ) return SCIP_OKAY; /* vbc is disabled on probing nodes */ if( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE ) return SCIP_OKAY; /* insert mapping node -> nodenum into hash map */ if( stat->ncreatednodesrun >= (SCIP_Longint)INT_MAX ) { SCIPerrorMessage("too many nodes to store in the VBC file\n"); return SCIP_INVALIDDATA; } nodenum = (size_t)stat->ncreatednodesrun; assert(nodenum > 0); SCIP_CALL( SCIPhashmapInsert(vbc->nodenum, node, (void*)nodenum) ); /* get nodenum of parent node from hash map */ parentnodenum = (node->parent != NULL ? (size_t)SCIPhashmapGetImage(vbc->nodenum, node->parent) : 0); assert(node->parent == NULL || parentnodenum > 0); /* get branching information */ getBranchInfo(node, &branchvar, &branchtype, &branchbound); printTime(vbc, stat); SCIPmessageFPrintInfo(vbc->messagehdlr, vbc->file, "N %d %d %d\n", (int)parentnodenum, (int)nodenum, SCIP_VBCCOLOR_UNSOLVED); printTime(vbc, stat); if( branchvar != NULL ) { SCIPmessageFPrintInfo(vbc->messagehdlr, vbc->file, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t%s [%g,%g] %s %f\\nbound:\\t%f\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), SCIPvarGetName(branchvar), SCIPvarGetLbLocal(branchvar), SCIPvarGetUbLocal(branchvar), branchtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbound, SCIPnodeGetLowerbound(node)); } else { SCIPmessageFPrintInfo(vbc->messagehdlr, vbc->file, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t-\\nbound:\\t%f\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), SCIPnodeGetLowerbound(node)); } return SCIP_OKAY; }
/** node comparison method of node selector */ static SCIP_DECL_NODESELCOMP(nodeselCompDfs) { /*lint --e{715}*/ int depth1; int depth2; assert(nodesel != NULL); assert(strcmp(SCIPnodeselGetName(nodesel), NODESEL_NAME) == 0); assert(scip != NULL); depth1 = SCIPnodeGetDepth(node1); depth2 = SCIPnodeGetDepth(node2); if( depth1 > depth2 ) return -1; else if( depth1 < depth2 ) return +1; else { SCIP_Real lowerbound1; SCIP_Real lowerbound2; lowerbound1 = SCIPnodeGetLowerbound(node1); lowerbound2 = SCIPnodeGetLowerbound(node2); if( lowerbound1 < lowerbound2 ) return -1; else if( lowerbound1 > lowerbound2 ) return +1; else return 0; } }
/** marks node as solved in visualization output file */ void SCIPvisualSolvedNode( SCIP_VISUAL* visual, /**< visualization information */ SCIP_SET* set, /**< global SCIP settings */ SCIP_STAT* stat, /**< problem statistics */ SCIP_NODE* node /**< node, that was solved */ ) { SCIP_VAR* branchvar; SCIP_BOUNDTYPE branchtype; SCIP_Real branchbound; SCIP_Real lowerbound; size_t nodenum; assert( visual != NULL ); assert( stat != NULL ); assert( node != NULL ); /* check whether output should be created */ if ( visual->vbcfile == NULL && visual->bakfile == NULL ) return; /* visualization is disabled on probing nodes */ if( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE ) return; /* get node num from hash map */ nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, node); assert(nodenum > 0); /* get branching information */ getBranchInfo(node, &branchvar, &branchtype, &branchbound); /* determine lower bound */ if ( set->visual_objextern ) lowerbound = SCIPretransformObj(set->scip, SCIPnodeGetLowerbound(node)); else lowerbound = SCIPnodeGetLowerbound(node); if ( visual->vbcfile != NULL ) { printTime(visual, stat, TRUE); if( branchvar != NULL ) { SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t%s [%g,%g] %s %f\\nbound:\\t%f\\nnr:\\t%" SCIP_LONGINT_FORMAT "\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), SCIPvarGetName(branchvar), SCIPvarGetLbLocal(branchvar), SCIPvarGetUbLocal(branchvar), branchtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbound, lowerbound, stat->nnodes); } else { SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t-\\nbound:\\t%f\\nnr:\\t%" SCIP_LONGINT_FORMAT "\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), lowerbound, stat->nnodes); } vbcSetColor(visual, stat, node, SCIP_VBCCOLOR_SOLVED); } /* do nothing for BAK */ }
/** changes the color of the node to the color of solved nodes */ void SCIPvbcSolvedNode( SCIP_VBC* vbc, /**< VBC information */ SCIP_STAT* stat, /**< problem statistics */ SCIP_NODE* node /**< node, that was solved */ ) { SCIP_VAR* branchvar; SCIP_BOUNDTYPE branchtype; SCIP_Real branchbound; size_t nodenum; assert(vbc != NULL); assert(stat != NULL); assert(node != NULL); /* check, if VBC output should be created */ if( vbc->file == NULL ) return; /* vbc is disabled on probing nodes */ if( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE ) return; /* get node num from hash map */ nodenum = (size_t)SCIPhashmapGetImage(vbc->nodenum, node); assert(nodenum > 0); /* get branching information */ getBranchInfo(node, &branchvar, &branchtype, &branchbound); printTime(vbc, stat); if( branchvar != NULL ) { SCIPmessageFPrintInfo(vbc->messagehdlr, vbc->file, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t%s [%g,%g] %s %f\\nbound:\\t%f\\nnr:\\t%"SCIP_LONGINT_FORMAT"\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), SCIPvarGetName(branchvar), SCIPvarGetLbLocal(branchvar), SCIPvarGetUbLocal(branchvar), branchtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbound, SCIPnodeGetLowerbound(node), stat->nnodes); } else { SCIPmessageFPrintInfo(vbc->messagehdlr, vbc->file, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t-\\nbound:\\t%f\\nnr:\\t%"SCIP_LONGINT_FORMAT"\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), SCIPnodeGetLowerbound(node), stat->nnodes); } vbcSetColor(vbc, stat, node, SCIP_VBCCOLOR_SOLVED); }
/** returns a weighted sum of the node's lower bound and estimate value */ static SCIP_Real getNodeselScore( SCIP_NODE* node, /**< branching node */ SCIP_Real estimweight /**< weight of estimate in score */ ) { return (1.0-estimweight) * SCIPnodeGetLowerbound(node) + estimweight * SCIPnodeGetEstimate(node); }
/** node comparison method of node selector */ static SCIP_DECL_NODESELCOMP(nodeselCompBfs) { /*lint --e{715}*/ SCIP_Real lowerbound1; SCIP_Real lowerbound2; assert(nodesel != NULL); assert(strcmp(SCIPnodeselGetName(nodesel), NODESEL_NAME) == 0); assert(scip != NULL); lowerbound1 = SCIPnodeGetLowerbound(node1); lowerbound2 = SCIPnodeGetLowerbound(node2); if( SCIPisLT(scip, lowerbound1, lowerbound2) ) return -1; else if( SCIPisGT(scip, lowerbound1, lowerbound2) ) return +1; else { SCIP_Real estimate1; SCIP_Real estimate2; estimate1 = SCIPnodeGetEstimate(node1); estimate2 = SCIPnodeGetEstimate(node2); if( (SCIPisInfinity(scip, estimate1) && SCIPisInfinity(scip, estimate2)) || (SCIPisInfinity(scip, -estimate1) && SCIPisInfinity(scip, -estimate2)) || SCIPisEQ(scip, estimate1, estimate2) ) { SCIP_NODETYPE nodetype1; SCIP_NODETYPE nodetype2; nodetype1 = SCIPnodeGetType(node1); nodetype2 = SCIPnodeGetType(node2); if( nodetype1 == SCIP_NODETYPE_CHILD && nodetype2 != SCIP_NODETYPE_CHILD ) return -1; else if( nodetype1 != SCIP_NODETYPE_CHILD && nodetype2 == SCIP_NODETYPE_CHILD ) return +1; else if( nodetype1 == SCIP_NODETYPE_SIBLING && nodetype2 != SCIP_NODETYPE_SIBLING ) return -1; else if( nodetype1 != SCIP_NODETYPE_SIBLING && nodetype2 == SCIP_NODETYPE_SIBLING ) return +1; else { int depth1; int depth2; depth1 = SCIPnodeGetDepth(node1); depth2 = SCIPnodeGetDepth(node2); if( depth1 < depth2 ) return -1; else if( depth1 > depth2 ) return +1; else return 0; } } if( SCIPisLT(scip, estimate1, estimate2) ) return -1; assert(SCIPisGT(scip, estimate1, estimate2)); return +1; } }
/** node selection method of node selector */ static SCIP_DECL_NODESELSELECT(nodeselSelectBfs) { /*lint --e{715}*/ SCIP_NODESELDATA* nodeseldata; int minplungedepth; int maxplungedepth; int plungedepth; SCIP_Real maxplungequot; assert(nodesel != NULL); assert(strcmp(SCIPnodeselGetName(nodesel), NODESEL_NAME) == 0); assert(scip != NULL); assert(selnode != NULL); *selnode = NULL; /* get node selector user data */ nodeseldata = SCIPnodeselGetData(nodesel); assert(nodeseldata != NULL); /* calculate minimal and maximal plunging depth */ minplungedepth = nodeseldata->minplungedepth; maxplungedepth = nodeseldata->maxplungedepth; maxplungequot = nodeseldata->maxplungequot; if( minplungedepth == -1 ) { minplungedepth = SCIPgetMaxDepth(scip)/10; if( SCIPgetNStrongbranchLPIterations(scip) > 2*SCIPgetNNodeLPIterations(scip) ) minplungedepth += 10; if( maxplungedepth >= 0 ) minplungedepth = MIN(minplungedepth, maxplungedepth); } if( maxplungedepth == -1 ) maxplungedepth = SCIPgetMaxDepth(scip)/2; maxplungedepth = MAX(maxplungedepth, minplungedepth); /* check, if we exceeded the maximal plunging depth */ plungedepth = SCIPgetPlungeDepth(scip); if( plungedepth > maxplungedepth ) { /* we don't want to plunge again: select best node from the tree */ SCIPdebugMessage("plungedepth: [%d,%d], cur: %d -> abort plunging\n", minplungedepth, maxplungedepth, plungedepth); *selnode = SCIPgetBestNode(scip); SCIPdebugMessage(" -> best node : lower=%g\n", *selnode != NULL ? SCIPnodeGetLowerbound(*selnode) : SCIPinfinity(scip)); } else { SCIP_NODE* node; SCIP_Real maxbound; /* check, if plunging is forced at the current depth */ if( plungedepth < minplungedepth ) { maxbound = SCIPinfinity(scip); SCIPdebugMessage("plungedepth: [%d,%d], cur: %d => maxbound: infinity\n", minplungedepth, maxplungedepth, plungedepth); } else { SCIP_Real lowerbound; SCIP_Real cutoffbound; /* get global lower and cutoff bound */ lowerbound = SCIPgetLowerbound(scip); cutoffbound = SCIPgetCutoffbound(scip); /* if we didn't find a solution yet, the cutoff bound is usually very bad: * use only 20% of the gap as cutoff bound */ if( SCIPgetNSolsFound(scip) == 0 ) cutoffbound = lowerbound + 0.2 * (cutoffbound - lowerbound); /* calculate maximal plunging bound */ maxbound = lowerbound + maxplungequot * (cutoffbound - lowerbound); SCIPdebugMessage("plungedepth: [%d,%d], cur: %d, bounds: [%g,%g], maxbound: %g\n", minplungedepth, maxplungedepth, plungedepth, lowerbound, cutoffbound, maxbound); } /* we want to plunge again: prefer children over siblings, and siblings over leaves, * but only select a child or sibling, if its dual bound is small enough; * prefer using nodes with higher node selection priority assigned by the branching rule */ node = SCIPgetPrioChild(scip); if( node != NULL && SCIPnodeGetLowerbound(node) < maxbound ) { *selnode = node; SCIPdebugMessage(" -> selected prio child: lower=%g\n", SCIPnodeGetLowerbound(*selnode)); } else { node = SCIPgetBestChild(scip); if( node != NULL && SCIPnodeGetLowerbound(node) < maxbound ) { *selnode = node; SCIPdebugMessage(" -> selected best child: lower=%g\n", SCIPnodeGetLowerbound(*selnode)); } else { node = SCIPgetPrioSibling(scip); if( node != NULL && SCIPnodeGetLowerbound(node) < maxbound ) { *selnode = node; SCIPdebugMessage(" -> selected prio sibling: lower=%g\n", SCIPnodeGetLowerbound(*selnode)); } else { node = SCIPgetBestSibling(scip); if( node != NULL && SCIPnodeGetLowerbound(node) < maxbound ) { *selnode = node; SCIPdebugMessage(" -> selected best sibling: lower=%g\n", SCIPnodeGetLowerbound(*selnode)); } else { *selnode = SCIPgetBestNode(scip); SCIPdebugMessage(" -> selected best leaf: lower=%g\n", *selnode != NULL ? SCIPnodeGetLowerbound(*selnode) : SCIPinfinity(scip)); } } } } } return SCIP_OKAY; }
/** changes the color of the node to the color of cutoff nodes */ void SCIPvisualCutoffNode( SCIP_VISUAL* visual, /**< visualization information */ SCIP_SET* set, /**< global SCIP settings */ SCIP_STAT* stat, /**< problem statistics */ SCIP_NODE* node, /**< node, that was cut off */ SCIP_Bool infeasible /**< whether the node is infeasible (otherwise exceeded the cutoff bound) */ ) { SCIP_VAR* branchvar; SCIP_BOUNDTYPE branchtype; SCIP_Real branchbound; SCIP_Real lowerbound; size_t nodenum; assert( visual != NULL ); assert( stat != NULL ); assert( node != NULL ); /* check whether output should be created */ if ( visual->vbcfile == NULL && visual->bakfile == NULL ) return; /* visualization is disabled on probing nodes */ if( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE ) return; /* get node num from hash map */ nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, node); assert(nodenum > 0); /* get branching information */ getBranchInfo(node, &branchvar, &branchtype, &branchbound); /* determine lower bound */ if ( set->visual_objextern ) lowerbound = SCIPretransformObj(set->scip, SCIPnodeGetLowerbound(node)); else lowerbound = SCIPnodeGetLowerbound(node); if ( visual->vbcfile != NULL ) { printTime(visual, stat, TRUE); if( branchvar != NULL ) { SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t%s [%g,%g] %s %f\\nbound:\\t%f\\nnr:\\t%" SCIP_LONGINT_FORMAT "\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), SCIPvarGetName(branchvar), SCIPvarGetLbLocal(branchvar), SCIPvarGetUbLocal(branchvar), branchtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbound, lowerbound, stat->nnodes); } else { SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t-\\nbound:\\t%f\\nnr:\\t%" SCIP_LONGINT_FORMAT "\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), lowerbound, stat->nnodes); } vbcSetColor(visual, stat, node, SCIP_VBCCOLOR_CUTOFF); } if ( visual->bakfile != NULL ) { size_t parentnodenum; char t = 'M'; /* determine branching type */ if ( branchvar != NULL ) t = (branchtype == SCIP_BOUNDTYPE_LOWER ? 'R' : 'L'); /* get nodenum of parent node from hash map */ parentnodenum = (node->parent != NULL ? (size_t)SCIPhashmapGetImage(visual->nodenum, node->parent) : 0); assert(node->parent == NULL || parentnodenum > 0); printTime(visual, stat, FALSE); if ( infeasible ) SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "infeasible %d %d %c\n", (int)nodenum, (int)parentnodenum, t); else SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "fathomed %d %d %c\n", (int)nodenum, (int)parentnodenum, t); } }
/** updates a node entry in the visualization output file */ SCIP_RETCODE SCIPvisualUpdateChild( SCIP_VISUAL* visual, /**< visualization information */ SCIP_SET* set, /**< global SCIP settings */ SCIP_STAT* stat, /**< problem statistics */ SCIP_NODE* node /**< new node, that was created */ ) { SCIP_VAR* branchvar; SCIP_BOUNDTYPE branchtype; SCIP_Real branchbound; SCIP_Real lowerbound; size_t nodenum; assert( visual != NULL ); assert( stat != NULL ); assert( node != NULL ); /* check whether output should be created */ if ( visual->vbcfile == NULL && visual->bakfile == NULL ) return SCIP_OKAY; /* visualization is disabled on probing nodes */ if( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE ) return SCIP_OKAY; /* get node num from hash map */ nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, node); assert(nodenum > 0); /* get branching information */ getBranchInfo(node, &branchvar, &branchtype, &branchbound); /* determine lower bound */ if ( set->visual_objextern ) lowerbound = SCIPretransformObj(set->scip, SCIPnodeGetLowerbound(node)); else lowerbound = SCIPnodeGetLowerbound(node); if ( visual->vbcfile != NULL ) { printTime(visual, stat, TRUE); if( branchvar != NULL ) { SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t%s [%g,%g] %s %f\\nbound:\\t%f\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), SCIPvarGetName(branchvar), SCIPvarGetLbLocal(branchvar), SCIPvarGetUbLocal(branchvar), branchtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbound, lowerbound); } else { SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t-\\nbound:\\t%f\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), lowerbound); } } if ( visual->bakfile != NULL ) { size_t parentnodenum; SCIP_Real* lpcandsfrac; SCIP_Real sum = 0.0; int nlpcands = 0; char t = 'M'; const char* nodeinfo; int j; /* determine branching type */ if ( branchvar != NULL ) t = (branchtype == SCIP_BOUNDTYPE_LOWER ? 'R' : 'L'); /* get nodenum of parent node from hash map */ parentnodenum = (node->parent != NULL ? (size_t)SCIPhashmapGetImage(visual->nodenum, node->parent) : 0); assert(node->parent == NULL || parentnodenum > 0); /* update info depending on the node type */ switch( SCIPnodeGetType(node) ) { case SCIP_NODETYPE_CHILD: /* the child is a new candidate */ nodeinfo = "candidate"; break; case SCIP_NODETYPE_FOCUSNODE: /* the focus node is updated to a branch node */ nodeinfo = "branched"; /* calculate infeasibility information */ SCIP_CALL( SCIPgetLPBranchCands(set->scip, NULL, NULL, &lpcandsfrac, &nlpcands, NULL, NULL) ); for (j = 0; j < nlpcands; ++j) sum += lpcandsfrac[j]; break; default: SCIPerrorMessage("Error: Unexpected node type <%d> in Update Child Method", SCIPnodeGetType(node)); return SCIP_INVALIDDATA; } /*lint !e788*/ /* append new status line with updated node information to the bakfile */ printTime(visual, stat, FALSE); SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "%s %d %d %c %f %f %d\n", nodeinfo, (int)nodenum, (int)parentnodenum, t, lowerbound, sum, nlpcands); } return SCIP_OKAY; }
/** creates a new node entry in the visualization output file */ SCIP_RETCODE SCIPvisualNewChild( SCIP_VISUAL* visual, /**< visualization information */ SCIP_SET* set, /**< global SCIP settings */ SCIP_STAT* stat, /**< problem statistics */ SCIP_NODE* node /**< new node, that was created */ ) { SCIP_VAR* branchvar; SCIP_BOUNDTYPE branchtype; SCIP_Real branchbound; SCIP_Real lowerbound; size_t parentnodenum; size_t nodenum; assert( visual != NULL ); assert( stat != NULL ); assert( node != NULL ); /* visualization is disabled on probing nodes */ if( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE ) return SCIP_OKAY; /* check whether output should be created */ if ( visual->vbcfile == NULL && visual->bakfile == NULL ) return SCIP_OKAY; /* insert mapping node -> nodenum into hash map */ if( stat->ncreatednodesrun >= (SCIP_Longint)INT_MAX ) { SCIPerrorMessage("too many nodes to store in the visualization file\n"); return SCIP_INVALIDDATA; } nodenum = (size_t)stat->ncreatednodesrun; assert(nodenum > 0); SCIP_CALL( SCIPhashmapInsert(visual->nodenum, node, (void*)nodenum) ); /* get nodenum of parent node from hash map */ parentnodenum = (node->parent != NULL ? (size_t)SCIPhashmapGetImage(visual->nodenum, node->parent) : 0); assert(node->parent == NULL || parentnodenum > 0); /* get branching information */ getBranchInfo(node, &branchvar, &branchtype, &branchbound); /* determine lower bound */ if ( set->visual_objextern ) lowerbound = SCIPretransformObj(set->scip, SCIPnodeGetLowerbound(node)); else lowerbound = SCIPnodeGetLowerbound(node); if ( visual->vbcfile != NULL ) { printTime(visual, stat, TRUE); SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "N %d %d %d\n", (int)parentnodenum, (int)nodenum, SCIP_VBCCOLOR_UNSOLVED); printTime(visual, stat, TRUE); if( branchvar != NULL ) { SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t%s [%g,%g] %s %f\\nbound:\\t%f\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), SCIPvarGetName(branchvar), SCIPvarGetLbLocal(branchvar), SCIPvarGetUbLocal(branchvar), branchtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbound, lowerbound); } else { SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t-\\nbound:\\t%f\n", (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), lowerbound); } } /* For BAK, not all available information is available here. Use SCIPvisualUpdateChild() instead */ return SCIP_OKAY; }
/** performs the all fullstrong branching */ static SCIP_RETCODE branch( SCIP* scip, /**< SCIP data structure */ SCIP_BRANCHRULE* branchrule, /**< branching rule */ SCIP_Bool allowaddcons, /**< should adding constraints be allowed to avoid a branching? */ SCIP_RESULT* result /**< pointer to store the result of the callback method */ ) { SCIP_BRANCHRULEDATA* branchruledata; SCIP_VAR** pseudocands; SCIP_Real bestdown; SCIP_Real bestup; SCIP_Real bestscore; SCIP_Real provedbound; SCIP_Bool exactsolve; SCIP_Bool allcolsinlp; SCIP_Bool bestdownvalid; SCIP_Bool bestupvalid; int npseudocands; int npriopseudocands; int bestpseudocand; #ifndef NDEBUG SCIP_Real cutoffbound; cutoffbound = SCIPgetCutoffbound(scip); #endif assert(branchrule != NULL); assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0); assert(scip != NULL); assert(result != NULL); /* check, if all existing columns are in LP, and thus the strong branching results give lower bounds */ allcolsinlp = SCIPallColsInLP(scip); /* check, if we want to solve the problem exactly, meaning that strong branching information is not useful * for cutting off sub problems and improving lower bounds of children */ exactsolve = SCIPisExactSolve(scip); /* get branching rule data */ branchruledata = SCIPbranchruleGetData(branchrule); assert(branchruledata != NULL); if( branchruledata->skipdown == NULL ) { int nvars; nvars = SCIPgetNVars(scip); assert(branchruledata->skipup == NULL); SCIP_CALL( SCIPallocMemoryArray(scip, &branchruledata->skipdown, nvars) ); SCIP_CALL( SCIPallocMemoryArray(scip, &branchruledata->skipup, nvars) ); BMSclearMemoryArray(branchruledata->skipdown, nvars); BMSclearMemoryArray(branchruledata->skipup, nvars); } /* get all non-fixed variables (not only the fractional ones) */ SCIP_CALL( SCIPgetPseudoBranchCands(scip, &pseudocands, &npseudocands, &npriopseudocands) ); assert(npseudocands > 0); assert(npriopseudocands > 0); SCIP_CALL( SCIPselectVarPseudoStrongBranching(scip, pseudocands, branchruledata->skipdown, branchruledata->skipup, npseudocands, npriopseudocands, allowaddcons, &bestpseudocand, &bestdown, &bestup, &bestscore, &bestdownvalid, &bestupvalid, &provedbound, result) ); if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM && *result != SCIP_CONSADDED ) { SCIP_NODE* downchild; SCIP_NODE* eqchild; SCIP_NODE* upchild; SCIP_VAR* var; assert(*result == SCIP_DIDNOTRUN); assert(0 <= bestpseudocand && bestpseudocand < npseudocands); assert(SCIPisLT(scip, provedbound, cutoffbound)); var = pseudocands[bestpseudocand]; /* perform the branching */ SCIPdebugMessage(" -> %d candidates, selected candidate %d: variable <%s>[%g,%g] (solval=%g, down=%g, up=%g, score=%g)\n", npseudocands, bestpseudocand, SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), SCIPvarGetLPSol(var), bestdown, bestup, bestscore); SCIP_CALL( SCIPbranchVarVal(scip, var, SCIPvarGetLPSol(var), &downchild, &eqchild, &upchild) ); /* update the lower bounds in the children */ if( allcolsinlp && !exactsolve ) { if( downchild != NULL ) { SCIP_CALL( SCIPupdateNodeLowerbound(scip, downchild, bestdownvalid ? MAX(bestdown, provedbound) : provedbound) ); SCIPdebugMessage(" -> down child's lowerbound: %g\n", SCIPnodeGetLowerbound(downchild)); } if( eqchild != NULL ) { SCIP_CALL( SCIPupdateNodeLowerbound(scip, eqchild, provedbound) ); SCIPdebugMessage(" -> eq child's lowerbound: %g\n", SCIPnodeGetLowerbound(eqchild)); } if( upchild != NULL ) { SCIP_CALL( SCIPupdateNodeLowerbound(scip, upchild, bestupvalid ? MAX(bestup, provedbound) : provedbound) ); SCIPdebugMessage(" -> up child's lowerbound: %g\n", SCIPnodeGetLowerbound(upchild)); } } *result = SCIP_BRANCHED; } return SCIP_OKAY; }