cons_setppc.c
Go to the documentation of this file.
18 * @brief Constraint handler for the set partitioning / packing / covering constraints \f$1^T x\ \{=, \le, \ge\}\ 1\f$.
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
61 #define CONSHDLR_ENFOPRIORITY -700000 /**< priority of the constraint handler for constraint enforcing */
62 #define CONSHDLR_CHECKPRIORITY -700000 /**< priority of the constraint handler for checking feasibility */
63 #define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
64 #define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
65 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
67 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
68 #define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
69 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
70 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
75 #define LINCONSUPGD_PRIORITY +700000 /**< priority of the constraint handler for upgrading of linear constraints */
76 #define NONLINCONSUPGD_PRIORITY +700000 /**< priority of the constraint handler for upgrading of nonlinear constraints */
79 #define EVENTHDLR_DESC "bound change event handler for set partitioning / packing / covering constraints"
85 #define DEFAULT_PRESOLPAIRWISE TRUE /**< should pairwise constraint comparison be performed in presolving? */
88 #define DEFAULT_PRESOLUSEHASHING TRUE /**< should hash table be used for detecting redundant constraints in advance */
90 #define MINGAINPERNMINCOMPARISONS 1e-06 /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
94 /*#define VARUSES*/ /* activate variable usage counting, that is necessary for LP and pseudo branching */
95 /*#define BRANCHLP*/ /* BRANCHLP is only useful if the ENFOPRIORITY is set to a positive value */
100 #define DEFAULT_NPSEUDOBRANCHES 2 /**< number of children created in pseudo branching (0: disable branching) */
103 #define DEFAULT_CLIQUELIFTING FALSE /**< should we try to lift variables into other clique constraints, fix
107 #define DEFAULT_ADDVARIABLESASCLIQUES FALSE/**< should we try to generate extra clique constraint out of all binary
110 #define DEFAULT_CLIQUESHRINKING TRUE /**< should we try to shrink the number of variables in a clique constraints, by
114 /* @todo maybe use event SCIP_EVENTTYPE_VARUNLOCKED to decide for another dual-presolving run on a constraint */
124 SCIP_CONSHDLR* conshdlrlinear; /**< pointer to linear constraint handler or NULL if not included */
129 int npseudobranches; /**< number of children created in pseudo branching (0 to disable branching) */
137 SCIP_Bool enablecliquelifting;/**< check whether we have enough changes to run the lifting procedure again */
141 SCIP_Bool addvariablesascliques;/**< should we try to generate extra clique constraint out of all binary
145 SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
146 SCIP_Bool presolusehashing; /**< should hash table be used for detecting redundant constraints in advance */
163 unsigned int cliqueadded:1; /**< was the set partitioning / packing constraint already added as clique? */
165 unsigned int changed:1; /**< was constraint changed since last redundancy round in preprocessing? */
168 unsigned int presolpropagated:1; /**< was the constraint already propagated in presolving w.r.t. the current domains? */
180 /** compares two active constraints of type set partitioning or set packing such that a "-1" is return if
182 * 2. both constraints are set partitioning constraints and the second has more! variables than the first or
183 * 3. both constraints are set packing constraints and the second has less! variables than the first
213 (consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->nvars < consdata2->nvars) || /*lint !e641*/
214 (consdata2->setppctype == SCIP_SETPPCTYPE_PACKING && consdata1->nvars > consdata2->nvars) ) /*lint !e641*/
216 else if( (consdata1->setppctype == consdata2->setppctype && consdata1->nvars == consdata2->nvars) ) /*lint !e641*/
220 assert(consdata1->setppctype > consdata2->setppctype || (consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->setppctype == consdata2->setppctype && consdata1->nvars > consdata2->nvars) || (consdata1->setppctype == SCIP_SETPPCTYPE_PACKING && consdata1->setppctype == consdata2->setppctype && consdata1->nvars < consdata2->nvars)); /*lint !e641*/
225 /** sort constraints first after type (partitioning before packing before covering) and second after number of
226 * variables such that the partitioning constraints have increasing number of variables and the packing constraints
234 /** compares two setppc constraints such that a "-1" is return if the first constraint is active and
237 * 3. both constraints are set partitioning constraints and the second has more! variables than the first or
238 * 4. both constraints are set packing constraints and the second has less! variables than the first
272 assert(SCIP_SETPPCTYPE_PARTITIONING < SCIP_SETPPCTYPE_PACKING && SCIP_SETPPCTYPE_PACKING < SCIP_SETPPCTYPE_COVERING); /*lint !e506*/
276 (((SCIP_SETPPCTYPE)consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->nvars < consdata2->nvars) ||
277 ((SCIP_SETPPCTYPE)consdata2->setppctype == SCIP_SETPPCTYPE_PACKING && consdata1->nvars > consdata2->nvars))) )
279 else if( ((SCIP_SETPPCTYPE)consdata2->setppctype == SCIP_SETPPCTYPE_COVERING || (consdata1->setppctype == consdata2->setppctype && consdata1->nvars == consdata2->nvars)) )
283 assert(consdata1->setppctype > consdata2->setppctype || ((consdata1->setppctype == consdata2->setppctype) &&
285 || (consdata1->setppctype == SCIP_SETPPCTYPE_PACKING && consdata1->nvars < consdata2->nvars)))); /*lint !e641*/
290 /** sort constraints first after type (partitioning before packing before covering) and second after number of
291 * variables such that the partitioning constraints have increasing number of variables and the packing constraints
364 /** creates constraint handler data for set partitioning / packing / covering constraint handler */
393 /** frees constraint handler data for set partitioning / packing / covering constraint handler */
433 /* if the variable is the negation of a problem variable, count the varuses in the problem variable */
561 SCIP_CONSDATA** consdata, /**< pointer to store the set partitioning / packing / covering constraint */
564 SCIP_SETPPCTYPE setppctype /**< type of constraint: set partitioning, packing, or covering constraint */
584 /* @todo the setppc constraint handler does not remove fixed variables from its var array; removing those
585 * variables is only possible if we consider the values of nfixedones and nfixedzeros in all propagation methods
635 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
642 (*consdata)->existmultaggr = (*consdata)->existmultaggr || (SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
678 SCIP_CONSDATA** consdata, /**< pointer to store the set partitioning / packing / covering constraint */
681 SCIP_SETPPCTYPE setppctype /**< type of constraint: set partitioning, packing, or covering constraint */
691 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
700 SCIP_CONSDATA** consdata /**< pointer to store the set partitioning / packing / covering constraint */
843 SCIPdebugMsg(scip, " -> converting <%s> into setppc type %d\n", SCIPconsGetName(cons), setppctype);
920 * - SCIP_EVENTTYPE_BOUNDCHANGED: Is used to count the number of variable fixed locally to zero and one. That helps
925 * - SCIP_EVENTTYPE_VARFIXED: Is used to get informed if a variable of the constraint was aggregated which means was
940 /* during presolving, we may fix the last unfixed variable or do an aggregation if there are two unfixed variables */
941 if( SCIPconsIsActive(cons) && ((SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE) && (consdata->nfixedzeros >= consdata->nvars - 2)) )
1115 if( !consdata->existmultaggr && SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_MULTAGGR )
1185 /* the last variable of the constraint was deleted; mark it for propagation (so that it can be deleted) */
1214 /** in case a part (more than one variable) in the setppc constraint is independent of every else (is locked only by
1226 * (ii) a variable x has exactly 0 uplocks and arbitrary downlocks and a variable y has exactly 1 downlock and
1238 * (ii) a variable x has exactly 1 uplock and arbitrary downlocks and a variable y has exactly 1 downlock and
1247 * - fix the variable with the smallest object coefficient to one if the object coefficient is negative or zero
1250 * (ii) a variable x has exactly 1 uplock and arbitrary downlocks and a variable y has exactly 0 downlocks and
1256 * Note: the following dual reduction for set covering and set packing constraints is already performed by the presolver
1259 * - if a variable in a set covering constraint is only locked by that constraint and has negative or zero
1262 * - if a variable in a set packing constraint is only locked by that constraint and has positive or zero
1265 * Note: all dual reduction (ii) could also be performed by the "domcol" presolver, but cause the pairwise comparison of
1266 * columns is only done heuristically (and here it should be even cheaper) we perform them here (too)
1275 SCIP_RESULT* result /**< pointer to store the result SCIP_SUCCESS, if presolving was performed */
1303 /* constraints for which the check flag is set to FALSE, did not contribute to the lock numbers; therefore, we cannot
1304 * use the locks to decide for a dual reduction using this constraint; for example after a restart the cuts which are
1315 /* modifiable non-covering constraints cannot be deleted if one variable is fixed to one, because the propagation for
1327 /* we don't want to consider small constraints (note that the constraints can be modifiable, so we can't delete this
1361 /* check if we can apply the dual reduction; therefore count the number of variables where the setppc has the only
1395 /* in case another constraint has also downlocks on that variable we cannot perform a dual reduction on these
1427 /* in case another constraint has also downlocks on that variable we cannot perform a dual reduction on these
1457 /* if we got a set covering constraint and not all variables are locked from this constraint it might not get
1458 * redundant (which is case if it is not possible to fix at least one variable to one), we fix all redundant
1472 /* in case another constraint has also downlocks on that variable we cannot perform a dual reduction on these
1485 || (SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == SCIPvarGetNLocksDownType(activevar, SCIP_LOCKTYPE_MODEL)
1486 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == SCIPvarGetNLocksUpType(activevar, SCIP_LOCKTYPE_MODEL)));
1488 || (SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == SCIPvarGetNLocksUpType(activevar, SCIP_LOCKTYPE_MODEL)
1489 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == SCIPvarGetNLocksDownType(activevar, SCIP_LOCKTYPE_MODEL)));
1501 /* if variables has a negative objective contribution, and is uplocked by another constraint we cannot fix
1504 if( (fixval == 1.0 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) > nlockups) || objval < bestobjval )
1511 SCIPdebugMsg(scip, " -> dual-fixed dominated variable <%s> == %g\n", SCIPvarGetName(var), fixval);
1517 /* if all variables but the domination variable is fixed and the constraint is not modifiable or the constraint is a
1518 * covering constraint and the bestobjval is less than or equal to zero, we can fix the domination variable (with best
1521 if( ((*nfixedvars - noldfixed == nvars - 1) && !SCIPconsIsModifiable(cons)) || (setppctype == SCIP_SETPPCTYPE_COVERING && bestobjval <= 0.0) )
1523 /* in case of a set packing constraint with positive objective values, all variables can be fixed to zero; in all
1539 SCIPdebugMsg(scip, " -> dual-fixed best variable <%s> == %g\n", SCIPvarGetName(vars[idx]), fixval);
1579 {
1622 assert(SCIPvarIsActive(var1) || SCIPvarGetStatus(var1) == SCIP_VARSTATUS_NEGATED || SCIPvarGetStatus(var1) == SCIP_VARSTATUS_FIXED);
1632 assert(SCIPvarIsActive(var2) || SCIPvarGetStatus(var2) == SCIP_VARSTATUS_NEGATED || SCIPvarGetStatus(var2) == SCIP_VARSTATUS_FIXED);
1701 SCIP_CALL( delCoefPos(scip, cons, v) ); /* only some changed behind position v-1, so it's okay */
1766 if( SCIPvarGetStatus(repvar) == SCIP_VARSTATUS_MULTAGGR || (SCIPvarGetStatus(repvar) == SCIP_VARSTATUS_NEGATED && SCIPvarGetStatus(SCIPvarGetNegatedVar(repvar)) == SCIP_VARSTATUS_MULTAGGR) )
1783 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
1790 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
1836 SCIPdebugMsg(scip, "trying to fix <%s> to 0 due to at least one variable is already fixed to 1\n", SCIPvarGetName(consdata->vars[v2]));
1858 if( ndelconss != NULL && (nfixedvars != NULL || consdata->nvars == 1 || (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_COVERING) )
1881 assert(SCIPvarIsActive(consvars[v2]) || (SCIPvarGetStatus(consvars[v2]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(consvars[v2]))));
1896 /* it might happen that there are more than one multi-aggregated variable, so we need to get the whole
1902 /* memory needed is at least old number of variables - 1 + number of variables in first multi-aggregation */
1918 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, size, &constant, &requiredsize, TRUE) );
1920 /* if space was not enough (we found another multi-aggregation), we need to resize the buffers */
1926 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
1987 SCIPwarningMessage(scip, "setppc constraint <%s> has a multi-aggregated variable, which was not resolved and therefore could lead to aborts\n", SCIPconsGetName(cons));
2018 /** analyzes conflicting assignment on given constraint where all of the variables where assigned to zero,
2024 SCIP_CONS* cons /**< set partitioning / packing / covering constraint that detected the conflict */
2031 if( (SCIPgetStage(scip) != SCIP_STAGE_SOLVING && !SCIPinProbing(scip)) || !SCIPisConflictAnalysisApplicable(scip) )
2039 /* initialize conflict analysis, and add all variables of infeasible constraint to conflict candidate queue */
2053 /** analyzes conflicting assignment on given constraint where two of the variables where assigned to one,
2059 SCIP_CONS* cons /**< set partitioning / packing / covering constraint that detected the conflict */
2067 if( (SCIPgetStage(scip) != SCIP_STAGE_SOLVING && !SCIPinProbing(scip)) || !SCIPisConflictAnalysisApplicable(scip) )
2075 /* initialize conflict analysis, and add the two variables assigned to one to conflict candidate queue */
2095 /** checks constraint for violation only looking at the fixed variables, applies further fixings if possible */
2103 SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
2105 {
2132 /*SCIPdebugMsg(scip, "processing constraint <%s> with respect to fixed variables (%d fixed to 0.0, %d fixed to 1.0)\n",
2161 SCIPdebugMsg(scip, " -> fixing all other variables to zero in set packing/partitioning constraint <%s>\n",
2165 * this could result in additional variables fixed to one due to aggregations; in this case, the
2176 assert(SCIPisFeasZero(scip, SCIPvarGetUbLocal(var)) || SCIPisFeasEQ(scip, SCIPvarGetUbLocal(var), 1.0));
2195 /* the fixed to one variable must have been found, and at least one variable must have been fixed */
2206 SCIPdebugMsg(scip, " -> disabling set packing/partitioning constraint <%s>\n", SCIPconsGetName(cons));
2226 SCIPdebugMsg(scip, " -> conflict on set packing/partitioning constraint <%s>\n", SCIPconsGetName(cons));
2241 * - a set partitioning or covering constraint is infeasible, and if it's unmodifiable, the node
2257 SCIPdebugMsg(scip, " -> set covering/partitioning constraint <%s> is infeasible\n", SCIPconsGetName(cons));
2276 * - an unmodifiable set partitioning or covering constraint is feasible and can be disabled after the
2305 assert(SCIPisFeasZero(scip, SCIPvarGetUbLocal(var)) || SCIPisFeasEQ(scip, SCIPvarGetUbLocal(var), 1.0));
2308 SCIPdebugMsg(scip, " -> fixing remaining variable <%s> to one in set covering/partitioning constraint <%s>\n",
2335 SCIP_CONSDATA* consdata, /**< set partitioning / packing / covering constraint to be checked */
2353 sumbound = ((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_COVERING ? 1.0 : 1.0 + 2*SCIPfeastol(scip));
2354 for( v = 0; v < nvars && sum < sumbound; ++v ) /* if sum >= sumbound, the feasibility is clearly decided */
2369 /* in case of partitioning, the violation is equal to the absolute difference between sum and 1 */
2433 SCIP_CALL( SCIPaddVarsToRowSameCoef(scip, consdata->row, consdata->nvars, consdata->vars, 1.0) );
2482 /* skip deactivated, redundant, or local constraints (the NLP does not allow for local rows at the moment) */
2546 )
2573 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
2632 {
2646 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
2691 /** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables */
2814 /* @todo: maybe sort cliques and accordingly the variables so it will be faster to add the constraints */
2823 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "extra_clq_%d_round_%d", cliquepartition[c], nrounds);
2837 /* @todo: try to find a good value for what are enough variables to create this constraint, maybe at least
2882 /** start to collect setpartitioning and setpacking constraints, and try to remove fixed variables and merged these
2923 /* we only want to consider constraints with either active or negated of active variables, applyfixings removes
2924 * aggregated and fixed variables to zero, processFixings removes fixings to one but no aggregation
2960 /* @todo: check for covering constraints with only two variables which are equal to a packing constraint with
2964 assert(consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
2974 /** creating all necessary data in array structure, collect all clique constraint variables and occurrences,
2985 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
2987 int**const varconsidxs, /**< storage for constraint indices in which the corresponding variable exists */
3021 /* here we should have no covering constraints anymore and the constraint data should be merged */
3022 assert(consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
3042 assert(SCIPvarIsActive(var) || (SCIPvarIsNegated(var) && SCIPvarIsActive(SCIPvarGetNegationVar(var))));
3057 SCIP_CALL( SCIPallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
3065 /* the number of occurrences of a variable is not limited by the locks (so maybe we have to increase memory),
3066 * because for examples converted cuts are not check and therefore they have no locks on their variables */
3070 SCIP_CALL( SCIPreallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
3090 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
3091 int**const varconsidxs /**< storage for constraint indices in which the corresponding variable exists */
3136 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
3138 int**const varconsidxs /**< storage for constraint indices in which the corresponding variable exists */
3157 assert(SCIPvarGetNegatedVar(addvar) != NULL && SCIPhashmapExists(vartoindex, (void*) SCIPvarGetNegatedVar(addvar)));
3159 /* @note because we can only have created a negated variable, and we already allocated enough memory for
3162 SCIPsortedvecInsertDownPtr((void**)usefulvars, SCIPvarCompActiveAndNegated, addvar, nusefulvars, NULL);
3169 SCIP_CALL( SCIPallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
3180 SCIP_CALL( SCIPreallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
3193 /** check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
3201 SCIP_VAR** undoneaggrvars, /**< array to store aggregation variables, if aggregation is not performed
3205 SCIP_Bool* undoneaggrtypes, /**< array to store aggregation type, if aggregation is not performed yet;
3209 int*const naggregations, /**< pointer to store number of aggregations which are not yet performed;
3212 int*const saggregations, /**< pointer to store size of the array for aggregation type and two times
3252 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
3254 SCIPdebugMsg(scip, "empty set-partition/-covering constraint <%s> found -> cutoff\n", SCIPconsGetName(cons));
3264 SCIPdebugMsg(scip, " -> deleting constraint <%s>, no variables left\n", SCIPconsGetName(cons));
3282 SCIPdebugMsg(scip, " -> deleting set-covering constraint <%s>, at least two variables are fixed to 1\n", SCIPconsGetName(cons));
3289 SCIPdebugMsg(scip, "set partitioning / packing constraint <%s> is infeasible, %d variables fixed to one\n", SCIPconsGetName(cons), consdata->nfixedones);
3301 if( consdata->setppctype != SCIP_SETPPCTYPE_COVERING && consdata->nfixedzeros < nvars - 1 ) /*lint !e641*/
3309 SCIPdebugMsg(scip, "trying to fix <%s> to 0 due to at least one variable is already fixed to 1\n", SCIPvarGetName(vars[v]));
3327 if( !SCIPconsIsModifiable(cons) || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
3330 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all variables are fixed\n", SCIPconsGetName(cons));
3345 /* all variables were fixed to zero then either delete the constraint or stop with infeasibility */
3354 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
3356 SCIPdebugMsg(scip, "set partitioning / covering constraint <%s> is infeasible\n", SCIPconsGetName(cons));
3363 SCIPdebugMsg(scip, " -> deleting set-packing constraint <%s>, all variables are fixed to zero\n", SCIPconsGetName(cons));
3371 /* all but one variable were fixed to zero then delete the constraint and for setpartition fix the remaining variable to 1 */
3381 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
3389 SCIPdebugMsg(scip, "trying to fix <%s> to 1 due to it's the last unfixed variable is the set-partitioning/covering constraint\n", SCIPvarGetName(vars[v]));
3410 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all %svariables are fixed\n", SCIPconsGetName(cons), consdata->setppctype == (int) SCIP_SETPPCTYPE_PACKING ? "but one " : "");
3418 /* all but two variable were fixed to zero in a setpartitioning constraint then delete the constraint and
3421 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata->nfixedzeros + 2 == nvars ) /*lint !e641*/
3450 SCIPdebugMsg(scip, "trying to aggregate <%s> and <%s> due to they are the last two unfixed variables in the set partitionning constraint <%s>\n", SCIPvarGetName(var), SCIPvarGetName(vars[v]), SCIPconsGetName(cons));
3453 /* in order to not mess up the variable usage counting, we have to decrease usage counting, aggregate,
3461 SCIP_CALL( SCIPaggregateVars(scip, var, vars[v], 1.0, 1.0, 1.0, cutoff, &redundant, &aggregated) );
3482 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all variables are fixed\n", SCIPconsGetName(cons));
3495 SCIPdebugMsg(scip, "memorize the aggregation of <%s> + <%s> = 1, because they are the last two unfixed variable in the set partitioning constraints <%s>\n", SCIPvarGetName(var), SCIPvarGetName(vars[v]), SCIPconsGetName(cons));
3505 /* clear the aggregation type array to set the default to the aggregation of the form x + y = 1 */
3506 BMSclearMemoryArray(&(undoneaggrtypes[*naggregations]), *saggregations - *naggregations); /*lint !e866*/
3518 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all variables are fixed\n", SCIPconsGetName(cons));
3529 /* we should never be here, because the last to unfixed variables should have been either aggregated or a cutoff
3550 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
3552 int**const varconsidxs, /**< storage for constraint indices in which the corresponding variable exists */
3553 int*const countofoverlapping, /**< the amount of variables of cons which overlap in all other constraint */
3558 SCIP_VAR** undoneaggrvars, /**< array to store aggregation variables, if aggregation is not performed
3561 SCIP_Bool* undoneaggrtypes, /**< array to store aggregation type, if aggregation is not performed yet;
3565 int*const naggregations, /**< pointer to store number of aggregations which are not yet performed; */
3566 int*const saggregations, /**< pointer to store size of the array for aggregation type and two times
3649 /* check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
3652 SCIP_CALL( presolvePropagateCons(scip, cons1, FALSE, undoneaggrvars, undoneaggrtypes, naggregations, saggregations, nfixedvars, naggrvars, ndelconss, cutoff) );
3677 SCIPdebugMsg(scip, "constraint <%s> overlaps with constraint <%s> by %d variables\n", SCIPconsGetName(cons), SCIPconsGetName(cons1), countofoverlapping[c]);
3698 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
3717 /* all variables inside the second clique constraint should be either active or negated of an active one */
3718 assert(SCIPvarIsActive(vars1[v1]) || (SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1]))));
3746 assert(SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1])));
3753 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
3759 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because it is in the same clique with a complete set partitioning constraint\n", SCIPvarGetName(vars1[v1]));
3776 /* because the constraint's are merged it is not possible that one constraint contains a negated
3792 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because it is in the same clique with a complete set partitioning constraint\n", SCIPvarGetName(vars1[v1]));
3808 /* if caused by all fixings now this set partitioning constraint doesn't have any variable which was
3810 if( consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->nfixedzeros == nvars1 && consdata1->nfixedones != 1 ) /*lint !e641*/
3812 SCIPdebugMsg(scip, "all variables in the set-partitioning constraint <%s> are fixed to zero, this leads to a cutoff\n", SCIPconsGetName(cons1));
3820 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> because it includes the setpartitioning constraint <%s> number <%d>\n", SCIPconsGetName(cons1), c, SCIPconsGetName(cons), considx);
3826 /* could already be deleted because the constraint was included in another set partition constraint */
3830 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> due to inclusion in constraint <%s> number <%d>\n", SCIPconsGetName(cons), considx, SCIPconsGetName(cons1), c);
3839 * @note that zero fixations from above can only appear through a set-partitioning constraint, this means if
3840 * cons was the set-partitioning constraint only variables which are not in this constraint could be fixed
3841 * to zero, and this also means that the overlapping variables in this particular case are still active or
3843 * later on it could be possible that even variables in cons are fixed to zero, which can lead to wrong
3844 * results when checking if countofoverlapping[c] + consdata1->nfixedzeros == nvars1, because a fixed
3847 else if( (!overlapdestroyed && countofoverlapping[c] + consdata1->nfixedzeros == nvars1) || countofoverlapping[c] == nvars1 )
3863 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
3882 /* all variables inside the second clique constraint should be either active or negated of an active one */
3883 assert(SCIPvarIsActive(vars1[v1]) || (SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1]))));
3884 /* all variables inside the first clique constraint should be either active or negated of an active one */
3885 assert(SCIPvarIsActive(vars[v]) || (SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v]))));
3897 assert(SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v])));
3914 assert(SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1])));
3921 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
3924 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because it is in the same clique with a complete set partitioning constraint\n", SCIPvarGetName(var));
3945 /* because the constraint's are merged it is not possible that one constraint contains a negated
3946 * variable of another and because all variables in cons1 are in cons this should be really the same
3962 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because it is in the same clique with a complete set partitioning constraint\n", SCIPvarGetName(vars[v]));
3977 /* if caused by all fixings now this set partitioning constraint doesn't have any variable which was
3979 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata->nfixedzeros == nvars && consdata->nfixedones != 1 ) /*lint !e641*/
3981 SCIPdebugMsg(scip, "all variables in the set-partitioning constraint <%s> are fixed to zero, this leads to a cutoff\n", SCIPconsGetName(cons1));
3987 /* could already be deleted because the constraint was included in another set partition constraint */
3991 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> because it includes the setpartitioning constraint <%s> number <%d>\n", SCIPconsGetName(cons), considx, SCIPconsGetName(cons1), c);
3999 /* due to fixings in cons0 mark overlapping invalid for checking with fixedzero variables together */
4008 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> due to inclusion in constraint <%s> number <%d>\n", SCIPconsGetName(cons1), c, SCIPconsGetName(cons), considx);
4016 /* if cons has only one unfixed variable which is not in cons1 and cons1 has one variable which does not appear in
4017 * cons and both constraints are setpartitioning constraints we might aggregate both not overlapping variables and
4020 else if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && countofoverlapping[c] == nvars - oldnfixedzeros - 1 && countofoverlapping[c] == nvars1 - 1 ) /*lint !e641*/
4036 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
4055 /* all variables inside the second clique constraint should be either active or negated of an active one */
4056 assert(SCIPvarIsActive(vars1[v1]) || (SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1]))));
4057 /* all variables inside the first clique constraint should be either active or negated of an active one */
4058 assert(SCIPvarIsActive(vars[v]) || (SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v]))));
4068 assert(SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v])));
4081 assert(SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1])));
4086 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
4110 /* because the constraint's are merged it is not possible that one constraint contains a negated variable
4118 SCIPdebugMsg(scip, "two set-partitioning constraint <%s> and <%s> have only one variable not in common, but this variable <%s> appears in one constraint as the negated version as in the other constraint\n", SCIPconsGetName(cons), SCIPconsGetName(cons1), SCIPvarGetName(vars[v]));
4128 /* due to fixings, it is possible that there are no active variables left, we we did not recognize which variables we could aggregate */
4158 /* due to fixings, it is possible that there are no active variables left, we we did not recognize which variables we could aggregate */
4162 SCIPdebugMsg(scip, "memorize the aggregation of <%s> == <%s>, because they are the last two variable which are different in these two set partitioning constraints <%s> <%s>\n", SCIPvarGetName(aggvar1), SCIPvarGetName(aggvar2), SCIPconsGetName(cons), SCIPconsGetName(cons1));
4172 /* clear the aggregation type array to set the default to the aggregation of the form x + y = 1 */
4173 BMSclearMemoryArray(&(undoneaggrtypes[*naggregations]), *saggregations - *naggregations); /*lint !e866*/
4185 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> because it is dominated by constraint <%s>\n", SCIPconsGetName(cons1), c, SCIPconsGetName(cons));
4193 /* w.l.o.g. cons is a setpartitioning constraint and countofoverlapping == nvars - oldnfixedzeros - 1 we can
4194 * delete all overlapping variables in cons1 and add the negated variable of the not overlapped variable to cons
4197 else if( shrinking && !overlapdestroyed && countofoverlapping[c] > 1 && ((consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && countofoverlapping[c] == nvars - oldnfixedzeros - 1) || (consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && countofoverlapping[c] == nvars1 - 1)) ) /*lint !e641*/
4216 assert((consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING) != (consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING) || countofoverlapping[c] != nvars - 1 || countofoverlapping[c] != nvars1 - 1); /*lint !e641*/
4222 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
4228 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && countofoverlapping[c] == nvars - oldnfixedzeros - 1) /*lint !e641*/
4253 /* iterate over the both cliques variables the "same" time, here we need the backward loop, because we
4269 /* all variables inside the second clique constraint should be either active or negated of an active one */
4270 assert(SCIPvarIsActive(varstochange[v1]) || (SCIPvarGetStatus(varstochange[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstochange[v1]))));
4271 /* all variables inside the first clique constraint should be either active or negated of an active one */
4272 assert(SCIPvarIsActive(varstostay[v]) || (SCIPvarGetStatus(varstostay[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstostay[v]))));
4282 assert(SCIPvarGetStatus(varstostay[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstostay[v])));
4295 assert(SCIPvarGetStatus(varstochange[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstochange[v1])));
4300 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
4314 /* because the constraint's are merged it is not possible that one constraint contains a negated variable
4321 SCIPdebugMsg(scip, "-> trying to fix <%s> to 0 because it would exist twice in a constraint\n", SCIPvarGetName(varstochange[v1]));
4335 /* the above fixing is equal to the fixation of varstostay[v] to 1, so we can call presolvePropagateCons() for consstay */
4336 SCIP_CALL( presolvePropagateCons(scip, constostay, FALSE, NULL, NULL, NULL, NULL, nfixedvars, naggrvars, ndelconss, cutoff) );
4342 /* correct local data structure, remove variable from constraint entry where it will be removed */
4345 SCIPdebugMsg(scip, " -> deleting variable <%s> in constraint <%s> number %d, because it will be replaced\n", SCIPvarGetName(varstochange[v1]), SCIPconsGetName(constochange), constochangeidx);
4367 /* all variables inside the first clique constraint should be either active or negated of an active one */
4368 assert(SCIPvarIsActive(varstostay[v]) || (SCIPvarGetStatus(varstostay[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstostay[v]))));
4380 SCIPdebugMsg(scip, " -> adding variable <%s> to constraint <%s> number %d\n", SCIPvarGetName(addvar), SCIPconsGetName(constochange), constochangeidx);
4390 SCIP_CALL( addCliqueDataEntry(scip, addvar, constochangeidx, TRUE, usefulvars, nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs) );
4402 /** @todo try another variant by determine lifting variables as the intersection of all cliques variables of the
4413 SCIP_Bool** cliquevalues, /**< pointer to clique values of constraint-variables, either one if the
4440 int nottocheck; /* will be the position for a variable in cons0 which is in negated form in the same clique */
4493 /* check that constraint variables are still correctly sorted, indices of active variables should be decreasing */
4500 /* all variables which we have inside the clique constraint and which can possibly be added should be either active or negated */
4501 assert(SCIPvarIsActive(vars[v]) || (SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v]))));
4502 assert(SCIPvarIsActive(usefulvars[v1]) || (SCIPvarGetStatus(usefulvars[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(usefulvars[v1]))));
4504 /* constraint should during adding of variables stay merged, because for each variable which is added holds that
4505 * the index of this corresponding active variable is pairwise different to all indices of all active
4507 * @note it should not happen that we add one variable and the corresponding counterpart to the same constraint */
4515 assert(SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v])));
4527 assert(SCIPvarGetStatus(usefulvars[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(usefulvars[v1])));
4535 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
4541 /* variable index in the constraint is greater than the other one, so check for possible inclusion of the variable */
4553 assert(SCIPvarIsActive(vars[k]) || (SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k]))));
4562 assert(SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k])));
4571 /* variable index in the constraint is equal to the index of the other variable, check if these variables are
4572 * negated of each other so memorize the position and check for possible inclusion of the new variable and if
4593 assert(SCIPvarIsActive(vars[k]) || (SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k]))));
4605 assert(SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k])));
4614 /* don't decrease v because it might happen that the corresponding negated variable of var is next in
4620 /* if k is smaller than 0 than the possible new variables is in the same clique with all variables of cons,
4626 /* we found a variable which is the negated variable of another one in this clique so we can fix all
4627 * other variable to zero and if it's a partitioning constraint we can also fix the variable of the
4643 assert(SCIPvarIsActive(vars[k]) || (SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k]))));
4647 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because we could lift a negated variable of another constraint variable\n", SCIPvarGetName(vars[k]));
4666 assert(SCIPvarIsActive(vars[nottocheck]) || (SCIPvarGetStatus(vars[nottocheck]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[nottocheck]))));
4668 SCIPdebugMsg(scip, "trying to fix <%s> to 1 due to this setpartitioning variable is with its negated in the same clique\n", SCIPvarGetName(vars[nottocheck]));
4669 /* fix the remaining variable to one, due to it's the only one left to satisfy the constraint */
4683 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> due to active and negated variable in the same clique constraint\n", SCIPconsGetName(cons), arraypos);
4690 /* we found a variable which could be added to a partitioning constraint so we can fix it to zero */
4693 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because this variable is in the same clique with a set partition\n", SCIPvarGetName(usefulvars[v1 + 1]));
4708 /* we have found a new variable for a set packing constraint cons, so add the found variable to the first constraint */
4720 SCIPdebugMsg(scip, " -> adding variable <%s> to constraint <%s> number %d\n", SCIPvarGetName(usefulvars[v1 + 1]), SCIPconsGetName(cons), arraypos);
4730 SCIP_CALL( addCliqueDataEntry(scip, addvar, arraypos, FALSE, usefulvars, nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs) );
4732 /* we need the new pointer to the variables, because due to adding variables it is possible that we
4733 * did reallocate the variables array inside the constraint, the index v should stay the same because the
4772 assert(SCIPvarGetStatus(usefulvars[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(usefulvars[v1])));
4788 assert(SCIPvarIsActive(vars[k]) || (SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k]))));
4797 assert(SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k])));
4809 /* we found a variable which could be added to a partitioning constraint so we can fix it to zero */
4812 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because this variable is in the same clique with a set partition\n", SCIPvarGetName(usefulvars[v1]));
4839 SCIPdebugMsg(scip, " -> adding variable <%s> to constraint <%s> number %d\n", SCIPvarGetName(addvar), SCIPconsGetName(cons), arraypos);
4849 SCIP_CALL( addCliqueDataEntry(scip, addvar, arraypos, FALSE, usefulvars, nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs) );
4851 /* we need the new pointer to the variables, because due to adding variables it is possible that we
4852 * did reallocate the variables array inside the constraint, the index v should stay the same because the
4884 SCIP_Bool*const undoneaggrtypes, /**< aggregation type storage, type FALSE means the aggregation is of the
4914 SCIPdebugMsg(scip, "trying to aggregate <%s> %s <%s>%s\n", SCIPvarGetName(var1), undoneaggrtypes[a] ? "=" : "+", SCIPvarGetName(var2), undoneaggrtypes[a] ? "" : " = 1");
4917 /* in order to not mess up the variable usage counting, we have to decrease usage counting, aggregate,
4927 SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, -1.0, 0.0, cutoff, &redundant, &aggregated) );
4931 SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, 1.0, 1.0, cutoff, &redundant, &aggregated) );
4940 /* binary variables should always be aggregated, or due to fixation the aggregation is redundant */
4956 /** check whether we can combine or grow cliques so some constraints become redundant or we can fix variables */
4957 /** @todo try another variant, by building up the clique graph and delete unnecessary (transitive closure) edges and do
4977 /* extend cliques/constraints by checking whether some variables are in the same clique, no pairwise clique lifting
4980 SCIP_CONS** usefulconss; /* array with pointers of constraint of setpartitioning and setpacking type */
4981 SCIP_VAR** usefulvars; /* array with pointers of variables in setpartitioning and setpacking constraints */
4982 int** varconsidxs; /* array consisting of constraint indices in which the corresponding variable exists */
4986 SCIP_Bool* cliquevalues = NULL; /* values of clique-variables, either one if the variable is active or zero if the variable is negated */
5002 SCIP_Bool* undoneaggrtypes; /* storage for not yet performed aggregation type (x = y or x + y = 1) */
5028 susefulvars = 2 * nvars; /* two times because of negated vars, maybe due to deleted variables we need to increase this */
5030 /* a hashmap from varindex to postion in varconsidxs array, because above is still too small */
5033 /* get temporary memory for the aggregation storage, to memorize aggregations which will be performed later, otherwise we would destroy our local data structures */
5040 /* get temporary memory for all clique constraints, all appearing variables and the mapping from variables to constraints */
5073 /* try to create a clique-partition over all binary variables and create these cliques as new setppc constraints
5074 * and add them to the usefulconss array and adjust all necessary data this will hopefully lead to faster
5084 /* add extra clique constraints resulting from the cliquepartition calculation to SCIP and to the local data structure */
5085 SCIP_CALL( addExtraCliques(scip, binvars, nbinvars, cliquepartition, ncliques, usefulconss, &nusefulconss,
5088 /* bad hack, we don't want to count these artificial created constraints if they got deleted, so ndelconss
5089 * can become negative which will be change to zero at the end of this method if it's still negative
5100 /* start to collect setpartitioning and setpacking constraints, and try to remove fixed variables and merged these
5103 SCIP_CALL( collectCliqueConss(scip, conss, nconss, usefulconss, &nusefulconss, nfixedvars, ndelconss, nchgcoefs, cutoff) );
5104 /* @Note: Even after the call above some constraints can have fixed variables, because it might happen that caused by
5114 /* @todo: maybe sort them after biggest indices too, or another variant would be to restore the order as they were
5117 /* sort constraints first after type (partitioning before packing) and second after number of variables such that the
5118 * partitioning constraints have increasing number of variables and the packing constraints have decreasing number of
5119 * variables, because we loop from back to front we sort them downwards, so they are the other way around
5123 /* creating all necessary data in array structure, collect all clique constraint variables and occurrences */
5124 SCIP_CALL( collectCliqueData(scip, usefulconss, nusefulconss, usefulvars, &nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs, &maxnvars) );
5132 /* sort usefulvars after indices of variables, negated and active counterparts will stand side by side */
5135 /* extend cliques/constraints by checking whether some variables of a second constraint are in the same clique */
5154 /* check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
5157 SCIP_CALL( presolvePropagateCons(scip, cons0, FALSE, undoneaggrvars, undoneaggrtypes, &naggregations, &saggregations, nfixedvars, naggrvars, ndelconss, cutoff) );
5168 /* we need to determine the cliquedata in each iteration because we eventual will change it later */
5175 /* sorting array after indices of variables, negated and active counterparts will stand side by side */
5208 SCIP_CALL( checkForOverlapping(scip, cons0, c, c, usefulconss, nusefulconss, usefulvars, &nusefulvars, vartoindex,
5209 varnconss, maxnvarconsidx, varconsidxs, countofoverlapping, conshdlrdata->cliqueshrinking, &chgcons0,
5228 /* sorting array after indices of variables, negated and active counterparts will stand side by side */
5234 /* check cons0 again for redundancy/fixings, because due to fixings in all other constraints it might happen that cons0 is redundant now */
5237 /* check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
5240 SCIP_CALL( presolvePropagateCons(scip, cons0, FALSE, undoneaggrvars, undoneaggrtypes, &naggregations, &saggregations, nfixedvars, naggrvars, ndelconss, cutoff) );
5254 /* iterate over the cliques variables and all possible new clique variables at the "same" time, determine starting
5257 * @note: it might be better to start the first round with our computed v1, but maybe it's better to switch to
5261 /* we try to add all variables to the partitioning constraints, to try to fix as much as possible */
5271 /* find start position of variable which we will try to add to our constraint, so we will get better clique constraints */
5272 (void) SCIPsortedvecFindDownPtr((void**)usefulvars, SCIPvarCompActiveAndNegated, (void*)cons0vars[ncons0vars - 1], nusefulvars, &v1);
5274 /* if constraint is not merged and we found a variable which is negated the same as it's neighbour we have to
5276 if( v1 + 1 < nusefulvars && ((SCIPvarIsNegated(usefulvars[v1 + 1]) && SCIPvarGetNegatedVar(usefulvars[v1 + 1]) == usefulvars[v1]) || (SCIPvarIsNegated(usefulvars[v1]) && SCIPvarGetNegatedVar(usefulvars[v1]) == usefulvars[v1 + 1])) )
5288 assert(SCIPvarIsActive(cons0vars[v]) || (SCIPvarGetStatus(cons0vars[v]) == SCIP_VARSTATUS_NEGATED &&
5297 SCIP_CALL( liftCliqueVariables(scip, cons0, c, usefulvars, &nusefulvars, v1, &cliquevalues, vartoindex, varnconss,
5347 /* check for overlapping constraint after lifting, in the first round we will only check up front */
5348 SCIP_CALL( checkForOverlapping(scip, cons0, c, (conshdlrdata->nclqpresolve > 0) ? nusefulconss : c,
5349 usefulconss, nusefulconss, usefulvars, &nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs,
5366 /* free temporary memory for constraints, variables and the mapping between them in reverse order as they were
5386 SCIP_CALL( performAggregations(scip, conshdlrdata, undoneaggrvars, undoneaggrtypes, naggregations, naggrvars, cutoff) );
5454 if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING )
5457 ((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING), &infeasible, &nlocalbdchgs) );
5468 /* a two-variable set covering constraint x + y >= 1 yields the implication x == 0 -> y == 1 */
5486 /** perform multi-aggregation on variables resulting from a set-partitioning/-packing constraint */
5490 SCIP_Bool linearconshdlrexist,/**< does the linear constraint handler exist, necessary for multi-aggregations */
5491 SCIP_VAR** vars, /**< all variables including the variable to which will be multi-aggregated */
5496 )
5513 SCIPdebugMsg(scip, "aggregating %s = 1 - %s\n", SCIPvarGetName(vars[pos]), SCIPvarGetName(vars[nvars - pos - 1]));
5516 SCIP_CALL( SCIPaggregateVars(scip, vars[pos], vars[nvars - pos - 1], 1.0, 1.0, 1.0, infeasible, &redundant, aggregated) );
5543 SCIPdebugMsg(scip, "multi-aggregating binary variable <%s> (locks: [%d,%d]; to %d variables)\n",
5548 SCIP_CALL( SCIPmultiaggregateVar(scip, vars[pos], nvars - 1, tmpvars, scalars, 1.0, infeasible, aggregated) );
5562 /** determine singleton variables in set-partitioning/-packing constraints, or doubleton variables (active and negated)
5565 * we can multi-aggregate the variable and either change the set-partitioning constraint to a set-packing constraint or
5568 * 1. c1: x + y + z = 1, uplocks(x) = 1, downlocks(x) = 1 => x = 1 - y - z and change c1 to y + z <= 1
5570 * 2. c2: x + y + z <= 1, uplocks(x) = 1, downlocks(x) = 0, obj(x) < 0 => x = 1 - y - z and change c2 to y + z <= 1
5576 * 4. e1: x + y + z == 1 and e2: ~x + u + v (<= or ==) 1, uplocks(x) = (1 or 2), downlocks(x) = 2
5579 * we can also aggregate a variable in a set-packing constraint with only two variables when the uplocks are equal to
5584 * @todo might want to multi-aggregate variables even with more locks, when the fill in is still smaller or equal to
5658 if( (nuplocks == 1 && ndownlocks <= 1) || (nuplocks <= 1 && ndownlocks == 1) || (nuplocks <= 2 && ndownlocks <= 2 && SCIPvarGetNegatedVar(binvars[v]) != NULL) )
5689 /* determine singleton variables in set-partitioning/-packing constraints, or doubleton variables (active and
5692 * we can multi-aggregate the variable and either change the set-partitioning constraint to a set-packing constraint
5763 /* if the constraint was not merged and consists of a variable with its negation, the constraint is redundant */
5784 SCIPdebugMsg(scip, "empty set partition constraint <%s> led to infeasibility\n", SCIPconsGetName(cons));
5790 SCIPdebugMsg(scip, "fixing <%s> to 1 because this variable is the last variable in a set partition constraint <%s>\n", SCIPvarGetName(consdata->vars[0]), SCIPconsGetName(cons));
5800 SCIPdebugMsg(scip, "deleting redundant set-partition constraint <%s>\n", SCIPconsGetName(cons));
5810 if( !donotaggr && consdata->nvars == 2 && dualpresolvingenabled && (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING )