/** checks whether given conflict is valid for the debugging solution */ SCIP_RETCODE SCIPdebugCheckConflict( BMS_BLKMEM* blkmem, /**< block memory */ SCIP_SET* set, /**< global SCIP settings */ SCIP_NODE* node, /**< node where the conflict clause is added */ SCIP_BDCHGINFO** bdchginfos, /**< bound change informations of the conflict set */ int nbdchginfos /**< number of bound changes in the conflict set */ ) { SCIP_Real solval; SCIP_Bool solcontained; int i; assert(set != NULL); assert(blkmem != NULL); assert(node != NULL); assert(nbdchginfos == 0 || bdchginfos != 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 whether the debugging solution is contained in the local subproblem */ SCIP_CALL( isSolutionInNode(blkmem, set, node, &solcontained) ); if( !solcontained ) return SCIP_OKAY; /* check, whether at least one literals is TRUE in the debugging solution */ for( i = 0; i < nbdchginfos; ++i ) { SCIP_VAR* var; SCIP_Real newbound; var = SCIPbdchginfoGetVar(bdchginfos[i]); newbound = SCIPbdchginfoGetNewbound(bdchginfos[i]); SCIP_CALL( getSolutionValue(set, var, &solval) ); if( solval == SCIP_UNKNOWN ) /*lint !e777*/ return SCIP_OKAY; if( SCIPbdchginfoGetBoundtype(bdchginfos[i]) == SCIP_BOUNDTYPE_LOWER ) { if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ) { if( SCIPsetIsLE(set, solval, newbound) ) return SCIP_OKAY; } else { if( SCIPsetIsLT(set, solval, newbound) ) return SCIP_OKAY; } } else { if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ) { if( SCIPsetIsGE(set, solval, newbound) ) return SCIP_OKAY; } else { if( SCIPsetIsGT(set, solval, newbound) ) return SCIP_OKAY; } } } SCIPerrorMessage("invalid conflict set:"); for( i = 0; i < nbdchginfos; ++i ) { SCIP_CALL( getSolutionValue(set, SCIPbdchginfoGetVar(bdchginfos[i]), &solval) ); printf(" <%s>[%.15g] %s %g", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfos[i])), solval, SCIPbdchginfoGetBoundtype(bdchginfos[i]) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", SCIPbdchginfoGetNewbound(bdchginfos[i])); } printf("\n"); SCIPABORT(); return SCIP_OKAY; /*lint !e527*/ }
/** update the primal-dual integral statistic. method accepts + and - SCIPsetInfinity() as values for * upper and lower bound, respectively */ void SCIPstatUpdatePrimalDualIntegral( SCIP_STAT* stat, /**< problem statistics data */ SCIP_SET* set, /**< global SCIP settings */ SCIP_PROB* transprob, /**< transformed problem */ SCIP_PROB* origprob, /**< original problem */ SCIP_Real upperbound, /**< current upper bound in transformed problem, or infinity */ SCIP_Real lowerbound /**< current lower bound in transformed space, or -infinity */ ) { SCIP_Real currentgap; SCIP_Real solvingtime; SCIP_Real primalbound; SCIP_Real dualbound; assert(stat != NULL); assert(set != NULL); solvingtime = SCIPclockGetTime(stat->solvingtime); assert(solvingtime >= stat->previntegralevaltime); if( !SCIPsetIsInfinity(set, upperbound) ) /*lint !e777*/ { /* get value in original space for gap calculation */ primalbound = SCIPprobExternObjval(transprob, origprob, set, upperbound); if( SCIPsetIsZero(set, primalbound) ) primalbound = 0.0; } else { /* no new upper bound: use stored values from last update */ upperbound = stat->lastupperbound; primalbound = stat->lastprimalbound; assert(SCIPsetIsZero(set, primalbound) == (primalbound == 0.0)); /*lint !e777*/ } if( !SCIPsetIsInfinity(set, -lowerbound) ) /*lint !e777*/ { /* get value in original space for gap calculation */ dualbound = SCIPprobExternObjval(transprob, origprob, set, lowerbound); if( SCIPsetIsZero(set, dualbound) ) dualbound = 0.0; } else { /* no new lower bound: use stored values from last update */ lowerbound = stat->lastlowerbound; dualbound = stat->lastdualbound; assert(SCIPsetIsZero(set, dualbound) == (dualbound == 0.0)); /*lint !e777*/ } /* computation of the gap, special cases are handled first */ if( primalbound == SCIP_UNKNOWN || dualbound == SCIP_UNKNOWN ) /*lint !e777*/ currentgap = 100.0; /* the gap is 0.0 if bounds coincide */ else if( SCIPsetIsGE(set, lowerbound, upperbound) || SCIPsetIsEQ(set, primalbound, dualbound) ) currentgap = 0.0; /* the gap is 100.0 if bounds have different signs */ else if( primalbound * dualbound <= 0.0 ) /*lint !e777*/ currentgap = 100.0; else if( !SCIPsetIsInfinity(set, REALABS(primalbound)) && !SCIPsetIsInfinity(set, REALABS(dualbound)) ) { SCIP_Real absprim = REALABS(primalbound); SCIP_Real absdual = REALABS(dualbound); /* The gap in the definition of the primal-dual integral differs from the default SCIP gap function. * Here, the MAX(primalbound, dualbound) is taken for gap quotient in order to ensure a gap <= 100. */ currentgap = 100.0 * REALABS(primalbound - dualbound) / MAX(absprim, absdual); assert(SCIPsetIsLE(set, currentgap, 100.0)); } else currentgap = 100.0; /* if primal and dual bound have opposite signs, the gap always evaluates to 100.0% */ assert(currentgap == 0.0 || currentgap == 100.0 || SCIPsetIsGE(set, primalbound * dualbound, 0.0)); assert(SCIPsetIsGE(set, stat->previousgap, currentgap) || (set->stage == SCIP_STAGE_EXITPRESOLVE && SCIPsetIsFeasGE(set, stat->previousgap, currentgap))); /* update the integral based on previous information */ stat->primaldualintegral += (solvingtime - stat->previntegralevaltime) * stat->previousgap; /* update all relevant information for next evaluation */ stat->previousgap = currentgap; stat->previntegralevaltime = solvingtime; stat->lastprimalbound = primalbound; stat->lastdualbound = dualbound; stat->lastlowerbound = lowerbound; stat->lastupperbound = upperbound; }
/** returns whether the debug solution is worse as the best known solution or if the debug solution was found */ static SCIP_Bool debugSolIsAchieved( SCIP_SET* set /**< global SCIP settings */ ) { SCIP_SOL* bestsol; SCIP* scip; if( solisachieved ) return TRUE; assert(set != NULL); scip = set->scip; assert(scip != NULL); bestsol = SCIPgetBestSol(scip); if( bestsol != NULL ) { SCIP_Real solvalue; /* don't check solution while in problem creation stage */ if( SCIPsetGetStage(set) == SCIP_STAGE_PROBLEM ) return TRUE; solvalue = SCIPgetSolOrigObj(scip, bestsol); /* make sure a debug solution has been read, so we do not compare against the initial debugsolval == 0 */ SCIP_CALL( readSolution(set) ); if( (SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE && SCIPsetIsLE(set, solvalue, debugsolval)) || (SCIPgetObjsense(scip) == SCIP_OBJSENSE_MAXIMIZE && SCIPsetIsGE(set, solvalue, debugsolval)) ) solisachieved = TRUE; } return solisachieved; }