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*/
60 #define CONSHDLR_ENFOPRIORITY -700000 /**< priority of the constraint handler for constraint enforcing */
61 #define CONSHDLR_CHECKPRIORITY -700000 /**< priority of the constraint handler for checking feasibility */
62 #define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
63 #define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
64 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
66 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
67 #define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
68 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
69 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
74 #define LINCONSUPGD_PRIORITY +700000 /**< priority of the constraint handler for upgrading of linear constraints */
75 #define QUADCONSUPGD_PRIORITY +700000 /**< priority of the constraint handler for upgrading of linear constraints */
78 #define EVENTHDLR_DESC "bound change event handler for set partitioning / packing / covering constraints"
84 #define DEFAULT_PRESOLPAIRWISE TRUE /**< should pairwise constraint comparison be performed in presolving? */
87 #define DEFAULT_PRESOLUSEHASHING TRUE /**< should hash table be used for detecting redundant constraints in advance */
89 #define MINGAINPERNMINCOMPARISONS 1e-06 /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
93 /*#define VARUSES*/ /* activate variable usage counting, that is necessary for LP and pseudo branching */
94 /*#define BRANCHLP*/ /* BRANCHLP is only useful if the ENFOPRIORITY is set to a positive value */
99 #define DEFAULT_NPSEUDOBRANCHES 2 /**< number of children created in pseudo branching (0: disable branching) */
102 #define DEFAULT_CLIQUELIFTING FALSE /**< should we try to lift variables into other clique constraints, fix
106 #define DEFAULT_ADDVARIABLESASCLIQUES FALSE/**< should we try to generate extra clique constraint out of all binary
109 #define DEFAULT_CLIQUESHRINKING TRUE /**< should we try to shrink the number of variables in a clique constraints, by
113 /* @todo maybe use event SCIP_EVENTTYPE_VARUNLOCKED to decide for another dual-presolving run on a constraint */
123 SCIP_CONSHDLR* conshdlrlinear; /**< pointer to linear constraint handler or NULL if not included */
128 int npseudobranches; /**< number of children created in pseudo branching (0 to disable branching) */
136 SCIP_Bool enablecliquelifting;/**< check whether we have enough changes to run the lifting procedure again */
140 SCIP_Bool addvariablesascliques;/**< should we try to generate extra clique constraint out of all binary
144 SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
145 SCIP_Bool presolusehashing; /**< should hash table be used for detecting redundant constraints in advance */
161 unsigned int cliqueadded:1; /**< was the set partitioning / packing constraint already added as clique? */
163 unsigned int changed:1; /**< was constraint changed since last redundancy round in preprocessing? */
166 unsigned int presolpropagated:1; /**< was the constraint already propagated in presolving w.r.t. the current domains? */
178 /** compares two active constraints of type set partitioning or set packing such that a "-1" is return if
180 * 2. both constraints are set partitioning constraints and the second has more! variables than the first or
181 * 3. both constraints are set packing constraints and the second has less! variables than the first
211 (consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->nvars < consdata2->nvars) || /*lint !e641*/
212 (consdata2->setppctype == SCIP_SETPPCTYPE_PACKING && consdata1->nvars > consdata2->nvars) ) /*lint !e641*/
214 else if( (consdata1->setppctype == consdata2->setppctype && consdata1->nvars == consdata2->nvars) ) /*lint !e641*/
218 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*/
223 /** sort constraints first after type (partitioning before packing before covering) and second after number of
224 * variables such that the partitioning constraints have increasing number of variables and the packing constraints
232 /** compares two setppc constraints such that a "-1" is return if the first constraint is active and
235 * 3. both constraints are set partitioning constraints and the second has more! variables than the first or
236 * 4. both constraints are set packing constraints and the second has less! variables than the first
270 assert(SCIP_SETPPCTYPE_PARTITIONING < SCIP_SETPPCTYPE_PACKING && SCIP_SETPPCTYPE_PACKING < SCIP_SETPPCTYPE_COVERING); /*lint !e506*/
274 (((SCIP_SETPPCTYPE)consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->nvars < consdata2->nvars) ||
275 ((SCIP_SETPPCTYPE)consdata2->setppctype == SCIP_SETPPCTYPE_PACKING && consdata1->nvars > consdata2->nvars))) )
277 else if( ((SCIP_SETPPCTYPE)consdata2->setppctype == SCIP_SETPPCTYPE_COVERING || (consdata1->setppctype == consdata2->setppctype && consdata1->nvars == consdata2->nvars)) )
281 assert(consdata1->setppctype > consdata2->setppctype || ((consdata1->setppctype == consdata2->setppctype) &&
283 || (consdata1->setppctype == SCIP_SETPPCTYPE_PACKING && consdata1->nvars < consdata2->nvars)))); /*lint !e641*/
288 /** sort constraints first after type (partitioning before packing before covering) and second after number of
289 * variables such that the partitioning constraints have increasing number of variables and the packing constraints
362 /** creates constraint handler data for set partitioning / packing / covering constraint handler */
391 /** frees constraint handler data for set partitioning / packing / covering constraint handler */
431 /* if the variable is the negation of a problem variable, count the varuses in the problem variable */
559 SCIP_CONSDATA** consdata, /**< pointer to store the set partitioning / packing / covering constraint */
562 SCIP_SETPPCTYPE setppctype /**< type of constraint: set partitioning, packing, or covering constraint */
581 /* @todo the setppc constraint handler does not remove fixed variables from its var array; removing those
582 * variables is only possible if we consider the values of nfixedones and nfixedzeros in all propagation methods
632 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
639 (*consdata)->existmultaggr = (*consdata)->existmultaggr || (SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
675 SCIP_CONSDATA** consdata, /**< pointer to store the set partitioning / packing / covering constraint */
678 SCIP_SETPPCTYPE setppctype /**< type of constraint: set partitioning, packing, or covering constraint */
688 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
697 SCIP_CONSDATA** consdata /**< pointer to store the set partitioning / packing / covering constraint */
834 SCIPdebugMsg(scip, " -> converting <%s> into setppc type %d\n", SCIPconsGetName(cons), setppctype);
911 * - SCIP_EVENTTYPE_BOUNDCHANGED: Is used to count the number of variable fixed locally to zero and one. That helps
916 * - SCIP_EVENTTYPE_VARFIXED: Is used to get informed if a variable of the constraint was aggregated which means was
931 /* during presolving, we may fix the last unfixed variable or do an aggregation if there are two unfixed variables */
932 if( SCIPconsIsActive(cons) && ((SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE) && (consdata->nfixedzeros >= consdata->nvars - 2)) )
1106 if( !consdata->existmultaggr && SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_MULTAGGR )
1176 /* the last variable of the constraint was deleted; mark it for propagation (so that it can be deleted) */
1205 /** in case a part (more than one variable) in the setppc constraint is independent of every else (is locked only by
1217 * (ii) a variable x has exactly 0 uplocks and arbitrary downlocks and a variable y has exactly 1 downlock and
1229 * (ii) a variable x has exactly 1 uplock and arbitrary downlocks and a variable y has exactly 1 downlock and
1238 * - fix the variable with the smallest object coefficient to one if the object coefficient is negative or zero
1241 * (ii) a variable x has exactly 1 uplock and arbitrary downlocks and a variable y has exactly 0 downlocks and
1247 * Note: the following dual reduction for set covering and set packing constraints is already performed by the presolver
1250 * - if a variable in a set covering constraint is only locked by that constraint and has negative or zero
1253 * - if a variable in a set packing constraint is only locked by that constraint and has positive or zero
1256 * Note: all dual reduction (ii) could also be performed by the "domcol" presolver, but cause the pairwise comparison of
1257 * columns is only done heuristically (and here it should be even cheaper) we perform them here (too)
1266 SCIP_RESULT* result /**< pointer to store the result SCIP_SUCCESS, if presolving was performed */
1294 /* constraints for which the check flag is set to FALSE, did not contribute to the lock numbers; therefore, we cannot
1295 * use the locks to decide for a dual reduction using this constraint; for example after a restart the cuts which are
1306 /* modifiable non-covering constraints cannot be deleted if one variable is fixed to one, because the propagation for
1318 /* we don't want to consider small constraints (note that the constraints can be modifiable, so we can't delete this
1352 /* check if we can apply the dual reduction; therefore count the number of variables where the setppc has the only
1386 /* in case another constraint has also downlocks on that variable we cannot perform a dual reduction on these
1418 /* in case another constraint has also downlocks on that variable we cannot perform a dual reduction on these
1448 /* if we got a set covering constraint and not all variables are locked from this constraint it might not get
1449 * redundant (which is case if it is not possible to fix at least one variable to one), we fix all redundant
1463 /* in case another constraint has also downlocks on that variable we cannot perform a dual reduction on these
1476 || (SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == SCIPvarGetNLocksDownType(activevar, SCIP_LOCKTYPE_MODEL)
1477 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == SCIPvarGetNLocksUpType(activevar, SCIP_LOCKTYPE_MODEL)));
1479 || (SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == SCIPvarGetNLocksUpType(activevar, SCIP_LOCKTYPE_MODEL)
1480 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == SCIPvarGetNLocksDownType(activevar, SCIP_LOCKTYPE_MODEL)));
1492 /* if variables has a negative objective contribution, and is uplocked by another constraint we cannot fix
1495 if( (fixval == 1.0 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) > nlockups) || objval < bestobjval )
1502 SCIPdebugMsg(scip, " -> dual-fixed dominated variable <%s> == %g\n", SCIPvarGetName(var), fixval);
1508 /* if all variables but the domination variable is fixed and the constraint is not modifiable or the constraint is a
1509 * covering constraint and the bestobjval is less than or equal to zero, we can fix the domination variable (with best
1512 if( ((*nfixedvars - noldfixed == nvars - 1) && !SCIPconsIsModifiable(cons)) || (setppctype == SCIP_SETPPCTYPE_COVERING && bestobjval <= 0.0) )
1514 /* in case of a set packing constraint with positive objective values, all variables can be fixed to zero; in all
1530 SCIPdebugMsg(scip, " -> dual-fixed best variable <%s> == %g\n", SCIPvarGetName(vars[idx]), fixval);
1570 {
1613 assert(SCIPvarIsActive(var1) || SCIPvarGetStatus(var1) == SCIP_VARSTATUS_NEGATED || SCIPvarGetStatus(var1) == SCIP_VARSTATUS_FIXED);
1623 assert(SCIPvarIsActive(var2) || SCIPvarGetStatus(var2) == SCIP_VARSTATUS_NEGATED || SCIPvarGetStatus(var2) == SCIP_VARSTATUS_FIXED);
1692 SCIP_CALL( delCoefPos(scip, cons, v) ); /* only some changed behind position v-1, so it's okay */
1757 if( SCIPvarGetStatus(repvar) == SCIP_VARSTATUS_MULTAGGR || (SCIPvarGetStatus(repvar) == SCIP_VARSTATUS_NEGATED && SCIPvarGetStatus(SCIPvarGetNegatedVar(repvar)) == SCIP_VARSTATUS_MULTAGGR) )
1774 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
1781 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
1827 SCIPdebugMsg(scip, "trying to fix <%s> to 0 due to at least one variable is already fixed to 1\n", SCIPvarGetName(consdata->vars[v2]));
1849 if( ndelconss != NULL && (nfixedvars != NULL || consdata->nvars == 1 || (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_COVERING) )
1872 assert(SCIPvarIsActive(consvars[v2]) || (SCIPvarGetStatus(consvars[v2]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(consvars[v2]))));
1887 /* it might happen that there are more than one multi-aggregated variable, so we need to get the whole
1893 /* memory needed is at least old number of variables - 1 + number of variables in first multi-aggregation */
1909 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, size, &constant, &requiredsize, TRUE) );
1911 /* if space was not enough (we found another multi-aggregation), we need to resize the buffers */
1917 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
1978 SCIPwarningMessage(scip, "setppc constraint <%s> has a multi-aggregated variable, which was not resolved and therefore could lead to aborts\n", SCIPconsGetName(cons));
2009 /** analyzes conflicting assignment on given constraint where all of the variables where assigned to zero,
2015 SCIP_CONS* cons /**< set partitioning / packing / covering constraint that detected the conflict */
2022 if( (SCIPgetStage(scip) != SCIP_STAGE_SOLVING && !SCIPinProbing(scip)) || !SCIPisConflictAnalysisApplicable(scip) )
2030 /* initialize conflict analysis, and add all variables of infeasible constraint to conflict candidate queue */
2044 /** analyzes conflicting assignment on given constraint where two of the variables where assigned to one,
2050 SCIP_CONS* cons /**< set partitioning / packing / covering constraint that detected the conflict */
2058 if( (SCIPgetStage(scip) != SCIP_STAGE_SOLVING && !SCIPinProbing(scip)) || !SCIPisConflictAnalysisApplicable(scip) )
2066 /* initialize conflict analysis, and add the two variables assigned to one to conflict candidate queue */
2086 /** checks constraint for violation only looking at the fixed variables, applies further fixings if possible */
2094 SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
2096 {
2123 /*SCIPdebugMsg(scip, "processing constraint <%s> with respect to fixed variables (%d fixed to 0.0, %d fixed to 1.0)\n",
2152 SCIPdebugMsg(scip, " -> fixing all other variables to zero in set packing/partitioning constraint <%s>\n",
2156 * this could result in additional variables fixed to one due to aggregations; in this case, the
2167 assert(SCIPisFeasZero(scip, SCIPvarGetUbLocal(var)) || SCIPisFeasEQ(scip, SCIPvarGetUbLocal(var), 1.0));
2186 /* the fixed to one variable must have been found, and at least one variable must have been fixed */
2197 SCIPdebugMsg(scip, " -> disabling set packing/partitioning constraint <%s>\n", SCIPconsGetName(cons));
2217 SCIPdebugMsg(scip, " -> conflict on set packing/partitioning constraint <%s>\n", SCIPconsGetName(cons));
2232 * - a set partitioning or covering constraint is infeasible, and if it's unmodifiable, the node
2248 SCIPdebugMsg(scip, " -> set covering/partitioning constraint <%s> is infeasible\n", SCIPconsGetName(cons));
2267 * - an unmodifiable set partitioning or covering constraint is feasible and can be disabled after the
2296 assert(SCIPisFeasZero(scip, SCIPvarGetUbLocal(var)) || SCIPisFeasEQ(scip, SCIPvarGetUbLocal(var), 1.0));
2299 SCIPdebugMsg(scip, " -> fixing remaining variable <%s> to one in set covering/partitioning constraint <%s>\n",
2326 SCIP_CONSDATA* consdata, /**< set partitioning / packing / covering constraint to be checked */
2344 sumbound = ((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_COVERING ? 1.0 : 1.0 + 2*SCIPfeastol(scip));
2345 for( v = 0; v < nvars && sum < sumbound; ++v ) /* if sum >= sumbound, the feasibility is clearly decided */
2360 /* in case of partitioning, the violation is equal to the absolute difference between sum and 1 */
2424 SCIP_CALL( SCIPaddVarsToRowSameCoef(scip, consdata->row, consdata->nvars, consdata->vars, 1.0) );
2472 )
2499 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
2558 {
2572 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
2617 /** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables */
2740 /* @todo: maybe sort cliques and accordingly the variables so it will be faster to add the constraints */
2749 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "extra_clq_%d_round_%d", cliquepartition[c], nrounds);
2763 /* @todo: try to find a good value for what are enough variables to create this constraint, maybe at least
2808 /** start to collect setpartitioning and setpacking constraints, and try to remove fixed variables and merged these
2849 /* we only want to consider constraints with either active or negated of active variables, applyfixings removes
2850 * aggregated and fixed variables to zero, processFixings removes fixings to one but no aggregation
2886 /* @todo: check for covering constraints with only two variables which are equal to a packing constraint with
2890 assert(consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
2900 /** creating all necessary data in array structure, collect all clique constraint variables and occurrences,
2911 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
2913 int**const varconsidxs, /**< storage for constraint indices in which the corresponding variable exists */
2947 /* here we should have no covering constraints anymore and the constraint data should be merged */
2948 assert(consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
2968 assert(SCIPvarIsActive(var) || (SCIPvarIsNegated(var) && SCIPvarIsActive(SCIPvarGetNegationVar(var))));
2983 SCIP_CALL( SCIPallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
2991 /* the number of occurrences of a variable is not limited by the locks (so maybe we have to increase memory),
2992 * because for examples converted cuts are not check and therefore they have no locks on their variables */
2996 SCIP_CALL( SCIPreallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
3016 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
3017 int**const varconsidxs /**< storage for constraint indices in which the corresponding variable exists */
3062 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
3064 int**const varconsidxs /**< storage for constraint indices in which the corresponding variable exists */
3083 assert(SCIPvarGetNegatedVar(addvar) != NULL && SCIPhashmapExists(vartoindex, (void*) SCIPvarGetNegatedVar(addvar)));
3085 /* @note because we can only have created a negated variable, and we already allocated enough memory for
3088 SCIPsortedvecInsertDownPtr((void**)usefulvars, SCIPvarCompActiveAndNegated, addvar, nusefulvars, NULL);
3095 SCIP_CALL( SCIPallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
3106 SCIP_CALL( SCIPreallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
3119 /** check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
3127 SCIP_VAR** undoneaggrvars, /**< array to store aggregation variables, if aggregation is not performed
3131 SCIP_Bool* undoneaggrtypes, /**< array to store aggregation type, if aggregation is not performed yet;
3135 int*const naggregations, /**< pointer to store number of aggregations which are not yet performed;
3138 int*const saggregations, /**< pointer to store size of the array for aggregation type and two times
3178 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
3180 SCIPdebugMsg(scip, "empty set-partition/-covering constraint <%s> found -> cutoff\n", SCIPconsGetName(cons));
3190 SCIPdebugMsg(scip, " -> deleting constraint <%s>, no variables left\n", SCIPconsGetName(cons));
3208 SCIPdebugMsg(scip, " -> deleting set-covering constraint <%s>, at least two variables are fixed to 1\n", SCIPconsGetName(cons));
3215 SCIPdebugMsg(scip, "set partitioning / packing constraint <%s> is infeasible, %d variables fixed to one\n", SCIPconsGetName(cons), consdata->nfixedones);
3227 if( consdata->setppctype != SCIP_SETPPCTYPE_COVERING && consdata->nfixedzeros < nvars - 1 ) /*lint !e641*/
3235 SCIPdebugMsg(scip, "trying to fix <%s> to 0 due to at least one variable is already fixed to 1\n", SCIPvarGetName(vars[v]));
3253 if( !SCIPconsIsModifiable(cons) || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
3256 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all variables are fixed\n", SCIPconsGetName(cons));
3271 /* all variables were fixed to zero then either delete the constraint or stop with infeasibility */
3280 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
3282 SCIPdebugMsg(scip, "set partitioning / covering constraint <%s> is infeasible\n", SCIPconsGetName(cons));
3289 SCIPdebugMsg(scip, " -> deleting set-packing constraint <%s>, all variables are fixed to zero\n", SCIPconsGetName(cons));
3297 /* all but one variable were fixed to zero then delete the constraint and for setpartition fix the remaining variable to 1 */
3307 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
3315 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]));
3336 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all %svariables are fixed\n", SCIPconsGetName(cons), consdata->setppctype == (int) SCIP_SETPPCTYPE_PACKING ? "but one " : "");
3344 /* all but two variable were fixed to zero in a setpartitioning constraint then delete the constraint and
3347 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata->nfixedzeros + 2 == nvars ) /*lint !e641*/
3376 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));
3379 /* in order to not mess up the variable usage counting, we have to decrease usage counting, aggregate,
3387 SCIP_CALL( SCIPaggregateVars(scip, var, vars[v], 1.0, 1.0, 1.0, cutoff, &redundant, &aggregated) );
3408 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all variables are fixed\n", SCIPconsGetName(cons));
3421 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));
3431 /* clear the aggregation type array to set the default to the aggregation of the form x + y = 1 */
3432 BMSclearMemoryArray(&(undoneaggrtypes[*naggregations]), *saggregations - *naggregations); /*lint !e866*/
3444 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all variables are fixed\n", SCIPconsGetName(cons));
3455 /* we should never be here, because the last to unfixed variables should have been either aggregated or a cutoff
3476 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
3478 int**const varconsidxs, /**< storage for constraint indices in which the corresponding variable exists */
3479 int*const countofoverlapping, /**< the amount of variables of cons which overlap in all other constraint */
3484 SCIP_VAR** undoneaggrvars, /**< array to store aggregation variables, if aggregation is not performed
3487 SCIP_Bool* undoneaggrtypes, /**< array to store aggregation type, if aggregation is not performed yet;
3491 int*const naggregations, /**< pointer to store number of aggregations which are not yet performed; */
3492 int*const saggregations, /**< pointer to store size of the array for aggregation type and two times
3575 /* check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
3578 SCIP_CALL( presolvePropagateCons(scip, cons1, FALSE, undoneaggrvars, undoneaggrtypes, naggregations, saggregations, nfixedvars, naggrvars, ndelconss, cutoff) );
3603 SCIPdebugMsg(scip, "constraint <%s> overlaps with constraint <%s> by %d variables\n", SCIPconsGetName(cons), SCIPconsGetName(cons1), countofoverlapping[c]);
3624 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
3643 /* all variables inside the second clique constraint should be either active or negated of an active one */
3644 assert(SCIPvarIsActive(vars1[v1]) || (SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1]))));
3672 assert(SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1])));
3679 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
3685 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]));
3702 /* because the constraint's are merged it is not possible that one constraint contains a negated
3718 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]));
3734 /* if caused by all fixings now this set partitioning constraint doesn't have any variable which was
3736 if( consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->nfixedzeros == nvars1 && consdata1->nfixedones != 1 ) /*lint !e641*/
3738 SCIPdebugMsg(scip, "all variables in the set-partitioning constraint <%s> are fixed to zero, this leads to a cutoff\n", SCIPconsGetName(cons1));
3746 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> because it includes the setpartitioning constraint <%s> number <%d>\n", SCIPconsGetName(cons1), c, SCIPconsGetName(cons), considx);
3752 /* could already be deleted because the constraint was included in another set partition constraint */
3756 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> due to inclusion in constraint <%s> number <%d>\n", SCIPconsGetName(cons), considx, SCIPconsGetName(cons1), c);
3765 * @note that zero fixations from above can only appear through a set-partitioning constraint, this means if
3766 * cons was the set-partitioning constraint only variables which are not in this constraint could be fixed
3767 * to zero, and this also means that the overlapping variables in this particular case are still active or
3769 * later on it could be possible that even variables in cons are fixed to zero, which can lead to wrong
3770 * results when checking if countofoverlapping[c] + consdata1->nfixedzeros == nvars1, because a fixed
3773 else if( (!overlapdestroyed && countofoverlapping[c] + consdata1->nfixedzeros == nvars1) || countofoverlapping[c] == nvars1 )
3789 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
3808 /* all variables inside the second clique constraint should be either active or negated of an active one */
3809 assert(SCIPvarIsActive(vars1[v1]) || (SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1]))));
3810 /* all variables inside the first clique constraint should be either active or negated of an active one */
3811 assert(SCIPvarIsActive(vars[v]) || (SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v]))));
3823 assert(SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v])));
3840 assert(SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1])));
3847 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
3850 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because it is in the same clique with a complete set partitioning constraint\n", SCIPvarGetName(var));
3871 /* because the constraint's are merged it is not possible that one constraint contains a negated
3872 * variable of another and because all variables in cons1 are in cons this should be really the same
3888 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]));
3903 /* if caused by all fixings now this set partitioning constraint doesn't have any variable which was
3905 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata->nfixedzeros == nvars && consdata->nfixedones != 1 ) /*lint !e641*/
3907 SCIPdebugMsg(scip, "all variables in the set-partitioning constraint <%s> are fixed to zero, this leads to a cutoff\n", SCIPconsGetName(cons1));
3913 /* could already be deleted because the constraint was included in another set partition constraint */
3917 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> because it includes the setpartitioning constraint <%s> number <%d>\n", SCIPconsGetName(cons), considx, SCIPconsGetName(cons1), c);
3925 /* due to fixings in cons0 mark overlapping invalid for checking with fixedzero variables together */
3934 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> due to inclusion in constraint <%s> number <%d>\n", SCIPconsGetName(cons1), c, SCIPconsGetName(cons), considx);
3942 /* if cons has only one unfixed variable which is not in cons1 and cons1 has one variable which does not appear in
3943 * cons and both constraints are setpartitioning constraints we might aggregate both not overlapping variables and
3946 else if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && countofoverlapping[c] == nvars - oldnfixedzeros - 1 && countofoverlapping[c] == nvars1 - 1 ) /*lint !e641*/
3962 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
3981 /* all variables inside the second clique constraint should be either active or negated of an active one */
3982 assert(SCIPvarIsActive(vars1[v1]) || (SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1]))));
3983 /* all variables inside the first clique constraint should be either active or negated of an active one */
3984 assert(SCIPvarIsActive(vars[v]) || (SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v]))));
3994 assert(SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v])));
4007 assert(SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1])));
4012 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
4036 /* because the constraint's are merged it is not possible that one constraint contains a negated variable
4044 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]));
4054 /* due to fixings, it is possible that there are no active variables left, we we did not recognize which variables we could aggregate */
4084 /* due to fixings, it is possible that there are no active variables left, we we did not recognize which variables we could aggregate */
4088 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));
4098 /* clear the aggregation type array to set the default to the aggregation of the form x + y = 1 */
4099 BMSclearMemoryArray(&(undoneaggrtypes[*naggregations]), *saggregations - *naggregations); /*lint !e866*/
4111 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> because it is dominated by constraint <%s>\n", SCIPconsGetName(cons1), c, SCIPconsGetName(cons));
4119 /* w.l.o.g. cons is a setpartitioning constraint and countofoverlapping == nvars - oldnfixedzeros - 1 we can
4120 * delete all overlapping variables in cons1 and add the negated variable of the not overlapped variable to cons
4123 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*/
4142 assert((consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING) != (consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING) || countofoverlapping[c] != nvars - 1 || countofoverlapping[c] != nvars1 - 1); /*lint !e641*/
4148 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
4154 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && countofoverlapping[c] == nvars - oldnfixedzeros - 1) /*lint !e641*/
4179 /* iterate over the both cliques variables the "same" time, here we need the backward loop, because we
4195 /* all variables inside the second clique constraint should be either active or negated of an active one */
4196 assert(SCIPvarIsActive(varstochange[v1]) || (SCIPvarGetStatus(varstochange[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstochange[v1]))));
4197 /* all variables inside the first clique constraint should be either active or negated of an active one */
4198 assert(SCIPvarIsActive(varstostay[v]) || (SCIPvarGetStatus(varstostay[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstostay[v]))));
4208 assert(SCIPvarGetStatus(varstostay[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstostay[v])));
4221 assert(SCIPvarGetStatus(varstochange[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstochange[v1])));
4226 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
4240 /* because the constraint's are merged it is not possible that one constraint contains a negated variable
4247 SCIPdebugMsg(scip, "-> trying to fix <%s> to 0 because it would exist twice in a constraint\n", SCIPvarGetName(varstochange[v1]));
4261 /* the above fixing is equal to the fixation of varstostay[v] to 1, so we can call presolvePropagateCons() for consstay */
4262 SCIP_CALL( presolvePropagateCons(scip, constostay, FALSE, NULL, NULL, NULL, NULL, nfixedvars, naggrvars, ndelconss, cutoff) );
4268 /* correct local data structure, remove variable from constraint entry where it will be removed */
4271 SCIPdebugMsg(scip, " -> deleting variable <%s> in constraint <%s> number %d, because it will be replaced\n", SCIPvarGetName(varstochange[v1]), SCIPconsGetName(constochange), constochangeidx);
4293 /* all variables inside the first clique constraint should be either active or negated of an active one */
4294 assert(SCIPvarIsActive(varstostay[v]) || (SCIPvarGetStatus(varstostay[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstostay[v]))));
4306 SCIPdebugMsg(scip, " -> adding variable <%s> to constraint <%s> number %d\n", SCIPvarGetName(addvar), SCIPconsGetName(constochange), constochangeidx);
4316 SCIP_CALL( addCliqueDataEntry(scip, addvar, constochangeidx, TRUE, usefulvars, nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs) );
4328 /** @todo try another variant by determine lifting variables as the intersection of all cliques variables of the
4339 SCIP_Bool** cliquevalues, /**< pointer to clique values of constraint-variables, either one if the
4366 int nottocheck; /* will be the position for a variable in cons0 which is in negated form in the same clique */
4419 /* check that constraint variables are still correctly sorted, indices of active variables should be decreasing */
4426 /* all variables which we have inside the clique constraint and which can possibly be added should be either active or negated */
4427 assert(SCIPvarIsActive(vars[v]) || (SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v]))));
4428 assert(SCIPvarIsActive(usefulvars[v1]) || (SCIPvarGetStatus(usefulvars[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(usefulvars[v1]))));
4430 /* constraint should during adding of variables stay merged, because for each variable which is added holds that
4431 * the index of this corresponding active variable is pairwise different to all indices of all active
4433 * @note it should not happen that we add one variable and the corresponding counterpart to the same constraint */
4441 assert(SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[v])));
4453 assert(SCIPvarGetStatus(usefulvars[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(usefulvars[v1])));
4461 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
4467 /* variable index in the constraint is greater than the other one, so check for possible inclusion of the variable */
4479 assert(SCIPvarIsActive(vars[k]) || (SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k]))));
4488 assert(SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k])));
4497 /* variable index in the constraint is equal to the index of the other variable, check if these variables are
4498 * negated of each other so memorize the position and check for possible inclusion of the new variable and if
4519 assert(SCIPvarIsActive(vars[k]) || (SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k]))));
4531 assert(SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k])));
4540 /* don't decrease v because it might happen that the corresponding negated variable of var is next in
4546 /* if k is smaller than 0 than the possible new variables is in the same clique with all variables of cons,
4552 /* we found a variable which is the negated variable of another one in this clique so we can fix all
4553 * other variable to zero and if it's a partitioning constraint we can also fix the variable of the
4569 assert(SCIPvarIsActive(vars[k]) || (SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k]))));
4573 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because we could lift a negated variable of another constraint variable\n", SCIPvarGetName(vars[k]));
4592 assert(SCIPvarIsActive(vars[nottocheck]) || (SCIPvarGetStatus(vars[nottocheck]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[nottocheck]))));
4594 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]));
4595 /* fix the remaining variable to one, due to it's the only one left to satisfy the constraint */
4609 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> due to active and negated variable in the same clique constraint\n", SCIPconsGetName(cons), arraypos);
4616 /* we found a variable which could be added to a partitioning constraint so we can fix it to zero */
4619 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]));
4634 /* we have found a new variable for a set packing constraint cons, so add the found variable to the first constraint */
4646 SCIPdebugMsg(scip, " -> adding variable <%s> to constraint <%s> number %d\n", SCIPvarGetName(usefulvars[v1 + 1]), SCIPconsGetName(cons), arraypos);
4656 SCIP_CALL( addCliqueDataEntry(scip, addvar, arraypos, FALSE, usefulvars, nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs) );
4658 /* we need the new pointer to the variables, because due to adding variables it is possible that we
4659 * did reallocate the variables array inside the constraint, the index v should stay the same because the
4698 assert(SCIPvarGetStatus(usefulvars[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(usefulvars[v1])));
4714 assert(SCIPvarIsActive(vars[k]) || (SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k]))));
4723 assert(SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[k])));
4735 /* we found a variable which could be added to a partitioning constraint so we can fix it to zero */
4738 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because this variable is in the same clique with a set partition\n", SCIPvarGetName(usefulvars[v1]));
4765 SCIPdebugMsg(scip, " -> adding variable <%s> to constraint <%s> number %d\n", SCIPvarGetName(addvar), SCIPconsGetName(cons), arraypos);
4775 SCIP_CALL( addCliqueDataEntry(scip, addvar, arraypos, FALSE, usefulvars, nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs) );
4777 /* we need the new pointer to the variables, because due to adding variables it is possible that we
4778 * did reallocate the variables array inside the constraint, the index v should stay the same because the
4810 SCIP_Bool*const undoneaggrtypes, /**< aggregation type storage, type FALSE means the aggregation is of the
4840 SCIPdebugMsg(scip, "trying to aggregate <%s> %s <%s>%s\n", SCIPvarGetName(var1), undoneaggrtypes[a] ? "=" : "+", SCIPvarGetName(var2), undoneaggrtypes[a] ? "" : " = 1");
4843 /* in order to not mess up the variable usage counting, we have to decrease usage counting, aggregate,
4853 SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, -1.0, 0.0, cutoff, &redundant, &aggregated) );
4857 SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, 1.0, 1.0, cutoff, &redundant, &aggregated) );
4866 /* binary variables should always be aggregated, or due to fixation the aggregation is redundant */
4882 /** check whether we can combine or grow cliques so some constraints become redundant or we can fix variables */
4883 /** @todo try another variant, by building up the clique graph and delete unnecessary (transitive closure) edges and do
4903 /* extend cliques/constraints by checking whether some variables are in the same clique, no pairwise clique lifting
4906 SCIP_CONS** usefulconss; /* array with pointers of constraint of setpartitioning and setpacking type */
4907 SCIP_VAR** usefulvars; /* array with pointers of variables in setpartitioning and setpacking constraints */
4908 int** varconsidxs; /* array consisting of constraint indices in which the corresponding variable exists */
4912 SCIP_Bool* cliquevalues = NULL; /* values of clique-variables, either one if the variable is active or zero if the variable is negated */
4928 SCIP_Bool* undoneaggrtypes; /* storage for not yet performed aggregation type (x = y or x + y = 1) */
4954 susefulvars = 2 * nvars; /* two times because of negated vars, maybe due to deleted variables we need to increase this */
4956 /* a hashmap from varindex to postion in varconsidxs array, because above is still too small */
4959 /* get temporary memory for the aggregation storage, to memorize aggregations which will be performed later, otherwise we would destroy our local data structures */
4966 /* get temporary memory for all clique constraints, all appearing variables and the mapping from variables to constraints */
4999 /* try to create a clique-partition over all binary variables and create these cliques as new setppc constraints
5000 * and add them to the usefulconss array and adjust all necessary data this will hopefully lead to faster
5010 /* add extra clique constraints resulting from the cliquepartition calculation to SCIP and to the local data structure */
5011 SCIP_CALL( addExtraCliques(scip, binvars, nbinvars, cliquepartition, ncliques, usefulconss, &nusefulconss,
5014 /* bad hack, we don't want to count these artificial created constraints if they got deleted, so ndelconss
5015 * can become negative which will be change to zero at the end of this method if it's still negative
5026 /* start to collect setpartitioning and setpacking constraints, and try to remove fixed variables and merged these
5029 SCIP_CALL( collectCliqueConss(scip, conss, nconss, usefulconss, &nusefulconss, nfixedvars, ndelconss, nchgcoefs, cutoff) );
5030 /* @Note: Even after the call above some constraints can have fixed variables, because it might happen that caused by
5040 /* @todo: maybe sort them after biggest indices too, or another variant would be to restore the order as they were
5043 /* sort constraints first after type (partitioning before packing) and second after number of variables such that the
5044 * partitioning constraints have increasing number of variables and the packing constraints have decreasing number of
5045 * variables, because we loop from back to front we sort them downwards, so they are the other way around
5049 /* creating all necessary data in array structure, collect all clique constraint variables and occurrences */
5050 SCIP_CALL( collectCliqueData(scip, usefulconss, nusefulconss, usefulvars, &nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs, &maxnvars) );
5058 /* sort usefulvars after indices of variables, negated and active counterparts will stand side by side */
5061 /* extend cliques/constraints by checking whether some variables of a second constraint are in the same clique */
5080 /* check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
5083 SCIP_CALL( presolvePropagateCons(scip, cons0, FALSE, undoneaggrvars, undoneaggrtypes, &naggregations, &saggregations, nfixedvars, naggrvars, ndelconss, cutoff) );
5094 /* we need to determine the cliquedata in each iteration because we eventual will change it later */
5101 /* sorting array after indices of variables, negated and active counterparts will stand side by side */
5134 SCIP_CALL( checkForOverlapping(scip, cons0, c, c, usefulconss, nusefulconss, usefulvars, &nusefulvars, vartoindex,
5135 varnconss, maxnvarconsidx, varconsidxs, countofoverlapping, conshdlrdata->cliqueshrinking, &chgcons0,
5154 /* sorting array after indices of variables, negated and active counterparts will stand side by side */
5160 /* check cons0 again for redundancy/fixings, because due to fixings in all other constraints it might happen that cons0 is redundant now */
5163 /* check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
5166 SCIP_CALL( presolvePropagateCons(scip, cons0, FALSE, undoneaggrvars, undoneaggrtypes, &naggregations, &saggregations, nfixedvars, naggrvars, ndelconss, cutoff) );
5180 /* iterate over the cliques variables and all possible new clique variables at the "same" time, determine starting
5183 * @note: it might be better to start the first round with our computed v1, but maybe it's better to switch to
5187 /* we try to add all variables to the partitioning constraints, to try to fix as much as possible */
5197 /* find start position of variable which we will try to add to our constraint, so we will get better clique constraints */
5198 (void) SCIPsortedvecFindDownPtr((void**)usefulvars, SCIPvarCompActiveAndNegated, (void*)cons0vars[ncons0vars - 1], nusefulvars, &v1);
5200 /* if constraint is not merged and we found a variable which is negated the same as it's neighbour we have to
5202 if( v1 + 1 < nusefulvars && ((SCIPvarIsNegated(usefulvars[v1 + 1]) && SCIPvarGetNegatedVar(usefulvars[v1 + 1]) == usefulvars[v1]) || (SCIPvarIsNegated(usefulvars[v1]) && SCIPvarGetNegatedVar(usefulvars[v1]) == usefulvars[v1 + 1])) )
5214 assert(SCIPvarIsActive(cons0vars[v]) || (SCIPvarGetStatus(cons0vars[v]) == SCIP_VARSTATUS_NEGATED &&
5223 SCIP_CALL( liftCliqueVariables(scip, cons0, c, usefulvars, &nusefulvars, v1, &cliquevalues, vartoindex, varnconss,
5273 /* check for overlapping constraint after lifting, in the first round we will only check up front */
5274 SCIP_CALL( checkForOverlapping(scip, cons0, c, (conshdlrdata->nclqpresolve > 0) ? nusefulconss : c,
5275 usefulconss, nusefulconss, usefulvars, &nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs,
5292 /* free temporary memory for constraints, variables and the mapping between them in reverse order as they were
5312 SCIP_CALL( performAggregations(scip, conshdlrdata, undoneaggrvars, undoneaggrtypes, naggregations, naggrvars, cutoff) );
5380 if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING )
5383 ((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING), &infeasible, &nlocalbdchgs) );
5394 /* a two-variable set covering constraint x + y >= 1 yields the implication x == 0 -> y == 1 */
5412 /** perform multi-aggregation on variables resulting from a set-partitioning/-packing constraint */
5416 SCIP_Bool linearconshdlrexist,/**< does the linear constraint handler exist, necessary for multi-aggregations */
5417 SCIP_VAR** vars, /**< all variables including the variable to which will be multi-aggregated */
5422 )
5439 SCIPdebugMsg(scip, "aggregating %s = 1 - %s\n", SCIPvarGetName(vars[pos]), SCIPvarGetName(vars[nvars - pos - 1]));
5442 SCIP_CALL( SCIPaggregateVars(scip, vars[pos], vars[nvars - pos - 1], 1.0, 1.0, 1.0, infeasible, &redundant, aggregated) );
5469 SCIPdebugMsg(scip, "multi-aggregating binary variable <%s> (locks: [%d,%d]; to %d variables)\n",
5474 SCIP_CALL( SCIPmultiaggregateVar(scip, vars[pos], nvars - 1, tmpvars, scalars, 1.0, infeasible, aggregated) );
5488 /** determine singleton variables in set-partitioning/-packing constraints, or doubleton variables (active and negated)
5491 * we can multi-aggregate the variable and either change the set-partitioning constraint to a set-packing constraint or
5494 * 1. c1: x + y + z = 1, uplocks(x) = 1, downlocks(x) = 1 => x = 1 - y - z and change c1 to y + z <= 1
5496 * 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
5502 * 4. e1: x + y + z == 1 and e2: ~x + u + v (<= or ==) 1, uplocks(x) = (1 or 2), downlocks(x) = 2
5505 * we can also aggregate a variable in a set-packing constraint with only two variables when the uplocks are equal to
5510 * @todo might want to multi-aggregate variables even with more locks, when the fill in is still smaller or equal to
5584 if( (nuplocks == 1 && ndownlocks <= 1) || (nuplocks <= 1 && ndownlocks == 1) || (nuplocks <= 2 && ndownlocks <= 2 && SCIPvarGetNegatedVar(binvars[v]) != NULL) )
5615 /* determine singleton variables in set-partitioning/-packing constraints, or doubleton variables (active and
5618 * we can multi-aggregate the variable and either change the set-partitioning constraint to a set-packing constraint
5689 /* if the constraint was not merged and consists of a variable with its negation, the constraint is redundant */
5710 SCIPdebugMsg(scip, "empty set partition constraint <%s> led to infeasibility\n", SCIPconsGetName(cons));
5716 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));
5726 SCIPdebugMsg(scip, "deleting redundant set-partition constraint <%s>\n", SCIPconsGetName(cons));
5736 if( !donotaggr && consdata->nvars == 2 && dualpresolvingenabled && (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING )
5744 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_NEGATED || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
5752 SCIPdebugMsg(scip, "dualpresolve, aggregating %s + %s = 1, in set-packing constraint %s\n", SCIPvarGetName(var), SCIPvarGetName(consdata->vars[1]), SCIPconsGetName(cons));
5755 SCIP_CALL( SCIPaggregateVars(scip, var, consdata->vars[1], 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
5775 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_NEGATED || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
5783 SCIPdebugMsg(scip, "dualpresolve, aggregating %s + %s = 1, in set-packing constraint %s\n", SCIPvarGetName(var), SCIPvarGetName(consdata->vars[0]), SCIPconsGetName(cons));
5786 SCIP_CALL( SCIPaggregateVars(scip, var, consdata->vars[0], 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
5803 else if( !donotaggr && consdata->nvars == 2 && (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING )
5807 SCIPdebugMsg(scip, "aggregating %s + %s = 1, in set-partition constraint %s\n", SCIPvarGetName(consdata->vars[0]), SCIPvarGetName(consdata->vars[1]), SCIPconsGetName(cons));