/** checks if a given branching candidate is better than a previous one and updates the best branching candidate accordingly */ static SCIP_RETCODE updateBestCandidate( SCIP* scip, /**< SCIP data structure */ SCIP_BRANCHRULEDATA* branchruledata, /**< branching rule data */ SCIP_VAR** bestvar, /**< best branching candidate */ SCIP_Real* bestbrpoint, /**< branching point for best branching candidate */ SCIP_Real* bestscore, /**< score of best branching candidate */ SCIP_VAR* cand, /**< branching candidate to consider */ SCIP_Real candscoremin, /**< minimal score of branching candidate */ SCIP_Real candscoremax, /**< maximal score of branching candidate */ SCIP_Real candscoresum, /**< sum of scores of branching candidate */ SCIP_Real candsol /**< proposed branching point of branching candidate */ ) { SCIP_Real candbrpoint; SCIP_Real branchscore; SCIP_Real deltaminus; SCIP_Real deltaplus; SCIP_Real pscostdown; SCIP_Real pscostup; char strategy; assert(scip != NULL); assert(branchruledata != NULL); assert(bestvar != NULL); assert(bestbrpoint != NULL); assert(bestscore != NULL); assert(cand != NULL); /* a branching variable candidate should either be an active problem variable or a multi-aggregated variable */ assert(SCIPvarIsActive(SCIPvarGetProbvar(cand)) || SCIPvarGetStatus(SCIPvarGetProbvar(cand)) == SCIP_VARSTATUS_MULTAGGR); if( SCIPvarGetStatus(SCIPvarGetProbvar(cand)) == SCIP_VARSTATUS_MULTAGGR ) { /* for a multi-aggregated variable, we call updateBestCandidate function recursively with all variables in the multi-aggregation */ SCIP_VAR** multvars; int nmultvars; int i; SCIP_Bool success; SCIP_Real multvarlb; SCIP_Real multvarub; cand = SCIPvarGetProbvar(cand); multvars = SCIPvarGetMultaggrVars(cand); nmultvars = SCIPvarGetMultaggrNVars(cand); /* if we have a candidate branching point, then first register only aggregation variables * for which we can compute a corresponding branching point too (see also comments below) * if this fails, then register all (unfixed) aggregation variables, thereby forgetting about candsol */ success = FALSE; if( candsol != SCIP_INVALID ) /*lint !e777*/ { SCIP_Real* multscalars; SCIP_Real minact; SCIP_Real maxact; SCIP_Real aggrvarsol; SCIP_Real aggrvarsol1; SCIP_Real aggrvarsol2; multscalars = SCIPvarGetMultaggrScalars(cand); /* for computing the branching point, we need the current bounds of the multi-aggregated variable */ minact = SCIPcomputeVarLbLocal(scip, cand); maxact = SCIPcomputeVarUbLocal(scip, cand); for( i = 0; i < nmultvars; ++i ) { /* skip fixed variables */ multvarlb = SCIPcomputeVarLbLocal(scip, multvars[i]); multvarub = SCIPcomputeVarUbLocal(scip, multvars[i]); if( SCIPisEQ(scip, multvarlb, multvarub) ) continue; assert(multscalars != NULL); assert(multscalars[i] != 0.0); /* we cannot ensure that both the upper bound in the left node and the lower bound in the right node * will be candsol by a clever choice for the branching point of multvars[i], * but we can try to ensure that at least one of them will be at candsol */ if( multscalars[i] > 0.0 ) { /* cand >= candsol * if multvars[i] >= (candsol - (maxact - multscalars[i] * ub(multvars[i]))) / multscalars[i] * = (candsol - maxact) / multscalars[i] + ub(multvars[i]) */ aggrvarsol1 = (candsol - maxact) / multscalars[i] + multvarub; /* cand <= candsol * if multvars[i] <= (candsol - (minact - multscalar[i] * lb(multvars[i]))) / multscalars[i] * = (candsol - minact) / multscalars[i] + lb(multvars[i]) */ aggrvarsol2 = (candsol - minact) / multscalars[i] + multvarlb; } else { /* cand >= candsol * if multvars[i] <= (candsol - (maxact - multscalars[i] * lb(multvars[i]))) / multscalars[i] * = (candsol - maxact) / multscalars[i] + lb(multvars[i]) */ aggrvarsol2 = (candsol - maxact) / multscalars[i] + multvarlb; /* cand <= candsol * if multvars[i] >= (candsol - (minact - multscalar[i] * ub(multvars[i]))) / multscalars[i] * = (candsol - minact) / multscalars[i] + ub(multvars[i]) */ aggrvarsol1 = (candsol - minact) / multscalars[i] + multvarub; } /* by the above choice, aggrvarsol1 <= ub(multvars[i]) and aggrvarsol2 >= lb(multvars[i]) * if aggrvarsol1 <= lb(multvars[i]) or aggrvarsol2 >= ub(multvars[i]), then choose the other one * if both are out of bounds, then give up * if both are inside bounds, then choose the one closer to 0.0 (someone has better idea???) */ if( SCIPisFeasLE(scip, aggrvarsol1, multvarlb) ) { if( SCIPisFeasGE(scip, aggrvarsol2, multvarub) ) continue; else aggrvarsol = aggrvarsol2; } else { if( SCIPisFeasGE(scip, aggrvarsol2, multvarub) ) aggrvarsol = aggrvarsol1; else aggrvarsol = REALABS(aggrvarsol1) < REALABS(aggrvarsol2) ? aggrvarsol1 : aggrvarsol2; } success = TRUE; SCIP_CALL( updateBestCandidate(scip, branchruledata, bestvar, bestbrpoint, bestscore, multvars[i], candscoremin, candscoremax, candscoresum, aggrvarsol) ); } } if( !success ) for( i = 0; i < nmultvars; ++i ) { /* skip fixed variables */ multvarlb = SCIPcomputeVarLbLocal(scip, multvars[i]); multvarub = SCIPcomputeVarUbLocal(scip, multvars[i]); if( SCIPisEQ(scip, multvarlb, multvarub) ) continue; SCIP_CALL( updateBestCandidate(scip, branchruledata, bestvar, bestbrpoint, bestscore, multvars[i], candscoremin, candscoremax, candscoresum, SCIP_INVALID) ); } assert(*bestvar != NULL); /* if all variables were fixed, something is strange */ return SCIP_OKAY; } /* select branching point for this variable */ candbrpoint = SCIPgetBranchingPoint(scip, cand, candsol); assert(candbrpoint >= SCIPvarGetLbLocal(cand)); assert(candbrpoint <= SCIPvarGetUbLocal(cand)); /* we cannot branch on a huge value for a discrete variable, because we simply cannot enumerate such huge integer values in floating point * arithmetics */ if( SCIPvarGetType(cand) != SCIP_VARTYPE_CONTINUOUS && (SCIPisHugeValue(scip, candbrpoint) || SCIPisHugeValue(scip, -candbrpoint)) ) return SCIP_OKAY; assert(SCIPvarGetType(cand) == SCIP_VARTYPE_CONTINUOUS || !SCIPisIntegral(scip, candbrpoint)); if( SCIPvarGetType(cand) == SCIP_VARTYPE_CONTINUOUS ) strategy = (branchruledata->strategy == 'u' ? branchruledata->updatestrategy : branchruledata->strategy); else strategy = (branchruledata->strategy == 'u' ? 'l' : branchruledata->strategy); switch( strategy ) { case 'l': if( SCIPisInfinity(scip, SCIPgetSolVal(scip, NULL, cand)) || SCIPgetSolVal(scip, NULL, cand) <= SCIPadjustedVarUb(scip, cand, candbrpoint) ) deltaminus = 0.0; else deltaminus = SCIPgetSolVal(scip, NULL, cand) - SCIPadjustedVarUb(scip, cand, candbrpoint); if( SCIPisInfinity(scip, -SCIPgetSolVal(scip, NULL, cand)) || SCIPgetSolVal(scip, NULL, cand) >= SCIPadjustedVarLb(scip, cand, candbrpoint) ) deltaplus = 0.0; else deltaplus = SCIPadjustedVarLb(scip, cand, candbrpoint) - SCIPgetSolVal(scip, NULL, cand); break; case 'd': if( SCIPisInfinity(scip, -SCIPvarGetLbLocal(cand)) ) deltaminus = SCIPisInfinity(scip, candscoremax) ? SCIPinfinity(scip) : WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum); else deltaminus = SCIPadjustedVarUb(scip, cand, candbrpoint) - SCIPvarGetLbLocal(cand); if( SCIPisInfinity(scip, SCIPvarGetUbLocal(cand)) ) deltaplus = SCIPisInfinity(scip, candscoremax) ? SCIPinfinity(scip) : WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum); else deltaplus = SCIPvarGetUbLocal(cand) - SCIPadjustedVarLb(scip, cand, candbrpoint); break; case 's': if( SCIPisInfinity(scip, -SCIPvarGetLbLocal(cand)) ) deltaplus = SCIPisInfinity(scip, candscoremax) ? SCIPinfinity(scip) : WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum); else deltaplus = SCIPadjustedVarUb(scip, cand, candbrpoint) - SCIPvarGetLbLocal(cand); if( SCIPisInfinity(scip, SCIPvarGetUbLocal(cand)) ) deltaminus = SCIPisInfinity(scip, candscoremax) ? SCIPinfinity(scip) : WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum); else deltaminus = SCIPvarGetUbLocal(cand) - SCIPadjustedVarLb(scip, cand, candbrpoint); break; case 'v': deltaplus = SCIPisInfinity(scip, candscoremax) ? SCIPinfinity(scip) : WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum); deltaminus = deltaplus; break; default : SCIPerrorMessage("branching strategy %c unknown\n", strategy); SCIPABORT(); return SCIP_INVALIDDATA; /*lint !e527*/ } if( SCIPisInfinity(scip, deltaminus) || SCIPisInfinity(scip, deltaplus) ) { branchscore = SCIPinfinity(scip); } else { pscostdown = SCIPgetVarPseudocostVal(scip, cand, -deltaminus); pscostup = SCIPgetVarPseudocostVal(scip, cand, deltaplus); branchscore = SCIPgetBranchScore(scip, cand, pscostdown, pscostup); assert(!SCIPisNegative(scip, branchscore)); } SCIPdebugMessage("branching score variable <%s>[%g,%g] = %g; wscore = %g; type=%d bestbrscore=%g\n", SCIPvarGetName(cand), SCIPvarGetLbLocal(cand), SCIPvarGetUbLocal(cand), branchscore, WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum), SCIPvarGetType(cand), *bestscore); if( SCIPisInfinity(scip, branchscore) ) branchscore = 0.9*SCIPinfinity(scip); if( SCIPisSumGT(scip, branchscore, *bestscore) ) { (*bestscore) = branchscore; (*bestvar) = cand; (*bestbrpoint) = candbrpoint; } else if( SCIPisSumEQ(scip, branchscore, *bestscore) && !(SCIPisInfinity(scip, -SCIPvarGetLbLocal(*bestvar)) && SCIPisInfinity(scip, SCIPvarGetUbLocal(*bestvar))) ) { /* if best candidate so far is not unbounded to both sides, maybe take new candidate */ if( (SCIPisInfinity(scip, -SCIPvarGetLbLocal(cand)) || SCIPisInfinity(scip, SCIPvarGetUbLocal(cand))) && (SCIPisInfinity(scip, -SCIPvarGetLbLocal(*bestvar)) || SCIPisInfinity(scip, SCIPvarGetUbLocal(*bestvar))) ) { /* if both variables are unbounded but one of them is bounded on one side, take the one with the larger bound on this side (hope that this avoids branching on always the same variable) */ if( SCIPvarGetUbLocal(cand) > SCIPvarGetUbLocal(*bestvar) || SCIPvarGetLbLocal(cand) < SCIPvarGetLbLocal(*bestvar) ) { (*bestscore) = branchscore; (*bestvar) = cand; (*bestbrpoint) = candbrpoint; } } else if( SCIPvarGetType(*bestvar) == SCIPvarGetType(cand) ) { /* if both have the same type, take the one with larger diameter */ if( SCIPvarGetUbLocal(*bestvar) - SCIPvarGetLbLocal(*bestvar) < SCIPvarGetUbLocal(cand) - SCIPvarGetLbLocal(cand) ) { (*bestscore) = branchscore; (*bestvar) = cand; (*bestbrpoint) = candbrpoint; } } else if( SCIPvarGetType(*bestvar) > SCIPvarGetType(cand) ) { /* take the one with better type ("more discrete") */ (*bestscore) = branchscore; (*bestvar) = cand; (*bestbrpoint) = candbrpoint; } } return SCIP_OKAY; }
/** selects a random active variable from a given list of variables */ static void getRandomVariable( SCIP* scip, /**< SCIP data structure */ SCIP_VAR** cands, /**< array of branching candidates */ SCIP_Real* candssol, /**< relaxation solution values of branching candidates, or NULL */ int ncands, /**< number of branching candidates */ SCIP_VAR** bestcand, /**< buffer to store pointer to best candidate */ SCIP_Real* bestcandsol, /**< buffer to store solution value of best candidate */ unsigned int* seed /**< seed for random number generator */ ) { int idx; int firstidx; assert(scip != NULL); assert(cands != NULL); assert(ncands > 0); assert(bestcand != NULL); assert(bestcandsol != NULL); assert(seed != NULL); idx = SCIPgetRandomInt(0, ncands-1, seed); assert(idx >= 0); /* handle case where cands[idx] is fixed by selecting next idx with unfixed var * this may happen if we are inside a multi-aggregation */ firstidx = idx; while( SCIPisEQ(scip, SCIPvarGetLbLocal(cands[idx]), SCIPvarGetUbLocal(cands[idx])) ) { ++idx; if( idx == ncands ) idx = 0; if( idx == firstidx ) { /* odd: all variables seem to be fixed */ SCIPdebugMessage("Warning: all branching candidates seem to be fixed\n"); return; } } /* a branching variable candidate should either be an active problem variable or a multi-aggregated variable */ assert(SCIPvarIsActive(SCIPvarGetProbvar(cands[idx])) || SCIPvarGetStatus(SCIPvarGetProbvar(cands[idx])) == SCIP_VARSTATUS_MULTAGGR); if( SCIPvarGetStatus(SCIPvarGetProbvar(cands[idx])) == SCIP_VARSTATUS_MULTAGGR ) { /* for a multi-aggregated variable, we call the getRandomVariable function recursively with all variables in the multi-aggregation */ SCIP_VAR* cand; cand = SCIPvarGetProbvar(cands[idx]); getRandomVariable(scip, SCIPvarGetMultaggrVars(cand), NULL, SCIPvarGetMultaggrNVars(cand), bestcand, bestcandsol, seed); return; } assert(idx >= 0 && idx < ncands); *bestcand = cands[idx]; assert(*bestcand != NULL); if( candssol != NULL ) *bestcandsol = candssol[idx]; }
/** compares the so far best branching candidate with a new candidate and updates best candidate, if new candidate is better */ static void updateBestCandidate( SCIP* scip, /**< SCIP data structure */ SCIP_VAR** bestvar, /**< best branching candidate */ SCIP_Real* bestscore, /**< score of best branching candidate */ SCIP_Real* bestobj, /**< absolute objective value of best branching candidate */ SCIP_Real* bestsol, /**< proposed branching point of best branching candidate */ SCIP_VAR* cand, /**< branching candidate to consider */ SCIP_Real candscore, /**< scoring of branching candidate */ SCIP_Real candsol /**< proposed branching point of branching candidate */ ) { SCIP_Real obj; assert(scip != NULL); assert(bestvar != NULL); assert(bestscore != NULL); assert(bestobj != NULL); assert(*bestobj >= 0.0); assert(cand != NULL); /* a branching variable candidate should either be an active problem variable or a multi-aggregated variable */ assert(SCIPvarIsActive(SCIPvarGetProbvar(cand)) || SCIPvarGetStatus(SCIPvarGetProbvar(cand)) == SCIP_VARSTATUS_MULTAGGR); if( SCIPvarGetStatus(SCIPvarGetProbvar(cand)) == SCIP_VARSTATUS_MULTAGGR ) { /* for a multi-aggregated variable, we call updateBestCandidate function recursively with all variables in the multi-aggregation */ SCIP_VAR** multvars; int nmultvars; int i; SCIP_Bool success; SCIP_Real multvarlb; SCIP_Real multvarub; cand = SCIPvarGetProbvar(cand); multvars = SCIPvarGetMultaggrVars(cand); nmultvars = SCIPvarGetMultaggrNVars(cand); /* if we have a candidate branching point, then first register only aggregation variables * for which we can compute a corresponding branching point too (see also comments below) * if this fails, then register all (unfixed) aggregation variables, thereby forgetting about candsol */ success = FALSE; if( candsol != SCIP_INVALID ) /*lint !e777*/ { SCIP_Real* multscalars; SCIP_Real minact; SCIP_Real maxact; SCIP_Real aggrvarsol; SCIP_Real aggrvarsol1; SCIP_Real aggrvarsol2; multscalars = SCIPvarGetMultaggrScalars(cand); /* for computing the branching point, we need the current bounds of the multi-aggregated variable */ minact = SCIPcomputeVarLbLocal(scip, cand); maxact = SCIPcomputeVarUbLocal(scip, cand); for( i = 0; i < nmultvars; ++i ) { /* skip fixed variables */ multvarlb = SCIPcomputeVarLbLocal(scip, multvars[i]); multvarub = SCIPcomputeVarUbLocal(scip, multvars[i]); if( SCIPisEQ(scip, multvarlb, multvarub) ) continue; assert(multscalars != NULL); assert(multscalars[i] != 0.0); /* we cannot ensure that both the upper bound in the left node and the lower bound in the right node * will be candsol by a clever choice for the branching point of multvars[i], * but we can try to ensure that at least one of them will be at candsol */ if( multscalars[i] > 0.0 ) { /* cand >= candsol * if multvars[i] >= (candsol - (maxact - multscalars[i] * ub(multvars[i]))) / multscalars[i] * = (candsol - maxact) / multscalars[i] + ub(multvars[i]) */ aggrvarsol1 = (candsol - maxact) / multscalars[i] + multvarub; /* cand <= candsol * if multvars[i] <= (candsol - (minact - multscalar[i] * lb(multvars[i]))) / multscalars[i] * = (candsol - minact) / multscalars[i] + lb(multvars[i]) */ aggrvarsol2 = (candsol - minact) / multscalars[i] + multvarlb; } else { /* cand >= candsol * if multvars[i] <= (candsol - (maxact - multscalars[i] * lb(multvars[i]))) / multscalars[i] * = (candsol - maxact) / multscalars[i] + lb(multvars[i]) */ aggrvarsol2 = (candsol - maxact) / multscalars[i] + multvarlb; /* cand <= candsol * if multvars[i] >= (candsol - (minact - multscalar[i] * ub(multvars[i]))) / multscalars[i] * = (candsol - minact) / multscalars[i] + ub(multvars[i]) */ aggrvarsol1 = (candsol - minact) / multscalars[i] + multvarub; } /* by the above choice, aggrvarsol1 <= ub(multvars[i]) and aggrvarsol2 >= lb(multvars[i]) * if aggrvarsol1 <= lb(multvars[i]) or aggrvarsol2 >= ub(multvars[i]), then choose the other one * if both are out of bounds, then give up * if both are inside bounds, then choose the one closer to 0.0 (someone has better idea???) */ if( SCIPisFeasLE(scip, aggrvarsol1, multvarlb) ) { if( SCIPisFeasGE(scip, aggrvarsol2, multvarub) ) continue; else aggrvarsol = aggrvarsol2; } else { if( SCIPisFeasGE(scip, aggrvarsol2, multvarub) ) aggrvarsol = aggrvarsol1; else aggrvarsol = REALABS(aggrvarsol1) < REALABS(aggrvarsol2) ? aggrvarsol1 : aggrvarsol2; } success = TRUE; updateBestCandidate(scip, bestvar, bestscore, bestobj, bestsol, multvars[i], candscore, aggrvarsol); } } if( !success ) for( i = 0; i < nmultvars; ++i ) { /* skip fixed variables */ multvarlb = SCIPcomputeVarLbLocal(scip, multvars[i]); multvarub = SCIPcomputeVarUbLocal(scip, multvars[i]); if( SCIPisEQ(scip, multvarlb, multvarub) ) continue; updateBestCandidate(scip, bestvar, bestscore, bestobj, bestsol, multvars[i], candscore, SCIP_INVALID); } assert(*bestvar != NULL); /* if all variables were fixed, something is strange */ return; } candscore *= SCIPvarGetBranchFactor(cand); obj = SCIPvarGetObj(cand); obj = REALABS(obj); if( SCIPisInfinity(scip, *bestscore) || (!SCIPisInfinity(scip, candscore) && (SCIPisLT(scip, candscore, *bestscore) || (SCIPisLE(scip, candscore, *bestscore) && obj > *bestobj))) ) { *bestvar = cand; *bestscore = candscore; *bestobj = obj; *bestsol = candsol; } }
/** problem writing method of reader */ static SCIP_DECL_READERWRITE(readerWriteCip) { /*lint --e{715}*/ SCIP_HASHTABLE* varhash = NULL; SCIP_READERDATA* readerdata; int i; assert(reader != NULL); assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0); SCIPinfoMessage(scip, file, "STATISTICS\n"); SCIPinfoMessage(scip, file, " Problem name : %s\n", name); SCIPinfoMessage(scip, file, " Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n", nvars, nbinvars, nintvars, nimplvars, ncontvars); SCIPinfoMessage(scip, file, " Constraints : %d initial, %d maximal\n", startnconss, maxnconss); SCIPinfoMessage(scip, file, "OBJECTIVE\n"); SCIPinfoMessage(scip, file, " Sense : %s\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "minimize" : "maximize"); if( !SCIPisZero(scip, objoffset) ) SCIPinfoMessage(scip, file, " Offset : %+.15g\n", objoffset); if( !SCIPisEQ(scip, objscale, 1.0) ) SCIPinfoMessage(scip, file, " Scale : %.15g\n", objscale); if ( nfixedvars > 0 ) { /* set up hash table for variables that have been written property (used for writing out fixed vars in the right order) */ SCIP_CALL( SCIPhashtableCreate(&varhash, SCIPblkmem(scip), SCIPcalcHashtableSize(10 * (nvars + nfixedvars)), hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) ); } if ( nvars + nfixedvars > 0 ) { SCIPinfoMessage(scip, file, "VARIABLES\n"); } if( nvars > 0 ) { for( i = 0; i < nvars; ++i ) { SCIP_VAR* var; var = vars[i]; assert( var != NULL ); SCIP_CALL( SCIPprintVar(scip, var, file) ); if ( varhash != NULL ) { /* add free variable to hashtable */ if ( ! SCIPhashtableExists(varhash, (void*) var) ) { SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) ); } } } } readerdata = SCIPreaderGetData(reader); assert(readerdata != NULL); if( readerdata->writefixedvars && nfixedvars > 0 ) { int nwritten = 0; SCIPinfoMessage(scip, file, "FIXED\n"); /* loop through variables until each has been written after the variables that it depends on have been written; this * requires several runs over the variables, but the depth (= number of loops) is usually small. */ while ( nwritten < nfixedvars ) { SCIPdebugMessage("written %d of %d fixed variables.\n", nwritten, nfixedvars); for (i = 0; i < nfixedvars; ++i) { SCIP_VAR* var; SCIP_VAR* tmpvar; var = fixedvars[i]; assert( var != NULL ); /* skip variables already written */ if ( SCIPhashtableExists(varhash, (void*) var) ) continue; switch ( SCIPvarGetStatus(var) ) { case SCIP_VARSTATUS_FIXED: /* fixed variables can simply be output and added to the hashtable */ SCIP_CALL( SCIPprintVar(scip, var, file) ); assert( ! SCIPhashtableExists(varhash, (void*) var) ); SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) ); ++nwritten; break; case SCIP_VARSTATUS_NEGATED: tmpvar = SCIPvarGetNegationVar(var); assert( tmpvar != NULL ); assert( var == SCIPvarGetNegatedVar(tmpvar) ); /* if the negated variable has been written, we can write the current variable */ if ( SCIPhashtableExists(varhash, (void*) tmpvar) ) { SCIP_CALL( SCIPprintVar(scip, var, file) ); assert( ! SCIPhashtableExists(varhash, (void*) var) ); SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) ); ++nwritten; } break; case SCIP_VARSTATUS_AGGREGATED: tmpvar = SCIPvarGetAggrVar(var); assert( tmpvar != NULL ); /* if the aggregating variable has been written, we can write the current variable */ if ( SCIPhashtableExists(varhash, (void*) tmpvar) ) { SCIP_CALL( SCIPprintVar(scip, var, file) ); assert( ! SCIPhashtableExists(varhash, (void*) var) ); SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) ); ++nwritten; } break; case SCIP_VARSTATUS_MULTAGGR: { SCIP_VAR** aggrvars; int naggrvars; int j; /* get the active representation */ SCIP_CALL( SCIPflattenVarAggregationGraph(scip, var) ); naggrvars = SCIPvarGetMultaggrNVars(var); aggrvars = SCIPvarGetMultaggrVars(var); assert(aggrvars != NULL || naggrvars == 0); for (j = 0; j < naggrvars; ++j) { if( !SCIPhashtableExists(varhash, (void*) aggrvars[j]) ) /*lint !e613*/ break; } /* if all multi-aggregating variables have been written, we can write the current variable */ if ( j >= naggrvars ) { SCIP_CALL( SCIPprintVar(scip, var, file) ); assert( ! SCIPhashtableExists(varhash, (void*) var) ); SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) ); ++nwritten; } break; } case SCIP_VARSTATUS_ORIGINAL: case SCIP_VARSTATUS_LOOSE: case SCIP_VARSTATUS_COLUMN: SCIPerrorMessage("Only fixed variables are allowed to be present in fixedvars list.\n"); SCIPABORT(); return SCIP_ERROR; /*lint !e527*/ } } } } if( nconss > 0 ) { SCIPinfoMessage(scip, file, "CONSTRAINTS\n"); for( i = 0; i < nconss; ++i ) { SCIP_CALL( SCIPprintCons(scip, conss[i], file) ); SCIPinfoMessage(scip, file, ";\n"); } } SCIPinfoMessage(scip, file, "END\n"); *result = SCIP_SUCCESS; if( nfixedvars > 0 ) SCIPhashtableFree(&varhash); else assert(varhash == NULL); return SCIP_OKAY; }