/** 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; } }
/** node comparison method of breadth first search: nodes with lower depth are preferred; in case of a tie, the node * which was created earlier (and therefore has a smaller node number) is preferred */ static SCIP_DECL_NODESELCOMP(nodeselCompBreadthfirst) { /*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 depths differ, prefer node with smaller depth */ if( depth1 < depth2 ) return -1; else if( depth1 > depth2 ) return +1; else { /* depths are equal; prefer node with smaller number */ SCIP_Longint number1; SCIP_Longint number2; number1 = SCIPnodeGetNumber(node1); number2 = SCIPnodeGetNumber(node2); assert(number1 != number2); if( number1 < number2 ) return -1; else return +1; } }
/** 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 */ }
/** node comparison method of node selector */ static SCIP_DECL_NODESELCOMP(nodeselCompHybridestim) { /*lint --e{715}*/ SCIP_NODESELDATA* nodeseldata; SCIP_Real score1; SCIP_Real score2; assert(nodesel != NULL); assert(strcmp(SCIPnodeselGetName(nodesel), NODESEL_NAME) == 0); assert(scip != NULL); nodeseldata = SCIPnodeselGetData(nodesel); assert(nodeseldata != NULL); score1 = getNodeselScore(node1, nodeseldata->estimweight); score2 = getNodeselScore(node2, nodeseldata->estimweight); if( (SCIPisInfinity(scip, score1) && SCIPisInfinity(scip, score2)) || (SCIPisInfinity(scip, -score1) && SCIPisInfinity(scip, -score2)) || SCIPisEQ(scip, score1, score2) ) { 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, score1, score2) ) return -1; assert(SCIPisGT(scip, score1, score2)); return +1; }
/** separation method of constraint handler for LP solutions */ static SCIP_DECL_CONSSEPALP(consSepalpStp) { /*lint --e{715}*/ SCIP_CONSHDLRDATA* conshdlrdata; int maxcuts; int ncuts = 0; int i; *result = SCIP_DIDNOTRUN; conshdlrdata = SCIPconshdlrGetData(conshdlr); assert(conshdlrdata != NULL); maxcuts = SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts; for( i = 0; i < nconss; ++i ) { SCIP_CONSDATA* consdata; consdata = SCIPconsGetData(conss[i]); SCIP_CALL( sep_flow(scip, conshdlr, conshdlrdata, consdata, maxcuts, &ncuts) ); SCIP_CALL( sep_2cut(scip, conshdlr, conshdlrdata, consdata, maxcuts, &ncuts) ); } if( ncuts > 0 ) *result = SCIP_SEPARATED; return SCIP_OKAY; }
/** constraint deactivation notification method of constraint handler */ static SCIP_DECL_CONSDEACTIVE(consDeactiveSamediff) { /*lint --e{715}*/ SCIP_CONSDATA* consdata; SCIP_PROBDATA* probdata; assert(scip != NULL); assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0); assert(cons != NULL); consdata = SCIPconsGetData(cons); assert(consdata != NULL); assert(consdata->propagated || SCIPgetNChildren(scip) == 0); probdata = SCIPgetProbData(scip); assert(probdata != NULL); /* check if all variables which are not fixed locally to zero are valid for this constraint/node */ assert( consdataCheck(scip, probdata, consdata) ); SCIPdebugMessage("deactivate constraint <%s> at node <%"SCIP_LONGINT_FORMAT"> in depth <%d>: ", SCIPconsGetName(cons), SCIPnodeGetNumber(consdata->node), SCIPnodeGetDepth(consdata->node)); SCIPdebug( consdataPrint(scip, consdata, NULL) ); /* set the number of propagated variables to current number of variables is SCIP */ consdata->npropagatedvars = SCIPprobdataGetNVars(probdata); /* check if all variables are valid for this constraint */ assert( consdataCheck(scip, probdata, consdata) ); return SCIP_OKAY; }
/** constraint activation notification method of constraint handler */ static SCIP_DECL_CONSACTIVE(consActiveSamediff) { /*lint --e{715}*/ SCIP_CONSDATA* consdata; assert(scip != NULL); assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0); assert(cons != NULL); consdata = SCIPconsGetData(cons); assert(consdata != NULL); assert(consdata->npropagatedvars <= SCIPprobdataGetNVars(SCIPgetProbData(scip))); SCIPdebugMessage("activate constraint <%s> at node <%"SCIP_LONGINT_FORMAT"> in depth <%d>: ", SCIPconsGetName(cons), SCIPnodeGetNumber(consdata->node), SCIPnodeGetDepth(consdata->node)); SCIPdebug( consdataPrint(scip, consdata, NULL) ); if( consdata->npropagatedvars != SCIPprobdataGetNVars(SCIPgetProbData(scip)) ) { SCIPdebugMessage("-> mark constraint to be repropagated\n"); consdata->propagated = FALSE; SCIP_CALL( SCIPrepropagateNode(scip, consdata->node) ); } return SCIP_OKAY; }
/** 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); }
/** branching execution method for fractional LP solutions */ static SCIP_DECL_BRANCHEXECLP(branchExeclpnodereopt) {/*lint --e{715}*/ assert(branchrule != NULL ); assert(*result != SCIP_BRANCHED); *result = SCIP_DIDNOTRUN; if( SCIPisReoptEnabled(scip) && SCIPreoptimizeNode(scip, SCIPgetCurrentNode(scip)) ) { SCIP_VAR** branchcands; SCIP_Real* branchcandssol; SCIP_Real* branchcandsfrac; int nbranchcands; SCIP_Bool sbinit; SCIP_Real objsimrootlp; SCIP_CALL( SCIPgetBoolParam(scip, "reoptimization/strongbranchinginit", &sbinit) ); SCIP_CALL( SCIPgetRealParam(scip, "reoptimization/objsimrootLP", &objsimrootlp) ); if( sbinit && SCIPgetCurrentNode(scip) == SCIPgetRootNode(scip) && SCIPgetReoptSimilarity(scip, SCIPgetNReoptRuns(scip), SCIPgetNReoptRuns(scip)) <= objsimrootlp ) /* check objsimrootlp */ { /* get branching candidates */ SCIP_CALL( SCIPgetLPBranchCands(scip, &branchcands, &branchcandssol, &branchcandsfrac, NULL, &nbranchcands, NULL) ); /* run strong branching initialization */ if( nbranchcands > 0 ) { SCIP_CALL( SCIPexecRelpscostBranching(scip, TRUE, branchcands, branchcandssol, branchcandsfrac, nbranchcands, FALSE, result) ); assert(*result == SCIP_DIDNOTRUN || *result == SCIP_CUTOFF || *result == SCIP_REDUCEDDOM); } } if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM) { assert((SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)) == 0 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 ) || 1 <= SCIPnodeGetReoptID(SCIPgetCurrentNode(scip))); SCIP_CALL( Exec(scip, result) ); } } return SCIP_OKAY; }
/** branching execution method for not completely fixed pseudo solutions */ static SCIP_DECL_BRANCHEXECPS(branchExecpsnodereopt) {/*lint --e{715}*/ assert(branchrule != NULL ); assert(*result != SCIP_BRANCHED); *result = SCIP_DIDNOTRUN; if( SCIPisReoptEnabled(scip) && SCIPreoptimizeNode(scip, SCIPgetCurrentNode(scip)) ) { assert((SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)) == 0 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 ) || 1 <= SCIPnodeGetReoptID(SCIPgetCurrentNode(scip))); SCIP_CALL( Exec(scip, result) ); } return SCIP_OKAY; }
/** checks the consistency of the origbranch constraints in the problem */ void GCGconsOrigbranchCheckConsistency( SCIP* scip /**< SCIP data structure */ ) { #ifdef CHECKCONSISTENCY SCIP_CONSHDLR* conshdlr; #ifndef NDEBUG SCIP_CONS** conss; int nconss; int i; SCIP_CONSDATA* consdata; #endif assert(scip != NULL); conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME); if( conshdlr == NULL ) { SCIPerrorMessage("origbranch constraint handler not found\n"); return; } #ifndef NDEBUG conss = SCIPconshdlrGetConss(conshdlr); nconss = SCIPconshdlrGetNConss(conshdlr); for( i = 0; i < nconss; i++ ) { consdata = SCIPconsGetData(conss[i]); assert(consdata != NULL); assert(consdata->node != NULL); assert((consdata->parentcons == NULL) == (SCIPnodeGetDepth(consdata->node) == 0)); assert(consdata->parentcons == NULL || SCIPconsGetData(consdata->parentcons)->child1cons == conss[i] || SCIPconsGetData(consdata->parentcons)->child2cons == conss[i] || ( SCIPinProbing(scip) && SCIPconsGetData(consdata->parentcons)->probingtmpcons == conss[i])); assert(consdata->child1cons == NULL || SCIPconsGetData(consdata->child1cons)->parentcons == conss[i]); assert(consdata->child2cons == NULL || SCIPconsGetData(consdata->child2cons)->parentcons == conss[i]); assert(consdata->probingtmpcons == NULL || SCIPinProbing(scip)); assert(consdata->probingtmpcons == NULL || SCIPconsGetData(consdata->probingtmpcons)->parentcons == conss[i]); assert(consdata->mastercons == NULL || GCGconsMasterbranchGetOrigcons(consdata->mastercons) == conss[i]); } #endif #endif }
/** informs solution debugger, that the given node will be freed */ SCIP_RETCODE SCIPdebugRemoveNode( BMS_BLKMEM* blkmem, /**< block memory */ SCIP_SET* set, /**< global SCIP settings */ SCIP_NODE* node /**< node that will be freed */ ) { assert(set != NULL); assert(blkmem != NULL); assert(node != NULL); /* check if we are in the original problem and not in a sub MIP */ if( !isSolutionInMip(set) ) return SCIP_OKAY; /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ if( debugSolIsAchieved(set) ) return SCIP_OKAY; /* check if a solution will be cutoff in tree */ if( SCIPgetStage(set->scip) != SCIP_STAGE_FREESOLVE && SCIPgetStage(set->scip) != SCIP_STAGE_PRESOLVING && SCIPnodeGetType(node) != SCIP_NODETYPE_PROBINGNODE ) { SCIP_Bool solisinnode; solisinnode = FALSE; SCIP_CALL( isSolutionInNode(blkmem, set, node, &solisinnode) ); /* wrong node will be cutoff */ if( solisinnode ) { SCIPerrorMessage("debugging solution was cut off in local node %p at depth %d\n", node, SCIPnodeGetDepth(node)); SCIPABORT(); } } /* remove node from the hash map */ if( solinnode != NULL ) { SCIP_CALL( SCIPhashmapRemove(solinnode, (void*)node) ); } 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; }
/** 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; } }
/** branching execution method for external candidates */ static SCIP_DECL_BRANCHEXECEXT(branchExecextPscost) { /*lint --e{715}*/ SCIP_BRANCHRULEDATA* branchruledata; SCIP_VAR** externcands; SCIP_Real* externcandssol; SCIP_Real* externcandsscore; int nprioexterncands; SCIP_VAR* brvar; SCIP_Real brpoint; int nchildren; assert(branchrule != NULL); assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0); assert(scip != NULL); assert(result != NULL); branchruledata = SCIPbranchruleGetData(branchrule); assert(branchruledata != NULL); SCIPdebugMessage("Execext method of pscost branching\n"); /* get branching candidates */ SCIP_CALL( SCIPgetExternBranchCands(scip, &externcands, &externcandssol, &externcandsscore, NULL, &nprioexterncands, NULL, NULL, NULL) ); assert(nprioexterncands > 0); /* get current update strategy for pseudo costs, if our multiplier rule is 'u' */ if( branchruledata->strategy == 'u' ) { SCIP_CALL( SCIPgetCharParam(scip, "branching/lpgainnormalize", &branchruledata->updatestrategy) ); } /* select branching variable */ SCIP_CALL( selectBranchVar(scip, branchrule, externcands, externcandssol, externcandsscore, nprioexterncands, &brvar, &brpoint) ); if( brvar == NULL ) { SCIPerrorMessage("branchExecextPscost failed to select a branching variable from %d candidates\n", nprioexterncands); *result = SCIP_DIDNOTRUN; return SCIP_OKAY; } assert(SCIPvarIsActive(SCIPvarGetProbvar(brvar))); SCIPdebugMessage("branching on variable <%s>: new intervals: [%g, %g] and [%g, %g]\n", SCIPvarGetName(brvar), SCIPvarGetLbLocal(brvar), SCIPadjustedVarUb(scip, brvar, brpoint), SCIPadjustedVarLb(scip, brvar, brpoint), SCIPvarGetUbLocal(brvar)); if( branchruledata->nchildren > 2 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) <= branchruledata->narymaxdepth ) { /* do n-ary branching */ SCIP_Real minwidth; minwidth = 0.0; if( !SCIPisInfinity(scip, -SCIPvarGetLbGlobal(brvar)) && !SCIPisInfinity(scip, SCIPvarGetUbGlobal(brvar)) ) minwidth = branchruledata->naryminwidth * (SCIPvarGetUbGlobal(brvar) - SCIPvarGetLbGlobal(brvar)); SCIP_CALL( SCIPbranchVarValNary(scip, brvar, brpoint, branchruledata->nchildren, minwidth, branchruledata->narywidthfactor, &nchildren) ); } else { /* do binary branching */ SCIP_CALL( SCIPbranchVarValNary(scip, brvar, brpoint, 2, 0.0, 1.0, &nchildren) ); } if( nchildren > 1 ) { *result = SCIP_BRANCHED; } else { /* if there are no children, then variable should have been fixed by SCIPbranchVarVal */ assert(SCIPisEQ(scip, SCIPvarGetLbLocal(brvar), SCIPvarGetUbLocal(brvar))); *result = SCIP_REDUCEDDOM; } 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); } }
/** node selection method of node selector */ static SCIP_DECL_NODESELSELECT(nodeselSelectBreadthfirst) { /*lint --e{715}*/ assert(nodesel != NULL); assert(strcmp(SCIPnodeselGetName(nodesel), NODESEL_NAME) == 0); assert(scip != NULL); assert(selnode != NULL); /* siblings come before leaves at the same level. Sometimes it can occur that no leaves are left except for children */ *selnode = SCIPgetBestSibling(scip); if( *selnode == NULL ) { *selnode = SCIPgetBestLeaf(scip); if( *selnode == NULL ) *selnode=SCIPgetBestChild(scip); } if( *selnode != NULL ) { SCIPdebugMessage("Selecting next node number %"SCIP_LONGINT_FORMAT" at depth %d\n", SCIPnodeGetNumber(*selnode), SCIPnodeGetDepth(*selnode)); } return SCIP_OKAY; }
/** call writing method */ static SCIP_RETCODE writeBounds( SCIP* scip, /**< SCIP data structure */ FILE* file, /**< file to write to or NULL */ SCIP_Bool writesubmipdualbound/**< write dualbounds of submip roots for all open nodes */ ) { SCIP_NODE** opennodes; int nopennodes; int n; int v; assert(scip != NULL); nopennodes = -1; #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Status after %"SCIP_LONGINT_FORMAT" processed nodes (%d open)\n", SCIPgetNNodes(scip), SCIPgetNNodesLeft(scip)); SCIPinfoMessage(scip, file, "Primalbound: %g\n", SCIPgetPrimalbound(scip)); SCIPinfoMessage(scip, file, "Dualbound: %g\n", SCIPgetDualbound(scip)); #else SCIPinfoMessage(scip, file, "PB %g\n", SCIPgetPrimalbound(scip)); #endif /* get all open nodes and therefor print all dualbounds */ for( v = 2; v >= 0; --v ) { SCIP_NODE* node; switch( v ) { case 2: SCIP_CALL( SCIPgetChildren(scip, &opennodes, &nopennodes) ); break; case 1: SCIP_CALL( SCIPgetSiblings(scip, &opennodes, &nopennodes) ); break; case 0: SCIP_CALL( SCIPgetLeaves(scip, &opennodes, &nopennodes) ); break; default: assert(0); break; } assert(nopennodes >= 0); /* print all node information */ for( n = nopennodes - 1; n >= 0 && !SCIPisStopped(scip); --n ) { node = opennodes[n]; if( writesubmipdualbound ) { SCIP* subscip; SCIP_Bool valid; SCIP_HASHMAP* varmap; /* mapping of SCIP variables to sub-SCIP variables */ SCIP_VAR** vars; /* original problem's variables */ int nvars; SCIP_Real submipdb; SCIP_Bool cutoff; SCIP_CALL( SCIPcreate(&subscip) ); SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) ); /* create the variable mapping hash map */ SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(subscip), SCIPcalcHashtableSize(5 * nvars)) ); submipdb = SCIP_INVALID; valid = FALSE; cutoff = FALSE; SCIP_CALL( SCIPcopy(scip, subscip, varmap, NULL, "__boundwriting", TRUE, FALSE, TRUE, &valid) ); if( valid ) { SCIP_VAR** branchvars; SCIP_Real* branchbounds; SCIP_BOUNDTYPE* boundtypes; int nbranchvars; int size; size = SCIPnodeGetDepth(node); /* allocate memory for all branching decisions */ SCIP_CALL( SCIPallocBufferArray(scip, &branchvars, size) ); SCIP_CALL( SCIPallocBufferArray(scip, &branchbounds, size) ); SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, size) ); /* we assume that we only have one branching decision at each node */ SCIPnodeGetAncestorBranchings( node, branchvars, branchbounds, boundtypes, &nbranchvars, size ); /* check if did not have enough memory */ if( nbranchvars > size ) { size = nbranchvars; SCIP_CALL( SCIPallocBufferArray(scip, &branchvars, size) ); SCIP_CALL( SCIPallocBufferArray(scip, &branchbounds, size) ); SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, size) ); /* now getting all information */ SCIPnodeGetAncestorBranchings( node, branchvars, branchbounds, boundtypes, &nbranchvars, size ); } /* apply all changes to the submip */ SCIP_CALL( applyDomainChanges(subscip, branchvars, branchbounds, boundtypes, nbranchvars, varmap) ); /* free memory for all branching decisions */ SCIPfreeBufferArray(scip, &boundtypes); SCIPfreeBufferArray(scip, &branchbounds); SCIPfreeBufferArray(scip, &branchvars); /* do not abort subproblem on CTRL-C */ SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) ); /* disable output to console */ SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) ); /* solve only root node */ SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) ); /* set cutoffbound as objective limit for subscip */ SCIP_CALL( SCIPsetObjlimit(subscip, SCIPgetCutoffbound(scip)) ); SCIP_CALL( SCIPsolve(subscip) ); cutoff = (SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE); submipdb = SCIPgetDualbound(subscip) * SCIPgetTransObjscale(scip) + SCIPgetTransObjoffset(scip); } #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g, nodesubmiprootdualbound: %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : ""); #else SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : ""); #endif /* free hash map */ SCIPhashmapFree(&varmap); SCIP_CALL( SCIPfree(&subscip) ); } else { #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node)); #else SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node)); #endif } } } #ifdef LONGSTATS SCIPinfoMessage(scip, file, "\n"); #endif return SCIP_OKAY; }
/** call writing method */ static SCIP_RETCODE writeBoundsFocusNode( SCIP* scip, /**< SCIP data structure */ SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */ ) { FILE* file; SCIP_Bool writesubmipdualbound; SCIP_NODE* node; assert(scip != NULL); assert(eventhdlrdata != NULL); file = eventhdlrdata->file; writesubmipdualbound = eventhdlrdata->writesubmipdualbound; node = SCIPgetCurrentNode(scip); /* do not process probing nodes */ if( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE ) return SCIP_OKAY; /* do not process cutoff nodes */ if( SCIPisInfinity(scip, SCIPgetNodeDualbound(scip, node)) ) return SCIP_OKAY; if( !SCIPisEQ(scip, eventhdlrdata->lastpb, SCIPgetPrimalbound(scip)) ) { #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Status after %"SCIP_LONGINT_FORMAT" processed nodes (%d open)\n", SCIPgetNNodes(scip), SCIPgetNNodesLeft(scip)); SCIPinfoMessage(scip, file, "Primalbound: %g\n", SCIPgetPrimalbound(scip)); SCIPinfoMessage(scip, file, "Dualbound: %g\n", SCIPgetDualbound(scip)); #else SCIPinfoMessage(scip, file, "PB %g\n", SCIPgetPrimalbound(scip)); #endif eventhdlrdata->lastpb = SCIPgetPrimalbound(scip); } if( writesubmipdualbound ) { SCIP* subscip; SCIP_Bool valid; SCIP_Real submipdb; SCIP_Bool cutoff; SCIP_CALL( SCIPcreate(&subscip) ); submipdb = SCIP_INVALID; valid = FALSE; cutoff = FALSE; SCIP_CALL( SCIPcopy(scip, subscip, NULL, NULL, "__boundwriting", FALSE, FALSE, TRUE, &valid) ); if( valid ) { /* do not abort subproblem on CTRL-C */ SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) ); /* disable output to console */ SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) ); /* solve only root node */ SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) ); #if 0 /* disable heuristics in subscip */ SCIP_CALL( SCIPsetHeuristics(subscip, SCIP_PARAMSETTING_OFF, TRUE) ); #endif /* set cutoffbound as objective limit for subscip */ SCIP_CALL( SCIPsetObjlimit(subscip, SCIPgetCutoffbound(scip)) ); SCIP_CALL( SCIPsolve(subscip) ); cutoff = (SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE); submipdb = SCIPgetDualbound(subscip) * SCIPgetTransObjscale(scip) + SCIPgetTransObjoffset(scip); } #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g, nodesubmiprootdualbound: %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : ""); #else SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : ""); #endif SCIP_CALL( SCIPfree(&subscip) ); } else { #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node)); #else SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node)); #endif } #ifdef LONGSTATS SCIPinfoMessage(scip, file, "\n"); #endif return SCIP_OKAY; }
/** adds cuts to the LP and clears separation storage */ SCIP_RETCODE SCIPsepastoreApplyCuts( SCIP_SEPASTORE* sepastore, /**< separation storage */ BMS_BLKMEM* blkmem, /**< block memory */ SCIP_SET* set, /**< global SCIP settings */ SCIP_STAT* stat, /**< problem statistics */ SCIP_TREE* tree, /**< branch and bound tree */ SCIP_LP* lp, /**< LP data */ SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */ SCIP_EVENTQUEUE* eventqueue, /**< event queue */ SCIP_EVENTFILTER* eventfilter, /**< global event filter */ SCIP_Bool root, /**< are we at the root node? */ SCIP_Bool* cutoff /**< pointer to store whether an empty domain was created */ ) { SCIP_NODE* node; SCIP_Real mincutorthogonality; int depth; int maxsepacuts; int ncutsapplied; int pos; assert(sepastore != NULL); assert(set != NULL); assert(tree != NULL); assert(lp != NULL); assert(cutoff != NULL); *cutoff = FALSE; SCIPdebugMessage("applying %d cuts\n", sepastore->ncuts); node = SCIPtreeGetCurrentNode(tree); assert(node != NULL); /* get maximal number of cuts to add to the LP */ maxsepacuts = SCIPsetGetSepaMaxcuts(set, root); ncutsapplied = 0; /* get depth of current node */ depth = SCIPnodeGetDepth(node); /* calculate minimal cut orthogonality */ mincutorthogonality = (root ? set->sepa_minorthoroot : set->sepa_minortho); mincutorthogonality = MAX(mincutorthogonality, set->num_epsilon); /* Compute scores for all non-forced cuts and initialize orthogonalities - make sure all cuts are initialized again for the current LP solution */ for( pos = sepastore->nforcedcuts; pos < sepastore->ncuts; pos++ ) { SCIP_CALL( computeScore(sepastore, set, stat, lp, TRUE, pos) ); } /* apply all forced cuts */ for( pos = 0; pos < sepastore->nforcedcuts && !(*cutoff); pos++ ) { SCIP_ROW* cut; cut = sepastore->cuts[pos]; assert(SCIPsetIsInfinity(set, sepastore->scores[pos])); /* if the cut is a bound change (i.e. a row with only one variable), add it as bound change instead of LP row */ if( !SCIProwIsModifiable(cut) && SCIProwGetNNonz(cut) == 1 ) { SCIPdebugMessage(" -> applying forced cut <%s> as boundchange\n", SCIProwGetName(cut)); SCIP_CALL( sepastoreApplyBdchg(sepastore, blkmem, set, stat, tree, lp, branchcand, eventqueue, cut, cutoff) ); } else { /* add cut to the LP and update orthogonalities */ SCIPdebugMessage(" -> applying forced cut <%s>\n", SCIProwGetName(cut)); /*SCIPdebug(SCIProwPrint(cut, NULL));*/ SCIP_CALL( sepastoreApplyCut(sepastore, blkmem, set, eventqueue, eventfilter, lp, cut, mincutorthogonality, depth, &ncutsapplied) ); } } /* apply non-forced cuts */ while( ncutsapplied < maxsepacuts && sepastore->ncuts > sepastore->nforcedcuts && !(*cutoff) ) { SCIP_ROW* cut; int bestpos; /* get best non-forced cut */ bestpos = sepastoreGetBestCut(sepastore); assert(sepastore->nforcedcuts <= bestpos && bestpos < sepastore->ncuts); assert(sepastore->scores[bestpos] != SCIP_INVALID ); /*lint !e777*/ assert(sepastore->efficacies[bestpos] != SCIP_INVALID ); /*lint !e777*/ cut = sepastore->cuts[bestpos]; assert(SCIProwIsModifiable(cut) || SCIProwGetNNonz(cut) != 1); /* bound changes are forced cuts */ assert(!SCIPsetIsInfinity(set, sepastore->scores[bestpos])); SCIPdebugMessage(" -> applying cut <%s> (pos=%d/%d, len=%d, efficacy=%g, objparallelism=%g, orthogonality=%g, score=%g)\n", SCIProwGetName(cut), bestpos, sepastore->ncuts, SCIProwGetNNonz(cut), sepastore->efficacies[bestpos], sepastore->objparallelisms[bestpos], sepastore->orthogonalities[bestpos], sepastore->scores[bestpos]); /*SCIPdebug(SCIProwPrint(cut, NULL));*/ /* capture cut such that it is not destroyed in sepastoreDelCut() */ SCIProwCapture(cut); /* release the row and delete the cut (also issuing ROWDELETEDSEPA event) */ SCIP_CALL( sepastoreDelCut(sepastore, blkmem, set, eventqueue, eventfilter, lp, bestpos) ); /* Do not add (non-forced) non-violated cuts. * Note: do not take SCIPsetIsEfficacious(), because constraint handlers often add cuts w.r.t. SCIPsetIsFeasPositive(). */ if( SCIPsetIsFeasPositive(set, sepastore->efficacies[bestpos]) ) { /* add cut to the LP and update orthogonalities */ SCIP_CALL( sepastoreApplyCut(sepastore, blkmem, set, eventqueue, eventfilter, lp, cut, mincutorthogonality, depth, &ncutsapplied) ); } /* release cut */ SCIP_CALL( SCIProwRelease(&cut, blkmem, set, lp) ); } /* clear the separation storage and reset statistics for separation round */ SCIP_CALL( SCIPsepastoreClearCuts(sepastore, blkmem, set, eventqueue, eventfilter, lp) ); return SCIP_OKAY; }
/** 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; }
/** returns whether the solution is contained in node's subproblem */ static SCIP_RETCODE isSolutionInNode( BMS_BLKMEM* blkmem, /**< block memory */ SCIP_SET* set, /**< global SCIP settings */ SCIP_NODE* node, /**< local node where this bound change was applied */ SCIP_Bool* solcontained /**< pointer to store whether the solution is contained in node's subproblem */ ) { SCIP_Bool* boolptr; assert(set != NULL); assert(blkmem != NULL); assert(node != NULL); assert(solcontained != NULL); /* check if we are in the original problem and not in a sub MIP */ if( !isSolutionInMip(set) ) { *solcontained = FALSE; return SCIP_OKAY; } /* generate the hashmap */ if( solinnode == NULL ) { SCIP_CALL( SCIPhashmapCreate(&solinnode, blkmem, SCIPcalcHashtableSize(SCIP_HASHSIZE_DEBUG)) ); } /* check, whether we know already whether the solution is contained in the given node */ boolptr = (SCIP_Bool*)SCIPhashmapGetImage(solinnode, (void*)node); if( boolptr != NULL ) { if( boolptr != &falseptr && boolptr != &trueptr ) { SCIPerrorMessage("wrong value in node hashmap\n"); SCIPABORT(); } *solcontained = *boolptr; return SCIP_OKAY; } /* if the solution is not contained in the parent of the node, it cannot be contained in the current node */ *solcontained = TRUE; if( node->parent != NULL ) { SCIP_CALL( isSolutionInNode(blkmem, set, node->parent, solcontained) ); } if( *solcontained ) { /* check whether the bound changes at the current node remove the debugging solution from the subproblem */ if( node->domchg != NULL ) { SCIP_DOMCHGBOUND* domchgbound; SCIP_BOUNDCHG* boundchgs; int i; domchgbound = &node->domchg->domchgbound; boundchgs = domchgbound->boundchgs; for( i = 0; i < (int)domchgbound->nboundchgs && *solcontained; ++i ) { SCIP_Real varsol; if( SCIPboundchgIsRedundant(&boundchgs[i]) ) continue; /* get solution value of variable */ SCIP_CALL( getSolutionValue(set, boundchgs[i].var, &varsol) ); if( varsol != SCIP_UNKNOWN ) /*lint !e777*/ { /* compare the bound change with the solution value */ if( SCIPboundchgGetBoundtype(&boundchgs[i]) == SCIP_BOUNDTYPE_LOWER ) *solcontained = SCIPsetIsFeasGE(set, varsol, boundchgs[i].newbound); else *solcontained = SCIPsetIsFeasLE(set, varsol, boundchgs[i].newbound); if( !(*solcontained) && SCIPboundchgGetBoundchgtype(&boundchgs[i]) != SCIP_BOUNDCHGTYPE_BRANCHING ) { SCIPerrorMessage("debugging solution was cut off in local node %p at depth %d by inference <%s>[%.15g] %s %.15g\n", node, SCIPnodeGetDepth(node), SCIPvarGetName(boundchgs[i].var), varsol, SCIPboundchgGetBoundtype(&boundchgs[i]) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", boundchgs[i].newbound); SCIPABORT(); } } else if( SCIPboundchgGetBoundchgtype(&boundchgs[i]) == SCIP_BOUNDCHGTYPE_BRANCHING ) { /* we branched on a variable were we don't know the solution: no debugging can be applied in this subtree */ *solcontained = FALSE; } } } } /* remember the status of the current node */ SCIP_CALL( SCIPhashmapSetImage(solinnode, (void*)node, *solcontained ? (void*)(&trueptr) : (void*)(&falseptr)) ); return SCIP_OKAY; }