/** branching execution method for not completely fixed pseudo solutions */ static SCIP_DECL_BRANCHEXECPS(branchExecpsRandom) { /*lint --e{715}*/ SCIP_BRANCHRULEDATA* branchruledata; SCIP_VAR** pseudocands; int npseudocands; int bestcand; assert(branchrule != NULL); assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0); assert(scip != NULL); assert(result != NULL); SCIPdebugMessage("Execps method of random branching\n"); branchruledata = SCIPbranchruleGetData(branchrule); assert(branchruledata != NULL); /* get branching candidates */ SCIP_CALL( SCIPgetPseudoBranchCands(scip, &pseudocands, NULL, &npseudocands) ); assert(npseudocands > 0); /* get random branching candidate */ bestcand = SCIPgetRandomInt(0, npseudocands-1, &branchruledata->seed); assert(bestcand >= 0); SCIPdebugMessage(" -> %d candidates, selected candidate %d: variable <%s>\n", npseudocands, bestcand, SCIPvarGetName(pseudocands[bestcand])); /* perform the branching */ SCIP_CALL( SCIPbranchVar(scip, pseudocands[bestcand], NULL, NULL, NULL) ); *result = SCIP_BRANCHED; return SCIP_OKAY; }
/** branching execution method for fractional LP solutions */ static SCIP_DECL_BRANCHEXECLP(branchExeclpLeastinf) { /*lint --e{715}*/ SCIP_VAR** lpcands; SCIP_Real* lpcandsfrac; int nlpcands; SCIP_Real infeasibility; SCIP_Real score; SCIP_Real obj; SCIP_Real bestscore; SCIP_Real bestobj; int bestcand; int i; assert(branchrule != NULL); assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0); assert(scip != NULL); assert(result != NULL); SCIPdebugMessage("Execlp method of leastinf branching\n"); /* get branching candidates */ SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, NULL, &lpcandsfrac, NULL, &nlpcands, NULL) ); assert(nlpcands > 0); /* search the least infeasible candidate */ bestscore = SCIP_REAL_MIN; bestobj = 0.0; bestcand = -1; for( i = 0; i < nlpcands; ++i ) { assert(lpcands[i] != NULL); infeasibility = lpcandsfrac[i]; infeasibility = MIN(infeasibility, 1.0-infeasibility); score = 1.0 - infeasibility; score *= SCIPvarGetBranchFactor(lpcands[i]); obj = SCIPvarGetObj(lpcands[i]); obj = REALABS(obj); if( SCIPisGT(scip, score, bestscore) || (SCIPisGE(scip, score, bestscore) && obj > bestobj) ) { bestscore = score; bestobj = obj; bestcand = i; } } assert(bestcand >= 0); SCIPdebugMessage(" -> %d candidates, selected candidate %d: variable <%s> (frac=%g, obj=%g, factor=%g, score=%g)\n", nlpcands, bestcand, SCIPvarGetName(lpcands[bestcand]), lpcandsfrac[bestcand], bestobj, SCIPvarGetBranchFactor(lpcands[bestcand]), bestscore); /* perform the branching */ SCIP_CALL( SCIPbranchVar(scip, lpcands[bestcand], NULL, NULL, NULL) ); *result = SCIP_BRANCHED; return SCIP_OKAY; }
/** branching execution method for fractional LP solutions */ static SCIP_DECL_BRANCHEXECLP(branchExeclpPscost) { /*lint --e{715}*/ SCIP_VAR** lpcands; SCIP_Real* lpcandssol; SCIP_Real bestscore; SCIP_Real bestrootdiff; int nlpcands; int bestcand; int c; assert(branchrule != NULL); assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0); assert(scip != NULL); assert(result != NULL); SCIPdebugMessage("Execlp method of pscost branching\n"); /* get branching candidates */ SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, NULL, NULL, &nlpcands, NULL) ); assert(nlpcands > 0); bestcand = -1; bestscore = -SCIPinfinity(scip); bestrootdiff = 0.0; for( c = 0; c < nlpcands; ++c ) { SCIP_Real score; SCIP_Real rootsolval; SCIP_Real rootdiff; score = SCIPgetVarPseudocostScore(scip, lpcands[c], lpcandssol[c]); rootsolval = SCIPvarGetRootSol(lpcands[c]); rootdiff = REALABS(lpcandssol[c] - rootsolval); if( SCIPisSumGT(scip, score, bestscore) || (SCIPisSumEQ(scip, score, bestscore) && rootdiff > bestrootdiff) ) { bestcand = c; bestscore = score; bestrootdiff = rootdiff; } } assert(0 <= bestcand && bestcand < nlpcands); assert(!SCIPisFeasIntegral(scip, lpcandssol[bestcand])); /* perform the branching */ SCIPdebugMessage(" -> %d cands, selected cand %d: variable <%s> (solval=%g, score=%g)\n", nlpcands, bestcand, SCIPvarGetName(lpcands[bestcand]), lpcandssol[bestcand], bestscore); /* perform the branching */ SCIP_CALL( SCIPbranchVar(scip, lpcands[bestcand], NULL, NULL, NULL) ); *result = SCIP_BRANCHED; return SCIP_OKAY; }
/** copy method for branchrule plugins (called when SCIP copies plugins) */ static SCIP_DECL_BRANCHCOPY(branchCopyPscost) { /*lint --e{715}*/ assert(scip != NULL); assert(branchrule != NULL); assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0); /* call inclusion method of branchrule */ SCIP_CALL( SCIPincludeBranchrulePscost(scip) ); return SCIP_OKAY; }
/** 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; }
/** branching execution method for external candidates */ static SCIP_DECL_BRANCHEXECEXT(branchExecextLeastinf) { /*lint --e{715}*/ SCIP_VAR** externcands; SCIP_Real* externcandssol; SCIP_Real* externcandsscore; int nexterncands; SCIP_VAR* bestcand; SCIP_Real bestscore; SCIP_Real bestobj; SCIP_Real bestsol; SCIP_Real brpoint; int i; SCIP_NODE* downchild; SCIP_NODE* eqchild; SCIP_NODE* upchild; assert(branchrule != NULL); assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0); assert(scip != NULL); assert(result != NULL); SCIPdebugMessage("Execext method of leastinf branching\n"); /* get branching candidates */ SCIP_CALL( SCIPgetExternBranchCands(scip, &externcands, &externcandssol, &externcandsscore, NULL, &nexterncands, NULL, NULL, NULL) ); assert(nexterncands > 0); /* search the least infeasible candidate */ bestscore = SCIPinfinity(scip); bestobj = 0.0; bestcand = NULL; bestsol = SCIP_INVALID; for( i = 0; i < nexterncands; ++i ) { updateBestCandidate(scip, &bestcand, &bestscore, &bestobj, &bestsol, externcands[i], externcandsscore[i], externcandssol[i]); } if( bestcand == NULL ) { SCIPerrorMessage("branchExecextLeastinf failed to select a branching variable from %d candidates\n", nexterncands); *result = SCIP_DIDNOTRUN; return SCIP_OKAY; } brpoint = SCIPgetBranchingPoint(scip, bestcand, bestsol); SCIPdebugMessage(" -> %d candidates, selected variable <%s> (infeas=%g, obj=%g, factor=%g, score=%g), branching point=%g\n", nexterncands, SCIPvarGetName(bestcand), bestsol, bestobj, SCIPvarGetBranchFactor(bestcand), bestscore, brpoint); /* perform the branching */ SCIP_CALL( SCIPbranchVarVal(scip, bestcand, brpoint, &downchild, &eqchild, &upchild) ); if( downchild != NULL || eqchild != NULL || upchild != NULL ) { *result = SCIP_BRANCHED; } else { /* if there are no children, then variable should have been fixed by SCIPbranchVarVal */ assert(SCIPisEQ(scip, SCIPvarGetLbLocal(bestcand), SCIPvarGetUbLocal(bestcand))); *result = SCIP_REDUCEDDOM; } return SCIP_OKAY; }
/** branching execution method for external candidates */ static SCIP_DECL_BRANCHEXECEXT(branchExecextRandom) { /*lint --e{715}*/ SCIP_BRANCHRULEDATA* branchruledata; SCIP_VAR** externcands; SCIP_Real* externcandssol; int nprioexterncands; SCIP_VAR* bestcand; SCIP_Real bestcandsol; SCIP_Real brpoint; SCIP_NODE* downchild; SCIP_NODE* eqchild; SCIP_NODE* upchild; assert(branchrule != NULL); assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0); assert(scip != NULL); assert(result != NULL); SCIPdebugMessage("Execrel method of random branching\n"); branchruledata = SCIPbranchruleGetData(branchrule); assert(branchruledata != NULL); bestcand = NULL; bestcandsol = 0.0; /* get branching candidates */ SCIP_CALL( SCIPgetExternBranchCands(scip, &externcands, &externcandssol, NULL, NULL, &nprioexterncands, NULL, NULL, NULL) ); assert(nprioexterncands > 0); /* get random branching candidate * * since variables can occur several times in the list of candidates, variables that have been added more often have * a higher probability to be chosen for branching */ getRandomVariable(scip, externcands, externcandssol, nprioexterncands, &bestcand, &bestcandsol, &branchruledata->seed); if( bestcand == NULL ) { SCIPerrorMessage("branchExecrelRandom failed to select a branching variable from %d candidates\n", nprioexterncands); *result = SCIP_DIDNOTRUN; return SCIP_OKAY; } brpoint = SCIPgetBranchingPoint(scip, bestcand, bestcandsol); SCIPdebugMessage(" -> %d candidates, selected variable <%s> with solution value %g, branching point=%g\n", nprioexterncands, SCIPvarGetName(bestcand), bestcandsol, brpoint); SCIP_CALL( SCIPbranchVarVal(scip, bestcand, brpoint, &downchild, &eqchild, &upchild) ); if( downchild != NULL || eqchild != NULL || upchild != NULL ) { *result = SCIP_BRANCHED; } else { /* if there are no children, then variable should have been fixed by SCIPbranchVarVal */ assert(SCIPisEQ(scip, SCIPvarGetLbLocal(bestcand), SCIPvarGetUbLocal(bestcand))); *result = SCIP_REDUCEDDOM; } return SCIP_OKAY; }
/** branching execution method for fractional LP solutions */ static SCIP_DECL_BRANCHEXECLP(branchExeclpStp) { /*lint --e{715}*/ SCIP_PROBDATA* probdata; SCIP_CONS* consin; SCIP_CONS* consout; SCIP_NODE* vertexin; SCIP_NODE* vertexout; SCIP_VAR** edgevars; SCIP_Real estimatein; SCIP_Real estimateout; GRAPH* g; int e; int branchvertex; assert(branchrule != NULL); assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0); assert(scip != NULL); assert(result != NULL); SCIPdebugMessage("Execlp method of Stp branching\n "); estimatein = SCIPgetUpperbound(scip); estimateout = SCIPgetUpperbound(scip); *result = SCIP_DIDNOTRUN; /* get problem data */ probdata = SCIPgetProbData(scip); assert(probdata != NULL); /* get graph */ g = SCIPprobdataGetGraph(probdata); assert(g != NULL); /* get vertex to branch on */ SCIP_CALL( selectBranchingVertex(scip, &branchvertex) ); if( branchvertex == UNKNOWN ) { SCIPdebugMessage("Branching did not run \n"); return SCIP_OKAY; } edgevars = SCIPprobdataGetEdgeVars(scip); /* create constraints */ SCIP_CALL( SCIPcreateConsLinear(scip, &consin, "consin", 0, NULL, NULL, 1.0, 1.0, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE) ); SCIP_CALL( SCIPcreateConsLinear(scip, &consout, "consout", 0, NULL, NULL, 0.0, 0.0, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE) ); for( e = g->inpbeg[branchvertex]; e != EAT_LAST; e = g->ieat[e] ) { SCIP_CALL( SCIPaddCoefLinear(scip, consin, edgevars[e], 1.0) ); SCIP_CALL( SCIPaddCoefLinear(scip, consout, edgevars[e], 1.0) ); SCIP_CALL( SCIPaddCoefLinear(scip, consout, edgevars[flipedge(e)], 1.0) ); } /* create the child nodes */ SCIP_CALL( SCIPcreateChild(scip, &vertexin, 1.0, estimatein) ); SCIP_CALL( SCIPcreateChild(scip, &vertexout, 1.0, estimateout) ); assert(vertexin != NULL); assert(vertexout != NULL); SCIP_CALL( SCIPaddConsNode(scip, vertexin, consin, NULL) ); SCIP_CALL( SCIPaddConsNode(scip, vertexout, consout, NULL) ); /* relase constraints */ SCIP_CALL( SCIPreleaseCons(scip, &consin) ); SCIP_CALL( SCIPreleaseCons(scip, &consout) ); SCIPdebugMessage("Branched on stp vertex %d \n", branchvertex); *result = SCIP_BRANCHED; 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; }