cons_pseudoboolean.c
Go to the documentation of this file.
24 * The constraint handler deals with pseudo Boolean constraints. These are constraints of the form
26 * \mbox{lhs} \leq \sum_{k=0}^m c_k \cdot x_k + \sum_{i=0}^n c_i \cdot \prod_{j \in I_i} x_j \leq \mbox{rhs}
33 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
71 #define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
72 #define CONSHDLR_CHECKPRIORITY -5000000 /**< priority of the constraint handler for checking feasibility */
73 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
75 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
76 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
78 #define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
80 #define DEFAULT_DECOMPOSENORMALPBCONS FALSE /**< decompose all normal pseudo boolean constraint into a "linear" constraint and "and" constraints */
81 #define DEFAULT_DECOMPOSEINDICATORPBCONS TRUE /**< decompose all indicator pseudo boolean constraint into a "linear" constraint and "and" constraints */
83 #define DEFAULT_SEPARATENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be separated during LP processing */
84 #define DEFAULT_PROPAGATENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be propagated during node processing */
85 #define DEFAULT_REMOVABLENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be removable */
95 #define HASHSIZE_PSEUDOBOOLEANNONLINEARTERMS 500 /**< minimal size of hash table in and constraint tables */
98 /* - create special linear(knapsack, setppc, logicor, (eqknapsack)) and and-constraints with check flags FALSE, to
99 * get smaller amount of locks on the term variables, do all presolving ...?! in these constraint handlers
101 * - do the checking here, lock and-resultants in both directions and all and-variables according to their
103 * @note this only works if the and-resultant has no objective cofficient, otherwise we need to lock variables also in both directions
105 * - need to keep and constraint pointer for special propagations like if two ands are due to their variables in
109 * check/IP/PseudoBoolean/normalized-PB07/OPT-SMALLINT-NLC/submittedPB07/manquinho/bsg/normalized-bsg_1000_25_1.opb.gz
115 * which "equals" a pseudoboolean constraint: 2 x1 + 2 x2 + 1 x3 x4 + 1 x5 x6 x7 + 1 x8 x9 <= 5 ;
119 * which "equals" a pseudoboolean constraint: 2 x1 + 2 x2 + 1 x3 x4 + 1 x5 x6 x7 + 1 x8 x9 <= 6 ;
130 /* @todo - in and-constraint better count nfixed zeros in both directions and maybe nfixedones for better propagation
132 * - do better conflict analysis by choosing the earliest fixed variable which led to a conflict instead of maybe
135 * - how to make sure that we aggregate in a right way, when aggregating a resultant and a "normal" variable,
136 * maybe add in SCIPaggregateVars a check for original variables, to prefer them if the variable type is the
137 * same; probably it would be better too if we would aggregate two resultants that the one with less variables
140 * @note since product resultants are artificial, we do not care for their solution value, but this can lead to fixation
141 * of the resultant not representing the product, in 'optimization mode' we do not care, but this might make
147 {
161 };
171 SCIP_LINEARCONSTYPE linconstype; /**< type of linear constraint which represents this pseudoboolean constraint */
205 CONSANDDATA** allconsanddatas; /**< array of all and-constraint data objects inside the whole problem,
217 SCIP_Bool decomposenormalpbcons;/**< decompose the pseudo boolean constraint into a "linear" constraint and "and" constraints */
218 SCIP_Bool decomposeindicatorpbcons;/**< decompose the indicator pseudo boolean constraint into a "linear" constraint and "and" constraints */
229 /** comparison method for sorting consanddatas according to the index of their corresponding resultant variables, if a
230 * consanddata object is delete it is handled like it has an inactive resultant, so this will be put in front while
235 {
302 /** returns TRUE iff both keys are equal; two non-linear terms are equal if they have the same variables */
305 {
394 /** initializes the hashmap and -table used in this constraint handler data for artificial variables and specific
416 SCIP_CALL( SCIPhashtableCreate(&((*conshdlrdata)->hashtable), SCIPblkmem(scip), (*conshdlrdata)->hashtablesize,
421 SCIP_CALL( SCIPhashmapCreate(&((*conshdlrdata)->hashmap), SCIPblkmem(scip), (*conshdlrdata)->hashmapsize) );
444 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((*conshdlrdata)->allconsanddatas), (*conshdlrdata)->sallconsanddatas ) );
491 SCIPfreeBlockMemoryArray(scip, &((*conshdlrdata)->allconsanddatas), (*conshdlrdata)->sallconsanddatas );
614 SCIP_VAR**const vars, /**< array to store sorted (after indices) variables of linear constraint */
768 /** calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
769 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
779 SCIP_VAR**const linvars, /**< array to store not and-resultant variables of linear constraint, or NULL */
780 SCIP_Real*const lincoefs, /**< array to store coefficients of not and-resultant variables of linear
783 SCIP_VAR**const andress, /**< array to store and-resultant variables of linear constraint, or NULL */
786 SCIP_Bool*const andnegs, /**< array to store negation status of and-resultant variables of linear
815 /* @note it is necessary that the linear constraint is merged (not needed for negated variables) and sorted after
843 /* if and resultant is not a resultant anymore (meaning the corresponding and-constraint was deleted/upgraded),
850 CONSANDDATA* consanddata = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)(hashmapvar));
954 SCIP_CALL_ABORT( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &newlhs, &newrhs) );
976 SCIP_CALL_ABORT( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
980 SCIP_CALL_ABORT( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars,
998 if( res == andresultant && consdata->andnegs[c] == andnegs[v] && consdata->andcoefs[c] == andcoefs[v] )
1001 assert(SCIPvarIsActive(res) || (SCIPvarIsNegated(res) && SCIPvarIsActive(SCIPvarGetNegationVar(res))));
1004 /* all and-resultants should be merged, so it is only allowed that each variable exists one time */
1034 /** transforming transformed consanddata object back to original space, if an corresponding original constraint exists,
1110 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(consanddata->vars), andvars, consanddata->nvars) );
1123 assert(consanddata == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddata)));
1124 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons)));
1125 assert(consanddata == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons))));
1155 assert(consanddata == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddata)));
1156 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons)));
1157 assert(consanddata == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons))));
1173 SCIP_CONS*const lincons, /**< linear constraint with artificial and-resultants representing this pseudoboolean constraint */
1175 SCIP_CONS**const andconss, /**< array of and-constraints which occur in this pseudoboolean constraint */
1177 SCIP_Bool*const andnegs, /**< negation status of and-constraints (or NULL, if no negated resultants) */
1182 SCIP_VAR* const intvar, /**< a artificial variable which was added only for the objective function,
1216 SCIPerrorMessage("left hand side of pseudo boolean constraint greater than right hand side\n");
1261 /* do not capture the and constraint when scip is in transformed mode; this automatically happens in
1288 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &((*consdata)->andcoefs), andcoefs, nandconss) );
1315 (*consdata)->consanddatas[c] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)andress[c]);
1317 assert((*consdata)->consanddatas[c]->origcons == andconss[c] || (*consdata)->consanddatas[c]->cons == andconss[c]);
1322 if( (*consdata)->consanddatas[c]->origcons != NULL && (*consdata)->consanddatas[c]->cons == NULL )
1328 /* do not capture the and constraint when scip is in transformed mode; this automatically happens in
1331 SCIP_CALL( SCIPtransformCons(scip, (*consdata)->consanddatas[c]->origcons, &((*consdata)->consanddatas[c]->cons)) );
1345 /* resort variables in transformed problem, because the order might change while tranforming */
1368 SCIPsortPtrPtrRealBool((void**)andress, (void**)((*consdata)->consanddatas), (*consdata)->andcoefs, (*consdata)->andnegs, SCIPvarComp, nandconss);
1433 /* count down uses and if necessary release constraints and delete data from hashtable and -map */
1449 /* if the consanddata is not used anymore, release the constraint and clear the hashmap- and table */
1463 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->cons)));
1464 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->cons)) );
1484 conshdlrdata->allconsanddatas[d] = conshdlrdata->allconsanddatas[conshdlrdata->nallconsanddatas];
1504 /* if the consanddata is not used anymore, release the constraint and clear the hashmap- and table */
1517 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)));
1518 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)) );
1550 conshdlrdata->allconsanddatas[d] = conshdlrdata->allconsanddatas[conshdlrdata->nallconsanddatas];
1617 assert(consanddatas[c] == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddatas[c])));
1618 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)));
1619 assert(consanddatas[c] == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons))));
1634 /** check the locks of an AND resultant and removes it from all global structures if the resultant is not locked anymore */
1644 /* the resultant has no locks left and might be dual fixed now, we need to delete all its cliques */
1646 && SCIPvarGetNLocksUpType(res, SCIP_LOCKTYPE_MODEL) == 0 && SCIPgetStage(scip) < SCIP_STAGE_FREETRANS )
1681 /* choose correct variable array to add locks for, we only add locks for now valid variables */
1728 CONSANDDATA*const consanddata, /**< CONSANDDATA object for which we want to delete the locks */
1833 /* more than one and-constraint is needed, otherwise this pseudoboolean constraint should be upgraded to a linear constraint */
1855 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
1858 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
1859 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
1866 /* number of variables should be consistent, number of 'real' linear variables plus number of and-constraints should
1922 SCIPinfoMessage(scip, file, " %+.15g %s<%s>[B]", andcoefs[v], negated ? "~" : "", SCIPvarGetName(aggrvar));
2005 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
2095 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, ARTIFICIALVARNAMEPREFIX"%d", conshdlrdata->nallconsanddatas);
2099 #if 1 /* @todo: check whether we want to branch on artificial variables, the test results show that it is of advantage */
2107 #if 0 /* does not work for since the value of artificial resultants must not be equal to the value computed by their
2127 if( (SCIPvarIsOriginal(resultant) || SCIPvarIsTransformedOrigvar(resultant)) && !SCIPisFeasEQ(scip, debugsolval, val) )
2129 SCIPerrorMessage("computed solution value %g for resultant <%s> violates debug solution value %g\n", val, SCIPvarGetName(resultant), debugsolval);
2165 SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(conshdlrdata->allconsanddatas), &(conshdlrdata->sallconsanddatas), SCIPcalcMemGrowSize(scip, conshdlrdata->sallconsanddatas + 1)) );
2252 SCIPconsIsInitial(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons), SCIPconsIsLocal(cons),
2260 SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(consdata->consanddatas), &(consdata->sconsanddatas), consdata->sconsanddatas + 1) );
2267 consdata->consanddatas[consdata->nconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res);
2309 SCIP_CALL( lockRoundingAndCons(scip, cons, consdata->consanddatas[consdata->nconsanddatas - 1], val, consdata->lhs, consdata->rhs) );
2418 SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &oldlhs, &oldrhs) );
2440 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
2443 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
2444 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
2447 SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars, andress, andcoefs, andnegs, &nandress) );
2533 /* check whether the left hand side is increased, if and only if that's the case we maybe can propagate, tighten and add more cliques */
2592 SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &oldlhs, &oldrhs) );
2614 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
2617 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
2618 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
2621 SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars, andress, andcoefs, andnegs, &nandress) );
2707 /* check whether the right hand side is decreased, if and only if that's the case we maybe can propagate, tighten and add more cliques */
2757 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
2834 SCIP_Bool const removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
2837 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
2842 SCIP_LINEARCONSTYPE*const linconstype /**< pointer to store the type of the linear constraint */
2953 SCIPdebugMsg(scip, "While creating the linear constraint of the pseudoboolean constraint we found %d zero coefficients that were removed\n", nzero);
2968 * - logic or constraints have left hand side of +1.0, and right hand side of +infinity: x(S) >= 1.0
2980 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3014 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3028 /* check, if linear constraint can be upgraded to set partitioning, packing, or covering constraint
3029 * - all set partitioning / packing / covering constraints consist only of binary variables with a
3036 * - a set partitioning constraint has left hand side of +1.0, and right hand side of +1.0 : x(S) == 1.0
3038 * - a set packing constraint has left hand side of -infinity, and right hand side of +1.0 : x(S) <= 1.0
3040 * - a set covering constraint has left hand side of +1.0, and right hand side of +infinity: x(S) >= 1.0
3048 if( SCIPisEQ(scip, *lhs, *rhs) && (SCIPisEQ(scip, *lhs, 1.0 - ncoeffsnone) || SCIPisEQ(scip, *lhs, ncoeffspone - 1.0)) )
3052 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3086 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3102 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3136 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3154 SCIPwarningMessage(scip, "Does not expect this, because this constraint should be a set packing constraint.\n");
3158 SCIPwarningMessage(scip, "Does not expect this, because this constraint should be a logicor constraint.\n");
3163 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3197 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3217 if( upgrconshdlr != NULL && !created && (ncoeffspone + ncoeffsnone + ncoeffspint + ncoeffsnint == nvars) && (SCIPisInfinity(scip, -*lhs) != SCIPisInfinity(scip, *rhs)) )
3231 /* if the right hand side is non-infinite, we have to negate all variables with negative coefficient;
3232 * otherwise, we have to negate all variables with positive coefficient and multiply the row with -1
3285 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3306 if( upgrconshdlr != NULL && !created && (ncoeffspone + ncoeffsnone + ncoeffspint + ncoeffsnint == nvars) && SCIPisEQ(scip, *lhs, *rhs) )
3316 SCIPdebugMsg(scip, "linear pseudoboolean constraint will be a equality-knapsack constraint\n");
3373 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3395 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3471 SCIPdebugMsg(scip, "checking original pseudo boolean constraint <%s>\n", SCIPconsGetName(cons));
3498 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
3501 /* number of variables should be consistent, number of 'real' linear variables plus number of and-constraints should
3518 /* split variables into original and artificial variables and compute activity on normal linear variables (without
3585 /* if after during or before presolving a solution will be transformed into original space and will be checked
3586 * there, but origcons was already removed and only the pointer to the transformed and-constraint is existing
3641 SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", lhs - activity);
3657 SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - rhs);
3674 /** checks all and-constraints inside the pseudoboolean constraint handler for feasibility of given solution or current
3757 SCIP_HASHMAP*const varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
3759 SCIP_HASHMAP*const consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
3769 SCIP_Bool const removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
3770 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
3846 SCIP_CALL( SCIPgetConsCopy(sourcescip, targetscip, sourcelincons, &targetlincons, conshdlrlinear, varmap, consmap, SCIPconsGetName(sourcelincons),
3847 SCIPconsIsInitial(sourcelincons), SCIPconsIsSeparated(sourcelincons), SCIPconsIsEnforced(sourcelincons), SCIPconsIsChecked(sourcelincons),
3848 SCIPconsIsPropagated(sourcelincons), SCIPconsIsLocal(sourcelincons), SCIPconsIsModifiable(sourcelincons), SCIPconsIsDynamic(sourcelincons),
3855 /* @note due to copying special linear constraints, now leads only to simple linear constraints, we check that
3856 * our target constraint handler is the same as our source constraint handler of the linear constraint,
3889 SCIP_CALL( getLinearConsNVars(targetscip, targetlincons, targetlinconstype, &ntargetlinvars) );
3901 SCIP_CALL( SCIPhashtableCreate(&linconsvarsmap, SCIPblkmem(targetscip), ntargetlinvars, SCIPvarGetHashkey,
3926 targetandresultant = (SCIP_VAR*) SCIPhashmapGetImage(varmap, SCIPgetResultantAnd(sourcescip, oldcons));
3940 SCIP_CALL( SCIPgetConsCopy(sourcescip, targetscip, oldcons, &targetandconss[ntargetandconss], conshdlrand, varmap, consmap, SCIPconsGetName(oldcons),
3941 SCIPconsIsInitial(oldcons), SCIPconsIsSeparated(oldcons), SCIPconsIsEnforced(oldcons), SCIPconsIsChecked(oldcons),
3942 SCIPconsIsPropagated(oldcons), SCIPconsIsLocal(oldcons), SCIPconsIsModifiable(oldcons), SCIPconsIsDynamic(oldcons),
3961 SCIPdebugMsg(sourcescip, "no and-constraints copied for pseudoboolean constraint <%s>\n", SCIPconsGetName(sourcecons));
3983 SCIP_CALL( SCIPgetVarCopy(sourcescip, targetscip, indvar, &indvar, varmap, consmap, global, valid) );
3989 SCIP_CALL( SCIPgetVarCopy(sourcescip, targetscip, intvar, &intvar, varmap, consmap, global, valid) );
4003 SCIP_CALL( getLinearConsSides(targetscip, targetlincons, targetlinconstype, &targetlhs, &targetrhs) );
4011 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
4017 SCIPverbMessage(sourcescip, SCIP_VERBLEVEL_MINIMAL, NULL, "could not copy constraint <%s>\n", SCIPconsGetName(sourcecons));
4091 assert(consanddata->nnewvars == 0 && ((consanddata->snewvars > 0) == (consanddata->newvars != NULL)));
4133 /* check for changings, if and-constraint did not change we do not need to copy all variables */
4157 SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(consanddata->newvars), &(consanddata->snewvars), nnewvars) );
4181 CONSANDDATA*const consanddata, /**< CONSANDDATA object for which we want to delete the locks and the
4209 CONSANDDATA*const consanddata, /**< CONSANDDATA object for which we want to delete the locks and the
4241 SCIP_Real*const andcoefs, /**< current and-resultants-coeffcients in pseudoboolean constraint */
4242 SCIP_Bool*const andnegs, /**< current negation status of and-resultants in pseudoboolean constraint */
4273 SCIPsortPtrRealBool((void**)(consdata->consanddatas), consdata->andcoefs, consdata->andnegs, resvarCompWithInactive, consdata->nconsanddatas);
4288 /* check that consanddata objects are sorted due to the index of the corresponding resultants, and coefficents are
4382 /* collect new consanddata objects in sorted order due to the variable index of corresponding and-resultants */
4389 SCIP_CALL( removeOldLocks(scip, cons, consanddatas[c], oldandnegs[c] ? -oldandcoefs[c] : oldandcoefs[c],
4400 newconsanddatas[nnewconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res2);
4406 SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4439 lhschanged = (SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -newlhs)) || (!SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -newlhs))
4441 rhschanged = (SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, newrhs)) || (!SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, newrhs))
4445 if( coefsignchanged || lhschanged || rhschanged || newconsanddatas[nnewconsanddatas]->nnewvars > 0)
4450 SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4499 SCIP_CALL( removeOldLocks(scip, cons, consanddatas[c], oldandnegs[c] ? -oldandcoefs[c] : oldandcoefs[c],
4516 newconsanddatas[nnewconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res2);
4522 SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4555 SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &(consdata->nlinvars)) );
4567 /* we need to re-sort and-constraints after indices of corresponding and-resultants, since we might have replaced
4570 SCIPsortPtrRealBool((void**)(consdata->consanddatas), consdata->andcoefs, consdata->andnegs, resvarCompWithInactive, consdata->nconsanddatas);
4577 /* check that consanddata objects are sorted with respect to the index of the corresponding resultants */
4633 /* if we have no and-constraints left, we should not be here and this constraint should be deleted (only the linaer should survive) */
4661 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, NULL, &nvars) );
4663 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
4664 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
4704 if( !SCIPvarIsActive(var1) && (!SCIPvarIsNegated(var1) || !SCIPvarIsActive(SCIPvarGetNegationVar(var1))) )
4721 if( !SCIPvarIsActive(var2) && (!SCIPvarIsNegated(var2) || !SCIPvarIsActive(SCIPvarGetNegationVar(var2))) )
4733 /* if variable in and-constraint1 is the negated variable of a normal linear variable, than we can add a
4734 * clique between the and-resultant and the normal linear variable, negated variables are not save in
4756 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4765 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4778 /* if a variable in an and-constraint is in a clique with another normal linear variable, we can add the
4799 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4808 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4874 if( !SCIPvarIsActive(var1) && (!SCIPvarIsNegated(var1) || !SCIPvarIsActive(SCIPvarGetNegationVar(var1))) )
4891 if( !SCIPvarIsActive(var2) && (!SCIPvarIsNegated(var2) || !SCIPvarIsActive(SCIPvarGetNegationVar(var2))) )
4903 /* if a variable in and-constraint1 is the negated variable of a variable in and-constraint2, than we can
4925 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4934 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4947 /* if a variable in an and-constraint is in a clique with a variable in another and-constraint, we can add
4969 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4978 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
5117 assert(consanddata->nnewvars == 0 || (consanddata->newvars != NULL && consanddata->snewvars > 0));
5163 /* the consanddata object is not used anymore, so extract the and constraint and delete other data */
5189 /* @note due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5215 /* all inactive variables have a loose, column, fixed or multi-aggregated variable as counterpart,
5236 SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activescalars, &nactivevars, SCIPgetNVars(scip),
5256 assert(SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_FIXED);
5264 assert(SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_FIXED);
5275 if( SCIPsortedvecFindPtr((void**)fixedvars, SCIPvarComp, SCIPgetResultantAnd(scip, consanddata->cons), nfixedvars, &pos) )
5307 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)));
5308 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)) );
5373 /** update the uses counter of consandata objects which are used in pseudoboolean constraint, that were deleted and
5416 SCIP_CALL( removeOldLocks(scip, cons, consanddata, consdata->andcoefs[c], consdata->lhs, consdata->rhs) );
5449 /* @note due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5470 /* all inactive variables have a loose, column, fixed or multi-aggregated variable as counterpart, but
5474 * @todo for multi-aggregated variables check also all active representatives for this resultant
5481 assert(SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_FIXED);
5494 /* we can only delete and constraints if the resultant is an artificial variable and also active, because
5495 * then the assigned value is not of interest and the artificial and constraint does not need to be
5498 * if this variable is not such an artificial variable we need the IRRELEVANT vartype which should be the
5504 strncmp(SCIPvarGetName(resvar)+2, ARTIFICIALVARNAMEPREFIX, strlen(ARTIFICIALVARNAMEPREFIX)) == 0
5515 /* @note due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5544 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)));
5545 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)) );
5558 /* maximal number to enumerate solutions for one pseudoboolean constraint to check for an upgrade to an XOR constraint */
5561 /** calculate result for a given pseudoboolean constraint with given values, this is used to decide whether a
5581 SCIP_Bool*const consanddatanegs, /**< negation status of and resultants in pseudo-boolean constraint */
5619 if( SCIPsortedvecFindPtr((void**)vars, SCIPvarCompActiveAndNegated, linvars[v], nvars, &pos) ) /*lint !e613*/