cons_pseudoboolean.c
Go to the documentation of this file.
33 * The constraint handler deals with pseudo Boolean constraints. These are constraints of the form
35 * \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}
42 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
78 #define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
79 #define CONSHDLR_CHECKPRIORITY -5000000 /**< priority of the constraint handler for checking feasibility */
80 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
82 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
83 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
85 #define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
87 #define DEFAULT_DECOMPOSENORMALPBCONS FALSE /**< decompose all normal pseudo boolean constraint into a "linear" constraint and "and" constraints */
88 #define DEFAULT_DECOMPOSEINDICATORPBCONS TRUE /**< decompose all indicator pseudo boolean constraint into a "linear" constraint and "and" constraints */
90 #define DEFAULT_SEPARATENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be separated during LP processing */
91 #define DEFAULT_PROPAGATENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be propagated during node processing */
92 #define DEFAULT_REMOVABLENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be removable */
102 #define HASHSIZE_PSEUDOBOOLEANNONLINEARTERMS 500 /**< minimal size of hash table in and constraint tables */
105 /* - create special linear(knapsack, setppc, logicor, (eqknapsack)) and and-constraints with check flags FALSE, to
106 * get smaller amount of locks on the term variables, do all presolving ...?! in these constraint handlers
108 * - do the checking here, lock and-resultants in both directions and all and-variables according to their
110 * @note this only works if the and-resultant has no objective cofficient, otherwise we need to lock variables also in both directions
112 * - need to keep and constraint pointer for special propagations like if two ands are due to their variables in
116 * check/IP/PseudoBoolean/normalized-PB07/OPT-SMALLINT-NLC/submittedPB07/manquinho/bsg/normalized-bsg_1000_25_1.opb.gz
122 * which "equals" a pseudoboolean constraint: 2 x1 + 2 x2 + 1 x3 x4 + 1 x5 x6 x7 + 1 x8 x9 <= 5 ;
126 * which "equals" a pseudoboolean constraint: 2 x1 + 2 x2 + 1 x3 x4 + 1 x5 x6 x7 + 1 x8 x9 <= 6 ;
137 /* @todo - in and-constraint better count nfixed zeros in both directions and maybe nfixedones for better propagation
139 * - do better conflict analysis by choosing the earliest fixed variable which led to a conflict instead of maybe
142 * - how to make sure that we aggregate in a right way, when aggregating a resultant and a "normal" variable,
143 * maybe add in SCIPaggregateVars a check for original variables, to prefer them if the variable type is the
144 * same; probably it would be better too if we would aggregate two resultants that the one with less variables
147 * @note since product resultants are artificial, we do not care for their solution value, but this can lead to fixation
148 * of the resultant not representing the product, in 'optimization mode' we do not care, but this might make
154 {
168 };
178 SCIP_LINEARCONSTYPE linconstype; /**< type of linear constraint which represents this pseudoboolean constraint */
212 CONSANDDATA** allconsanddatas; /**< array of all and-constraint data objects inside the whole problem,
224 SCIP_Bool decomposenormalpbcons;/**< decompose the pseudo boolean constraint into a "linear" constraint and "and" constraints */
225 SCIP_Bool decomposeindicatorpbcons;/**< decompose the indicator pseudo boolean constraint into a "linear" constraint and "and" constraints */
236 /** comparison method for sorting consanddatas according to the index of their corresponding resultant variables, if a
237 * consanddata object is delete it is handled like it has an inactive resultant, so this will be put in front while
242 {
309 /** returns TRUE iff both keys are equal; two non-linear terms are equal if they have the same variables */
312 {
401 /** initializes the hashmap and -table used in this constraint handler data for artificial variables and specific
423 SCIP_CALL( SCIPhashtableCreate(&((*conshdlrdata)->hashtable), SCIPblkmem(scip), (*conshdlrdata)->hashtablesize,
428 SCIP_CALL( SCIPhashmapCreate(&((*conshdlrdata)->hashmap), SCIPblkmem(scip), (*conshdlrdata)->hashmapsize) );
451 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((*conshdlrdata)->allconsanddatas), (*conshdlrdata)->sallconsanddatas ) );
498 SCIPfreeBlockMemoryArray(scip, &((*conshdlrdata)->allconsanddatas), (*conshdlrdata)->sallconsanddatas );
621 SCIP_VAR**const vars, /**< array to store sorted (after indices) variables of linear constraint */
775 /** calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
776 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
786 SCIP_VAR**const linvars, /**< array to store not and-resultant variables of linear constraint, or NULL */
787 SCIP_Real*const lincoefs, /**< array to store coefficients of not and-resultant variables of linear
790 SCIP_VAR**const andress, /**< array to store and-resultant variables of linear constraint, or NULL */
793 SCIP_Bool*const andnegs, /**< array to store negation status of and-resultant variables of linear
822 /* @note it is necessary that the linear constraint is merged (not needed for negated variables) and sorted after
850 /* if and resultant is not a resultant anymore (meaning the corresponding and-constraint was deleted/upgraded),
857 CONSANDDATA* consanddata = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)(hashmapvar));
961 SCIP_CALL_ABORT( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &newlhs, &newrhs) );
983 SCIP_CALL_ABORT( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
987 SCIP_CALL_ABORT( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars,
1005 if( res == andresultant && consdata->andnegs[c] == andnegs[v] && consdata->andcoefs[c] == andcoefs[v] )
1008 assert(SCIPvarIsActive(res) || (SCIPvarIsNegated(res) && SCIPvarIsActive(SCIPvarGetNegationVar(res))));
1011 /* all and-resultants should be merged, so it is only allowed that each variable exists one time */
1041 /** transforming transformed consanddata object back to original space, if an corresponding original constraint exists,
1117 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(consanddata->vars), andvars, consanddata->nvars) );
1130 assert(consanddata == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddata)));
1131 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons)));
1132 assert(consanddata == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons))));
1162 assert(consanddata == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddata)));
1163 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons)));
1164 assert(consanddata == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons))));
1180 SCIP_CONS*const lincons, /**< linear constraint with artificial and-resultants representing this pseudoboolean constraint */
1182 SCIP_CONS**const andconss, /**< array of and-constraints which occur in this pseudoboolean constraint */
1184 SCIP_Bool*const andnegs, /**< negation status of and-constraints (or NULL, if no negated resultants) */
1189 SCIP_VAR* const intvar, /**< a artificial variable which was added only for the objective function,
1223 SCIPerrorMessage("left hand side of pseudo boolean constraint greater than right hand side\n");
1268 /* do not capture the and constraint when scip is in transformed mode; this automatically happens in
1295 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &((*consdata)->andcoefs), andcoefs, nandconss) );
1322 (*consdata)->consanddatas[c] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)andress[c]);
1324 assert((*consdata)->consanddatas[c]->origcons == andconss[c] || (*consdata)->consanddatas[c]->cons == andconss[c]);
1329 if( (*consdata)->consanddatas[c]->origcons != NULL && (*consdata)->consanddatas[c]->cons == NULL )
1335 /* do not capture the and constraint when scip is in transformed mode; this automatically happens in
1338 SCIP_CALL( SCIPtransformCons(scip, (*consdata)->consanddatas[c]->origcons, &((*consdata)->consanddatas[c]->cons)) );
1352 /* resort variables in transformed problem, because the order might change while tranforming */
1375 SCIPsortPtrPtrRealBool((void**)andress, (void**)((*consdata)->consanddatas), (*consdata)->andcoefs, (*consdata)->andnegs, SCIPvarComp, nandconss);
1440 /* count down uses and if necessary release constraints and delete data from hashtable and -map */
1456 /* if the consanddata is not used anymore, release the constraint and clear the hashmap- and table */
1470 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->cons)));
1471 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->cons)) );
1491 conshdlrdata->allconsanddatas[d] = conshdlrdata->allconsanddatas[conshdlrdata->nallconsanddatas];
1511 /* if the consanddata is not used anymore, release the constraint and clear the hashmap- and table */
1524 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)));
1525 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)) );
1557 conshdlrdata->allconsanddatas[d] = conshdlrdata->allconsanddatas[conshdlrdata->nallconsanddatas];
1624 assert(consanddatas[c] == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddatas[c])));
1625 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)));
1626 assert(consanddatas[c] == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons))));
1641 /** check the locks of an AND resultant and removes it from all global structures if the resultant is not locked anymore */
1651 /* the resultant has no locks left and might be dual fixed now, we need to delete all its cliques */
1653 && SCIPvarGetNLocksUpType(res, SCIP_LOCKTYPE_MODEL) == 0 && SCIPgetStage(scip) < SCIP_STAGE_FREETRANS )
1688 /* choose correct variable array to add locks for, we only add locks for now valid variables */
1735 CONSANDDATA*const consanddata, /**< CONSANDDATA object for which we want to delete the locks */
1840 /* more than one and-constraint is needed, otherwise this pseudoboolean constraint should be upgraded to a linear constraint */
1862 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
1865 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
1866 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
1873 /* number of variables should be consistent, number of 'real' linear variables plus number of and-constraints should
1929 SCIPinfoMessage(scip, file, " %+.15g %s<%s>[B]", andcoefs[v], negated ? "~" : "", SCIPvarGetName(aggrvar));
2012 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
2102 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, ARTIFICIALVARNAMEPREFIX"%d", conshdlrdata->nallconsanddatas);
2106 #if 1 /* @todo: check whether we want to branch on artificial variables, the test results show that it is of advantage */
2114 #if 0 /* does not work for since the value of artificial resultants must not be equal to the value computed by their
2134 if( (SCIPvarIsOriginal(resultant) || SCIPvarIsTransformedOrigvar(resultant)) && !SCIPisFeasEQ(scip, debugsolval, val) )
2136 SCIPerrorMessage("computed solution value %g for resultant <%s> violates debug solution value %g\n", val, SCIPvarGetName(resultant), debugsolval);
2172 SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(conshdlrdata->allconsanddatas), &(conshdlrdata->sallconsanddatas), SCIPcalcMemGrowSize(scip, conshdlrdata->sallconsanddatas + 1)) );
2259 SCIPconsIsInitial(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons), SCIPconsIsLocal(cons),
2267 SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(consdata->consanddatas), &(consdata->sconsanddatas), consdata->sconsanddatas + 1) );
2274 consdata->consanddatas[consdata->nconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res);
2316 SCIP_CALL( lockRoundingAndCons(scip, cons, consdata->consanddatas[consdata->nconsanddatas - 1], val, consdata->lhs, consdata->rhs) );
2425 SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &oldlhs, &oldrhs) );
2447 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
2450 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
2451 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
2454 SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars, andress, andcoefs, andnegs, &nandress) );
2540 /* 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 */
2599 SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &oldlhs, &oldrhs) );
2621 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
2624 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
2625 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
2628 SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars, andress, andcoefs, andnegs, &nandress) );
2714 /* 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 */
2764 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
2841 SCIP_Bool const removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
2844 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
2849 SCIP_LINEARCONSTYPE*const linconstype /**< pointer to store the type of the linear constraint */
2960 SCIPdebugMsg(scip, "While creating the linear constraint of the pseudoboolean constraint we found %d zero coefficients that were removed\n", nzero);
2975 * - logic or constraints have left hand side of +1.0, and right hand side of +infinity: x(S) >= 1.0
2987 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3021 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3035 /* check, if linear constraint can be upgraded to set partitioning, packing, or covering constraint
3036 * - all set partitioning / packing / covering constraints consist only of binary variables with a
3043 * - a set partitioning constraint has left hand side of +1.0, and right hand side of +1.0 : x(S) == 1.0
3045 * - a set packing constraint has left hand side of -infinity, and right hand side of +1.0 : x(S) <= 1.0
3047 * - a set covering constraint has left hand side of +1.0, and right hand side of +infinity: x(S) >= 1.0
3055 if( SCIPisEQ(scip, *lhs, *rhs) && (SCIPisEQ(scip, *lhs, 1.0 - ncoeffsnone) || SCIPisEQ(scip, *lhs, ncoeffspone - 1.0)) )
3059 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3093 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3109 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3143 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3161 SCIPwarningMessage(scip, "Does not expect this, because this constraint should be a set packing constraint.\n");
3165 SCIPwarningMessage(scip, "Does not expect this, because this constraint should be a logicor constraint.\n");
3170 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3204 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3224 if( upgrconshdlr != NULL && !created && (ncoeffspone + ncoeffsnone + ncoeffspint + ncoeffsnint == nvars) && (SCIPisInfinity(scip, -*lhs) != SCIPisInfinity(scip, *rhs)) )
3238 /* if the right hand side is non-infinite, we have to negate all variables with negative coefficient;
3239 * otherwise, we have to negate all variables with positive coefficient and multiply the row with -1
3292 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3313 if( upgrconshdlr != NULL && !created && (ncoeffspone + ncoeffsnone + ncoeffspint + ncoeffsnint == nvars) && SCIPisEQ(scip, *lhs, *rhs) )
3323 SCIPdebugMsg(scip, "linear pseudoboolean constraint will be a equality-knapsack constraint\n");
3380 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3402 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3478 SCIPdebugMsg(scip, "checking original pseudo boolean constraint <%s>\n", SCIPconsGetName(cons));
3505 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
3508 /* number of variables should be consistent, number of 'real' linear variables plus number of and-constraints should
3525 /* split variables into original and artificial variables and compute activity on normal linear variables (without
3592 /* if after during or before presolving a solution will be transformed into original space and will be checked
3593 * there, but origcons was already removed and only the pointer to the transformed and-constraint is existing
3648 SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", lhs - activity);
3664 SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - rhs);
3681 /** checks all and-constraints inside the pseudoboolean constraint handler for feasibility of given solution or current
3777 SCIP_HASHMAP*const varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
3779 SCIP_HASHMAP*const consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
3789 SCIP_Bool const removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
3790 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
3866 SCIP_CALL( SCIPgetConsCopy(sourcescip, targetscip, sourcelincons, &targetlincons, conshdlrlinear, varmap, consmap, SCIPconsGetName(sourcelincons),
3867 SCIPconsIsInitial(sourcelincons), SCIPconsIsSeparated(sourcelincons), SCIPconsIsEnforced(sourcelincons), SCIPconsIsChecked(sourcelincons),
3868 SCIPconsIsPropagated(sourcelincons), SCIPconsIsLocal(sourcelincons), SCIPconsIsModifiable(sourcelincons), SCIPconsIsDynamic(sourcelincons),
3875 /* @note due to copying special linear constraints, now leads only to simple linear constraints, we check that
3876 * our target constraint handler is the same as our source constraint handler of the linear constraint,
3909 SCIP_CALL( getLinearConsNVars(targetscip, targetlincons, targetlinconstype, &ntargetlinvars) );
3921 SCIP_CALL( SCIPhashtableCreate(&linconsvarsmap, SCIPblkmem(targetscip), ntargetlinvars, SCIPvarGetHashkey,
3946 targetandresultant = (SCIP_VAR*) SCIPhashmapGetImage(varmap, SCIPgetResultantAnd(sourcescip, oldcons));
3960 SCIP_CALL( SCIPgetConsCopy(sourcescip, targetscip, oldcons, &targetandconss[ntargetandconss], conshdlrand, varmap, consmap, SCIPconsGetName(oldcons),
3961 SCIPconsIsInitial(oldcons), SCIPconsIsSeparated(oldcons), SCIPconsIsEnforced(oldcons), SCIPconsIsChecked(oldcons),
3962 SCIPconsIsPropagated(oldcons), SCIPconsIsLocal(oldcons), SCIPconsIsModifiable(oldcons), SCIPconsIsDynamic(oldcons),
3981 SCIPdebugMsg(sourcescip, "no and-constraints copied for pseudoboolean constraint <%s>\n", SCIPconsGetName(sourcecons));
4003 SCIP_CALL( SCIPgetVarCopy(sourcescip, targetscip, indvar, &indvar, varmap, consmap, global, valid) );
4009 SCIP_CALL( SCIPgetVarCopy(sourcescip, targetscip, intvar, &intvar, varmap, consmap, global, valid) );
4023 SCIP_CALL( getLinearConsSides(targetscip, targetlincons, targetlinconstype, &targetlhs, &targetrhs) );
4031 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
4037 SCIPverbMessage(sourcescip, SCIP_VERBLEVEL_MINIMAL, NULL, "could not copy constraint <%s>\n", SCIPconsGetName(sourcecons));
4111 assert(consanddata->nnewvars == 0 && ((consanddata->snewvars > 0) == (consanddata->newvars != NULL)));
4153 /* check for changings, if and-constraint did not change we do not need to copy all variables */
4177 SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(consanddata->newvars), &(consanddata->snewvars), nnewvars) );
4201 CONSANDDATA*const consanddata, /**< CONSANDDATA object for which we want to delete the locks and the
4229 CONSANDDATA*const consanddata, /**< CONSANDDATA object for which we want to delete the locks and the
4261 SCIP_Real*const andcoefs, /**< current and-resultants-coeffcients in pseudoboolean constraint */
4262 SCIP_Bool*const andnegs, /**< current negation status of and-resultants in pseudoboolean constraint */
4293 SCIPsortPtrRealBool((void**)(consdata->consanddatas), consdata->andcoefs, consdata->andnegs, resvarCompWithInactive, consdata->nconsanddatas);
4308 /* check that consanddata objects are sorted due to the index of the corresponding resultants, and coefficents are
4402 /* collect new consanddata objects in sorted order due to the variable index of corresponding and-resultants */
4409 SCIP_CALL( removeOldLocks(scip, cons, consanddatas[c], oldandnegs[c] ? -oldandcoefs[c] : oldandcoefs[c],
4420 newconsanddatas[nnewconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res2);
4426 SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4459 lhschanged = (SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -newlhs)) || (!SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -newlhs))
4461 rhschanged = (SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, newrhs)) || (!SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, newrhs))
4465 if( coefsignchanged || lhschanged || rhschanged || newconsanddatas[nnewconsanddatas]->nnewvars > 0)
4470 SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4519 SCIP_CALL( removeOldLocks(scip, cons, consanddatas[c], oldandnegs[c] ? -oldandcoefs[c] : oldandcoefs[c],
4536 newconsanddatas[nnewconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res2);
4542 SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4575 SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &(consdata->nlinvars)) );
4587 /* we need to re-sort and-constraints after indices of corresponding and-resultants, since we might have replaced
4590 SCIPsortPtrRealBool((void**)(consdata->consanddatas), consdata->andcoefs, consdata->andnegs, resvarCompWithInactive, consdata->nconsanddatas);
4597 /* check that consanddata objects are sorted with respect to the index of the corresponding resultants */
4653 /* if we have no and-constraints left, we should not be here and this constraint should be deleted (only the linaer should survive) */
4681 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, NULL, &nvars) );
4683 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
4684 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
4724 if( !SCIPvarIsActive(var1) && (!SCIPvarIsNegated(var1) || !SCIPvarIsActive(SCIPvarGetNegationVar(var1))) )
4741 if( !SCIPvarIsActive(var2) && (!SCIPvarIsNegated(var2) || !SCIPvarIsActive(SCIPvarGetNegationVar(var2))) )
4753 /* if variable in and-constraint1 is the negated variable of a normal linear variable, than we can add a
4754 * clique between the and-resultant and the normal linear variable, negated variables are not save in
4776 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4785 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4798 /* if a variable in an and-constraint is in a clique with another normal linear variable, we can add the
4819 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4828 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4894 if( !SCIPvarIsActive(var1) && (!SCIPvarIsNegated(var1) || !SCIPvarIsActive(SCIPvarGetNegationVar(var1))) )
4911 if( !SCIPvarIsActive(var2) && (!SCIPvarIsNegated(var2) || !SCIPvarIsActive(SCIPvarGetNegationVar(var2))) )
4923 /* if a variable in and-constraint1 is the negated variable of a variable in and-constraint2, than we can
4945 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4954 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4967 /* if a variable in an and-constraint is in a clique with a variable in another and-constraint, we can add
4989 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4998 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
5137 assert(consanddata->nnewvars == 0 || (consanddata->newvars != NULL && consanddata->snewvars > 0));
5183 /* the consanddata object is not used anymore, so extract the and constraint and delete other data */
5209 /* @note due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5235 /* all inactive variables have a loose, column, fixed or multi-aggregated variable as counterpart,
5256 SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activescalars, &nactivevars, SCIPgetNVars(scip),
5276 assert(SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_FIXED);
5284 assert(SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_FIXED);
5295 if( SCIPsortedvecFindPtr((void**)fixedvars, SCIPvarComp, SCIPgetResultantAnd(scip, consanddata->cons), nfixedvars, &pos) )
5327 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)));
5328 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)) );
5393 /** update the uses counter of consandata objects which are used in pseudoboolean constraint, that were deleted and
5436 SCIP_CALL( removeOldLocks(scip, cons, consanddata, consdata->andcoefs[c], consdata->lhs, consdata->rhs) );
5469 /* @note due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5490 /* all inactive variables have a loose, column, fixed or multi-aggregated variable as counterpart, but
5494 * @todo for multi-aggregated variables check also all active representatives for this resultant
5501 assert(SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_FIXED);
5514 /* we can only delete and constraints if the resultant is an artificial variable and also active, because
5515 * then the assigned value is not of interest and the artificial and constraint does not need to be
5518 * if this variable is not such an artificial variable we need the IRRELEVANT vartype which should be the
5524 strncmp(SCIPvarGetName(resvar)+2, ARTIFICIALVARNAMEPREFIX, strlen(ARTIFICIALVARNAMEPREFIX)) == 0
5535 /* @note due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5564 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)));
5565 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)) );
5578 /* maximal number to enumerate solutions for one pseudoboolean constraint to check for an upgrade to an XOR constraint */
5581 /** calculate result for a given pseudoboolean constraint with given values, this is used to decide whether a
5601 SCIP_Bool*const consanddatanegs, /**< negation status of and resultants in pseudo-boolean constraint */
5639 if( SCIPsortedvecFindPtr((void**)vars, SCIPvarCompActiveAndNegated, linvars[v], nvars, &pos) ) /*lint !e613*/