/** branches on disjunctive constraint */ static SCIP_RETCODE branchCons( SCIP* scip, /**< SCIP data structure */ SCIP_CONS* cons, /**< active disjunction constraint */ SCIP_RESULT* result /**< pointer to store the result */ ) { SCIP_CONSDATA* consdata; SCIP_CONS** conss; SCIP_NODE* child; SCIP_Real estimate; int nconss; int i; assert(result != NULL); /* cannot branch on modifiable constraint */ if( SCIPconsIsModifiable(cons) ) return SCIP_OKAY; consdata = SCIPconsGetData(cons); assert(consdata != NULL); conss = consdata->conss; assert(conss != NULL); nconss = consdata->nconss; assert(nconss > 0); estimate = SCIPgetLocalTransEstimate(scip); /* add all inactive constraints to local subproblem */ for( i = 0; i < nconss; ++i ) { /* create the branch-and-bound tree child nodes of the current node */ SCIP_CALL( SCIPcreateChild(scip, &child, 0.0, estimate) ); /* add constraints to nodes */ SCIP_CALL( SCIPaddConsNode(scip, child, conss[i], NULL) ); /* remove disjunction constraint, from child node */ SCIP_CALL( SCIPdelConsNode(scip, child, cons) ); } /* reset constraint age */ SCIP_CALL( SCIPresetConsAge(scip, cons) ); *result = SCIP_BRANCHED; return SCIP_OKAY; }
/** selects a variable out of the given candidate array and performs the branching */ static SCIP_RETCODE performBranching( SCIP* scip, /**< SCIP data structure */ SCIP_VAR** cands, /**< candidate array */ SCIP_Real* candsols, /**< array of candidate solution values, or NULL */ int ncands, /**< number of candidates */ SCIP_Real conflictweight, /**< weight in score calculations for conflict score */ SCIP_Real inferenceweight, /**< weight in score calculations for inference score */ SCIP_Real cutoffweight, /**< weight in score calculations for cutoff score */ SCIP_Real reliablescore, /**< score which is seen to be reliable for a branching decision */ SCIP_Bool useweightedsum, /**< should a weighted sum of inference, conflict and cutoff weights be used? */ SCIP_RESULT* result /**< buffer to store result (branched, reduced domain, ...) */ ) { SCIP_VAR* bestaggrcand; SCIP_VAR* bestvaluecand; SCIP_Real bestval; SCIP_Real bestaggrscore; SCIP_Real bestvaluescore; SCIP_Real bestbranchpoint; SCIP_BRANCHDIR bestbranchdir; SCIP_NODE* downchild; SCIP_NODE* eqchild; SCIP_NODE* upchild; bestbranchpoint = SCIP_UNKNOWN; bestbranchdir = SCIP_BRANCHDIR_DOWNWARDS; bestvaluescore = 0.0; bestvaluecand = NULL; assert(ncands > 0); assert(result != NULL); *result = SCIP_DIDNOTFIND; /* check if the weighted sum between the average inferences and conflict score should be used */ if( useweightedsum ) { int c; bestaggrcand = cands[0]; bestvaluecand = cands[0]; assert(cands[0] != NULL); if( candsols == NULL ) { bestval = SCIP_UNKNOWN; /* get domain value score for the first candidate */ bestvaluescore = getValueScore(scip, cands[0], conflictweight, cutoffweight, reliablescore, &bestbranchpoint, &bestbranchdir); SCIPdebugMessage("current best value candidate <%s>[%g,%g] %s <%g> (value %g)\n", SCIPvarGetName(bestvaluecand), SCIPvarGetLbLocal(bestvaluecand), SCIPvarGetUbLocal(bestvaluecand), bestbranchdir == SCIP_BRANCHDIR_DOWNWARDS ? "<=" : ">=", bestbranchpoint, bestvaluescore); } else bestval = candsols[0]; /* get aggregated score for the first candidate */ bestaggrscore = getAggrScore(scip, cands[0], conflictweight, inferenceweight, cutoffweight, reliablescore); for( c = 1; c < ncands; ++c ) { SCIP_VAR* cand; SCIP_Real val; SCIP_Real aggrscore; SCIP_Real branchpoint; SCIP_BRANCHDIR branchdir; cand = cands[c]; assert(cand != NULL); if( candsols == NULL ) { SCIP_Real valuescore; val = SCIP_UNKNOWN; /* get domain value score for the candidate */ valuescore = getValueScore(scip, cand, conflictweight, cutoffweight, reliablescore, &branchpoint, &branchdir); /* evaluate the candidate against the currently best candidate w.r.t. domain value score */ evaluateValueCand(cand, valuescore, branchpoint, branchdir, &bestvaluecand, &bestvaluescore, &bestbranchpoint, &bestbranchdir); SCIPdebugMessage("current best value candidate <%s>[%g,%g] %s <%g> (value %g)\n", SCIPvarGetName(bestvaluecand), SCIPvarGetLbLocal(bestvaluecand), SCIPvarGetUbLocal(bestvaluecand), bestbranchdir == SCIP_BRANCHDIR_DOWNWARDS ? "<=" : ">=", bestbranchpoint, bestvaluescore); } else val = candsols[c]; /* get aggregated score for the candidate */ aggrscore = getAggrScore(scip, cand, conflictweight, inferenceweight, cutoffweight, reliablescore); SCIPdebugMessage(" -> cand <%s>: prio=%d, solval=%g, score=%g\n", SCIPvarGetName(cand), SCIPvarGetBranchPriority(cand), val == SCIP_UNKNOWN ? SCIPgetVarSol(scip, cand) : val, aggrscore); /*lint !e777*/ /* evaluate the candidate against the currently best candidate w.r.t. aggregated score */ evaluateAggrCand(cand, aggrscore, val, &bestaggrcand, &bestaggrscore, &bestval); } } else { int c; bestaggrcand = cands[0]; assert(cands[0] != NULL); if( candsols != NULL ) bestval = candsols[0]; else bestval = SCIP_UNKNOWN; bestaggrscore = SCIPgetVarAvgInferenceScore(scip, cands[0]); /* search for variable with best score w.r.t. average inferences per branching */ for( c = 1; c < ncands; ++c ) { SCIP_VAR* cand; SCIP_Real val; SCIP_Real aggrscore; cand = cands[c]; assert(cand != NULL); if( candsols != NULL ) val = candsols[c]; else val = SCIP_UNKNOWN; aggrscore = SCIPgetVarAvgInferenceScore(scip, cand); /* in case the average inferences score is below the reliable score we set it to zero since it is seen to be * unreliable */ if( aggrscore < reliablescore ) aggrscore = 0.0; SCIPdebugMessage(" -> cand <%s>: prio=%d, solval=%g, score=%g\n", SCIPvarGetName(cand), SCIPvarGetBranchPriority(cand), val == SCIP_UNKNOWN ? SCIPgetVarSol(scip, cand) : val, aggrscore); /*lint !e777*/ /* evaluate the candidate against the currently best candidate */ evaluateAggrCand(cand, aggrscore, val, &bestaggrcand, &bestaggrscore, &bestval); } } assert(bestaggrcand != NULL); SCIPdebugMessage(" -> %d candidates, selected variable <%s>[%g,%g] (prio=%d, solval=%.12f, score=%g, conflict=%g cutoff=%g, inference=%g)\n", ncands, SCIPvarGetName(bestaggrcand), SCIPvarGetLbLocal (bestaggrcand), SCIPvarGetUbLocal(bestaggrcand), SCIPvarGetBranchPriority(bestaggrcand), bestval == SCIP_UNKNOWN ? SCIPgetVarSol(scip, bestaggrcand) : bestval, bestaggrscore, /*lint !e777*/ SCIPgetVarConflictScore(scip, bestaggrcand), SCIPgetVarAvgInferenceCutoffScore(scip, bestaggrcand, cutoffweight), SCIPgetVarAvgInferenceScore(scip, bestaggrcand)); /* perform the branching */ if( candsols != NULL ) { SCIP_CALL( SCIPbranchVarVal(scip, bestaggrcand, SCIPgetBranchingPoint(scip, bestaggrcand, bestval), &downchild, &eqchild, &upchild) ); } else if( bestbranchpoint == SCIP_UNKNOWN ) /*lint !e777*/ { SCIP_CALL( SCIPbranchVar(scip, bestaggrcand, &downchild, &eqchild, &upchild) ); } else { SCIP_Real estimate; SCIP_Real downprio; SCIP_Real upprio; SCIP_Real downub; SCIP_Real uplb; assert(bestvaluecand != NULL); downprio = 0.0; upprio = 0.0; if( bestbranchdir == SCIP_BRANCHDIR_DOWNWARDS ) { downprio = 1.0; downub = bestbranchpoint; uplb = bestbranchpoint + 1.0; } else { upprio = 1.0; downub = bestbranchpoint - 1.0; uplb = bestbranchpoint; } /* calculate the child estimate */ estimate = SCIPcalcChildEstimate(scip, bestvaluecand, downub); /* create down child */ SCIP_CALL( SCIPcreateChild(scip, &downchild, downprio, estimate) ); /* change upper bound in down child */ SCIP_CALL( SCIPchgVarUbNode(scip, downchild, bestvaluecand, downub) ); /* calculate the child estimate */ estimate = SCIPcalcChildEstimate(scip, bestvaluecand, uplb); /* create up child */ SCIP_CALL( SCIPcreateChild(scip, &upchild, upprio, estimate) ); /* change lower bound in up child */ SCIP_CALL( SCIPchgVarLbNode(scip, upchild, bestvaluecand, uplb) ); SCIPdebugMessage("branch on variable <%s> and value <%g>\n", SCIPvarGetName(bestvaluecand), bestbranchpoint); eqchild = NULL; } if( downchild != NULL || eqchild != NULL || upchild != NULL ) { *result = SCIP_BRANCHED; } else { /* if there are no children, then variable should have been fixed by SCIPbranchVar(Val) */ assert(SCIPisEQ(scip, SCIPvarGetLbLocal(bestaggrcand), SCIPvarGetUbLocal(bestaggrcand))); *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; }