Scippy

    SCIP

    Solving Constraint Integer Programs

    cons_setppc.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file cons_setppc.c
    26 * @ingroup DEFPLUGINS_CONS
    27 * @brief Constraint handler for the set partitioning / packing / covering constraints \f$1^T x\ \{=, \le, \ge\}\ 1\f$.
    28 * @author Tobias Achterberg
    29 * @author Michael Winkler
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    35#include "scip/cons_nonlinear.h"
    36#include "scip/cons_linear.h"
    37#include "scip/cons_setppc.h"
    38#include "scip/pub_conflict.h"
    39#include "scip/pub_cons.h"
    40#include "scip/pub_event.h"
    41#include "scip/pub_lp.h"
    42#include "scip/pub_message.h"
    43#include "scip/pub_misc.h"
    44#include "scip/pub_misc_sort.h"
    45#include "scip/pub_var.h"
    46#include "scip/scip_conflict.h"
    47#include "scip/scip_cons.h"
    48#include "scip/scip_cut.h"
    49#include "scip/scip_event.h"
    50#include "scip/scip_general.h"
    51#include "scip/scip_lp.h"
    52#include "scip/scip_mem.h"
    53#include "scip/scip_message.h"
    54#include "scip/scip_nlp.h"
    55#include "scip/scip_numerics.h"
    56#include "scip/scip_param.h"
    57#include "scip/scip_prob.h"
    58#include "scip/scip_probing.h"
    60#include "scip/scip_sol.h"
    62#include "scip/scip_var.h"
    63#include "scip/symmetry_graph.h"
    65#include <string.h>
    66
    67
    68#define CONSHDLR_NAME "setppc"
    69#define CONSHDLR_DESC "set partitioning / packing / covering constraints"
    70#define CONSHDLR_SEPAPRIORITY +700000 /**< priority of the constraint handler for separation */
    71#define CONSHDLR_ENFOPRIORITY -700000 /**< priority of the constraint handler for constraint enforcing */
    72#define CONSHDLR_CHECKPRIORITY -700000 /**< priority of the constraint handler for checking feasibility */
    73#define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
    74#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
    75#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
    76 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
    77#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
    78#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
    79#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    80#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
    81
    82#define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_ALWAYS
    83#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
    84
    85#define LINCONSUPGD_PRIORITY +700000 /**< priority of the constraint handler for upgrading of linear constraints */
    86#define NONLINCONSUPGD_PRIORITY +700000 /**< priority of the constraint handler for upgrading of nonlinear constraints */
    87
    88#define EVENTHDLR_NAME "setppc"
    89#define EVENTHDLR_DESC "bound change event handler for set partitioning / packing / covering constraints"
    90
    91#define CONFLICTHDLR_NAME "setppc"
    92#define CONFLICTHDLR_DESC "conflict handler creating set covering constraints"
    93#define CONFLICTHDLR_PRIORITY LINCONSUPGD_PRIORITY
    94
    95#define DEFAULT_PRESOLPAIRWISE TRUE /**< should pairwise constraint comparison be performed in presolving? */
    96
    97#define HASHSIZE_SETPPCCONS 500 /**< minimal size of hash table in setppc constraint tables */
    98#define DEFAULT_PRESOLUSEHASHING TRUE /**< should hash table be used for detecting redundant constraints in advance */
    99#define NMINCOMPARISONS 200000 /**< number for minimal pairwise presolving comparisons */
    100#define MINGAINPERNMINCOMPARISONS 1e-06 /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
    101
    102#define DEFAULT_RANDSEED 3
    103
    104/*#define VARUSES*/ /* activate variable usage counting, that is necessary for LP and pseudo branching */
    105/*#define BRANCHLP*/ /* BRANCHLP is only useful if the ENFOPRIORITY is set to a positive value */
    106#ifdef BRANCHLP
    107#define MINBRANCHWEIGHT 0.3 /**< minimum weight of both sets in binary set branching */
    108#define MAXBRANCHWEIGHT 0.7 /**< maximum weight of both sets in binary set branching */
    109#endif
    110#define DEFAULT_NPSEUDOBRANCHES 2 /**< number of children created in pseudo branching (0: disable branching) */
    111#define DEFAULT_DUALPRESOLVING TRUE /**< should dual presolving steps be performed? */
    112
    113#define DEFAULT_CLIQUELIFTING FALSE /**< should we try to lift variables into other clique constraints, fix
    114 * variables, aggregate them, and also shrink the amount of variables in
    115 * clique constraints
    116 */
    117#define DEFAULT_ADDVARIABLESASCLIQUES FALSE/**< should we try to generate extra clique constraint out of all binary
    118 * variables to hopefully fasten the detection of redundant clique
    119 * constraints */
    120#define DEFAULT_CLIQUESHRINKING TRUE /**< should we try to shrink the number of variables in a clique constraints, by
    121 * replacing more than one variable by only one
    122 */
    123
    124/* @todo maybe use event SCIP_EVENTTYPE_VARUNLOCKED to decide for another dual-presolving run on a constraint */
    125
    126/*
    127 * Data structures
    128 */
    129
    130/** constraint handler data */
    131struct SCIP_ConshdlrData
    132{
    133 SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
    134 SCIP_CONSHDLR* conshdlrlinear; /**< pointer to linear constraint handler or NULL if not included */
    135#ifdef VARUSES
    136 SCIP_INTARRAY* varuses; /**< number of times a var is used in the active setppc constraints */
    137#endif
    138 SCIP_Longint nsetpart; /**< number of set partitioning constraints in transformed problem */
    139 int npseudobranches; /**< number of children created in pseudo branching (0 to disable branching) */
    140 int noldfixedvars; /**< number of fixed variables after last clique lifting run */
    141 int noldimpls; /**< number of implication before last clique lifting run */
    142 int noldcliques; /**< number of cliques before last clique lifting run */
    143 int noldupgrs; /**< number of setppc constraints since the last clique lifting run */
    144 int nclqpresolve; /**< number of setppc clique lifting runs */
    145 SCIP_Bool updatedsetppctype; /**< remember whether we upgraded a constraint type */
    146 SCIP_Bool cliquelifting; /**< should we perform the clique lifting procedure */
    147 SCIP_Bool enablecliquelifting;/**< check whether we have enough changes to run the lifting procedure again */
    148 SCIP_Bool cliqueshrinking; /**< should we try to shrink the number of variables in a clique
    149 * constraints, by replacing more than one variable by only one
    150 */
    151 SCIP_Bool addvariablesascliques;/**< should we try to generate extra clique constraint out of all binary
    152 * variables to hopefully fasten the detection of redundant clique
    153 * constraints */
    154 SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
    155 SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
    156 SCIP_Bool presolusehashing; /**< should hash table be used for detecting redundant constraints in advance */
    157 SCIP_Bool dualpresolving; /**< should dual presolving steps be performed? */
    158 int* probtoidxmap; /**< cleared memory array with default values -1; used for clique partitions */
    159 int probtoidxmapsize; /**< size of probtoidxmap */
    160};
    161
    162/** constraint data for set partitioning / packing / covering constraints */
    163struct SCIP_ConsData
    164{
    165 uint64_t signature; /**< bit signature of vars array */
    166 SCIP_ROW* row; /**< LP row, if constraint is already stored in LP row format */
    167 SCIP_NLROW* nlrow; /**< NLP row, if constraint has been added to NLP relaxation */
    168 SCIP_VAR** vars; /**< variables of the constraint */
    169 int varssize; /**< size of vars array */
    170 int nvars; /**< number of variables in the constraint */
    171 int nfixedzeros; /**< current number of variables fixed to zero in the constraint */
    172 int nfixedones; /**< current number of variables fixed to one in the constraint */
    173 unsigned int setppctype:2; /**< type of constraint: set partitioning, packing or covering */
    174 unsigned int sorted:1; /**< are the constraint's variables sorted? */
    175 unsigned int cliqueadded:1; /**< was the set partitioning / packing constraint already added as clique? */
    176 unsigned int validsignature:1; /**< is the bit signature valid? */
    177 unsigned int changed:1; /**< was constraint changed since last redundancy round in preprocessing? */
    178 unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
    179 unsigned int merged:1; /**< are the constraint's equal/negated variables already merged? */
    180 unsigned int presolpropagated:1; /**< was the constraint already propagated in presolving w.r.t. the current domains? */
    181 unsigned int existmultaggr:1; /**< does this constraint contain aggregations */
    182 unsigned int catchevents:1; /**< are events installed for this constraint? */
    183};
    184
    185
    186
    187
    188/*
    189 * Local methods
    190 */
    191
    192/** compares two active constraints of type set partitioning or set packing such that a "-1" is return if
    193 * 1. the first constraint is a set partitioning constraint and the second is a set packing or
    194 * 2. both constraints are set partitioning constraints and the second has more! variables than the first or
    195 * 3. both constraints are set packing constraints and the second has less! variables than the first
    196 * a "0" is return if
    197 * 1. both constraint are of the same type and have the amount of variables or
    198 * and a "1" is returned otherwise
    199 */
    200static
    202 SCIP_CONS*const cons1, /**< first problem variable */
    203 SCIP_CONS*const cons2 /**< second problem variable */
    204 )
    205{
    206 SCIP_CONSDATA* consdata1;
    207 SCIP_CONSDATA* consdata2;
    208
    209 assert(cons1 != NULL);
    210 assert(cons2 != NULL);
    211 assert(SCIPconsIsActive(cons1));
    212 assert(SCIPconsIsActive(cons2));
    213
    214 /* the partitioning type should be the smallest value and the packing the second smallest */
    216
    217 consdata1 = SCIPconsGetData(cons1);
    218 assert(consdata1 != NULL);
    219 assert(consdata1->setppctype != SCIP_SETPPCTYPE_COVERING); /*lint !e641*/
    220 consdata2 = SCIPconsGetData(cons2);
    221 assert(consdata2 != NULL);
    222 assert(consdata2->setppctype != SCIP_SETPPCTYPE_COVERING); /*lint !e641*/
    223
    224 if( consdata1->setppctype < consdata2->setppctype ||
    225 (consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->nvars < consdata2->nvars) || /*lint !e641*/
    226 (consdata2->setppctype == SCIP_SETPPCTYPE_PACKING && consdata1->nvars > consdata2->nvars) ) /*lint !e641*/
    227 return -1;
    228 else if( (consdata1->setppctype == consdata2->setppctype && consdata1->nvars == consdata2->nvars) ) /*lint !e641*/
    229 return 0;
    230 else
    231 {
    232 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*/
    233 return +1;
    234 }
    235}
    236
    237/** sort constraints first after type (partitioning before packing before covering) and second after number of
    238 * variables such that the partitioning constraints have increasing number of variables and the packing constraints
    239 * have decreasing number of variables */
    240static
    241SCIP_DECL_SORTPTRCOMP(setppcConssSort)
    242{
    243 return setppcCompare((SCIP_CONS*)elem1, (SCIP_CONS*)elem2);
    244}
    245
    246/** compares two setppc constraints such that a "-1" is return if the first constraint is active and
    247 * 1. the second constraint is deleted
    248 * 2. the first constraint is a set partitioning constraint and the second is a set packing or
    249 * 3. both constraints are set partitioning constraints and the second has more! variables than the first or
    250 * 4. both constraints are set packing constraints and the second has less! variables than the first
    251 * a "0" is return if
    252 * 1. both constraint are set-covering constraints
    253 * 2. both constraint are of the same type and have the amount of variables or
    254 * and a "1" is returned otherwise
    255 */
    256static
    258 SCIP_CONS*const cons1, /**< first problem variable */
    259 SCIP_CONS*const cons2 /**< second problem variable */
    260 )
    261{
    262 SCIP_CONSDATA* consdata1;
    263 SCIP_CONSDATA* consdata2;
    264
    265 assert(cons1 != NULL);
    266 assert(cons2 != NULL);
    267
    268 if( SCIPconsIsDeleted(cons1) )
    269 {
    270 if( SCIPconsIsDeleted(cons2) )
    271 return 0;
    272 else
    273 return +1;
    274 }
    275 else if( SCIPconsIsDeleted(cons2) )
    276 return -1;
    277
    278 consdata1 = SCIPconsGetData(cons1);
    279 assert(consdata1 != NULL);
    280 consdata2 = SCIPconsGetData(cons2);
    281 assert(consdata2 != NULL);
    282
    283 /* the partitioning type should be the smallest value and the packing the second smallest */
    285
    286 if( consdata1->setppctype < consdata2->setppctype ||
    287 ((SCIP_SETPPCTYPE)consdata1->setppctype != SCIP_SETPPCTYPE_COVERING &&
    288 (((SCIP_SETPPCTYPE)consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->nvars < consdata2->nvars) ||
    289 ((SCIP_SETPPCTYPE)consdata2->setppctype == SCIP_SETPPCTYPE_PACKING && consdata1->nvars > consdata2->nvars))) )
    290 return -1;
    291 else if( ((SCIP_SETPPCTYPE)consdata2->setppctype == SCIP_SETPPCTYPE_COVERING || (consdata1->setppctype == consdata2->setppctype && consdata1->nvars == consdata2->nvars)) )
    292 return 0;
    293 else
    294 {
    295 assert(consdata1->setppctype > consdata2->setppctype || ((consdata1->setppctype == consdata2->setppctype) &&
    296 ((consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->nvars > consdata2->nvars)
    297 || (consdata1->setppctype == SCIP_SETPPCTYPE_PACKING && consdata1->nvars < consdata2->nvars)))); /*lint !e641*/
    298 return +1;
    299 }
    300}
    301
    302/** sort constraints first after type (partitioning before packing before covering) and second after number of
    303 * variables such that the partitioning constraints have increasing number of variables and the packing constraints
    304 * have decreasing number of variables */
    305static
    306SCIP_DECL_SORTPTRCOMP(setppcConssSort2)
    307{
    308 return setppcCompare2((SCIP_CONS*)elem1, (SCIP_CONS*)elem2);
    309}
    310
    311
    312/** installs rounding locks for the given variable in the given setppc constraint */
    313static
    315 SCIP* scip, /**< SCIP data structure */
    316 SCIP_CONS* cons, /**< setppc constraint */
    317 SCIP_VAR* var /**< variable of constraint entry */
    318 )
    319{
    320 SCIP_CONSDATA* consdata;
    321
    322 consdata = SCIPconsGetData(cons);
    323 assert(consdata != NULL);
    324
    325 switch( consdata->setppctype )
    326 {
    328 SCIP_CALL( SCIPlockVarCons(scip, var, cons, TRUE, TRUE) );
    329 break;
    331 SCIP_CALL( SCIPlockVarCons(scip, var, cons, FALSE, TRUE) );
    332 break;
    334 SCIP_CALL( SCIPlockVarCons(scip, var, cons, TRUE, FALSE) );
    335 break;
    336 default:
    337 SCIPerrorMessage("unknown setppc type\n");
    338 return SCIP_INVALIDDATA;
    339 }
    340
    341 return SCIP_OKAY;
    342}
    343
    344/** removes rounding locks for the given variable in the given setppc constraint */
    345static
    347 SCIP* scip, /**< SCIP data structure */
    348 SCIP_CONS* cons, /**< setppc constraint */
    349 SCIP_VAR* var /**< variable of constraint entry */
    350 )
    351{
    352 SCIP_CONSDATA* consdata;
    353
    354 consdata = SCIPconsGetData(cons);
    355 assert(consdata != NULL);
    356
    357 switch( consdata->setppctype )
    358 {
    360 SCIP_CALL( SCIPunlockVarCons(scip, var, cons, TRUE, TRUE) );
    361 break;
    363 SCIP_CALL( SCIPunlockVarCons(scip, var, cons, FALSE, TRUE) );
    364 break;
    366 SCIP_CALL( SCIPunlockVarCons(scip, var, cons, TRUE, FALSE) );
    367 break;
    368 default:
    369 SCIPerrorMessage("unknown setppc type\n");
    370 return SCIP_INVALIDDATA;
    371 }
    372
    373 return SCIP_OKAY;
    374}
    375
    376/** creates constraint handler data for set partitioning / packing / covering constraint handler */
    377static
    379 SCIP* scip, /**< SCIP data structure */
    380 SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
    381 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    382 )
    383{
    384 assert(scip != NULL);
    385 assert(conshdlrdata != NULL);
    386 assert(eventhdlr != NULL);
    387
    388 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
    389#ifdef VARUSES
    390 SCIP_CALL( SCIPcreateIntarray(scip, &(*conshdlrdata)->varuses) );
    391#endif
    392 (*conshdlrdata)->npseudobranches = DEFAULT_NPSEUDOBRANCHES;
    393
    394 /* set event handler for bound change events */
    395 (*conshdlrdata)->eventhdlr = eventhdlr;
    396 (*conshdlrdata)->nsetpart = 0;
    397 (*conshdlrdata)->probtoidxmap = NULL;
    398 (*conshdlrdata)->probtoidxmapsize = 0;
    399
    400 /* create a random number generator */
    401 SCIP_CALL( SCIPcreateRandom(scip, &(*conshdlrdata)->randnumgen,
    403
    404 return SCIP_OKAY;
    405}
    406
    407/** frees constraint handler data for set partitioning / packing / covering constraint handler */
    408static
    410 SCIP* scip, /**< SCIP data structure */
    411 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
    412 )
    413{
    414 assert(conshdlrdata != NULL);
    415 assert(*conshdlrdata != NULL);
    416
    417#ifdef VARUSES
    418 SCIP_CALL( SCIPfreeIntarray(scip, &(*conshdlrdata)->varuses) );
    419#endif
    420
    421 /* free random number generator */
    422 SCIPfreeRandom(scip, &(*conshdlrdata)->randnumgen);
    423
    424 SCIPfreeBlockMemoryArrayNull(scip, &(*conshdlrdata)->probtoidxmap, (*conshdlrdata)->probtoidxmapsize);
    425 SCIPfreeBlockMemory(scip, conshdlrdata);
    426
    427 return SCIP_OKAY;
    428}
    429
    430#ifdef VARUSES
    431/** adds the given value to the usage counter of the given variable */
    432static
    433SCIP_RETCODE conshdlrdataAddVaruses(
    434 SCIP* scip, /**< SCIP data structure */
    435 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    436 SCIP_VAR* var, /**< variable to increase usage counter for */
    437 int addval /**< value to add to the usage counter */
    438 )
    439{
    440 SCIP_INTARRAY* varuses;
    441
    442 assert(conshdlrdata != NULL);
    443 assert(var != NULL);
    444
    445 varuses = conshdlrdata->varuses;
    446 assert(varuses != NULL);
    447
    448 /* if the variable is the negation of a problem variable, count the varuses in the problem variable */
    449 if( SCIPvarIsNegated(var) )
    450 {
    451 SCIP_VAR* negvar;
    452 int varindex;
    453
    454 /* move the varuses value of the negated variable to the active problem variable */
    455 varindex = SCIPvarGetIndex(var);
    456 addval += SCIPgetIntarrayVal(scip, varuses, varindex);
    457 SCIP_CALL( SCIPsetIntarrayVal(scip, varuses, varindex, 0) );
    458 SCIP_CALL( SCIPgetNegatedVar(scip, var, &negvar) );
    459 var = negvar;
    460 }
    461
    462 /* increase varuses counter */
    463 SCIP_CALL( SCIPincIntarrayVal(scip, varuses, SCIPvarGetIndex(var), addval) );
    464
    465 SCIPdebugMsg(scip, "added %d to varuses of <%s>: %d\n",
    466 addval, SCIPvarGetName(var), SCIPgetIntarrayVal(scip, varuses, SCIPvarGetIndex(var)));
    467
    468 return SCIP_OKAY;
    469}
    470
    471/** increases the usage counter of the given variable */
    472static
    473SCIP_RETCODE conshdlrdataIncVaruses(
    474 SCIP* scip, /**< SCIP data structure */
    475 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    476 SCIP_VAR* var /**< variable to increase usage counter for */
    477 )
    478{
    479 assert(conshdlrdata != NULL);
    480
    481 SCIPdebugMsg(scip, "increasing varuses of <%s>: %d\n",
    482 SCIPvarGetName(var), SCIPgetIntarrayVal(scip, conshdlrdata->varuses, SCIPvarGetIndex(var)));
    483
    484 SCIP_CALL( conshdlrdataAddVaruses(scip, conshdlrdata, var, +1) );
    485
    486 return SCIP_OKAY;
    487}
    488
    489/** decreases the usage counter of the given variable */
    490static
    491SCIP_RETCODE conshdlrdataDecVaruses(
    492 SCIP* scip, /**< SCIP data structure */
    493 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    494 SCIP_VAR* var /**< variable to increase usage counter for */
    495 )
    496{
    497 assert(conshdlrdata != NULL);
    498
    499 SCIPdebugMsg(scip, "decreasing varuses of <%s>: %d\n",
    500 SCIPvarGetName(var), SCIPgetIntarrayVal(scip, conshdlrdata->varuses, SCIPvarGetIndex(var)));
    501
    502 SCIP_CALL( conshdlrdataAddVaruses(scip, conshdlrdata, var, -1) );
    503
    504 return SCIP_OKAY;
    505}
    506
    507/** increases the usage counter of all variable in the constraint */
    508static
    509SCIP_RETCODE consdataIncVaruses(
    510 SCIP* scip, /**< SCIP data structure */
    511 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    512 SCIP_CONSDATA* consdata /**< setppc constraint data */
    513 )
    514{
    515 int v;
    516
    517 assert(consdata != NULL);
    518
    519 for( v = 0; v < consdata->nvars; ++v )
    520 {
    521 SCIP_CALL( conshdlrdataIncVaruses(scip, conshdlrdata, consdata->vars[v]) );
    522 }
    523
    524 return SCIP_OKAY;
    525}
    526
    527/** decreases the usage counter of all variable in the constraint */
    528static
    529SCIP_RETCODE consdataDecVaruses(
    530 SCIP* scip, /**< SCIP data structure */
    531 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    532 SCIP_CONSDATA* consdata /**< setppc constraint data */
    533 )
    534{
    535 int v;
    536
    537 assert(consdata != NULL);
    538
    539 for( v = 0; v < consdata->nvars; ++v )
    540 {
    541 SCIP_CALL( conshdlrdataDecVaruses(scip, conshdlrdata, consdata->vars[v]) );
    542 }
    543
    544 return SCIP_OKAY;
    545}
    546#endif
    547
    548/** ensures, that the vars array can store at least num entries */
    549static
    551 SCIP* scip, /**< SCIP data structure */
    552 SCIP_CONSDATA* consdata, /**< setppc constraint data */
    553 int num /**< minimum number of entries to store */
    554 )
    555{
    556 assert(consdata != NULL);
    557 assert(consdata->nvars <= consdata->varssize);
    558
    559 if( num > consdata->varssize )
    560 {
    561 int newsize;
    562
    563 newsize = SCIPcalcMemGrowSize(scip, num);
    564 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
    565 consdata->varssize = newsize;
    566 }
    567 assert(num <= consdata->varssize);
    568
    569 return SCIP_OKAY;
    570}
    571
    572/** creates a set partitioning / packing / covering constraint data object */
    573static
    575 SCIP* scip, /**< SCIP data structure */
    576 SCIP_CONSDATA** consdata, /**< pointer to store the set partitioning / packing / covering constraint */
    577 int nvars, /**< number of variables in the constraint */
    578 SCIP_VAR** vars, /**< variables of the constraint */
    579 SCIP_SETPPCTYPE setppctype /**< type of constraint: set partitioning, packing, or covering constraint */
    580 )
    581{
    582 assert(consdata != NULL);
    583 assert(nvars == 0 || vars != NULL);
    584
    585 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
    586
    587 (*consdata)->signature = 0;
    588 (*consdata)->row = NULL;
    589 (*consdata)->nlrow = NULL;
    590 (*consdata)->existmultaggr = FALSE;
    591 (*consdata)->catchevents = FALSE;
    592 (*consdata)->nfixedzeros = 0;
    593 (*consdata)->nfixedones = 0;
    594
    595 if( nvars > 0 )
    596 {
    597 int v;
    598
    599 /* @todo the setppc constraint handler does not remove fixed variables from its var array; removing those
    600 * variables is only possible if we consider the values of nfixedones and nfixedzeros in all propagation methods
    601 */
    602#ifdef SCIP_DISABLED_CODE
    603
    605 {
    606 SCIP_VAR** varsbuffer;
    607 int k;
    608
    609 /* allocate temporary buffer storage for active variables */
    610 SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
    611
    612 k = 0;
    613 /* collect fixed variables to compress the required memory */
    614 for( v = 0; v < nvars; ++v )
    615 {
    616 assert(SCIPvarIsBinary(vars[v]));
    617
    618 /* already fixed variables account as fixed ones or zero, only unfixed are appended */
    619 if( SCIPvarGetLbGlobal(vars[v]) > 0.5 )
    620 (*consdata)->nfixedones++;
    621 else if( SCIPvarGetUbGlobal(vars[v]) < 0.5 )
    622 (*consdata)->nfixedzeros++;
    623 else
    624 varsbuffer[k++] = vars[v];
    625 }
    626
    627 (*consdata)->varssize = k;
    628 (*consdata)->nvars = k;
    629 /* copy unfixed variables into constraint data */
    630 if( k > 0 )
    631 {
    632 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
    633 }
    634
    635 /* free temporary storage */
    636 SCIPfreeBufferArray(scip, &varsbuffer);
    637 }
    638 else
    639#endif
    640 {
    641 /* for uncompressed copies, simply duplicate the whole array */
    642 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, vars, nvars) );
    643 (*consdata)->varssize = nvars;
    644 (*consdata)->nvars = nvars;
    645 }
    646
    648 {
    649 /* get transformed variables */
    650 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
    651
    652 /* check for multi-aggregations and capture variables */
    653 for( v = 0; v < (*consdata)->nvars; v++ )
    654 {
    655 SCIP_VAR* var = SCIPvarGetProbvar((*consdata)->vars[v]);
    656 assert(var != NULL);
    657 (*consdata)->existmultaggr = (*consdata)->existmultaggr || (SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
    658 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
    659 }
    660 }
    661 else
    662 {
    663 /* capture variables */
    664 for( v = 0; v < (*consdata)->nvars; v++ )
    665 {
    666 assert((*consdata)->vars[v] != NULL);
    667 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
    668 }
    669 }
    670 }
    671 else
    672 {
    673 (*consdata)->vars = NULL;
    674 (*consdata)->varssize = 0;
    675 (*consdata)->nvars = 0;
    676 }
    677 (*consdata)->setppctype = setppctype; /*lint !e641*/
    678 (*consdata)->sorted = (nvars <= 1);
    679 (*consdata)->cliqueadded = FALSE;
    680 (*consdata)->validsignature = FALSE;
    681 (*consdata)->changed = TRUE;
    682 (*consdata)->varsdeleted = FALSE;
    683 (*consdata)->merged = FALSE;
    684 (*consdata)->presolpropagated = FALSE;
    685
    686 return SCIP_OKAY;
    687}
    688
    689/** creates a transformed set partitioning / packing / covering constraint data object */
    690static
    692 SCIP* scip, /**< SCIP data structure */
    693 SCIP_CONSDATA** consdata, /**< pointer to store the set partitioning / packing / covering constraint */
    694 int nvars, /**< number of variables in the constraint */
    695 SCIP_VAR** vars, /**< variables of the constraint */
    696 SCIP_SETPPCTYPE setppctype /**< type of constraint: set partitioning, packing, or covering constraint */
    697 )
    698{
    699 assert(consdata != NULL);
    700 assert(nvars == 0 || vars != NULL);
    701
    702 /* create constraint data */
    703 SCIP_CALL( consdataCreate(scip, consdata, nvars, vars, setppctype) );
    704
    705 /* transform the variables */
    706 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
    707
    708 return SCIP_OKAY;
    709}
    710
    711/** frees a set partitioning / packing / covering constraint data */
    712static
    714 SCIP* scip, /**< SCIP data structure */
    715 SCIP_CONSDATA** consdata /**< pointer to store the set partitioning / packing / covering constraint */
    716 )
    717{
    718 int v;
    719
    720 assert(consdata != NULL);
    721 assert(*consdata != NULL);
    722
    723 /* release the row */
    724 if( (*consdata)->row != NULL )
    725 {
    726 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row) );
    727 }
    728
    729 /* release the nlrow */
    730 if( (*consdata)->nlrow != NULL )
    731 {
    732 SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow) );
    733 }
    734
    735 /* release variables */
    736 for( v = 0; v < (*consdata)->nvars; v++ )
    737 {
    738 assert((*consdata)->vars[v] != NULL);
    739 SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
    740 }
    741
    742 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
    743 SCIPfreeBlockMemory(scip, consdata);
    744
    745 return SCIP_OKAY;
    746}
    747
    748/** prints set partitioning / packing / covering constraint to file stream */
    749static
    751 SCIP* scip, /**< SCIP data structure */
    752 SCIP_CONSDATA* consdata, /**< set partitioning / packing / covering constraint data */
    753 FILE* file /**< output file (or NULL for standard output) */
    754 )
    755{
    756 assert(consdata != NULL);
    757
    758 /* print coefficients */
    759 if( consdata->nvars == 0 )
    760 SCIPinfoMessage(scip, file, "0 ");
    761
    762 /* write linear sum */
    763 SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, consdata->vars, NULL, consdata->nvars, TRUE) );
    764
    765 /* print right hand side */
    766 switch( consdata->setppctype )
    767 {
    769 SCIPinfoMessage(scip, file, " == 1");
    770 break;
    772 SCIPinfoMessage(scip, file, " <= 1");
    773 break;
    775 SCIPinfoMessage(scip, file, " >= 1");
    776 break;
    777 default:
    778 SCIPerrorMessage("unknown setppc type\n");
    779 return SCIP_ERROR;
    780 }
    781
    782 return SCIP_OKAY;
    783}
    784
    785/** returns the bit signature of the given constraint data */
    786static
    788 SCIP_CONSDATA* consdata /**< set partitioning / packing / covering constraint data */
    789 )
    790{
    791 assert(consdata != NULL);
    792
    793 if( !consdata->validsignature )
    794 {
    795 int i;
    796
    797 consdata->signature = 0;
    798 for( i = 0; i < consdata->nvars; ++i )
    799 consdata->signature |= SCIPhashSignature64(SCIPvarGetIndex(consdata->vars[i]));
    800 consdata->validsignature = TRUE;
    801 }
    802
    803 return consdata->signature;
    804}
    805
    806/** sorts setppc constraint's variables by non-decreasing variable index */
    807static
    809 SCIP_CONSDATA* consdata /**< linear constraint data */
    810 )
    811{
    812 assert(consdata != NULL);
    813
    814 if( !consdata->sorted )
    815 {
    816 if( consdata->nvars <= 1 )
    817 consdata->sorted = TRUE;
    818 else
    819 {
    820 SCIPsortPtr((void**)consdata->vars, SCIPvarComp, consdata->nvars);
    821 consdata->sorted = TRUE;
    822 }
    823 }
    824 assert(consdata->sorted);
    825#ifdef SCIP_DEBUG
    826 /* check sorting */
    827 {
    828 int v;
    829
    830 for( v = 0; v < consdata->nvars; ++v )
    831 {
    832 assert(v == consdata->nvars-1 || SCIPvarCompare(consdata->vars[v], consdata->vars[v+1]) <= 0);
    833 }
    834 }
    835#endif
    836}
    837
    838/** changes the type of a setppc constraint */
    839static
    841 SCIP* scip, /**< SCIP data structure */
    842 SCIP_CONS* cons, /**< setppc constraint */
    843 SCIP_SETPPCTYPE setppctype /**< new type of constraint */
    844 )
    845{
    846 SCIP_CONSHDLR* conshdlr;
    847 SCIP_CONSHDLRDATA* conshdlrdata;
    848 SCIP_CONSDATA* consdata;
    849 SCIP_Bool locked;
    850 int i;
    851
    852 consdata = SCIPconsGetData(cons);
    853 assert(consdata != NULL);
    854
    855 if( (SCIP_SETPPCTYPE)consdata->setppctype == setppctype )
    856 return SCIP_OKAY;
    857
    858 SCIPdebugMsg(scip, " -> converting <%s> into setppc type %d\n", SCIPconsGetName(cons), setppctype);
    859
    860 /* remove rounding locks */
    861 locked = FALSE;
    862 for( i = 0; i < NLOCKTYPES && !locked; i++ )
    863 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
    864
    865 if( locked )
    866 {
    867 for( i = 0; i < consdata->nvars; ++i )
    868 {
    869 SCIP_CALL( unlockRounding(scip, cons, consdata->vars[i]) );
    870 }
    871 }
    872
    873 conshdlr = SCIPconsGetHdlr(cons);
    874 assert(conshdlr != NULL);
    875 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    876 assert(conshdlrdata != NULL);
    877
    879 {
    880 if( setppctype == SCIP_SETPPCTYPE_PARTITIONING )
    881 {
    882 ++(conshdlrdata->nsetpart);
    883 assert(conshdlrdata->nsetpart >= 0);
    884 }
    885 else if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING )
    886 {
    887 --(conshdlrdata->nsetpart);
    888 assert(conshdlrdata->nsetpart >= 0);
    889 }
    890 }
    891
    892 /* change the constraint type */
    893 consdata->setppctype = setppctype; /*lint !e641*/
    894
    895 /* reinstall rounding locks again */
    896 if( locked )
    897 {
    898 for( i = 0; i < consdata->nvars; ++i )
    899 {
    900 SCIP_CALL( lockRounding(scip, cons, consdata->vars[i]) );
    901 }
    902 }
    903
    904 /* remember that we changed a constraint type for clique lifting procedure */
    905 if( setppctype != SCIP_SETPPCTYPE_COVERING )
    906 conshdlrdata->updatedsetppctype = TRUE;
    907
    908 return SCIP_OKAY;
    909}
    910
    911/** catches events for variable at given position */
    912static
    914 SCIP* scip, /**< SCIP data structure */
    915 SCIP_CONS* cons, /**< set partitioning / packing / covering constraint */
    916 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    917 int pos /**< array position of variable to catch bound change events for */
    918 )
    919{
    920 SCIP_CONSDATA* consdata;
    921 SCIP_EVENTTYPE eventtype;
    922 SCIP_VAR* var;
    923
    924 consdata = SCIPconsGetData(cons);
    925 assert(consdata != NULL);
    926 assert(eventhdlr != NULL);
    927 assert(0 <= pos && pos < consdata->nvars);
    928 assert(consdata->vars != NULL);
    929
    930 var = consdata->vars[pos];
    931 assert(var != NULL);
    932
    933 /* we are catching the following events:
    934 *
    935 * - SCIP_EVENTTYPE_BOUNDCHANGED: Is used to count the number of variable fixed locally to zero and one. That helps
    936 * to speed up the propagation
    937 *
    938 * - SCIP_EVENTTYPE_VARDELETED: Is caught to remove a deleted variable from the constraint
    939 *
    940 * - SCIP_EVENTTYPE_VARFIXED: Is used to get informed if a variable of the constraint was aggregated which means was
    941 * detected to be equal or a negated variable of on other variable. in case of a negation
    942 * this could lead to a redundant constraint if the (other) active variable is also part
    943 * of the constraint.
    944 */
    946
    947 /* catch bound change events on variable */
    948 SCIP_CALL( SCIPcatchVarEvent(scip, var, eventtype, eventhdlr, (SCIP_EVENTDATA*)cons, NULL) );
    949
    950 /* update the fixed variables counters for this variable */
    951 if( SCIPisEQ(scip, SCIPvarGetUbLocal(var), 0.0) )
    952 {
    953 consdata->nfixedzeros++;
    954
    955 /* during presolving, we may fix the last unfixed variable or do an aggregation if there are two unfixed variables */
    956 if( SCIPconsIsActive(cons) && ((SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE) && (consdata->nfixedzeros >= consdata->nvars - 2)) )
    957 {
    958 consdata->presolpropagated = FALSE;
    959
    960 /* during solving, we only propagate again if there is only one unfixed variable left */
    961 if( consdata->nfixedzeros >= consdata->nvars - 1 )
    962 {
    964 }
    965 }
    966 }
    967 else if( SCIPisEQ(scip, SCIPvarGetLbLocal(var), 1.0) )
    968 {
    969 consdata->nfixedones++;
    970
    971 if( SCIPconsIsActive(cons) )
    972 {
    973 consdata->presolpropagated = FALSE;
    975 }
    976 }
    977
    978 return SCIP_OKAY;
    979}
    980
    981/** drops events for variable at given position */
    982static
    984 SCIP* scip, /**< SCIP data structure */
    985 SCIP_CONS* cons, /**< set partitioning / packing / covering constraint */
    986 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    987 int pos /**< array position of variable to catch bound change events for */
    988 )
    989{
    990 SCIP_CONSDATA* consdata;
    991 SCIP_EVENTTYPE eventtype;
    992 SCIP_VAR* var;
    993
    994 consdata = SCIPconsGetData(cons);
    995 assert(consdata != NULL);
    996 assert(eventhdlr != NULL);
    997 assert(0 <= pos && pos < consdata->nvars);
    998 assert(consdata->vars != NULL);
    999
    1000 var = consdata->vars[pos];
    1001 assert(var != NULL);
    1002
    1004
    1005 /* drop events on variable */
    1006 SCIP_CALL( SCIPdropVarEvent(scip, var, eventtype, eventhdlr, (SCIP_EVENTDATA*)cons, -1) );
    1007
    1008 /* update the fixed variables counters for this variable */
    1009 if( SCIPisEQ(scip, SCIPvarGetUbLocal(var), 0.0) )
    1010 consdata->nfixedzeros--;
    1011 else if( SCIPisEQ(scip, SCIPvarGetLbLocal(var), 1.0) )
    1012 consdata->nfixedones--;
    1013
    1014 return SCIP_OKAY;
    1015}
    1016
    1017/** catches bound change events for all variables in transformed setppc constraint */
    1018static
    1020 SCIP* scip, /**< SCIP data structure */
    1021 SCIP_CONS* cons, /**< set partitioning / packing / covering constraint */
    1022 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
    1023 )
    1024{
    1025 SCIP_CONSDATA* consdata;
    1026 int i;
    1027
    1028 consdata = SCIPconsGetData(cons);
    1029 assert(consdata != NULL);
    1030
    1031 if( consdata->catchevents == TRUE )
    1032 return SCIP_OKAY;
    1033
    1034 /* catch event for every single variable */
    1035 for( i = 0; i < consdata->nvars; ++i )
    1036 {
    1037 SCIP_CALL( catchEvent(scip, cons, eventhdlr, i) );
    1038 }
    1039
    1040 consdata->catchevents = TRUE;
    1041
    1042 return SCIP_OKAY;
    1043}
    1044
    1045/** drops bound change events for all variables in transformed setppc constraint */
    1046static
    1048 SCIP* scip, /**< SCIP data structure */
    1049 SCIP_CONS* cons, /**< set partitioning / packing / covering constraint */
    1050 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
    1051 )
    1052{
    1053 SCIP_CONSDATA* consdata;
    1054 int i;
    1055
    1056 consdata = SCIPconsGetData(cons);
    1057 assert(consdata != NULL);
    1058
    1059 if( consdata->catchevents == FALSE )
    1060 return SCIP_OKAY;
    1061
    1062 /* drop event of every single variable */
    1063 for( i = 0; i < consdata->nvars; ++i )
    1064 {
    1065 SCIP_CALL( dropEvent(scip, cons, eventhdlr, i) );
    1066 }
    1067
    1068 consdata->catchevents = FALSE;
    1069
    1070 return SCIP_OKAY;
    1071}
    1072
    1073/** adds coefficient in setppc constraint */
    1074static
    1076 SCIP* scip, /**< SCIP data structure */
    1077 SCIP_CONS* cons, /**< setppc constraint */
    1078 SCIP_VAR* var /**< variable to add to the constraint */
    1079 )
    1080{
    1081 SCIP_CONSDATA* consdata;
    1082 SCIP_Bool transformed;
    1083
    1084 assert(var != NULL);
    1085
    1086 consdata = SCIPconsGetData(cons);
    1087 assert(consdata != NULL);
    1088
    1089 /* are we in the transformed problem? */
    1090 transformed = SCIPconsIsTransformed(cons);
    1091
    1092 /* always use transformed variables in transformed constraints */
    1093 if( transformed )
    1094 {
    1095 SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
    1096 }
    1097 assert(var != NULL);
    1098 assert(transformed == SCIPvarIsTransformed(var));
    1099
    1100 SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
    1101 consdata->vars[consdata->nvars] = var;
    1102 consdata->nvars++;
    1103 if( consdata->validsignature )
    1104 consdata->signature |= SCIPhashSignature64(SCIPvarGetIndex(var));
    1105 consdata->sorted = (consdata->nvars == 1);
    1106 consdata->changed = TRUE;
    1107
    1108 /* capture the variable */
    1109 SCIP_CALL( SCIPcaptureVar(scip, var) );
    1110
    1111 /* if we are in transformed problem, catch the variable's events */
    1112 if( transformed )
    1113 {
    1114 SCIP_CONSHDLR* conshdlr;
    1115 SCIP_CONSHDLRDATA* conshdlrdata;
    1116
    1117 /* get event handler */
    1118 conshdlr = SCIPconsGetHdlr(cons);
    1119 assert(conshdlr != NULL);
    1120 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    1121 assert(conshdlrdata != NULL);
    1122 assert(conshdlrdata->eventhdlr != NULL);
    1123
    1124 /* catch bound change events of variable */
    1125 if( consdata->catchevents )
    1126 {
    1127 SCIP_CALL( catchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
    1128 }
    1129
    1130 if( !consdata->existmultaggr && SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_MULTAGGR )
    1131 consdata->existmultaggr = TRUE;
    1132
    1133#ifdef VARUSES
    1134 /* if the constraint is currently active, increase the variable usage counter */
    1135 if( SCIPconsIsActive(cons) )
    1136 {
    1137 SCIP_CALL( conshdlrdataIncVaruses(scip, conshdlrdata, var) );
    1138 }
    1139#endif
    1140 }
    1141
    1142 /* install the rounding locks for the new variable */
    1143 SCIP_CALL( lockRounding(scip, cons, var) );
    1144
    1145 /* add the new coefficient to the LP row */
    1146 if( consdata->row != NULL )
    1147 {
    1148 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, 1.0) );
    1149 }
    1150
    1151 consdata->merged = FALSE;
    1152 consdata->cliqueadded = FALSE;
    1153
    1154 return SCIP_OKAY;
    1155}
    1156
    1157/** deletes coefficient at given position from setppc constraint data */
    1158static
    1160 SCIP* scip, /**< SCIP data structure */
    1161 SCIP_CONS* cons, /**< set partitioning / packing / covering constraint */
    1162 int pos /**< position of coefficient to delete */
    1163 )
    1164{
    1165 SCIP_CONSDATA* consdata;
    1166 SCIP_VAR* var;
    1167
    1168 assert(scip != NULL);
    1169 assert(cons != NULL);
    1170
    1171 consdata = SCIPconsGetData(cons);
    1172 assert(consdata != NULL);
    1173 assert(0 <= pos && pos < consdata->nvars);
    1174
    1175 var = consdata->vars[pos];
    1176 assert(var != NULL);
    1177 assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
    1178
    1179 /* remove the rounding locks for the deleted variable */
    1180 SCIP_CALL( unlockRounding(scip, cons, var) );
    1181
    1182 /* if we are in transformed problem, delete the event data of the variable */
    1183 if( SCIPconsIsTransformed(cons) )
    1184 {
    1185 SCIP_CONSHDLR* conshdlr;
    1186 SCIP_CONSHDLRDATA* conshdlrdata;
    1187
    1188 /* get event handler */
    1189 conshdlr = SCIPconsGetHdlr(cons);
    1190 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    1191 assert(conshdlrdata != NULL);
    1192 assert(conshdlrdata->eventhdlr != NULL);
    1193
    1194 /* drop bound change events of variable */
    1195 if( consdata->catchevents )
    1196 {
    1197 SCIP_CALL( dropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
    1198 }
    1199
    1200 /* the last variable of the constraint was deleted; mark it for propagation (so that it can be deleted) */
    1201 if( consdata->nvars == 1 )
    1202 {
    1203 consdata->presolpropagated = FALSE;
    1204 }
    1205 }
    1206
    1207 /* delete coefficient from the LP row */
    1208 if( consdata->row != NULL )
    1209 {
    1210 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, -1.0) );
    1211 }
    1212
    1213 /* move the last variable to the free slot */
    1214 if( pos != consdata->nvars - 1 )
    1215 {
    1216 consdata->vars[pos] = consdata->vars[consdata->nvars-1];
    1217 consdata->sorted = FALSE;
    1218 }
    1219 consdata->nvars--;
    1220 consdata->validsignature = FALSE;
    1221 consdata->changed = TRUE;
    1222
    1223 /* release variable */
    1224 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    1225
    1226 return SCIP_OKAY;
    1227}
    1228
    1229/** preform dual presolving
    1230 *
    1231 * In case a part (more than one variable) in the setppc constraint is independent of everything else (is locked only by
    1232 * this constraint), we can perform dual reductions:
    1233 *
    1234 * (1) set covering
    1235 *
    1236 * - fix all independent variables with negative object coefficient to one
    1237 * - fix all remaining independent variables to zero
    1238 *
    1239 * (i) all variables are independent and the constraint is not modifiable
    1240 *
    1241 * - fix the variable with the smallest object coefficient to one
    1242 *
    1243 * (ii) a variable x has exactly 0 uplocks and arbitrary downlocks and a variable y has exactly 1 downlock and
    1244 * arbitrary uplocks and obj(x) <= obj(y) and obj(y) >= 0
    1245 *
    1246 * - fix y to 0, because it is dominated by x
    1247 *
    1248 * (2) set partitioning
    1249 *
    1250 * (i) all variables are independent and the constraint is not modifiable
    1251 *
    1252 * - fix the variable with the smallest object coefficient to one
    1253 * - fix all remaining independent variables to zero
    1254 *
    1255 * (ii) a variable x has exactly 1 uplock and arbitrary downlocks and a variable y has exactly 1 downlock and
    1256 * arbitrary uplocks and obj(x) <= obj(y)
    1257 *
    1258 * - fix y to 0, because it is dominated by x
    1259 *
    1260 * (3) set packing
    1261 *
    1262 * (i) all variables are independent and the constraint is not modifiable
    1263 *
    1264 * - fix the variable with the smallest object coefficient to one if the object coefficient is negative or zero
    1265 * - fix all remaining independent variables to zero
    1266 *
    1267 * (ii) a variable x has exactly 1 uplock and arbitrary downlocks and a variable y has exactly 0 downlocks and
    1268 * arbitrary uplocks and obj(x) <= obj(y)
    1269 *
    1270 * - fix y to 0, because it is dominated by x
    1271 *
    1272 *
    1273 * Note: the following dual reduction for set covering and set packing constraints is already performed by the presolver
    1274 * "dualfix"
    1275 * (1) in case of a set covering constraint the following dual reduction can be performed:
    1276 * - if a variable in a set covering constraint is only locked by that constraint and has negative or zero
    1277 * objective coefficient than it can be fixed to one
    1278 * (2) in case of a set packing constraint the following dual reduction can be performed:
    1279 * - if a variable in a set packing constraint is only locked by that constraint and has positive or zero
    1280 * objective coefficient than it can be fixed to zero
    1281 *
    1282 * Note: all dual reduction (ii) could also be performed by the "domcol" presolver, but because the pairwise comparison of
    1283 * columns is only done heuristically (and here it should be even cheaper) we perform them here (too).
    1284 *
    1285 * Moreover, if there exists a variable that is only locked by a covering or packing constraint with two variables, one
    1286 * can aggregate variables.
    1287 */
    1288static
    1290 SCIP* scip, /**< SCIP data structure */
    1291 SCIP_CONS* cons, /**< setppc constraint */
    1292 int* nfixedvars, /**< pointer to count number of fixings */
    1293 int* ndelconss, /**< pointer to count number of deleted constraints */
    1294 int* naggrvars, /**< pointer to count number of variables aggregated */
    1295 SCIP_RESULT* result /**< pointer to store the result SCIP_SUCCESS, if presolving was performed */
    1296 )
    1297{
    1298 SCIP_CONSDATA* consdata;
    1299 SCIP_SETPPCTYPE setppctype;
    1300 SCIP_VAR** vars;
    1301 SCIP_VAR* activevar;
    1302 SCIP_VAR* var;
    1303 SCIP_Real bestobjval;
    1304 SCIP_Real objval;
    1305 SCIP_Real objsign;
    1306 SCIP_Real fixval;
    1307 SCIP_Bool infeasible;
    1308 SCIP_Bool fixed;
    1309 SCIP_Bool negated;
    1310 int noldfixed;
    1311 int nposfixings;
    1312 int nlockdowns;
    1313 int nlockups;
    1314 int nvars;
    1315 int indepidx = -1;
    1316 int idx;
    1317 int v;
    1318
    1319 assert(scip != NULL);
    1320 assert(cons != NULL);
    1321 assert(nfixedvars != NULL);
    1322 assert(ndelconss != NULL);
    1323 assert(result != NULL);
    1324
    1325 /* constraints for which the check flag is set to FALSE, did not contribute to the lock numbers; therefore, we cannot
    1326 * use the locks to decide for a dual reduction using this constraint; for example after a restart the cuts which are
    1327 * added to the problems have the check flag set to FALSE
    1328 */
    1329 if( !SCIPconsIsChecked(cons) )
    1330 return SCIP_OKAY;
    1331
    1332 assert(SCIPconsIsActive(cons));
    1333
    1334 consdata = SCIPconsGetData(cons);
    1335 assert(consdata != NULL);
    1336
    1337 /* modifiable non-covering constraints cannot be deleted if one variable is fixed to one, because the propagation for
    1338 * newly inserted variables must be considered later
    1339 */
    1340 if( consdata->nfixedones == 1 && SCIPconsIsModifiable(cons) )
    1341 return SCIP_OKAY;
    1342
    1343 /* all fixed variables should be removed at that point */
    1344 assert(consdata->nfixedones == 0);
    1345 assert(consdata->nfixedzeros == 0);
    1346
    1347 nvars = consdata->nvars;
    1348
    1349 /* we don't want to consider small constraints (note that the constraints can be modifiable, so we can't delete this
    1350 * constraint)
    1351 */
    1352 if( nvars < 2 )
    1353 return SCIP_OKAY;
    1354
    1355 setppctype = (SCIP_SETPPCTYPE)consdata->setppctype;
    1356 vars = consdata->vars;
    1357 idx = -1;
    1358 bestobjval = SCIP_INVALID;
    1359
    1360 /* collect the rounding locks depending on the setppc type */
    1361 switch( setppctype )
    1362 {
    1364 nlockdowns = 1;
    1365 nlockups = 1;
    1366 objsign = 0.0;
    1367 break;
    1369 nlockdowns = 0;
    1370 nlockups = 1;
    1371 objsign = -1.0;
    1372 break;
    1374 nlockdowns = 1;
    1375 nlockups = 0;
    1376 objsign = 1.0;
    1377 break;
    1378 default:
    1379 SCIPerrorMessage("unknown setppc type\n");
    1380 SCIPABORT();
    1381 return SCIP_INVALIDDATA; /*lint !e527*/
    1382 }
    1383
    1384 nposfixings = 0;
    1385
    1386 /* check if we can apply the dual reduction; therefore count the number of variables where the setppc has the only
    1387 * locks on this constraint
    1388 */
    1389 for( v = 0; v < nvars; ++v )
    1390 {
    1391 var = vars[v];
    1392 assert(var != NULL);
    1393
    1394 /* the variable should not be (globally) fixed */
    1395 assert(SCIPvarGetLbGlobal(var) < 0.5 && SCIPvarGetUbGlobal(var) > 0.5);
    1396
    1397 if( SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= nlockdowns
    1398 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlockups )
    1399 {
    1400 activevar = var;
    1401 negated = FALSE;
    1402
    1403 /* get the active variable */
    1404 SCIP_CALL( SCIPvarGetProbvarBinary(&activevar, &negated) );
    1405 assert(SCIPvarIsActive(activevar));
    1406
    1407 if( negated )
    1408 objval = -SCIPvarGetObj(activevar);
    1409 else
    1410 objval = SCIPvarGetObj(activevar);
    1411
    1412 /* check if the current variable has a smaller objective coefficient */
    1413 if( idx == -1 || objval < bestobjval )
    1414 {
    1415 idx = v;
    1416 bestobjval = objval;
    1417 }
    1418
    1419 /* determine independent variable, i.e., only locked by the current constraint */
    1420 if( SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlockdowns )
    1421 {
    1422 assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlockups);
    1423
    1424 /* store variables that have the right objective sign */
    1425 if ( objval * objsign >= 0.0 )
    1426 indepidx = v;
    1427 }
    1428 }
    1429
    1430 /* in case another constraint has also downlocks on that variable we cannot perform a dual reduction on these
    1431 * variables
    1432 */
    1433 if( SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlockdowns
    1434 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= nlockups )
    1435 ++nposfixings;
    1436 }
    1437
    1438 if( idx == -1 || nposfixings == 0 )
    1439 return SCIP_OKAY;
    1440
    1441 SCIPdebugMsg(scip, "dual fixing constraint: \n");
    1444
    1445 assert(idx >= 0 && idx < nvars);
    1446 assert(bestobjval < SCIPinfinity(scip));
    1447
    1448 noldfixed = *nfixedvars;
    1449
    1450 /* In the special case of two variables, where one variable is independent and will be minimized for covering or
    1451 * maximized for packing or does not appear in the objective, we can aggregate variables:
    1452 * - Covering: var1 + var2 >= 1 and the objective of var1 is non-negative.
    1453 * - Packing: var1 + var2 <= 1 and the objective of var1 is non-positive.
    1454 * In both cases, var1 + var2 = 1 holds in every optimal solution.
    1455 */
    1456 if( setppctype != SCIP_SETPPCTYPE_PARTITIONING && nvars == 2 && indepidx >= 0 )
    1457 {
    1458 SCIP_Bool redundant;
    1459 SCIP_Bool aggregated;
    1460 int idx2;
    1461
    1462 idx2 = 1 - indepidx;
    1463 assert( 0 <= idx2 && idx2 < 2 );
    1464
    1465 SCIP_CALL( SCIPaggregateVars(scip, vars[indepidx], vars[idx2], 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
    1466 assert(!infeasible);
    1467 assert(redundant);
    1468 assert(aggregated);
    1469 ++(*naggrvars);
    1470
    1471 /* remove constraint since it is redundant */
    1472 SCIP_CALL( SCIPdelCons(scip, cons) );
    1473 ++(*ndelconss);
    1474
    1475 *result = SCIP_SUCCESS;
    1476
    1477 return SCIP_OKAY;
    1478 }
    1479
    1480 /* in case of set packing and set partitioning we fix the dominated variables to zero */
    1481 if( setppctype != SCIP_SETPPCTYPE_COVERING )
    1482 {
    1483 /* first part of all variables */
    1484 for( v = nvars - 1; v >= 0; --v )
    1485 {
    1486 if( v == idx )
    1487 continue;
    1488
    1489 var = vars[v];
    1490 assert(var != NULL);
    1491
    1492 /* in case another constraint has also downlocks on that variable we cannot perform a dual reduction on these
    1493 * variables
    1494 */
    1495 if( SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlockdowns
    1496 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= nlockups )
    1497 {
    1498 activevar = var;
    1499 negated = FALSE;
    1500
    1501 /* get the active variable */
    1502 SCIP_CALL( SCIPvarGetProbvarBinary(&activevar, &negated) );
    1503 assert(SCIPvarIsActive(activevar));
    1504
    1505 if( negated )
    1506 objval = -SCIPvarGetObj(activevar);
    1507 else
    1508 objval = SCIPvarGetObj(activevar);
    1509
    1510 if( objval >= bestobjval )
    1511 {
    1512 SCIP_CALL( SCIPfixVar(scip, var, 0.0, &infeasible, &fixed) );
    1513 assert(!infeasible);
    1514 assert(fixed);
    1515
    1516 SCIPdebugMsg(scip, " -> dual-fixed dominated variable <%s> == 0.0\n", SCIPvarGetName(var));
    1517 ++(*nfixedvars);
    1518 }
    1519 }
    1520 }
    1521 }
    1522 /* if we got a set covering constraint and not all variables are locked from this constraint it might not get
    1523 * redundant (which is case if it is not possible to fix at least one variable to one), we fix all redundant
    1524 * variables to their best bound
    1525 */
    1526 else
    1527 {
    1528 /* first part of all variables */
    1529 for( v = nvars - 1; v >= 0; --v )
    1530 {
    1531 if( v == idx )
    1532 continue;
    1533
    1534 var = vars[v];
    1535 assert(var != NULL);
    1536
    1537 /* in case another constraint has also downlocks on that variable we cannot perform a dual reduction on these
    1538 * variables
    1539 */
    1540 if( SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlockdowns
    1541 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= nlockups )
    1542 {
    1543 activevar = var;
    1544 negated = FALSE;
    1545
    1546 /* get the active variable */
    1547 SCIP_CALL( SCIPvarGetProbvarBinary(&activevar, &negated) );
    1548 assert(SCIPvarIsActive(activevar));
    1549 assert(negated
    1552 assert(!negated
    1555
    1556 if( negated )
    1557 objval = -SCIPvarGetObj(activevar);
    1558 else
    1559 objval = SCIPvarGetObj(activevar);
    1560
    1561 if( objval > 0.0 )
    1562 fixval = 0.0;
    1563 else
    1564 fixval = 1.0;
    1565
    1566 /* if variables has a negative objective contribution, and is uplocked by another constraint we cannot fix
    1567 * the variables to 1
    1568 */
    1569 if( (fixval == 1.0 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) > nlockups) || objval < bestobjval )
    1570 continue;
    1571
    1572 SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
    1573 assert(!infeasible);
    1574 assert(fixed);
    1575
    1576 SCIPdebugMsg(scip, " -> dual-fixed dominated variable <%s> == %g\n", SCIPvarGetName(var), fixval);
    1577 ++(*nfixedvars);
    1578 }
    1579 }
    1580 }
    1581
    1582 /* if all variables but the domination variable is fixed and the constraint is not modifiable or the constraint is a
    1583 * covering constraint and the bestobjval is less than or equal to zero, we can fix the domination variable (with best
    1584 * objective coefficient) and the constraint gets redundant
    1585 */
    1586 if( ((*nfixedvars - noldfixed == nvars - 1) && !SCIPconsIsModifiable(cons)) || (setppctype == SCIP_SETPPCTYPE_COVERING && bestobjval <= 0.0) )
    1587 {
    1588 /* in case of a set packing constraint with positive objective values, all variables can be fixed to zero; in all
    1589 * other cases the variable with the smallest objective values is fixed to one
    1590 */
    1591 if( (setppctype == SCIP_SETPPCTYPE_PACKING && bestobjval > 0.0
    1593 || setppctype != SCIP_SETPPCTYPE_PACKING || bestobjval <= 0.0 )
    1594 {
    1595 if( setppctype == SCIP_SETPPCTYPE_PACKING && bestobjval > 0.0 )
    1596 fixval = 0.0;
    1597 else
    1598 fixval = 1.0;
    1599
    1600 SCIP_CALL( SCIPfixVar(scip, vars[idx], fixval, &infeasible, &fixed) );
    1601 assert(!infeasible);
    1602 assert(fixed);
    1603
    1604 SCIPdebugMsg(scip, " -> dual-fixed best variable <%s> == %g\n", SCIPvarGetName(vars[idx]), fixval);
    1605 ++(*nfixedvars);
    1606 }
    1607
    1608 /* check that we really have a non-violated constraint in hand before deleting */
    1609 assert((setppctype == SCIP_SETPPCTYPE_PACKING && consdata->nfixedones <= 1) ||
    1610 (setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata->nfixedones == 1) ||
    1611 (setppctype == SCIP_SETPPCTYPE_COVERING && consdata->nfixedones >= 1));
    1612
    1613 /* remove constraint since it is redundant */
    1614 SCIP_CALL( SCIPdelCons(scip, cons) );
    1615 ++(*ndelconss);
    1616 }
    1617
    1618 assert(*nfixedvars >= noldfixed);
    1619
    1620 /* set result pointer to SCIP_SUCCESS, if variables could be fixed */
    1621 if( *nfixedvars != noldfixed )
    1622 *result = SCIP_SUCCESS;
    1623
    1624 return SCIP_OKAY;
    1625}
    1626
    1627/** find pairs of negated variables in constraint:
    1628 * partitioning/packing: all other variables must be zero, constraint is redundant
    1629 * covering: constraint is redundant
    1630 *
    1631 * find sets of equal variables in constraint:
    1632 * partitioning/packing: variable must be zero
    1633 * covering: multiple entries of variable can be replaced by single entry
    1634 */
    1635static
    1637 SCIP* scip, /**< SCIP data structure */
    1638 SCIP_CONS* cons, /**< knapsack constraint */
    1639 int* nfixedvars, /**< pointer to store number of fixed variables */
    1640 int* ndelconss, /**< pointer to store number of deleted constraints */
    1641 int* nchgcoefs, /**< pointer to store number of changed coefficients */
    1642 SCIP_Bool* cutoff /**< pointer to store whether a fixing leads to a cutoff */
    1643 )
    1644{
    1645 SCIP_CONSDATA* consdata;
    1646 int v;
    1647
    1648 assert(scip != NULL);
    1649 assert(cons != NULL);
    1650 assert(nfixedvars != NULL);
    1651 assert(ndelconss != NULL);
    1652 assert(nchgcoefs != NULL);
    1653 assert(cutoff != NULL);
    1654
    1655 consdata = SCIPconsGetData(cons);
    1656 assert(consdata != NULL);
    1657
    1658 if( consdata->merged || SCIPconsIsDeleted(cons) )
    1659 return SCIP_OKAY;
    1660
    1661 if( consdata->nvars <= 1 )
    1662 {
    1663 consdata->merged = TRUE;
    1664 return SCIP_OKAY;
    1665 }
    1666
    1667 assert(consdata->vars != NULL || consdata->nvars == 0);
    1668
    1669 /* sorting array after indices of variables, that's only for faster merging */
    1670 SCIPsortPtr((void**)consdata->vars, SCIPvarCompActiveAndNegated, consdata->nvars);
    1671 /* setppc sorting now lost */
    1672 consdata->sorted = FALSE;
    1673
    1674 /* loop backwards through the items: deletion only affects rear items */
    1675 for( v = consdata->nvars - 1; v > 0; --v )
    1676 {
    1677 SCIP_VAR* var1;
    1678 SCIP_VAR* var2;
    1679 SCIP_Bool negated1;
    1680 SCIP_Bool negated2;
    1681
    1682 negated1 = FALSE;
    1683 negated2 = FALSE;
    1684
    1685 var1 = consdata->vars[v];
    1686 assert(SCIPvarIsBinary(var1));
    1689 {
    1690 var1 = SCIPvarGetNegatedVar(var1);
    1691 negated1 = TRUE;
    1692 }
    1693 assert(var1 != NULL);
    1694
    1695 var2 = consdata->vars[v-1];
    1696 assert(SCIPvarIsBinary(var2));
    1699 {
    1700 var2 = SCIPvarGetNegatedVar(var2);
    1701 negated2 = TRUE;
    1702 }
    1703 assert(var2 != NULL);
    1704
    1705 if( var1 == var2 )
    1706 {
    1707 SCIP_Bool infeasible;
    1708 SCIP_Bool fixed;
    1709
    1710 /* one variables is active and the other is the same negated variable */
    1711 if( negated1 != negated2 )
    1712 {
    1713 /* all other variable have to be zero if it's a partitioning or packing constraint */
    1714 if( consdata->setppctype != SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    1715 {
    1716 int i;
    1717
    1718 assert(consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING
    1719 || consdata->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
    1720
    1721 for( i = consdata->nvars - 1; i >= 0; --i )
    1722 if( i != v && i != (v-1) )
    1723 {
    1724 SCIP_CALL( SCIPfixVar(scip, consdata->vars[i], 0.0, &infeasible, &fixed) );
    1725 if( infeasible )
    1726 {
    1727 SCIPdebugMsg(scip, "setppc constraint <%s>: infeasible fixing <%s> == 0\n",
    1728 SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]));
    1729 *cutoff = TRUE;
    1730 return SCIP_OKAY;
    1731 }
    1732
    1733 if( fixed )
    1734 ++(*nfixedvars);
    1735 }
    1736 }
    1737 /* all setppc-type constraints are redundant */
    1738 SCIP_CALL( SCIPdelCons(scip, cons) );
    1739 ++(*ndelconss);
    1740 return SCIP_OKAY;
    1741 }
    1742 /* both variables are either active or negated */
    1743 else
    1744 {
    1745 /* this variable can be fixed to zero if it's a partitioning or packing constraint */
    1746 if( consdata->setppctype != SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    1747 {
    1748 assert(consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING
    1749 || consdata->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
    1750
    1751 SCIP_CALL( SCIPfixVar(scip, var1, negated1 ? 1.0 : 0.0, &infeasible, &fixed) );
    1752 if( infeasible )
    1753 {
    1754 SCIPdebugMsg(scip, "setppc constraint <%s>: infeasible fixing <%s> == %g\n",
    1755 SCIPconsGetName(cons), SCIPvarGetName(var1), negated1 ? 1.0 : 0.0);
    1756 *cutoff = TRUE;
    1757 return SCIP_OKAY;
    1758 }
    1759
    1760 if( fixed )
    1761 ++(*nfixedvars);
    1762 }
    1763 /* multiple entries of variable can be replaced by single entry */
    1764 else
    1765 {
    1766 SCIP_CALL( delCoefPos(scip, cons, v) ); /* only some changed behind position v-1, so it's okay */
    1767 ++(*nchgcoefs);
    1768 }
    1769 }
    1770 consdata->changed = TRUE;
    1771 }
    1772 }
    1773 consdata->merged = TRUE;
    1774
    1775 return SCIP_OKAY;
    1776}
    1777
    1778/** deletes all zero-fixed variables and replace aggregated variables */
    1779static
    1781 SCIP* scip, /**< SCIP data structure */
    1782 SCIP_CONS* cons, /**< set partitioning / packing / covering constraint */
    1783 int* naddconss, /**< pointer to count number of added constraints, or NULL indicating we
    1784 * can not resolve multi-aggregations
    1785 */
    1786 int* ndelconss, /**< pointer to count number of deleted constraints, or NULL indicating we
    1787 * can not resolve multi-aggregations
    1788 */
    1789 int* nfixedvars, /**< pointer to store number of fixed variables, or NULL indicating we can
    1790 * not resolve multi-aggregations
    1791 */
    1792 SCIP_Bool* cutoff /**< pointer to store whether a fixing leads to a cutoff, or NULL
    1793 * indicating we can not resolve multi-aggregations
    1794 */
    1795 )
    1796{
    1797 SCIP_CONSDATA* consdata;
    1798 int v;
    1799
    1800 assert(scip != NULL);
    1801 assert(cons != NULL);
    1802
    1803 consdata = SCIPconsGetData(cons);
    1804 assert(consdata != NULL);
    1805
    1806 /* all multi-aggregations should be resolved */
    1807 consdata->existmultaggr = FALSE;
    1808
    1809 v = 0;
    1810 while( v < consdata->nvars )
    1811 {
    1812 SCIP_VAR* var;
    1813
    1814 var = consdata->vars[v];
    1815 assert(SCIPvarIsBinary(var));
    1816
    1817 if( SCIPvarGetUbGlobal(var) < 0.5 )
    1818 {
    1819 assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), 0.0));
    1820 SCIP_CALL( delCoefPos(scip, cons, v) );
    1821 }
    1822 else
    1823 {
    1824 SCIP_VAR* repvar;
    1825 SCIP_Bool negated;
    1826
    1827 /* get binary representative of variable */
    1828 SCIP_CALL( SCIPgetBinvarRepresentative(scip, var, &repvar, &negated) );
    1829
    1830 /* resolve multi-aggregation */
    1832 {
    1833 SCIP_VAR** consvars;
    1834 SCIP_Real* consvals;
    1835 SCIP_Real constant = 0.0;
    1836 SCIP_Bool easycase;
    1837 int nconsvars;
    1838 int requiredsize;
    1839 int consvarssize = 10;
    1840 int v2;
    1841
    1842 nconsvars = 1;
    1843 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, consvarssize) );
    1844 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, consvarssize) );
    1845 consvars[0] = repvar;
    1846 consvals[0] = 1.0;
    1847
    1848 /* get active variables for new constraint */
    1849 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, consvarssize, &constant, &requiredsize) );
    1850 /* if space was not enough we need to resize the buffers */
    1851 if( requiredsize > consvarssize )
    1852 {
    1853 consvarssize = requiredsize;
    1854 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, consvarssize) );
    1855 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, consvarssize) );
    1856
    1857 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, consvarssize, &constant, &requiredsize) );
    1858 assert(requiredsize <= consvarssize);
    1859 }
    1860 assert(requiredsize == nconsvars);
    1861
    1862 easycase = FALSE;
    1863
    1864 if( SCIPisZero(scip, constant) )
    1865 {
    1866 /* add active representation */
    1867 for( v2 = nconsvars - 1; v2 >= 0; --v2 )
    1868 {
    1869 if( !SCIPvarIsBinary(consvars[v2]) )
    1870 break;
    1871
    1872 if( !SCIPisEQ(scip, consvals[v2], 1.0) )
    1873 break;
    1874 }
    1875
    1876 if( v2 < 0 )
    1877 easycase = TRUE;
    1878 }
    1879 else if( SCIPisFeasEQ(scip, constant, 1.0) )
    1880 {
    1881 /* check for another multi-aggregation */
    1882 for( v2 = consdata->nvars - 1; v2 > v; --v2 )
    1883 {
    1885 break;
    1886 }
    1887
    1888 /* constraint is redundant */
    1889 if( v2 == v && nconsvars == 0 )
    1890 {
    1891 /* we can fix */
    1892 if( consdata->nvars > 1 && (SCIP_SETPPCTYPE)consdata->setppctype != SCIP_SETPPCTYPE_COVERING )
    1893 {
    1894 if( nfixedvars != NULL )
    1895 {
    1896 SCIP_Bool fixed;
    1897
    1898 assert(cutoff != NULL);
    1899
    1900 for( v2 = consdata->nvars - 1; v2 >= 0; --v2 )
    1901 {
    1902 if( consdata->vars[v2] != var )
    1903 {
    1904 SCIPdebugMsg(scip, "trying to fix <%s> to 0 due to at least one variable is already fixed to 1\n", SCIPvarGetName(consdata->vars[v2]));
    1905
    1906 /* fix all remaining variables to zero, constraint is already feasible or infeasible */
    1907 SCIP_CALL( SCIPfixVar(scip, consdata->vars[v2], 0.0, cutoff, &fixed) );
    1908 if( *cutoff )
    1909 {
    1910 SCIPdebugMsg(scip, "setppc constraint <%s>: infeasible fixing <%s> == 0\n",
    1911 SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[v2]));
    1912
    1913 SCIPfreeBufferArray(scip, &consvals);
    1914 SCIPfreeBufferArray(scip, &consvars);
    1915
    1916 goto TERMINATE;
    1917 }
    1918
    1919 if( fixed )
    1920 ++(*nfixedvars);
    1921 }
    1922 }
    1923 }
    1924 }
    1925
    1926 if( ndelconss != NULL && (nfixedvars != NULL || consdata->nvars == 1 || (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_COVERING) )
    1927 {
    1928 /* delete old constraint */
    1929 SCIP_CALL( SCIPdelCons(scip, cons) );
    1930 ++(*ndelconss);
    1931 }
    1932 SCIPfreeBufferArray(scip, &consvals);
    1933 SCIPfreeBufferArray(scip, &consvars);
    1934
    1935 goto TERMINATE;
    1936 }
    1937 }
    1938
    1939 /* we can easily add the coefficients and still have a setppc constraint */
    1940 if( easycase )
    1941 {
    1942 /* delete old (multi-aggregated) variable */
    1943 SCIP_CALL( delCoefPos(scip, cons, v) );
    1944
    1945 /* add active representation */
    1946 for( v2 = nconsvars - 1; v2 >= 0; --v2 )
    1947 {
    1948 assert(SCIPvarIsBinary(consvars[v2]));
    1949 assert(SCIPvarIsActive(consvars[v2]) || (SCIPvarGetStatus(consvars[v2]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(consvars[v2]))));
    1950
    1951 SCIP_CALL( addCoef(scip, cons, consvars[v2]) );
    1952 }
    1953 }
    1954 /* we need to degrade this setppc constraint to a linear constraint */
    1955 else if( (ndelconss != NULL && naddconss != NULL) || SCIPconsIsAdded(cons) )
    1956 {
    1957 char name[SCIP_MAXSTRLEN];
    1958 SCIP_CONS* newcons;
    1959 SCIP_Real lhs;
    1960 SCIP_Real rhs;
    1961 int size;
    1962 int k;
    1963
    1964 /* it might happen that there are more than one multi-aggregated variable, so we need to get the whole
    1965 * probvar sum over all variables
    1966 */
    1967
    1968 size = MAX(nconsvars, 1) + consdata->nvars - 1;
    1969
    1970 /* memory needed is at least old number of variables - 1 + number of variables in first multi-aggregation */
    1971 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, size) );
    1972 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, size) );
    1973
    1974 nconsvars = consdata->nvars;
    1975
    1976 /* add constraint variables to new linear variables */
    1977 for( k = consdata->nvars - 1; k >= 0; --k )
    1978 {
    1979 consvars[k] = consdata->vars[k];
    1980 consvals[k] = 1.0;
    1981 }
    1982
    1983 constant = 0.0;
    1984
    1985 /* get active variables for new constraint */
    1986 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, size, &constant, &requiredsize) );
    1987
    1988 /* if space was not enough (we found another multi-aggregation), we need to resize the buffers */
    1989 if( requiredsize > size )
    1990 {
    1991 size = requiredsize;
    1992 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, size) );
    1993 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, size) );
    1994
    1995 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, size, &constant, &requiredsize) );
    1996 assert(requiredsize <= size);
    1997 }
    1998 assert(requiredsize == nconsvars);
    1999
    2000 /* compute sides */
    2001 if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING )
    2002 {
    2003 lhs = -SCIPinfinity(scip);
    2004 rhs = 1.0 - constant;
    2005 }
    2006 else if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING )
    2007 {
    2008 lhs = 1.0 - constant;
    2009 rhs = 1.0 - constant;
    2010 }
    2011 else
    2012 {
    2013 assert((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_COVERING);
    2014 lhs = 1.0 - constant;
    2015 rhs = SCIPinfinity(scip);
    2016 }
    2017
    2018 /* create linear constraint */
    2019 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s", SCIPconsGetName(cons));
    2020 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, nconsvars, consvars, consvals, lhs, rhs,
    2021 SCIPconsIsInitial(cons),
    2025
    2026 /* add the downgraded constraint to the problem */
    2027 SCIPdebugMsg(scip, "adding linear constraint: ");
    2028 SCIPdebugPrintCons(scip, newcons, NULL);
    2029 SCIP_CALL( SCIPaddCons(scip, newcons) );
    2030 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    2031
    2032 /* free constraint arrays */
    2033 SCIPfreeBufferArray(scip, &consvals);
    2034 SCIPfreeBufferArray(scip, &consvars);
    2035
    2036 /* delete old constraint */
    2037 SCIP_CALL( SCIPdelCons(scip, cons) );
    2038 if( ndelconss != NULL && naddconss != NULL )
    2039 {
    2040 ++(*ndelconss);
    2041 ++(*naddconss);
    2042 }
    2043
    2044 goto TERMINATE;
    2045 }
    2046 /* we need to degrade this setppc constraint to a linear constraint*/
    2047 else
    2048 {
    2049 /* check, if the variable should be replaced with the representative */
    2050 if( repvar != var )
    2051 {
    2052 /* delete old (aggregated) variable */
    2053 SCIP_CALL( delCoefPos(scip, cons, v) );
    2054
    2055 /* add representative instead */
    2056 SCIP_CALL( addCoef(scip, cons, repvar) );
    2057 }
    2058
    2059 SCIPwarningMessage(scip, "setppc constraint <%s> has a multi-aggregated variable, which was not resolved and therefore could lead to aborts\n", SCIPconsGetName(cons));
    2060 ++v;
    2061 }
    2062
    2063 SCIPfreeBufferArray(scip, &consvals);
    2064 SCIPfreeBufferArray(scip, &consvars);
    2065 }
    2066 else
    2067 {
    2068 /* check, if the variable should be replaced with the representative */
    2069 if( repvar != var )
    2070 {
    2071 /* delete old (aggregated) variable */
    2072 SCIP_CALL( delCoefPos(scip, cons, v) );
    2073
    2074 /* add representative instead */
    2075 SCIP_CALL( addCoef(scip, cons, repvar) );
    2076 }
    2077 else
    2078 ++v;
    2079 }
    2080 }
    2081 }
    2082
    2083 TERMINATE:
    2084 /* all multi-aggregations should be resolved */
    2085 consdata->existmultaggr = FALSE;
    2086
    2087 return SCIP_OKAY;
    2088}
    2089
    2090/** analyzes conflicting assignment on given constraint where all of the variables where assigned to zero,
    2091 * and adds conflict constraint to problem
    2092 */
    2093static
    2095 SCIP* scip, /**< SCIP data structure */
    2096 SCIP_CONS* cons /**< set partitioning / packing / covering constraint that detected the conflict */
    2097 )
    2098{
    2099 SCIP_CONSDATA* consdata;
    2100 int v;
    2101
    2102 /* conflict analysis can only be applied in solving stage and if it is applicable */
    2104 return SCIP_OKAY;
    2105
    2106 consdata = SCIPconsGetData(cons);
    2107 assert(consdata != NULL);
    2108 assert(consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING
    2109 || consdata->setppctype == SCIP_SETPPCTYPE_COVERING); /*lint !e641*/
    2110
    2111 /* initialize conflict analysis, and add all variables of infeasible constraint to conflict candidate queue */
    2113
    2114 for( v = 0; v < consdata->nvars; ++v )
    2115 {
    2116 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->vars[v]) );
    2117 }
    2118
    2119 /* analyze the conflict */
    2121
    2122 return SCIP_OKAY;
    2123}
    2124
    2125/** analyzes conflicting assignment on given constraint where two of the variables where assigned to one,
    2126 * and adds conflict constraint to problem
    2127 */
    2128static
    2130 SCIP* scip, /**< SCIP data structure */
    2131 SCIP_CONS* cons /**< set partitioning / packing / covering constraint that detected the conflict */
    2132 )
    2133{
    2134 SCIP_CONSDATA* consdata;
    2135 int v;
    2136 int n;
    2137
    2138 /* conflict analysis can only be applied in solving stage and if it is applicable */
    2140 return SCIP_OKAY;
    2141
    2142 consdata = SCIPconsGetData(cons);
    2143 assert(consdata != NULL);
    2144 assert(consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING
    2145 || consdata->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
    2146
    2147 /* initialize conflict analysis, and add the two variables assigned to one to conflict candidate queue */
    2149
    2150 n = 0;
    2151 for( v = 0; v < consdata->nvars && n < 2; ++v )
    2152 {
    2153 if( SCIPvarGetLbLocal(consdata->vars[v]) > 0.5 )
    2154 {
    2155 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->vars[v]) );
    2156 n++;
    2157 }
    2158 }
    2159 assert(n == 2);
    2160
    2161 /* analyze the conflict */
    2163
    2164 return SCIP_OKAY;
    2165}
    2166
    2167/** checks constraint for violation only looking at the fixed variables, applies further fixings if possible */
    2168static
    2170 SCIP* scip, /**< SCIP data structure */
    2171 SCIP_CONS* cons, /**< set partitioning / packing / covering constraint to be processed */
    2172 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    2173 int* nfixedvars, /**< pointer to count number of deleted variables */
    2174 SCIP_Bool* addcut, /**< pointer to store whether this constraint must be added as a cut */
    2175 SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
    2176 )
    2177{
    2178 SCIP_CONSDATA* consdata;
    2179#ifndef NDEBUG
    2180 int oldnfixedvars;
    2181#endif
    2182
    2183 assert(cons != NULL);
    2184 assert(SCIPconsGetHdlr(cons) != NULL);
    2185 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
    2186 assert(cutoff != NULL);
    2187 assert(nfixedvars != NULL);
    2188 assert(addcut != NULL);
    2189 assert(mustcheck != NULL);
    2190
    2191#ifndef NDEBUG
    2192 oldnfixedvars = *nfixedvars;
    2193#endif
    2194
    2195 consdata = SCIPconsGetData(cons);
    2196 assert(consdata != NULL);
    2197 assert(consdata->nvars == 0 || consdata->vars != NULL);
    2198 assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nvars);
    2199 assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nvars);
    2200
    2201 *addcut = FALSE;
    2202 *mustcheck = TRUE;
    2203
    2204 /*SCIPdebugMsg(scip, "processing constraint <%s> with respect to fixed variables (%d fixed to 0.0, %d fixed to 1.0)\n",
    2205 SCIPconsGetName(cons), consdata->nfixedzeros, consdata->nfixedones);*/
    2206
    2207 if( consdata->nfixedones == 1 )
    2208 {
    2209 /* exactly one variable is fixed to 1:
    2210 * - a set covering constraint is feasible anyway and can be disabled
    2211 * - all other variables in a set partitioning or packing constraint must be zero
    2212 */
    2213 if( consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    2214 {
    2215 SCIPdebugMsg(scip, " -> disabling set covering constraint <%s>\n", SCIPconsGetName(cons));
    2217 }
    2218 else
    2219 {
    2220 if( consdata->nfixedzeros < consdata->nvars - 1 )
    2221 {
    2222 SCIP_VAR** vars;
    2223 SCIP_VAR* var;
    2224#ifndef NDEBUG
    2225 SCIP_Bool fixedonefound;
    2226#endif
    2227 SCIP_Bool infeasible;
    2228 SCIP_Bool tightened;
    2229 int nvars;
    2230 int v;
    2231 int oneidx = -1;
    2232
    2233 SCIPdebugMsg(scip, " -> fixing all other variables to zero in set packing/partitioning constraint <%s>\n",
    2234 SCIPconsGetName(cons));
    2235
    2236 /* unfixed variables exist: fix them to zero;
    2237 * this could result in additional variables fixed to one due to aggregations; in this case, the
    2238 * constraint is infeasible in local bounds
    2239 */
    2240 vars = consdata->vars;
    2241 nvars = consdata->nvars;
    2242#ifndef NDEBUG
    2243 fixedonefound = FALSE;
    2244#endif
    2245 for( v = 0; v < nvars && consdata->nfixedones == 1; ++v ) /* cppcheck-suppress knownConditionTrueFalse */
    2246 {
    2247 var = vars[v];
    2249 if( SCIPvarGetLbLocal(var) < 0.5 )
    2250 {
    2251 SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, oneidx, &infeasible, &tightened) );
    2252 assert(!infeasible);
    2253
    2254 if( tightened )
    2255 ++(*nfixedvars);
    2256
    2257 SCIPdebugMsg(scip, " -> fixed <%s> to zero (tightened=%u)\n", SCIPvarGetName(var), tightened);
    2258 }
    2259 else
    2260 {
    2261#ifndef NDEBUG
    2262 fixedonefound = TRUE;
    2263#endif
    2264 oneidx = v;
    2265 }
    2266 }
    2267 /* the fixed to one variable must have been found, and at least one variable must have been fixed */
    2268 assert(consdata->nfixedones >= 2 || (fixedonefound && *nfixedvars > oldnfixedvars));
    2269
    2271 }
    2272
    2273 /* now all other variables are fixed to zero:
    2274 * the constraint is feasible, and if it's not modifiable, it is redundant
    2275 */
    2276 if( !SCIPconsIsModifiable(cons) && consdata->nfixedones == 1 )
    2277 {
    2278 SCIPdebugMsg(scip, " -> disabling set packing/partitioning constraint <%s>\n", SCIPconsGetName(cons));
    2280 }
    2281 }
    2282 *mustcheck = FALSE;
    2283 }
    2284
    2285 if( consdata->nfixedones >= 2 )
    2286 {
    2287 /* at least two variables are fixed to 1:
    2288 * - a set covering constraint is feasible anyway and can be disabled
    2289 * - a set partitioning or packing constraint is infeasible
    2290 */
    2291 if( consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    2292 {
    2293 SCIPdebugMsg(scip, " -> disabling set covering constraint <%s>\n", SCIPconsGetName(cons));
    2295 }
    2296 else
    2297 {
    2298 SCIPdebugMsg(scip, " -> conflict on set packing/partitioning constraint <%s>\n", SCIPconsGetName(cons));
    2299
    2301
    2302 /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
    2304
    2305 *cutoff = TRUE;
    2306 }
    2307 *mustcheck = FALSE;
    2308 }
    2309 else if( consdata->nfixedzeros == consdata->nvars )
    2310 {
    2311 /* all variables are fixed to zero:
    2312 * - a set packing constraint is feasible anyway, and if it's unmodifiable, it can be disabled
    2313 * - a set partitioning or covering constraint is infeasible, and if it's unmodifiable, the node
    2314 * can be cut off -- otherwise, the constraint must be added as a cut and further pricing must
    2315 * be performed
    2316 */
    2317 assert(consdata->nfixedones == 0);
    2318
    2319 if( consdata->setppctype == SCIP_SETPPCTYPE_PACKING ) /*lint !e641*/
    2320 {
    2321 if( !SCIPconsIsModifiable(cons) )
    2322 {
    2323 SCIPdebugMsg(scip, " -> disabling set packing constraint <%s>\n", SCIPconsGetName(cons));
    2325 }
    2326 }
    2327 else
    2328 {
    2329 SCIPdebugMsg(scip, " -> set covering/partitioning constraint <%s> is infeasible\n", SCIPconsGetName(cons));
    2330
    2332 if( SCIPconsIsModifiable(cons) )
    2333 *addcut = TRUE;
    2334 else
    2335 {
    2336 /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
    2338
    2339 *cutoff = TRUE;
    2340 }
    2341 }
    2342 *mustcheck = FALSE;
    2343 }
    2344 else if( consdata->nfixedzeros == consdata->nvars - 1 && consdata->nfixedones == 0 )
    2345 {
    2346 /* all variables except one are fixed to zero:
    2347 * - a set packing constraint is feasible anyway, and if it's unmodifiable, it can be disabled
    2348 * - an unmodifiable set partitioning or covering constraint is feasible and can be disabled after the
    2349 * remaining variable is fixed to one
    2350 * - a modifiable set partitioning or covering constraint must be checked manually
    2351 */
    2352 if( consdata->setppctype == SCIP_SETPPCTYPE_PACKING ) /*lint !e641*/
    2353 {
    2354 if( !SCIPconsIsModifiable(cons) )
    2355 {
    2356 SCIPdebugMsg(scip, " -> disabling set packing constraint <%s>\n", SCIPconsGetName(cons));
    2358 }
    2359 *mustcheck = FALSE;
    2360 }
    2361 else if( !SCIPconsIsModifiable(cons) )
    2362 {
    2363 SCIP_VAR** vars;
    2364 SCIP_VAR* var;
    2365 SCIP_Bool infeasible;
    2366 SCIP_Bool tightened;
    2367 int nvars;
    2368 int v;
    2369
    2370 /* search the single variable that can be fixed */
    2371 vars = consdata->vars;
    2372 nvars = consdata->nvars;
    2373 for( v = 0; v < nvars; ++v )
    2374 {
    2375 var = vars[v];
    2376 assert(SCIPisFeasZero(scip, SCIPvarGetLbLocal(var)));
    2378 if( SCIPvarGetUbLocal(var) > 0.5 )
    2379 {
    2380 SCIPdebugMsg(scip, " -> fixing remaining variable <%s> to one in set covering/partitioning constraint <%s>\n",
    2381 SCIPvarGetName(var), SCIPconsGetName(cons));
    2382 SCIP_CALL( SCIPinferBinvarCons(scip, var, TRUE, cons, 0, &infeasible, &tightened) );
    2383 assert(!infeasible);
    2384 assert(tightened);
    2385
    2386 ++(*nfixedvars);
    2387 break;
    2388 }
    2389 }
    2390 assert(v < nvars);
    2391 assert(consdata->nfixedzeros == consdata->nvars - 1);
    2392 assert(consdata->nfixedones == 1);
    2393
    2395 *mustcheck = FALSE;
    2396 }
    2397 }
    2398 assert(consdata->nfixedzeros + consdata->nfixedones <= consdata->nvars);
    2399
    2400 return SCIP_OKAY;
    2401}
    2402
    2403/** checks constraint for violation, returns TRUE iff constraint is feasible */
    2404static
    2406 SCIP* scip, /**< SCIP data structure */
    2407 SCIP_CONSDATA* consdata, /**< set partitioning / packing / covering constraint to be checked */
    2408 SCIP_SOL* sol /**< primal CIP solution */
    2409 )
    2410{
    2411 SCIP_VAR** vars;
    2412 SCIP_Real solval;
    2413 SCIP_Real sum;
    2414 SCIP_Real sumbound;
    2415 SCIP_Real absviol;
    2416 SCIP_Real relviol;
    2417 SCIP_Bool check;
    2418 int nvars;
    2419 int v;
    2420
    2421 /* calculate the constraint's activity */
    2422 vars = consdata->vars;
    2423 nvars = consdata->nvars;
    2424 sum = 0.0;
    2425 sumbound = ((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_COVERING ? 1.0 : 1.0 + 2*SCIPfeastol(scip));
    2426 for( v = 0; v < nvars && sum < sumbound; ++v ) /* if sum >= sumbound, the feasibility is clearly decided */
    2427 {
    2428 assert(SCIPvarIsBinary(vars[v]));
    2429
    2430 solval = SCIPgetSolVal(scip, sol, vars[v]);
    2431 assert(SCIPisFeasGE(scip, solval, 0.0) && SCIPisFeasLE(scip, solval, 1.0));
    2432
    2433 sum += solval;
    2434 }
    2435
    2436 absviol = sum - 1.0;
    2437 relviol = SCIPrelDiff(sum, 1.0);
    2438 switch( consdata->setppctype )
    2439 {
    2441 /* in case of partitioning, the violation is equal to the absolute difference between sum and 1 */
    2442 absviol = REALABS(absviol);
    2443 relviol = REALABS(relviol);
    2444 check = SCIPisFeasEQ(scip, sum, 1.0);
    2445 break;
    2447 /* in case of packing, the violation is equal to how much sum exceeds 1 */
    2448 check = SCIPisFeasLE(scip, sum, 1.0);
    2449 break;
    2451 /* in case of covering, the violation is equal to how much 1 exceeds sum */
    2452 absviol = -absviol;
    2453 relviol = -relviol;
    2454 check = SCIPisFeasGE(scip, sum, 1.0);
    2455 break;
    2456 default:
    2457 SCIPerrorMessage("unknown setppc type\n");
    2458 SCIPABORT();
    2459 return FALSE; /*lint !e527*/
    2460 }
    2461
    2462 if( sol != NULL )
    2463 SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
    2464
    2465 return check;
    2466}
    2467
    2468/** creates an LP row in a set partitioning / packing / covering constraint data object */
    2469static
    2471 SCIP* scip, /**< SCIP data structure */
    2472 SCIP_CONS* cons /**< set partitioning / packing / covering constraint */
    2473 )
    2474{
    2475 SCIP_CONSDATA* consdata;
    2476 SCIP_Real lhs;
    2477 SCIP_Real rhs;
    2478
    2479 consdata = SCIPconsGetData(cons);
    2480 assert(consdata != NULL);
    2481 assert(consdata->row == NULL);
    2482
    2483 switch( consdata->setppctype )
    2484 {
    2486 lhs = 1.0;
    2487 rhs = 1.0;
    2488 break;
    2490 lhs = -SCIPinfinity(scip);
    2491 rhs = 1.0;
    2492 break;
    2494 lhs = 1.0;
    2495 rhs = SCIPinfinity(scip);
    2496 break;
    2497 default:
    2498 SCIPerrorMessage("unknown setppc type\n");
    2499 return SCIP_INVALIDDATA;
    2500 }
    2501
    2502 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, cons, SCIPconsGetName(cons), lhs, rhs,
    2504
    2505 SCIP_CALL( SCIPaddVarsToRowSameCoef(scip, consdata->row, consdata->nvars, consdata->vars, 1.0) );
    2506
    2507 return SCIP_OKAY;
    2508}
    2509
    2510/** adds setppc constraint as cut to the LP */
    2511static
    2513 SCIP* scip, /**< SCIP data structure */
    2514 SCIP_CONS* cons, /**< setppc constraint */
    2515 SCIP_Bool* cutoff /**< whether a cutoff has been detected */
    2516 )
    2517{
    2518 SCIP_CONSDATA* consdata;
    2519
    2520 assert( cutoff != NULL );
    2521 *cutoff = FALSE;
    2522
    2523 consdata = SCIPconsGetData(cons);
    2524 assert(consdata != NULL);
    2525
    2526 if( consdata->row == NULL )
    2527 {
    2528 /* convert set partitioning constraint data into LP row */
    2529 SCIP_CALL( createRow(scip, cons) );
    2530 }
    2531 assert(consdata->row != NULL);
    2532
    2533 /* insert LP row as cut */
    2534 if( !SCIProwIsInLP(consdata->row) )
    2535 {
    2536 SCIPdebugMsg(scip, "adding constraint <%s> as cut to the LP\n", SCIPconsGetName(cons));
    2537 SCIP_CALL( SCIPaddRow(scip, consdata->row, FALSE, cutoff) );
    2538 }
    2539
    2540 return SCIP_OKAY;
    2541}
    2542
    2543/** adds setppc constraint as row to the NLP, if not added yet */
    2544static
    2546 SCIP* scip, /**< SCIP data structure */
    2547 SCIP_CONS* cons /**< setppc constraint */
    2548 )
    2549{
    2550 SCIP_CONSDATA* consdata;
    2551
    2552 assert(SCIPisNLPConstructed(scip));
    2553
    2554 /* skip deactivated, redundant, or local constraints (the NLP does not allow for local rows at the moment) */
    2555 if( !SCIPconsIsActive(cons) || !SCIPconsIsChecked(cons) || SCIPconsIsLocal(cons) )
    2556 return SCIP_OKAY;
    2557
    2558 consdata = SCIPconsGetData(cons);
    2559 assert(consdata != NULL);
    2560
    2561 if( consdata->nlrow == NULL )
    2562 {
    2563 SCIP_Real lhs, rhs;
    2564 SCIP_Real* coefs;
    2565 int i;
    2566
    2567 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, consdata->nvars) );
    2568 for( i = 0; i < consdata->nvars; ++i )
    2569 coefs[i] = 1.0;
    2570
    2571 switch( SCIPgetTypeSetppc(scip, cons) )
    2572 {
    2574 lhs = 1.0;
    2575 rhs = 1.0;
    2576 break;
    2577
    2579 lhs = -SCIPinfinity(scip);
    2580 rhs = 1.0;
    2581 break;
    2582
    2584 lhs = 1.0;
    2585 rhs = SCIPinfinity(scip);
    2586 break;
    2587
    2588 default:
    2589 SCIPerrorMessage("unexpected setppc type\n");
    2590 return SCIP_ERROR;
    2591 }
    2592
    2593 SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow, SCIPconsGetName(cons),
    2594 0.0, consdata->nvars, consdata->vars, coefs, NULL, lhs, rhs, SCIP_EXPRCURV_LINEAR) );
    2595 assert(consdata->nlrow != NULL);
    2596
    2597 SCIPfreeBufferArray(scip, &coefs);
    2598 }
    2599
    2600 if( !SCIPnlrowIsInNLP(consdata->nlrow) )
    2601 {
    2602 SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow) );
    2603 }
    2604
    2605 return SCIP_OKAY;
    2606}
    2607
    2608/** checks constraint for violation, and adds it as a cut if possible */
    2609static
    2611 SCIP* scip, /**< SCIP data structure */
    2612 SCIP_CONS* cons, /**< set partitioning / packing / covering constraint to be separated */
    2613 SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
    2614 SCIP_Bool lpfeas, /**< is the given solution feasible for the current LP ? */
    2615 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    2616 SCIP_Bool* separated, /**< pointer to store TRUE, if a cut was found */
    2617 SCIP_Bool* reduceddom /**< pointer to store TRUE, if a domain reduction was found */
    2618 )
    2619{
    2620 SCIP_CONSDATA* consdata;
    2621 SCIP_Bool addcut;
    2622 SCIP_Bool mustcheck;
    2623
    2624 assert(cons != NULL);
    2625 assert(SCIPconsGetHdlr(cons) != NULL);
    2626 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
    2627 assert(cutoff != NULL);
    2628 assert(separated != NULL);
    2629 assert(reduceddom != NULL);
    2630
    2631 *cutoff = FALSE;
    2632
    2633 consdata = SCIPconsGetData(cons);
    2634 assert(consdata != NULL);
    2635 assert(consdata->nvars == 0 || consdata->vars != NULL);
    2636 assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nvars);
    2637 assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nvars);
    2638
    2639 /* skip constraints already in the LP */
    2640 if( lpfeas && consdata->row != NULL && SCIProwIsInLP(consdata->row) )
    2641 return SCIP_OKAY;
    2642
    2643 SCIPdebugMsg(scip, "separating constraint <%s>\n", SCIPconsGetName(cons));
    2644
    2645 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
    2646 if( lpfeas )
    2647 {
    2648 int nfixedvars = 0;
    2649
    2650 SCIP_CALL( processFixings(scip, cons, cutoff, &nfixedvars, &addcut, &mustcheck) );
    2651
    2652 *reduceddom = (nfixedvars > 0);
    2653 }
    2654 else
    2655 {
    2656 mustcheck = TRUE;
    2657 addcut = FALSE;
    2658 }
    2659
    2660 if( mustcheck )
    2661 {
    2662 assert(!addcut);
    2663
    2664 /* variable's fixings didn't give us any information -> we have to check the constraint */
    2665 if( lpfeas && consdata->row != NULL )
    2666 {
    2667 SCIP_Real feasibility;
    2668
    2669 assert(!SCIProwIsInLP(consdata->row));
    2670 feasibility = SCIPgetRowSolFeasibility(scip, consdata->row, sol);
    2671 addcut = SCIPisFeasNegative(scip, feasibility);
    2672 }
    2673 else
    2674 addcut = !checkCons(scip, consdata, sol);
    2675
    2676 if( !addcut )
    2677 {
    2678 /* constraint was feasible -> increase age */
    2679 SCIP_CALL( SCIPincConsAge(scip, cons) );
    2680 }
    2681 }
    2682
    2683 if( addcut )
    2684 {
    2685 /* insert LP row as cut */
    2686 SCIP_CALL( addCut(scip, cons, cutoff) );
    2688 *separated = TRUE;
    2689 }
    2690
    2691 return SCIP_OKAY;
    2692}
    2693
    2694/** enforces the pseudo solution on the given constraint */
    2695static
    2697 SCIP* scip, /**< SCIP data structure */
    2698 SCIP_CONS* cons, /**< set partitioning / packing / covering constraint to be separated */
    2699 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    2700 SCIP_Bool* infeasible, /**< pointer to store TRUE, if the constraint was infeasible */
    2701 SCIP_Bool* reduceddom, /**< pointer to store TRUE, if a domain reduction was found */
    2702 SCIP_Bool* solvelp /**< pointer to store TRUE, if the LP has to be solved */
    2703 )
    2704{
    2705 SCIP_Bool addcut;
    2706 SCIP_Bool mustcheck;
    2707 int nfixedvars = 0;
    2708
    2709 assert(!SCIPhasCurrentNodeLP(scip));
    2710 assert(cons != NULL);
    2711 assert(SCIPconsGetHdlr(cons) != NULL);
    2712 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
    2713 assert(cutoff != NULL);
    2714 assert(infeasible != NULL);
    2715 assert(reduceddom != NULL);
    2716 assert(solvelp != NULL);
    2717
    2718 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
    2719 SCIP_CALL( processFixings(scip, cons, cutoff, &nfixedvars, &addcut, &mustcheck) );
    2720
    2721 *reduceddom = (nfixedvars > 0);
    2722
    2723 if( mustcheck )
    2724 {
    2725 SCIP_CONSDATA* consdata;
    2726
    2727 assert(!addcut);
    2728
    2729 consdata = SCIPconsGetData(cons);
    2730 assert(consdata != NULL);
    2731
    2732 if( checkCons(scip, consdata, NULL) )
    2733 {
    2734 /* constraint was feasible -> increase age */
    2735 SCIP_CALL( SCIPincConsAge(scip, cons) );
    2736 }
    2737 else
    2738 {
    2739 /* constraint was infeasible -> reset age */
    2741 *infeasible = TRUE;
    2742 }
    2743 }
    2744
    2745 if( addcut )
    2746 {
    2747 /* a cut must be added to the LP -> we have to solve the LP immediately */
    2749 *solvelp = TRUE;
    2750 }
    2751
    2752 return SCIP_OKAY;
    2753}
    2754
    2755/** gets the key of the given element */
    2756static
    2757SCIP_DECL_HASHGETKEY(hashGetKeySetppccons)
    2758{ /*lint --e{715}*/
    2759 /* the key is the element itself */
    2760 return elem;
    2761}
    2762
    2763/** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables */
    2764static
    2765SCIP_DECL_HASHKEYEQ(hashKeyEqSetppccons)
    2766{
    2767#ifndef NDEBUG
    2768 SCIP* scip;
    2769#endif
    2770 SCIP_CONSDATA* consdata1;
    2771 SCIP_CONSDATA* consdata2;
    2772 SCIP_Bool coefsequal;
    2773 int i;
    2774
    2775 consdata1 = SCIPconsGetData((SCIP_CONS*)key1);
    2776 consdata2 = SCIPconsGetData((SCIP_CONS*)key2);
    2777 assert(consdata1->sorted);
    2778 assert(consdata2->sorted);
    2779#ifndef NDEBUG
    2780 scip = (SCIP*)userptr;
    2781 assert(scip != NULL);
    2782#endif
    2783
    2784 /* checks trivial case */
    2785 if( consdata1->nvars != consdata2->nvars )
    2786 return FALSE;
    2787
    2788 coefsequal = TRUE;
    2789
    2790 for( i = 0; i < consdata1->nvars; ++i )
    2791 {
    2792 /* tests if variables are equal */
    2793 if( consdata1->vars[i] != consdata2->vars[i] )
    2794 {
    2795 assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 1 ||
    2796 SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == -1);
    2797 coefsequal = FALSE;
    2798 break;
    2799 }
    2800 assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 0);
    2801 }
    2802
    2803 return coefsequal;
    2804}
    2805
    2806/** returns the hash value of the key */
    2807static
    2808SCIP_DECL_HASHKEYVAL(hashKeyValSetppccons)
    2809{
    2810 SCIP_CONSDATA* consdata;
    2811 int minidx;
    2812 int mididx;
    2813 int maxidx;
    2814#ifndef NDEBUG
    2815 SCIP* scip;
    2816
    2817 scip = (SCIP*)userptr;
    2818 assert(scip != NULL);
    2819#endif
    2820
    2821 consdata = SCIPconsGetData((SCIP_CONS*)key);
    2822 assert(consdata != NULL);
    2823 assert(consdata->nvars > 0);
    2824
    2825 /* sorts the constraints */
    2826 consdataSort(consdata);
    2827
    2828 minidx = SCIPvarGetIndex(consdata->vars[0]);
    2829 mididx = SCIPvarGetIndex(consdata->vars[consdata->nvars / 2]);
    2830 maxidx = SCIPvarGetIndex(consdata->vars[consdata->nvars - 1]);
    2831 assert(minidx >= 0 && minidx <= maxidx);
    2832
    2833 return SCIPhashFour(consdata->nvars, minidx, mididx, maxidx);
    2834}
    2835
    2836/** add extra clique-constraints resulting from a given cliquepartition to SCIP */
    2837static
    2839 SCIP*const scip, /**< SCIP data structure */
    2840 SCIP_VAR**const binvars, /**< binary variables to create clique constraints */
    2841 int const nbinvars, /**< number of binary variables to create clique constraints */
    2842 int*const cliquepartition, /**< clique partition of binary variables */
    2843 int const ncliques, /**< number of cliques in cliquepartition */
    2844 SCIP_CONS**const usefulconss, /**< storage for created constraints */
    2845 int*const nusefulconss, /**< pointer to store number of useful created constraints */
    2846 int const nrounds, /**< actual presolving round */
    2847 int*const nfixedvars, /**< pointer to count number of deleted variables */
    2848 int*const naddconss, /**< pointer to count number of added constraints */
    2849 int*const ndelconss, /**< pointer to count number of deleted constraints */
    2850 int*const nchgcoefs, /**< pointer to count number of deleted coefficients */
    2851 SCIP_Bool*const cutoff /**< pointer to store if the problem is infeasible due to a fixing */
    2852 )
    2853{
    2854 SCIP_CONS* cliquecons;
    2855 char name[SCIP_MAXSTRLEN];
    2856 int lastclqidx;
    2857 int nadded;
    2858 int c;
    2859 int v;
    2860
    2861 assert(scip != NULL);
    2862 assert(binvars != NULL || nbinvars == 0);
    2863 assert(cliquepartition != NULL || nbinvars == 0);
    2864 assert(ncliques >= 0 && ncliques <= nbinvars);
    2865 assert(usefulconss != NULL);
    2866 assert(nusefulconss != NULL);
    2867 assert(nfixedvars != NULL);
    2868 assert(naddconss != NULL);
    2869 assert(ndelconss != NULL);
    2870 assert(nchgcoefs != NULL);
    2871 assert(cutoff != NULL);
    2872
    2873 /* no given binary variables */
    2874 if( nbinvars == 0 || ncliques == 0 )
    2875 return SCIP_OKAY;
    2876
    2877 assert(binvars != NULL);
    2878 assert(cliquepartition != NULL);
    2879
    2880 /* no useful clique information */
    2881 if( ncliques == nbinvars )
    2882 return SCIP_OKAY;
    2883
    2884 lastclqidx = 0;
    2885
    2886 /* @todo: maybe sort cliques and accordingly the variables so it will be faster to add the constraints */
    2887 for( c = 0; c < ncliques - 1; ++c )
    2888 {
    2889 if( lastclqidx >= cliquepartition[c] )
    2890 continue;
    2891
    2892 nadded = 0;
    2893
    2894 /* name the clique constraint */
    2895 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "extra_clq_%d_round_%d", cliquepartition[c], nrounds);
    2896 SCIP_CALL( SCIPcreateConsSetpack(scip, &cliquecons, name, 0, NULL,
    2898
    2899 /* add variables to clique constraint */
    2900 for( v = c; v < nbinvars - 1; ++v )
    2901 {
    2902 if( cliquepartition[c] == cliquepartition[v] )
    2903 {
    2904 SCIP_CALL( addCoef(scip, cliquecons, binvars[v]) );
    2905 ++nadded;
    2906 }
    2907 }
    2908
    2909 /* @todo: try to find a good value for what are enough variables to create this constraint, maybe at least
    2910 * (nmaxvars(over all conss)-nminvars(over all conss))/2 */
    2911 if( nadded >= 2 )
    2912 {
    2913 SCIP_CONSDATA* cliqueconsdata;
    2914
    2915 SCIPdebugMsg(scip, " -> adding clique constraint: ");
    2916 SCIPdebugPrintCons(scip, cliquecons, NULL);
    2917 SCIP_CALL( SCIPaddCons(scip, cliquecons) );
    2918 ++(*naddconss);
    2919
    2920 /* we only want to consider merged constraints */
    2921 SCIP_CALL( mergeMultiples(scip, cliquecons, nfixedvars, ndelconss, nchgcoefs, cutoff) );
    2922 if( *cutoff )
    2923 {
    2924 SCIP_CALL( SCIPreleaseCons(scip, &cliquecons) );
    2925
    2926 return SCIP_OKAY;
    2927 }
    2928
    2929 cliqueconsdata = SCIPconsGetData(cliquecons);
    2930 assert(cliqueconsdata != NULL);
    2931
    2932 /* the artificial constraints could be deleted while merging */
    2933 if( !SCIPconsIsDeleted(cliquecons) && nadded - cliqueconsdata->nfixedzeros >= 2 )
    2934 {
    2935 assert(cliqueconsdata->nfixedones == 0);
    2936
    2937 /* save the type and constraint */
    2938 usefulconss[*nusefulconss] = cliquecons;
    2939 ++(*nusefulconss);
    2940 }
    2941 SCIP_CALL( SCIPreleaseCons(scip, &cliquecons) );
    2942 }
    2943 else
    2944 {
    2945 SCIP_CALL( SCIPreleaseCons(scip, &cliquecons) );
    2946 }
    2947 lastclqidx = cliquepartition[c];
    2948 }
    2949
    2950 return SCIP_OKAY;
    2951}
    2952
    2953
    2954/** start to collect setpartitioning and setpacking constraints, and try to remove fixed variables and merged these
    2955 * constraints
    2956 */
    2957static
    2959 SCIP*const scip, /**< SCIP data structure */
    2960 SCIP_CONS**const conss, /**< constraint set */
    2961 int const nconss, /**< number of constraints in constraint set */
    2962 SCIP_CONS**const usefulconss, /**< storage for created constraints */
    2963 int*const nusefulconss, /**< pointer to store number of useful created constraints */
    2964 int*const nfixedvars, /**< pointer to count number of deleted variables */
    2965 int*const ndelconss, /**< pointer to count number of deleted constraints */
    2966 int*const nchgcoefs, /**< pointer to count number of deleted coefficients */
    2967 SCIP_Bool*const cutoff /**< pointer to store if the problem is infeasible due to a fixing */
    2968 )
    2969{
    2970 SCIP_CONS* cons;
    2971 SCIP_CONSDATA* consdata;
    2972 SCIP_Bool addcut;
    2973 SCIP_Bool mustcheck;
    2974 int nlocaladdconss = 0;
    2975 int c;
    2976
    2977 assert(scip != NULL);
    2978 assert(conss != NULL || nconss == 0);
    2979 assert(usefulconss != NULL);
    2980 assert(nusefulconss != NULL);
    2981 assert(nfixedvars != NULL);
    2982 assert(ndelconss != NULL);
    2983 assert(nchgcoefs != NULL);
    2984 assert(cutoff != NULL);
    2985
    2986 if( nconss == 0 )
    2987 return SCIP_OKAY;
    2988
    2989 assert(conss != NULL);
    2990
    2991 for( c = nconss - 1; c >= 0; --c )
    2992 {
    2993 cons = conss[c];
    2994
    2995 /* we only want to consider constraints with either active or negated of active variables, applyfixings removes
    2996 * aggregated and fixed variables to zero, processFixings removes fixings to one but no aggregation
    2997 *
    2998 * @todo: maybe write a new method for deleting aggregations and all fixings
    2999 */
    3000 SCIP_CALL( applyFixings(scip, cons, &nlocaladdconss, ndelconss, nfixedvars, cutoff) );
    3001 if( *cutoff )
    3002 return SCIP_OKAY;
    3003
    3004 if( SCIPconsIsDeleted(cons) )
    3005 {
    3006 /* reset nlocaladdconss and continue */
    3007 nlocaladdconss = 0;
    3008 continue;
    3009 }
    3010 assert(nlocaladdconss == 0);
    3011
    3012 SCIP_CALL( processFixings(scip, cons, cutoff, nfixedvars, &addcut, &mustcheck) );
    3013 if( *cutoff )
    3014 return SCIP_OKAY;
    3015
    3016 consdata = SCIPconsGetData(cons);
    3017 assert(consdata != NULL);
    3018
    3019 /* we only want to consider merged constraints */
    3020 SCIP_CALL( mergeMultiples(scip, cons, nfixedvars, ndelconss, nchgcoefs, cutoff) );
    3021 if( *cutoff )
    3022 return SCIP_OKAY;
    3023
    3024 if( SCIPconsIsModifiable(cons) || !SCIPconsIsActive(cons) )
    3025 continue;
    3026
    3027 assert(consdata->nfixedones == 0);
    3028
    3029 if( consdata->nvars == 0 )
    3030 continue;
    3031
    3032 /* @todo: check for covering constraints with only two variables which are equal to a packing constraint with
    3033 * negated variables */
    3034 if( consdata->setppctype != SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    3035 {
    3036 assert(consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
    3037
    3038 usefulconss[*nusefulconss] = cons;
    3039 ++(*nusefulconss);
    3040 }
    3041 }
    3042
    3043 return SCIP_OKAY; /*lint !e438*/
    3044}
    3045
    3046/** creating all necessary data in array structure, collect all clique constraint variables and occurrences,
    3047 * @note works only with merged and active not set-covering constraints
    3048 */
    3049static
    3051 SCIP*const scip, /**< SCIP data structure */
    3052 SCIP_CONS**const usefulconss, /**< clique constraints */
    3053 int const nusefulconss, /**< number of clique constraints */
    3054 SCIP_VAR**const usefulvars, /**< storage for all found variables */
    3055 int*const nusefulvars, /**< pointer to store number of added variables */
    3056 SCIP_HASHMAP*const vartoindex, /**< hashmap mapping variables to indices */
    3057 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
    3058 int*const maxnvarconsidx, /**< storage for the maximal number of occurrences of a variable */
    3059 int**const varconsidxs, /**< storage for constraint indices in which the corresponding variable exists */
    3060 int*const maxnvars /**< pointer to store maximal number of variables of a constraint */
    3061 )
    3062{
    3063 SCIP_CONS* cons;
    3064 SCIP_CONSDATA* consdata;
    3065 int varindex;
    3066 int c;
    3067 int v;
    3068
    3069 assert(scip != NULL);
    3070 assert(usefulconss != NULL || nusefulconss == 0);
    3071 assert(usefulvars != NULL);
    3072 assert(nusefulvars != NULL);
    3073 assert(vartoindex != NULL);
    3074 assert(varnconss != NULL);
    3075 assert(maxnvarconsidx != NULL);
    3076 assert(varconsidxs != NULL);
    3077 assert(maxnvars != NULL);
    3078
    3079 if( nusefulconss == 0 )
    3080 return SCIP_OKAY;
    3081
    3082 assert(usefulconss != NULL);
    3083
    3084 for( c = nusefulconss - 1; c >= 0; --c )
    3085 {
    3086 cons = usefulconss[c];
    3087
    3088 assert(SCIPconsIsActive(cons));
    3089
    3090 consdata = SCIPconsGetData(cons);
    3091 assert(consdata != NULL);
    3092
    3093 /* here we should have no covering constraints anymore and the constraint data should be merged */
    3094 assert(consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
    3095 assert(consdata->merged);
    3096
    3097 /* save maximal number of vars */
    3098 if( consdata->nvars > *maxnvars )
    3099 *maxnvars = consdata->nvars;
    3100
    3101 /* adding variables and information about occurrences to local data structure */
    3102 for( v = consdata->nvars - 1; v >= 0; --v )
    3103 {
    3104 SCIP_VAR* var;
    3105
    3106 var = consdata->vars[v];
    3107 assert(var != NULL);
    3108
    3109 /* don't remember fixed vars */
    3110 if( SCIPvarGetLbLocal(var) > 0.5 || SCIPvarGetUbLocal(var) < 0.5 )
    3111 continue;
    3112
    3113 /* only collect active or negated active variables */
    3115
    3116 if( !SCIPhashmapExists(vartoindex, (void*) var) )
    3117 {
    3118 SCIP_VAR* tmpvar;
    3119
    3120 usefulvars[*nusefulvars] = var;
    3121 ++(*nusefulvars);
    3122 varindex = *nusefulvars;
    3123 SCIP_CALL( SCIPhashmapInsertInt(vartoindex, (void*) var, varindex) );
    3124
    3125 /* get the maximal number of occurrences of this variable, if this variables */
    3126 tmpvar = SCIPvarIsNegated(var) ? SCIPvarGetNegatedVar(var) : var;
    3127 maxnvarconsidx[varindex] = SCIPvarGetNLocksDownType(tmpvar, SCIP_LOCKTYPE_MODEL)
    3129 SCIP_CALL( SCIPallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
    3130 }
    3131 else
    3132 {
    3133 assert(SCIPhashmapExists(vartoindex, (void*) var));
    3134 varindex = SCIPhashmapGetImageInt(vartoindex, (void*) var);
    3135 }
    3136
    3137 /* the number of occurrences of a variable is not limited by the locks (so maybe we have to increase memory),
    3138 * because for examples converted cuts are not check and therefore they have no locks on their variables */
    3139 if( varnconss[varindex] == maxnvarconsidx[varindex] )
    3140 {
    3141 maxnvarconsidx[varindex] = SCIPcalcMemGrowSize(scip, maxnvarconsidx[varindex] + 1);
    3142 SCIP_CALL( SCIPreallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
    3143 }
    3144
    3145 assert(varnconss[varindex] < maxnvarconsidx[varindex]);
    3146 /* add the constraint number to the variable list */
    3147 varconsidxs[varindex][varnconss[varindex]] = c;
    3148 /* increase number of occurrences for variables */
    3149 ++(varnconss[varindex]);
    3150 }
    3151 } /* data structure created */
    3152
    3153 return SCIP_OKAY;
    3154}
    3155
    3156/** correct clique data due to an aggregation */
    3157static
    3159 SCIP_VAR*const var, /**< variable which appears less */
    3160 int const considx, /**< constraint index which to remove */
    3161 SCIP_HASHMAP*const vartoindex, /**< hashmap mapping variables to indices */
    3162 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
    3163 int**const varconsidxs /**< storage for constraint indices in which the corresponding variable exists */
    3164 )
    3165{
    3166 int varindex;
    3167 int i;
    3168#ifndef NDEBUG
    3169 SCIP_Bool found = FALSE;
    3170#endif
    3171
    3172 assert(var != NULL);
    3173 assert(SCIPvarGetLbLocal(var) < 0.5 && SCIPvarGetUbLocal(var) > 0.5);
    3174 assert(considx >= 0);
    3175 assert(vartoindex != NULL);
    3176 assert(varnconss != NULL);
    3177 assert(varconsidxs != NULL);
    3178
    3179 assert(SCIPhashmapExists(vartoindex, (void*) var));
    3180 varindex = SCIPhashmapGetImageInt(vartoindex, (void*) var);
    3181
    3182 /* remove entry of variable at the given position */
    3183 for( i = 0; i < varnconss[varindex]; ++i )
    3184 {
    3185 if( varconsidxs[varindex][i] == considx )
    3186 {
    3187 varconsidxs[varindex][i] = varconsidxs[varindex][varnconss[varindex] - 1];
    3188#ifndef NDEBUG
    3189 found = TRUE;
    3190#endif
    3191 --(varnconss[varindex]);
    3192 break;
    3193 }
    3194 }
    3195 assert(found);
    3196}
    3197
    3198/* correct local data structure, add constraint entry to variable data */
    3199static
    3201 SCIP*const scip, /**< SCIP data structure */
    3202 SCIP_VAR*const addvar, /**< variable which was added */
    3203 int const considx, /**< constraint index which to add */
    3204 SCIP_Bool const maybenew, /**< could be a new variables, a negated of an already existing */
    3205 SCIP_VAR**const usefulvars, /**< storage for all found variables */
    3206 int*const nusefulvars, /**< pointer to store number of added variables */
    3207 SCIP_HASHMAP*const vartoindex, /**< hashmap mapping variables to indices */
    3208 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
    3209 int*const maxnvarconsidx, /**< storage for the maximal number of occurrences of a variable */
    3210 int**const varconsidxs /**< storage for constraint indices in which the corresponding variable exists */
    3211 )
    3212{
    3213 int varindex;
    3214
    3215 assert(scip != NULL);
    3216 assert(addvar != NULL);
    3217 assert(SCIPvarGetLbLocal(addvar) < 0.5 && SCIPvarGetUbLocal(addvar) > 0.5);
    3218 assert(usefulvars != NULL);
    3219 assert(nusefulvars != NULL);
    3220 assert(vartoindex != NULL);
    3221 assert(varnconss != NULL);
    3222 assert(maxnvarconsidx != NULL);
    3223 assert(varconsidxs != NULL);
    3224
    3225 /* we add the variable to the hashmap if its new */
    3226 if( maybenew && !SCIPhashmapExists(vartoindex, (void*) addvar) )
    3227 {
    3228 assert(SCIPvarIsActive(addvar) || SCIPvarIsNegated(addvar));
    3229 assert(SCIPvarGetNegatedVar(addvar) != NULL && SCIPhashmapExists(vartoindex, (void*) SCIPvarGetNegatedVar(addvar)));
    3230
    3231 /* @note because we can only have created a negated variable, and we already allocated enough memory for
    3232 * all (even not existing) negated variables the usefulvars array should be big enough
    3233 */
    3234 SCIPsortedvecInsertDownPtr((void**)usefulvars, SCIPvarCompActiveAndNegated, addvar, nusefulvars, NULL);
    3235 varindex = *nusefulvars;
    3236 SCIP_CALL( SCIPhashmapInsertInt(vartoindex, (void*) addvar, varindex) );
    3237
    3238 assert(varconsidxs[varindex] == NULL);
    3239
    3240 maxnvarconsidx[varindex] = 1;
    3241 SCIP_CALL( SCIPallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
    3242 varnconss[varindex] = 0;
    3243 }
    3244 else
    3245 {
    3246 varindex = SCIPhashmapGetImageInt(vartoindex, (void*) addvar);
    3247
    3248 /* grow the needed memory if we added a variable */
    3249 if( varnconss[varindex] == maxnvarconsidx[varindex] )
    3250 {
    3251 maxnvarconsidx[varindex] = SCIPcalcMemGrowSize(scip, maxnvarconsidx[varindex] + 1);
    3252 SCIP_CALL( SCIPreallocBufferArray(scip, &(varconsidxs[varindex]), maxnvarconsidx[varindex]) ); /*lint !e866*/
    3253 }
    3254 }
    3255 assert(varnconss[varindex] < maxnvarconsidx[varindex]);
    3256 varconsidxs[varindex][varnconss[varindex]] = considx;
    3257
    3258 /* increase number of occurrences for variables */
    3259 ++(varnconss[varindex]);
    3260
    3261 return SCIP_OKAY;
    3262}
    3263
    3264
    3265/** check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
    3266 * possible
    3267 */
    3268static
    3270 SCIP*const scip, /**< SCIP data structure */
    3271 SCIP_CONS*const cons, /**< constraint */
    3272 SCIP_Bool const aggregate, /**< try to aggregate if possible */
    3273 SCIP_VAR** undoneaggrvars, /**< array to store aggregation variables, if aggregation is not performed
    3274 * yet; both variables are standing next to each other; or NULL if
    3275 * aggregate == TRUE
    3276 */
    3277 SCIP_Bool* undoneaggrtypes, /**< array to store aggregation type, if aggregation is not performed yet;
    3278 * type FALSE means the aggregation is of the form x + y = 1; type TRUE means
    3279 * the aggregation is of the form x = y; or NULL if aggregate == TRUE
    3280 */
    3281 int*const naggregations, /**< pointer to store number of aggregations which are not yet performed;
    3282 * or NULL if aggregate == TRUE
    3283 */
    3284 int*const saggregations, /**< pointer to store size of the array for aggregation type and two times
    3285 * the value is the size of the array for the aggregation variables which
    3286 * are not yet performed; or NULL if aggregate == TRUE
    3287 */
    3288 int*const nfixedvars, /**< pointer to count number of deleted variables */
    3289 int*const naggrvars, /**< pointer to count number of aggregated variables */
    3290 int*const ndelconss, /**< pointer to count number of deleted constraints */
    3291 SCIP_Bool*const cutoff /**< pointer to store if the problem is infeasible due to a fixing */
    3292 )
    3293{
    3294 SCIP_CONSDATA* consdata;
    3295 SCIP_VAR** vars;
    3296 int nvars;
    3297 int v;
    3298 SCIP_Bool fixed;
    3299
    3300 assert(scip != NULL);
    3301 assert(cons != NULL);
    3302 assert(nfixedvars != NULL);
    3303 assert(naggrvars != NULL);
    3304 assert(ndelconss != NULL);
    3305 assert(cutoff != NULL);
    3306
    3307 if( !SCIPconsIsActive(cons) )
    3308 return SCIP_OKAY;
    3309
    3310 consdata = SCIPconsGetData(cons);
    3311 assert(consdata != NULL);
    3312
    3313 if( consdata->presolpropagated )
    3314 return SCIP_OKAY;
    3315
    3316 consdata->presolpropagated = TRUE;
    3317
    3318 vars = consdata->vars;
    3319 nvars = consdata->nvars;
    3320
    3321 /* no variables left */
    3322 if( nvars == 0 && !SCIPconsIsModifiable(cons) )
    3323 {
    3324 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    3325 {
    3326 SCIPdebugMsg(scip, "empty set-partition/-covering constraint <%s> found -> cutoff\n", SCIPconsGetName(cons));
    3327 *cutoff = TRUE;
    3328
    3329 return SCIP_OKAY;
    3330 }
    3331 else
    3332 {
    3333 assert(consdata->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
    3334
    3335 /* delete constraint */
    3336 SCIPdebugMsg(scip, " -> deleting constraint <%s>, no variables left\n", SCIPconsGetName(cons));
    3337 SCIP_CALL( SCIPdelCons(scip, cons) );
    3338 ++(*ndelconss);
    3339
    3340 return SCIP_OKAY;
    3341 }
    3342 }
    3343
    3344 /* more then two variables are fixed */
    3345 if( consdata->nfixedones > 1 )
    3346 {
    3347 /* at least two variables are fixed to 1:
    3348 * - a set covering constraint is feasible anyway and can be deleted
    3349 * - a set partitioning or packing constraint is infeasible
    3350 */
    3351 if( consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    3352 {
    3353 /* delete constraint */
    3354 SCIPdebugMsg(scip, " -> deleting set-covering constraint <%s>, at least two variables are fixed to 1\n", SCIPconsGetName(cons));
    3355 SCIP_CALL( SCIPdelCons(scip, cons) );
    3356 ++(*ndelconss);
    3357
    3358 return SCIP_OKAY;
    3359 }
    3360
    3361 SCIPdebugMsg(scip, "set partitioning / packing constraint <%s> is infeasible, %d variables fixed to one\n", SCIPconsGetName(cons), consdata->nfixedones);
    3362 *cutoff = TRUE;
    3363
    3364 return SCIP_OKAY;
    3365 }
    3366
    3367 if( consdata->nfixedones == 1 )
    3368 {
    3369 /* exactly one variable is fixed to 1:
    3370 * - a set covering constraint is feasible anyway and can be disabled
    3371 * - all other variables in a set partitioning or packing constraint must be zero
    3372 */
    3373 if( consdata->setppctype != SCIP_SETPPCTYPE_COVERING && consdata->nfixedzeros < nvars - 1 ) /*lint !e641*/
    3374 {
    3375 assert(vars != NULL);
    3376
    3377 for( v = nvars - 1; v >= 0; --v )
    3378 {
    3379 if( SCIPvarGetLbLocal(vars[v]) + 0.5 < SCIPvarGetUbLocal(vars[v]) )
    3380 {
    3381 SCIPdebugMsg(scip, "trying to fix <%s> to 0 due to at least one variable is already fixed to 1\n", SCIPvarGetName(vars[v]));
    3382
    3383 /* fix all remaining variables to zero, constraint is already feasible or infeasible */
    3384 SCIP_CALL( SCIPfixVar(scip, vars[v], 0.0, cutoff, &fixed) );
    3385 if( *cutoff )
    3386 {
    3387 SCIPdebugMsg(scip, "setppc constraint <%s>: infeasible fixing <%s> == 0\n",
    3388 SCIPconsGetName(cons), SCIPvarGetName(vars[v]));
    3389
    3390 return SCIP_OKAY;
    3391 }
    3392
    3393 assert(fixed);
    3394 ++(*nfixedvars);
    3395 }
    3396 }
    3397 }
    3398
    3399 if( !SCIPconsIsModifiable(cons) || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    3400 {
    3401 /* delete constraint */
    3402 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all variables are fixed\n", SCIPconsGetName(cons));
    3403 assert(SCIPconsIsActive(cons));
    3404 SCIP_CALL( SCIPdelCons(scip, cons) );
    3405 ++(*ndelconss);
    3406 }
    3407
    3408 return SCIP_OKAY;
    3409 }
    3410
    3411 /* other propagations can only be done on not modifiable constraints */
    3412 if( SCIPconsIsModifiable(cons) )
    3413 return SCIP_OKAY;
    3414
    3415 assert(vars != NULL);
    3416
    3417 /* all variables were fixed to zero then either delete the constraint or stop with infeasibility */
    3418 if( consdata->nfixedzeros == nvars )
    3419 {
    3420 assert(consdata->nfixedones == 0);
    3421
    3422 /* all variables are fixed to zero:
    3423 * - a set packing constraint is feasible anyway and can be deleted
    3424 * - a set partitioning or covering constraint is infeasible, and so is the whole problem
    3425 */
    3426 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    3427 {
    3428 SCIPdebugMsg(scip, "set partitioning / covering constraint <%s> is infeasible\n", SCIPconsGetName(cons));
    3429 *cutoff = TRUE;
    3430
    3431 return SCIP_OKAY;
    3432 }
    3433
    3434 /* delete constraint */
    3435 SCIPdebugMsg(scip, " -> deleting set-packing constraint <%s>, all variables are fixed to zero\n", SCIPconsGetName(cons));
    3436 assert(SCIPconsIsActive(cons));
    3437 SCIP_CALL( SCIPdelCons(scip, cons) );
    3438 ++(*ndelconss);
    3439
    3440 return SCIP_OKAY;
    3441 }
    3442
    3443 /* all but one variable were fixed to zero then delete the constraint and for setpartition fix the remaining variable to 1 */
    3444 if( consdata->nfixedzeros + 1 == nvars )
    3445 {
    3446 assert(consdata->nfixedones == 0);
    3447
    3448 /* all variables except one are fixed to zero:
    3449 * - a set packing constraint is feasible anyway, and can be deleted
    3450 * - a set partitioning or covering constraint is feasible and can be deleted after the
    3451 * remaining variable is fixed to one
    3452 */
    3453 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || consdata->setppctype == SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    3454 {
    3455 fixed = FALSE;
    3456 for( v = nvars - 1; v >= 0; --v )
    3457 {
    3458 assert(SCIPvarGetLbLocal(vars[v]) < 0.5);
    3459 if( SCIPvarGetUbLocal(vars[v]) > 0.5 )
    3460 {
    3461 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]));
    3462
    3463 /* fix the remaining set partition variable */
    3464 SCIP_CALL( SCIPfixVar(scip, vars[v], 1.0, cutoff, &fixed) );
    3465 if( *cutoff )
    3466 {
    3467 SCIPdebugMsg(scip, "setppc constraint <%s>: infeasible fixing <%s> == 1\n",
    3468 SCIPconsGetName(cons), SCIPvarGetName(vars[v]));
    3469
    3470 return SCIP_OKAY;
    3471 }
    3472
    3473 assert(fixed);
    3474 ++(*nfixedvars);
    3475 break;
    3476 }
    3477 }
    3478 assert(fixed);
    3479 }
    3480
    3481 /* delete constraint */
    3482 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all %svariables are fixed\n", SCIPconsGetName(cons), consdata->setppctype == (int) SCIP_SETPPCTYPE_PACKING ? "but one " : "");
    3483 assert(SCIPconsIsActive(cons));
    3484 SCIP_CALL( SCIPdelCons(scip, cons) );
    3485 ++(*ndelconss);
    3486
    3487 return SCIP_OKAY;
    3488 }
    3489
    3490 /* all but two variable were fixed to zero in a setpartitioning constraint then delete the constraint and
    3491 * aggregate the remaining two variables
    3492 */
    3493 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata->nfixedzeros + 2 == nvars ) /*lint !e641*/
    3494 {
    3495 SCIP_VAR* var;
    3496
    3497 var = NULL;
    3498 for( v = nvars - 1; v >= 0; --v )
    3499 {
    3500 assert(SCIPvarGetLbLocal(vars[v]) < 0.5);
    3501
    3502 if( SCIPvarGetUbLocal(vars[v]) > 0.5 )
    3503 {
    3504 if( var == NULL )
    3505 var = vars[v];
    3506 else
    3507 {
    3508 SCIP_Bool redundant;
    3509 SCIP_Bool aggregated;
    3510#ifdef VARUSES
    3511 SCIP_CONSHDLR* conshdlr;
    3512 SCIP_CONSHDLRDATA* conshdlrdata;
    3513
    3514 /* get event handler and event handler data */
    3515 conshdlr = SCIPconsGetHdlr(cons);
    3516 assert(conshdlr != NULL);
    3517 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3518 assert(conshdlrdata != NULL);
    3519#endif
    3520 if( aggregate )
    3521 {
    3522 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));
    3523
    3524#ifdef VARUSES
    3525 /* in order to not mess up the variable usage counting, we have to decrease usage counting, aggregate,
    3526 * and increase usage counting again
    3527 */
    3528 SCIP_CALL( conshdlrdataDecVaruses(scip, conshdlrdata, var) );
    3529 SCIP_CALL( conshdlrdataDecVaruses(scip, conshdlrdata, vars[v]) );
    3530#endif
    3531
    3532 /* aggregate last remaining variables in the set partitioning constraint */
    3533 SCIP_CALL( SCIPaggregateVars(scip, var, vars[v], 1.0, 1.0, 1.0, cutoff, &redundant, &aggregated) );
    3534 if( *cutoff )
    3535 {
    3536 SCIPdebugMsg(scip, "set partitioning constraint <%s>: aggregate <%s> + <%s> == 1\n",
    3537 SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetName(vars[v]));
    3538
    3539 return SCIP_OKAY;
    3540 }
    3541
    3542#ifdef VARUSES
    3543 /* increase variable usage counting again */
    3544 SCIP_CALL( conshdlrdataIncVaruses(scip, conshdlrdata, var) );
    3545 SCIP_CALL( conshdlrdataIncVaruses(scip, conshdlrdata, vars[v]) );
    3546#endif
    3547
    3548 if( aggregated )
    3549 ++(*naggrvars);
    3550
    3551 if( redundant )
    3552 {
    3553 /* delete constraint */
    3554 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all variables are fixed\n", SCIPconsGetName(cons));
    3555 assert(SCIPconsIsActive(cons));
    3556 SCIP_CALL( SCIPdelCons(scip, cons) );
    3557 ++(*ndelconss);
    3558 }
    3559 }
    3560 else
    3561 {
    3562 assert(undoneaggrvars != NULL);
    3563 assert(undoneaggrtypes != NULL);
    3564 assert(naggregations != NULL);
    3565 assert(saggregations != NULL);
    3566
    3567 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));
    3568
    3569 /* resize the aggregation arrays if necessary */
    3570 if( *saggregations == *naggregations )
    3571 {
    3572 *saggregations = SCIPcalcMemGrowSize(scip, *naggregations + 1);
    3573 assert(*saggregations > *naggregations);
    3574 SCIP_CALL( SCIPreallocBufferArray(scip, &undoneaggrtypes, *saggregations) );
    3575 SCIP_CALL( SCIPreallocBufferArray(scip, &undoneaggrvars, 2 * (*saggregations)) );
    3576
    3577 /* clear the aggregation type array to set the default to the aggregation of the form x + y = 1 */
    3578 BMSclearMemoryArray(&(undoneaggrtypes[*naggregations]), *saggregations - *naggregations); /*lint !e866*/
    3579 }
    3580
    3581 /* memorize aggregation variables*/
    3582 assert(undoneaggrtypes[*naggregations] == FALSE);
    3583 undoneaggrvars[2 * (*naggregations)] = var;
    3584 undoneaggrvars[2 * (*naggregations) + 1] = vars[v];
    3585 ++(*naggregations);
    3586
    3587 if( !SCIPdoNotAggr(scip) )
    3588 {
    3589 /* delete constraint */
    3590 SCIPdebugMsg(scip, " -> deleting constraint <%s>, all variables are fixed\n", SCIPconsGetName(cons));
    3591 assert(SCIPconsIsActive(cons));
    3592 SCIP_CALL( SCIPdelCons(scip, cons) );
    3593 ++(*ndelconss);
    3594 }
    3595 }
    3596
    3597 return SCIP_OKAY;
    3598 }
    3599 }
    3600 }
    3601 /* we should never be here, because the last to unfixed variables should have been either aggregated or a cutoff
    3602 * should be applied
    3603 */
    3604 assert(FALSE); /*lint !e506*/
    3605 }
    3606
    3607 return SCIP_OKAY;
    3608}
    3609
    3610/** check for overlapping constraint */
    3611static
    3613 SCIP*const scip, /**< SCIP data structure */
    3614 SCIP_CONS*const cons, /**< constraint which may overlap */
    3615 int const considx, /**< constraint index to avoid checking against itself */
    3616 int const endidx, /**< end index to check against given constraint */
    3617 SCIP_CONS**const usefulconss, /**< clique constraints */
    3618 int const nusefulconss, /**< number of clique constraints */
    3619 SCIP_VAR**const usefulvars, /**< storage for all found variables */
    3620 int*const nusefulvars, /**< pointer to store number of added variables */
    3621 SCIP_HASHMAP*const vartoindex, /**< hashmap mapping variables to indices */
    3622 int*const varnconss, /**< storage for remembering the number of constraints a variable occurs */
    3623 int*const maxnvarconsidx, /**< storage for the maximal number of occurrences of a variable */
    3624 int**const varconsidxs, /**< storage for constraint indices in which the corresponding variable exists */
    3625 int*const countofoverlapping, /**< the amount of variables of cons which overlap in all other constraint */
    3626 SCIP_Bool const shrinking, /**< try to replace some variables with one variable */
    3627 SCIP_Bool*const chgcons, /**< pointer to store if the given constraint was changed, due to
    3628 * added/deleted variables
    3629 */
    3630 SCIP_VAR** undoneaggrvars, /**< array to store aggregation variables, if aggregation is not performed
    3631 * yet; both variables are standing next to each other;
    3632 */
    3633 SCIP_Bool* undoneaggrtypes, /**< array to store aggregation type, if aggregation is not performed yet;
    3634 * type FALSE means the aggregation is of the form x + y = 1; type TRUE means
    3635 * the aggregation is of the form x = y;
    3636 */
    3637 int*const naggregations, /**< pointer to store number of aggregations which are not yet performed; */
    3638 int*const saggregations, /**< pointer to store size of the array for aggregation type and two times
    3639 * the value is the size of the array for the aggregation variables which
    3640 * are not yet performed;
    3641 */
    3642 int*const nfixedvars, /**< pointer to count number of deleted variables */
    3643 int*const naggrvars, /**< pointer to count number of aggregated variables */
    3644 int*const nchgcoefs, /**< pointer to count number of changed coefficients */
    3645 int*const ndelconss, /**< pointer to count number of deleted constraints */
    3646 SCIP_Bool*const cutoff /**< pointer to store if the problem is infeasible due to a fixing */
    3647 )
    3648{
    3649 SCIP_CONS* cons1;
    3650 SCIP_CONSDATA* consdata1;
    3651 SCIP_CONSDATA* consdata;
    3652 SCIP_VAR** vars;
    3653 SCIP_VAR** vars1;
    3654 SCIP_VAR* var;
    3655 SCIP_VAR* var1;
    3656 SCIP_Bool fixed;
    3657 SCIP_Bool overlapdestroyed;
    3658 int nvars;
    3659 int nvars1;
    3660 int oldnfixedzeros;
    3661 int c;
    3662 int v;
    3663 int v1;
    3664#ifndef NDEBUG
    3665 int oldnaggrvars;
    3666#endif
    3667
    3668 assert(scip != NULL);
    3669 assert(cons != NULL);
    3670 assert(usefulconss != NULL && nusefulconss > 0);
    3671 assert(0 <= considx && considx < nusefulconss);
    3672 assert(usefulconss[considx] == cons);
    3673 assert(0 <= endidx && endidx <= nusefulconss);
    3674 assert(countofoverlapping != NULL);
    3675 assert(chgcons != NULL);
    3676 assert(undoneaggrvars != NULL);
    3677 assert(undoneaggrtypes != NULL);
    3678 assert(naggregations != NULL);
    3679 assert(saggregations != NULL);
    3680 assert(nfixedvars != NULL);
    3681 assert(naggrvars != NULL);
    3682 assert(nchgcoefs != NULL);
    3683 assert(ndelconss != NULL);
    3684 assert(cutoff != NULL);
    3685
    3686 if( !SCIPconsIsActive(cons) )
    3687 return SCIP_OKAY;
    3688
    3689 consdata = SCIPconsGetData(cons);
    3690 assert(consdata != NULL);
    3691
    3692 nvars = consdata->nvars;
    3693
    3694 if( nvars == 0 )
    3695 return SCIP_OKAY;
    3696
    3697 vars = consdata->vars;
    3698 assert(vars != NULL);
    3699
    3700 oldnfixedzeros = consdata->nfixedzeros;
    3701 overlapdestroyed = FALSE;
    3702
    3703 /* first check for redundancy for all unprocessed constraints with cons */
    3704 for( c = endidx - 1; c >= 0; --c )
    3705 {
    3706 cons1 = usefulconss[c];
    3707
    3708 if( !SCIPconsIsActive(cons1) )
    3709 continue;
    3710
    3711 /* avoid checking constraint against itself */
    3712 if( considx == c )
    3713 continue;
    3714
    3715 assert(usefulconss[c] != cons);
    3716
    3717#ifndef NDEBUG
    3718 oldnaggrvars = *naggrvars;
    3719#endif
    3720
    3721 /* check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
    3722 * possible
    3723 */
    3724 SCIP_CALL( presolvePropagateCons(scip, cons1, FALSE, undoneaggrvars, undoneaggrtypes, naggregations, saggregations, nfixedvars, naggrvars, ndelconss, cutoff) );
    3725
    3726 if( *cutoff )
    3727 return SCIP_OKAY;
    3728
    3729 /* we can't handle aggregated variables later on so we should have saved them for later */
    3730 assert(*naggrvars == oldnaggrvars);
    3731
    3732 if( !SCIPconsIsActive(cons1) )
    3733 continue;
    3734
    3735 consdata1 = SCIPconsGetData(cons1);
    3736 assert(consdata1 != NULL);
    3737
    3738 nvars1 = consdata1->nvars;
    3739
    3740 if( nvars1 == 0 )
    3741 continue;
    3742
    3743 /* no more variables from cons as nvars1 can overlap */
    3744 assert(countofoverlapping[c] <= nvars1);
    3745
    3746 /* constraint should not be redundant or infeasible */
    3747 assert(consdata1->nfixedones == 0);
    3748
    3749 SCIPdebugMsg(scip, "constraint <%s> overlaps with constraint <%s> by %d variables\n", SCIPconsGetName(cons), SCIPconsGetName(cons1), countofoverlapping[c]);
    3750
    3751 /* cons1 includes cons */
    3752 if( !overlapdestroyed && countofoverlapping[c] == nvars - consdata->nfixedzeros )
    3753 {
    3754 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING ) /*lint !e641*/
    3755 {
    3756 if( nvars - consdata->nfixedzeros < nvars1 )
    3757 {
    3758#ifndef NDEBUG
    3759 SCIP_Bool negated0;
    3760 SCIP_Bool negated1;
    3761#endif
    3762
    3763 /* both constraints should stay merged */
    3764 assert(consdata->merged);
    3765 assert(consdata1->merged);
    3766
    3767 vars1 = consdata1->vars;
    3768 assert(vars1 != NULL);
    3769
    3770 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
    3771 SCIPsortDownPtr((void**)vars1, SCIPvarCompActiveAndNegated, nvars1);
    3772 /* standard setppc-sorting now lost */
    3773 consdata1->sorted = FALSE;
    3774
    3775 /* iterate over the both cliques variables the "same" time */
    3776 for( v = nvars - 1, v1 = nvars1 - 1; v >= 0 && v1 >= 0; )
    3777 {
    3778 if( SCIPvarGetLbLocal(vars1[v1]) > 0.5 || SCIPvarGetUbLocal(vars1[v1]) < 0.5 )
    3779 {
    3780 --v1;
    3781 continue;
    3782 }
    3783 if( SCIPvarGetLbLocal(vars[v]) > 0.5 || SCIPvarGetUbLocal(vars[v]) < 0.5 )
    3784 {
    3785 --v;
    3786 continue;
    3787 }
    3788
    3789 /* all variables inside the second clique constraint should be either active or negated of an active one */
    3790 assert(SCIPvarIsActive(vars1[v1]) || (SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1]))));
    3791
    3792 /* get not negated variable and clique value in cons */
    3794 {
    3795 var = vars[v];
    3796#ifndef NDEBUG
    3797 negated0 = FALSE;
    3798#endif
    3799 }
    3800 else
    3801 {
    3802 var = SCIPvarGetNegationVar(vars[v]);
    3803#ifndef NDEBUG
    3804 negated0 = TRUE;
    3805#endif
    3806 }
    3807
    3808 /* get active variable and clique value of next variable */
    3809 if( SCIPvarIsActive(vars1[v1]) )
    3810 {
    3811 var1 = vars1[v1];
    3812#ifndef NDEBUG
    3813 negated1 = FALSE;
    3814#endif
    3815 }
    3816 else
    3817 {
    3819 var1 = SCIPvarGetNegationVar(vars1[v1]);
    3820#ifndef NDEBUG
    3821 negated1 = TRUE;
    3822#endif
    3823 }
    3824
    3825 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
    3826 if( SCIPvarGetIndex(var) < SCIPvarGetIndex(var1) )
    3827 --v;
    3828 /* variable index in the constraint is greater than the other one, so fix this variable */
    3829 else if( SCIPvarGetIndex(var) > SCIPvarGetIndex(var1) )
    3830 {
    3831 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]));
    3832
    3833 /* fix all variables except the one which has the negated var in the clique to zero */
    3834 SCIP_CALL( SCIPfixVar(scip, vars1[v1], 0.0, cutoff, &fixed) );
    3835 if( *cutoff )
    3836 {
    3837 SCIPdebugMsg(scip, "fixing led to cutoff\n");
    3838
    3839 return SCIP_OKAY;
    3840 }
    3841
    3842 assert(fixed);
    3843 ++(*nfixedvars);
    3844 --v1;
    3845 }
    3846 else
    3847 {
    3848 /* because the constraint's are merged it is not possible that one constraint contains a negated
    3849 * variable of another and because all variables in cons are in cons1 this should be really the
    3850 * same variable here; so we can decrease v and v1
    3851 */
    3852 assert(negated0 == negated1);
    3853
    3854 --v;
    3855 --v1;
    3856 }
    3857 }
    3858 /* maybe we ended because of cons(v reached -1) so try to add rest of cons1 to cons */
    3859 for( ; v1 >= 0; --v1)
    3860 {
    3861 if( SCIPvarGetLbLocal(vars1[v1]) > 0.5 || SCIPvarGetUbLocal(vars1[v1]) < 0.5 )
    3862 continue;
    3863
    3864 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]));
    3865
    3866 /* fix all variables except the one which has the negated var in the clique to zero */
    3867 SCIP_CALL( SCIPfixVar(scip, vars1[v1], 0.0, cutoff, &fixed) );
    3868 if( *cutoff )
    3869 {
    3870 SCIPdebugMsg(scip, "fixing led to cutoff\n");
    3871
    3872 return SCIP_OKAY;
    3873 }
    3874
    3875 assert(fixed);
    3876 ++(*nfixedvars);
    3877 }
    3878 }
    3879
    3880 /* if caused by all fixings now this set partitioning constraint doesn't have any variable which was
    3881 * fixed to one, it's infeasible */
    3882 if( consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->nfixedzeros == nvars1 && consdata1->nfixedones != 1 ) /*lint !e641*/
    3883 {
    3884 SCIPdebugMsg(scip, "all variables in the set-partitioning constraint <%s> are fixed to zero, this leads to a cutoff\n", SCIPconsGetName(cons1));
    3885 *cutoff = TRUE;
    3886
    3887 return SCIP_OKAY;
    3888 }
    3889
    3890 assert(SCIPconsIsActive(cons1));
    3891 /* delete second constraint */
    3892 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> because it includes the setpartitioning constraint <%s> number <%d>\n", SCIPconsGetName(cons1), c, SCIPconsGetName(cons), considx);
    3893
    3894 SCIP_CALL( SCIPupdateConsFlags(scip, cons, cons1) );
    3895 SCIP_CALL( SCIPdelCons(scip, cons1) );
    3896 ++(*ndelconss);
    3897 }
    3898 /* could already be deleted because the constraint was included in another set partition constraint */
    3899 else if( SCIPconsIsActive(cons) )
    3900 {
    3901 /* delete cons due to redundancy to cons1 */
    3902 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> due to inclusion in constraint <%s> number <%d>\n", SCIPconsGetName(cons), considx, SCIPconsGetName(cons1), c);
    3903
    3904 SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons) );
    3905 SCIP_CALL( SCIPdelCons(scip, cons) );
    3906 ++(*ndelconss);
    3907 }
    3908 }
    3909 /* cons includes cons1
    3910 *
    3911 * @note that zero fixations from above can only appear through a set-partitioning constraint, this means if
    3912 * cons was the set-partitioning constraint only variables which are not in this constraint could be fixed
    3913 * to zero, and this also means that the overlapping variables in this particular case are still active or
    3914 * fixed to 1
    3915 * later on it could be possible that even variables in cons are fixed to zero, which can lead to wrong
    3916 * results when checking if countofoverlapping[c] + consdata1->nfixedzeros == nvars1, because a fixed
    3917 * variable could be counted twice
    3918 */
    3919 else if( (!overlapdestroyed && countofoverlapping[c] + consdata1->nfixedzeros == nvars1) || countofoverlapping[c] == nvars1 )
    3920 {
    3921 /* even in deleted constraints we may fix unfixed variables */
    3922 if( consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING ) /*lint !e641*/
    3923 {
    3924 const int oldnfixedvars = *nfixedvars;
    3925#ifndef NDEBUG
    3926 SCIP_Bool negated0;
    3927 SCIP_Bool negated1;
    3928#endif
    3929 /* both constraints should stay merged */
    3930 assert(consdata->merged);
    3931 assert(consdata1->merged);
    3932
    3933 vars1 = consdata1->vars;
    3934
    3935 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
    3936 SCIPsortDownPtr((void**)vars1, SCIPvarCompActiveAndNegated, nvars1);
    3937 /* standard setppc-sorting now lost */
    3938 consdata1->sorted = FALSE;
    3939
    3940 /* iterate over the both cliques variables the "same" time */
    3941 for( v = nvars - 1, v1 = nvars1 - 1; v >= 0 && v1 >= 0; )
    3942 {
    3943 if( SCIPvarGetLbLocal(vars1[v1]) > 0.5 || SCIPvarGetUbLocal(vars1[v1]) < 0.5 )
    3944 {
    3945 --v1;
    3946 continue;
    3947 }
    3948 if( SCIPvarGetLbLocal(vars[v]) > 0.5 || SCIPvarGetUbLocal(vars[v]) < 0.5 )
    3949 {
    3950 --v;
    3951 continue;
    3952 }
    3953
    3954 /* all variables inside the second clique constraint should be either active or negated of an active one */
    3955 assert(SCIPvarIsActive(vars1[v1]) || (SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1]))));
    3956 /* all variables inside the first clique constraint should be either active or negated of an active one */
    3958
    3959 /* get not negated variable and clique value in cons */
    3960 if( SCIPvarIsActive(vars[v]) )
    3961 {
    3962 var = vars[v];
    3963#ifndef NDEBUG
    3964 negated0 = FALSE;
    3965#endif
    3966 }
    3967 else
    3968 {
    3970 var = SCIPvarGetNegationVar(vars[v]);
    3971#ifndef NDEBUG
    3972 negated0 = TRUE;
    3973#endif
    3974 }
    3975
    3976 /* get active variable and clique value of next variable */
    3977 if( SCIPvarIsActive(vars1[v1]) )
    3978 {
    3979 var1 = vars1[v1];
    3980#ifndef NDEBUG
    3981 negated1 = FALSE;
    3982#endif
    3983 }
    3984 else
    3985 {
    3987 var1 = SCIPvarGetNegationVar(vars1[v1]);
    3988#ifndef NDEBUG
    3989 negated1 = TRUE;
    3990#endif
    3991 }
    3992
    3993 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
    3994 if( SCIPvarGetIndex(var) < SCIPvarGetIndex(var1) )
    3995 {
    3996 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because it is in the same clique with a complete set partitioning constraint\n", SCIPvarGetName(var));
    3997
    3998 /* fix all variables except the one which has the negated var in the clique to zero */
    3999 SCIP_CALL( SCIPfixVar(scip, vars[v], 0.0, cutoff, &fixed) );
    4000 if( *cutoff )
    4001 {
    4002 SCIPdebugMsg(scip, "fixing led to cutoff\n");
    4003
    4004 return SCIP_OKAY;
    4005 }
    4006
    4007 assert(fixed);
    4008 ++(*nfixedvars);
    4009
    4010 --v;
    4011 }
    4012 /* variable index in the constraint is greater than the other one, so fix this variable */
    4013 else if( SCIPvarGetIndex(var) > SCIPvarGetIndex(var1) )
    4014 --v1;
    4015 else
    4016 {
    4017 /* because the constraint's are merged it is not possible that one constraint contains a negated
    4018 * variable of another and because all variables in cons1 are in cons this should be really the same
    4019 * variable here; so we can decrease v and v1
    4020 */
    4021 assert(negated0 == negated1);
    4022
    4023 --v;
    4024 --v1;
    4025 }
    4026 }
    4027
    4028 /* maybe we ended because of cons1(v1 reached -1) so try to add rest of cons to cons1 */
    4029 for( ; v >= 0; --v)
    4030 {
    4031 if( SCIPvarGetLbLocal(vars[v]) > 0.5 || SCIPvarGetUbLocal(vars[v]) < 0.5 )
    4032 continue;
    4033
    4034 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]));
    4035
    4036 /* fix all variables except the one which has the negated var in the clique to zero */
    4037 SCIP_CALL( SCIPfixVar(scip, vars[v], 0.0, cutoff, &fixed) );
    4038 if( *cutoff )
    4039 {
    4040 SCIPdebugMsg(scip, "fixing led to cutoff\n");
    4041
    4042 return SCIP_OKAY;
    4043 }
    4044
    4045 assert(fixed);
    4046 ++(*nfixedvars);
    4047 }
    4048
    4049 /* if caused by all fixings now this set partitioning constraint doesn't have any variable which was
    4050 * fixed to one, it's infeasible */
    4051 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata->nfixedzeros == nvars && consdata->nfixedones != 1 ) /*lint !e641*/
    4052 {
    4053 SCIPdebugMsg(scip, "all variables in the set-partitioning constraint <%s> are fixed to zero, this leads to a cutoff\n", SCIPconsGetName(cons1));
    4054 *cutoff = TRUE;
    4055
    4056 return SCIP_OKAY;
    4057 }
    4058
    4059 /* could already be deleted because the constraint was included in another set partition constraint */
    4060 if( SCIPconsIsActive(cons) )
    4061 {
    4062 /* delete cons because it include another set partitioning constraint */
    4063 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> because it includes the setpartitioning constraint <%s> number <%d>\n", SCIPconsGetName(cons), considx, SCIPconsGetName(cons1), c);
    4064 assert(SCIPconsIsActive(cons));
    4065
    4066 SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons) );
    4067 SCIP_CALL( SCIPdelCons(scip, cons) );
    4068 ++(*ndelconss);
    4069 }
    4070
    4071 /* due to fixings in cons0 mark overlapping invalid for checking with fixedzero variables together */
    4072 if( oldnfixedvars < *nfixedvars )
    4073 overlapdestroyed = TRUE;
    4074 }
    4075 else
    4076 {
    4077 assert(consdata1->setppctype == SCIP_SETPPCTYPE_PACKING); /*lint !e641*/
    4078
    4079 /* delete cons1 due to redundancy to cons */
    4080 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> due to inclusion in constraint <%s> number <%d>\n", SCIPconsGetName(cons1), c, SCIPconsGetName(cons), considx);
    4081 assert(SCIPconsIsActive(cons1));
    4082
    4083 SCIP_CALL( SCIPupdateConsFlags(scip, cons, cons1) );
    4084 SCIP_CALL( SCIPdelCons(scip, cons1) );
    4085 ++(*ndelconss);
    4086 }
    4087 }
    4088 /* if cons has only one unfixed variable which is not in cons1 and cons1 has one variable which does not appear in
    4089 * cons and both constraints are setpartitioning constraints we might aggregate both not overlapping variables and
    4090 * delete one constraint
    4091 */
    4092 else if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING && countofoverlapping[c] == nvars - oldnfixedzeros - 1 && countofoverlapping[c] == nvars1 - 1 ) /*lint !e641*/
    4093 {
    4094 SCIP_VAR* aggvar1;
    4095 SCIP_VAR* aggvar2;
    4096 SCIP_Bool negated0;
    4097 SCIP_Bool negated1;
    4098
    4099 aggvar1 = NULL;
    4100 aggvar2 = NULL;
    4101
    4102 /* both constraints should stay merged */
    4103 assert(consdata->merged);
    4104 assert(consdata1->merged);
    4105
    4106 vars1 = consdata1->vars;
    4107
    4108 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
    4109 SCIPsortDownPtr((void**)vars1, SCIPvarCompActiveAndNegated, nvars1);
    4110 /* standard setppc-sorting now lost */
    4111 consdata1->sorted = FALSE;
    4112
    4113 /* iterate over the both cliques variables the "same" time */
    4114 for( v = nvars - 1, v1 = nvars1 - 1; v >= 0 && v1 >= 0; )
    4115 {
    4116 if( SCIPvarGetLbLocal(vars1[v1]) > 0.5 || SCIPvarGetUbLocal(vars1[v1]) < 0.5 )
    4117 {
    4118 --v1;
    4119 continue;
    4120 }
    4121 if( SCIPvarGetLbLocal(vars[v]) > 0.5 || SCIPvarGetUbLocal(vars[v]) < 0.5 )
    4122 {
    4123 --v;
    4124 continue;
    4125 }
    4126
    4127 /* all variables inside the second clique constraint should be either active or negated of an active one */
    4128 assert(SCIPvarIsActive(vars1[v1]) || (SCIPvarGetStatus(vars1[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars1[v1]))));
    4129 /* all variables inside the first clique constraint should be either active or negated of an active one */
    4131
    4132 /* get not negated variable and clique value in cons */
    4133 if( SCIPvarIsActive(vars[v]) )
    4134 {
    4135 var = vars[v];
    4136 negated0 = FALSE;
    4137 }
    4138 else
    4139 {
    4141 var = SCIPvarGetNegationVar(vars[v]);
    4142 negated0 = TRUE;
    4143 }
    4144
    4145 /* get active variable and clique value of next variable */
    4146 if( SCIPvarIsActive(vars1[v1]) )
    4147 {
    4148 var1 = vars1[v1];
    4149 negated1 = FALSE;
    4150 }
    4151 else
    4152 {
    4154 var1 = SCIPvarGetNegationVar(vars1[v1]);
    4155 negated1 = TRUE;
    4156 }
    4157
    4158 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
    4159 if( SCIPvarGetIndex(var) < SCIPvarGetIndex(var1) )
    4160 {
    4161 assert(aggvar1 == NULL);
    4162 aggvar1 = vars[v];
    4163
    4164 if( aggvar2 != NULL )
    4165 break;
    4166
    4167 --v;
    4168 }
    4169 /* variable index in the constraint is greater than the other one, so fix this variable */
    4170 else if( SCIPvarGetIndex(var) > SCIPvarGetIndex(var1) )
    4171 {
    4172 assert(aggvar2 == NULL);
    4173 aggvar2 = vars1[v1];
    4174
    4175 if( aggvar1 != NULL )
    4176 break;
    4177
    4178 --v1;
    4179 }
    4180 else
    4181 {
    4182 /* because the constraint's are merged it is not possible that one constraint contains a negated variable
    4183 * of another, but both variables in both constraints still can be negated to each other
    4184 */
    4185 if( negated0 != negated1 )
    4186 {
    4187 /* cons is except for one variable equal to cons1 and the unequal variable in cons is negated
    4188 * to the one in cons1, so the problem is infeasible
    4189 */
    4190 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]));
    4191 *cutoff = TRUE;
    4192
    4193 return SCIP_OKAY;
    4194 }
    4195 --v;
    4196 --v1;
    4197 }
    4198 }
    4199
    4200 /* due to fixings, it is possible that there are no active variables left, we we did not recognize which variables we could aggregate */
    4201 if( aggvar1 == NULL && aggvar2 == NULL )
    4202 continue;
    4203
    4204 /* determine second aggregation var, if not yet done */
    4205 if( aggvar2 == NULL )
    4206 {
    4207 for( ; v1 >= 0; --v1)
    4208 {
    4209 if( SCIPvarGetLbLocal(vars1[v1]) > 0.5 || SCIPvarGetUbLocal(vars1[v1]) < 0.5 )
    4210 continue;
    4211
    4212 aggvar2 = vars1[v1];
    4213 break;
    4214 }
    4215 }
    4216 /* determine first aggregation var, if not yet done */
    4217 else if( aggvar1 == NULL )
    4218 {
    4219 /* maybe we ended because of cons1(v1 reached -1) so find the aggvar1 in cons */
    4220 for( ; v >= 0; --v)
    4221 {
    4222 if( SCIPvarGetLbLocal(vars[v]) > 0.5 || SCIPvarGetUbLocal(vars[v]) < 0.5 )
    4223 continue;
    4224
    4225 aggvar1 = vars[v];
    4226 break;
    4227 }
    4228 }
    4229
    4230 /* due to fixings, it is possible that there are no active variables left, we we did not recognize which variables we could aggregate */
    4231 if( aggvar1 == NULL || aggvar2 == NULL )
    4232 continue;
    4233
    4234 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));
    4235
    4236 /* resize the aggregation arrays if necessary */
    4237 if( *saggregations == *naggregations )
    4238 {
    4239 *saggregations = SCIPcalcMemGrowSize(scip, *naggregations + 1);
    4240 assert(*saggregations > *naggregations);
    4241 SCIP_CALL( SCIPreallocBufferArray(scip, &undoneaggrtypes, *saggregations) );
    4242 SCIP_CALL( SCIPreallocBufferArray(scip, &undoneaggrvars, 2 * (*saggregations)) );
    4243
    4244 /* clear the aggregation type array to set the default to the aggregation of the form x + y = 1 */
    4245 BMSclearMemoryArray(&(undoneaggrtypes[*naggregations]), *saggregations - *naggregations); /*lint !e866*/
    4246 }
    4247
    4248 /* memorize aggregation variables*/
    4249 undoneaggrtypes[*naggregations] = TRUE;
    4250 undoneaggrvars[2 * (*naggregations)] = aggvar1;
    4251 undoneaggrvars[2 * (*naggregations) + 1] = aggvar2;
    4252 ++(*naggregations);
    4253
    4254 if( !SCIPdoNotAggr(scip) )
    4255 {
    4256 /* delete constraint */
    4257 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> because it is dominated by constraint <%s>\n", SCIPconsGetName(cons1), c, SCIPconsGetName(cons));
    4258 assert(SCIPconsIsActive(cons1));
    4259
    4260 SCIP_CALL( SCIPupdateConsFlags(scip, cons, cons1) );
    4261 SCIP_CALL( SCIPdelCons(scip, cons1) );
    4262 ++(*ndelconss);
    4263 }
    4264 }
    4265 /* w.l.o.g. cons is a setpartitioning constraint and countofoverlapping == nvars - oldnfixedzeros - 1 we can
    4266 * delete all overlapping variables in cons1 and add the negated variable of the not overlapped variable to cons
    4267 * 1; the result should be a shorter constraint with the same impact
    4268 */
    4269 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*/
    4270 {
    4271 SCIP_CONSDATA* consdatachange;
    4272 SCIP_VAR** varstostay;
    4273 SCIP_VAR** varstochange;
    4274 SCIP_CONS* constochange;
    4275 SCIP_CONS* constostay;
    4276 SCIP_VAR* addvar;
    4277 SCIP_Bool negated0;
    4278 SCIP_Bool negated1;
    4279 int nvarstostay;
    4280 int nvarstochange;
    4281 int constochangeidx;
    4282#ifndef NDEBUG
    4283 const int oldnchgcoefs = *nchgcoefs;
    4284#endif
    4285
    4286 addvar = NULL;
    4287
    4288 assert((consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING) != (consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING) || countofoverlapping[c] != nvars - 1 || countofoverlapping[c] != nvars1 - 1); /*lint !e641*/
    4289
    4290 /* both constraints should stay merged */
    4291 assert(consdata->merged);
    4292 assert(consdata1->merged);
    4293
    4294 /* sorting array after indices of variables, negated and active counterparts would stand side by side */
    4295 SCIPsortDownPtr((void**)(consdata1->vars), SCIPvarCompActiveAndNegated, nvars1);
    4296 /* standard setppc-sorting now lost */
    4297 consdata1->sorted = FALSE;
    4298
    4299 /* initialize variables */
    4300 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && countofoverlapping[c] == nvars - oldnfixedzeros - 1) /*lint !e641*/
    4301 {
    4302 varstostay = vars;
    4303 varstochange = consdata1->vars;
    4304 nvarstostay = nvars;
    4305 nvarstochange = nvars1;
    4306 constostay = cons;
    4307 constochange = cons1;
    4308 consdatachange = consdata1;
    4309 constochangeidx = c;
    4310 }
    4311 else
    4312 {
    4313 varstostay = consdata1->vars;
    4314 varstochange = vars;
    4315 nvarstostay = nvars1;
    4316 nvarstochange = nvars;
    4317 constostay = cons1;
    4318 constochange = cons;
    4319 consdatachange = consdata;
    4320 constochangeidx = considx;
    4321
    4322 *chgcons = TRUE;
    4323 }
    4324
    4325 /* iterate over the both cliques variables the "same" time, here we need the backward loop, because we
    4326 * delete some variables and we don not want to loose order
    4327 */
    4328 for( v = nvarstostay - 1, v1 = nvarstochange - 1; v >= 0 && v1 >= 0; )
    4329 {
    4330 if( SCIPvarGetLbLocal(varstochange[v1]) > 0.5 || SCIPvarGetUbLocal(varstochange[v1]) < 0.5 )
    4331 {
    4332 --v1;
    4333 continue;
    4334 }
    4335 if( SCIPvarGetLbLocal(varstostay[v]) > 0.5 || SCIPvarGetUbLocal(varstostay[v]) < 0.5 )
    4336 {
    4337 --v;
    4338 continue;
    4339 }
    4340
    4341 /* all variables inside the second clique constraint should be either active or negated of an active one */
    4342 assert(SCIPvarIsActive(varstochange[v1]) || (SCIPvarGetStatus(varstochange[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstochange[v1]))));
    4343 /* all variables inside the first clique constraint should be either active or negated of an active one */
    4344 assert(SCIPvarIsActive(varstostay[v]) || (SCIPvarGetStatus(varstostay[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstostay[v]))));
    4345
    4346 /* get not negated variable and clique value in constostay */
    4347 if( SCIPvarIsActive(varstostay[v]) )
    4348 {
    4349 var = varstostay[v];
    4350 negated0 = FALSE;
    4351 }
    4352 else
    4353 {
    4354 assert(SCIPvarGetStatus(varstostay[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstostay[v])));
    4355 var = SCIPvarGetNegationVar(varstostay[v]);
    4356 negated0 = TRUE;
    4357 }
    4358
    4359 /* get active variable and clique value of in constochange*/
    4360 if( SCIPvarIsActive(varstochange[v1]) )
    4361 {
    4362 var1 = varstochange[v1];
    4363 negated1 = FALSE;
    4364 }
    4365 else
    4366 {
    4367 assert(SCIPvarGetStatus(varstochange[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstochange[v1])));
    4368 var1 = SCIPvarGetNegationVar(varstochange[v1]);
    4369 negated1 = TRUE;
    4370 }
    4371
    4372 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
    4373 if( SCIPvarGetIndex(var) < SCIPvarGetIndex(var1) )
    4374 {
    4375 assert(addvar == NULL);
    4376 addvar = varstostay[v];
    4377 --v;
    4378 }
    4379 /* variable index in the constraint is greater than the other one, so fix this variable */
    4380 else if( SCIPvarGetIndex(var) > SCIPvarGetIndex(var1) )
    4381 {
    4382 --v1;
    4383 }
    4384 else
    4385 {
    4386 /* because the constraint's are merged it is not possible that one constraint contains a negated variable
    4387 * of another, but both constraint might have a variable in negated form of the other
    4388 */
    4389 if( negated0 != negated1 )
    4390 {
    4391 assert(addvar == NULL);
    4392
    4393 SCIPdebugMsg(scip, "-> trying to fix <%s> to 0 because it would exist twice in a constraint\n", SCIPvarGetName(varstochange[v1]));
    4394
    4395 /* fix variable to zero */
    4396 SCIP_CALL( SCIPfixVar(scip, varstochange[v1], 0.0, cutoff, &fixed) );
    4397 if( *cutoff )
    4398 {
    4399 SCIPdebugMsg(scip, "fixing led to cutoff\n");
    4400
    4401 return SCIP_OKAY;
    4402 }
    4403
    4404 assert(fixed);
    4405 ++(*nfixedvars);
    4406
    4407 /* the above fixing is equal to the fixation of varstostay[v] to 1, so we can call presolvePropagateCons() for consstay */
    4408 SCIP_CALL( presolvePropagateCons(scip, constostay, FALSE, NULL, NULL, NULL, NULL, nfixedvars, naggrvars, ndelconss, cutoff) );
    4409
    4410 return SCIP_OKAY;
    4411 }
    4412 else
    4413 {
    4414 /* correct local data structure, remove variable from constraint entry where it will be removed */
    4415 deleteCliqueDataEntry(varstochange[v1], constochangeidx, vartoindex, varnconss, varconsidxs);
    4416
    4417 SCIPdebugMsg(scip, " -> deleting variable <%s> in constraint <%s> number %d, because it will be replaced\n", SCIPvarGetName(varstochange[v1]), SCIPconsGetName(constochange), constochangeidx);
    4418 /* delete overlapping variables in constochange */
    4419 SCIP_CALL( delCoefPos(scip, constochange, v1) );
    4420 ++(*nchgcoefs);
    4421 }
    4422
    4423 --v;
    4424 --v1;
    4425 }
    4426 }
    4427 assert(addvar != NULL || v >= 0);
    4428 /* we should have removed exactly countofoverlapping[c] variables from the constochange */
    4429 assert(*nchgcoefs - oldnchgcoefs == countofoverlapping[c]);
    4430
    4431 /* determine addvar if not yet found */
    4432 if( addvar == NULL )
    4433 {
    4434 for( ; v >= 0; --v)
    4435 {
    4436 if( SCIPvarGetLbLocal(varstostay[v]) > 0.5 || SCIPvarGetUbLocal(varstostay[v]) < 0.5 )
    4437 continue;
    4438
    4439 /* all variables inside the first clique constraint should be either active or negated of an active one */
    4440 assert(SCIPvarIsActive(varstostay[v]) || (SCIPvarGetStatus(varstostay[v]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(varstostay[v]))));
    4441
    4442 addvar = varstostay[v];
    4443 break;
    4444 }
    4445 }
    4446 assert(addvar != NULL);
    4447
    4448 /* get representative variable for all deleted variables */
    4449 SCIP_CALL( SCIPgetNegatedVar(scip, addvar, &addvar) );
    4450 assert(addvar != NULL);
    4451
    4452 SCIPdebugMsg(scip, " -> adding variable <%s> to constraint <%s> number %d\n", SCIPvarGetName(addvar), SCIPconsGetName(constochange), constochangeidx);
    4453 /* add representative for overlapping instead */
    4454 SCIP_CALL( addCoef(scip, constochange, addvar) );
    4455 ++(*nchgcoefs);
    4456
    4457 /* constraint should be still merged because this added variable is new in this constraint */
    4458 consdatachange->merged = TRUE;
    4459 assert(constochangeidx == (cons == constochange ? considx : c));
    4460
    4461 /* correct local data structure, add constraint entry to variable data */
    4462 SCIP_CALL( addCliqueDataEntry(scip, addvar, constochangeidx, TRUE, usefulvars, nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs) );
    4463
    4464 /* cons changed so much, that it cannot be used for more overlapping checks */
    4465 if( *chgcons )
    4466 return SCIP_OKAY;
    4467 }
    4468 }
    4469
    4470 return SCIP_OKAY;
    4471}
    4472
    4473/** try to lift variables to given constraint */
    4474/** @todo try another variant by determine lifting variables as the intersection of all cliques variables of the
    4475 * constraint variables, note that the intersection changes after one variable was added
    4476 */
    4477static
    4479 SCIP*const scip, /**< SCIP data structure */
    4480 SCIP_CONS*const cons, /**< constraint which may overlap */
    4481 int const arraypos, /**< position of constraint in global array */
    4482 SCIP_VAR**const usefulvars, /**< possible variables to lift */
    4483 int*const nusefulvars, /**< pointer to store number of added variables */
    4484 int const endidx, /**< end index for possible lifting variables */
    4485 SCIP_Bool** cliquevalues, /**< pointer to clique values of constraint-variables, either one if the
    4486 * variable is active or zero if the variable is negated
    4487 * @note this array can be resized in this method
    4488 */
    4489 SCIP_HASHMAP*const vartoindex, /**< hashmap mapping variables to indices */
    4490 int*const varnconss, /**< array with number of constraints a variable occurs */
    4491 int*const maxnvarconsidx, /**< array with the maximal number of occurrences of a variable */
    4492 int**const varconsidxs, /**< array with constraint indices in which the corresponding variable
    4493 * exists
    4494 */
    4495 int*const maxnvars, /**< pointer to store maximal number of variables of a constraint */
    4496 int*const nadded, /**< pointer to store number of possible added variables */
    4497 SCIP_Bool*const chgcons, /**< pointer to store if the constraint was changed, due to added
    4498 * variables
    4499 */
    4500 int*const nfixedvars, /**< pointer to count number of deleted variables */
    4501 int*const ndelconss, /**< pointer to count number of deleted constraints */
    4502 SCIP_Bool*const cutoff /**< pointer to store if the problem is infeasible due to a fixing */
    4503 )
    4504{
    4505 SCIP_CONSDATA* consdata;
    4506 SCIP_VAR** vars;
    4507 SCIP_VAR* var;
    4508 SCIP_VAR* var1;
    4509 SCIP_Bool fixed;
    4510 SCIP_Bool value;
    4511 int nvars;
    4512 int nottocheck; /* will be the position for a variable in cons0 which is in negated form in the same clique */
    4513 int v;
    4514 int v1;
    4515 int k;
    4516
    4517 assert(scip != NULL);
    4518 assert(cons != NULL);
    4519 assert(usefulvars != NULL);
    4520 assert(cliquevalues != NULL);
    4521 assert(*cliquevalues != NULL);
    4522 assert(vartoindex != NULL);
    4523 assert(varnconss != NULL);
    4524 assert(maxnvarconsidx != NULL);
    4525 assert(varconsidxs != NULL);
    4526 assert(maxnvars != NULL);
    4527 assert(nadded != NULL);
    4528 assert(chgcons != NULL);
    4529 assert(nfixedvars != NULL);
    4530 assert(ndelconss != NULL);
    4531 assert(cutoff != NULL);
    4532
    4533 if( !SCIPconsIsActive(cons) )
    4534 return SCIP_OKAY;
    4535
    4536 consdata = SCIPconsGetData(cons);
    4537 assert(consdata != NULL);
    4538
    4539 nvars = consdata->nvars;
    4540
    4541 if( nvars == 0 )
    4542 return SCIP_OKAY;
    4543
    4544 assert(nvars <= *maxnvars);
    4545
    4546 vars = consdata->vars;
    4547 assert(vars != NULL);
    4548
    4549 v1 = endidx;
    4550
    4551 /* now we try to add variables with index prior to endidx to cons */
    4552 for( v = nvars - 1; v >= 0 && v1 >= 0; )
    4553 {
    4554 if( SCIPvarGetLbLocal(usefulvars[v1]) > 0.5 || SCIPvarGetUbLocal(usefulvars[v1]) < 0.5 )
    4555 {
    4556 --v1;
    4557 continue;
    4558 }
    4559 if( SCIPvarGetUbLocal(vars[v]) < 0.5 )
    4560 {
    4561 --v;
    4562 continue;
    4563 }
    4564
    4565 /* check that constraint variables are still correctly sorted, indices of active variables should be decreasing */
    4566 assert(v == 0 || SCIPvarCompareActiveAndNegated(vars[v], vars[v - 1]) <= 0);
    4567
    4568 /* there should no variables fixed to one occur in our constraint */
    4569 assert(SCIPvarGetLbLocal(vars[v]) < 0.5 && SCIPvarGetUbLocal(vars[v]) > 0.5);
    4570 assert(SCIPvarGetLbLocal(usefulvars[v1]) < 0.5 && SCIPvarGetUbLocal(usefulvars[v1]) > 0.5);
    4571
    4572 /* all variables which we have inside the clique constraint and which can possibly be added should be either active or negated */
    4574 assert(SCIPvarIsActive(usefulvars[v1]) || (SCIPvarGetStatus(usefulvars[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(usefulvars[v1]))));
    4575
    4576 /* constraint should during adding of variables stay merged, because for each variable which is added holds that
    4577 * the index of this corresponding active variable is pairwise different to all indices of all active
    4578 * corresponding variables inside the constraint
    4579 * @note it should not happen that we add one variable and the corresponding counterpart to the same constraint */
    4580 assert(consdata->merged);
    4581
    4582 /* get active variable and clique value in cons */
    4583 if( (*cliquevalues)[v] )
    4584 var = vars[v];
    4585 else
    4586 {
    4588 var = SCIPvarGetNegationVar(vars[v]);
    4589 }
    4590
    4591 /* get active variable and clique value of next variable */
    4592 if( SCIPvarIsActive(usefulvars[v1]) )
    4593 {
    4594 var1 = usefulvars[v1];
    4595 value = TRUE;
    4596 }
    4597 else
    4598 {
    4599 assert(SCIPvarGetStatus(usefulvars[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(usefulvars[v1])));
    4600 var1 = SCIPvarGetNegationVar(usefulvars[v1]);
    4601 value = FALSE;
    4602 }
    4603
    4604 nottocheck = -1;
    4605 k = 0;
    4606
    4607 /* variable index in the constraint smaller than the other one, so go to the next variable in cons */
    4608 if( SCIPvarGetIndex(var) < SCIPvarGetIndex(var1) )
    4609 {
    4610 --v;
    4611 continue;
    4612 }
    4613 /* variable index in the constraint is greater than the other one, so check for possible inclusion of the variable */
    4614 else if( SCIPvarGetIndex(var) > SCIPvarGetIndex(var1) )
    4615 {
    4616 assert(consdata == SCIPconsGetData(cons));
    4617
    4618 /* check if every variable in the actual clique is in clique with the new variable */
    4619 for( k = nvars - 1; k >= 0; --k )
    4620 {
    4621 if( SCIPvarGetUbLocal(vars[k]) > 0.5 )
    4622 {
    4623 /* there should no variables fixed to one occur in our constraint */
    4624 assert(SCIPvarGetLbLocal(vars[k]) < 0.5);
    4626
    4627 if( (*cliquevalues)[k] )
    4628 {
    4629 assert(SCIPvarIsActive(vars[k]));
    4630 var = vars[k];
    4631 }
    4632 else
    4633 {
    4635 var = SCIPvarGetNegationVar(vars[k]);
    4636 }
    4637 if( !SCIPhaveVarsCommonClique(scip, var1, value, var, (*cliquevalues)[k], TRUE) )
    4638 break;
    4639 }
    4640 }
    4641 --v1;
    4642 }
    4643 /* variable index in the constraint is equal to the index of the other variable, check if these variables are
    4644 * negated of each other so memorize the position and check for possible inclusion of the new variable and if
    4645 * possible decrease indices
    4646 */
    4647 else
    4648 {
    4649 /* one clique contains the negated and the other clique the corresponding active var */
    4650 if( value != (*cliquevalues)[v] )
    4651 {
    4652 nottocheck = v;
    4653
    4654 assert(consdata == SCIPconsGetData(cons));
    4655 assert(nvars <= consdata->nvars);
    4656
    4657 /* check if every variable in the actual clique is in clique with the new variable */
    4658 for( k = nvars - 1; k >= 0; --k )
    4659 {
    4660 if( SCIPvarGetUbLocal(vars[k]) > 0.5 )
    4661 {
    4662 /* there should no variables fixed to one occur in our constraint */
    4663 assert(SCIPvarGetLbLocal(vars[k]) < 0.5);
    4664
    4666
    4667 if( k == nottocheck )
    4668 continue;
    4669
    4670 if( (*cliquevalues)[k] )
    4671 {
    4672 assert(SCIPvarIsActive(vars[k]));
    4673 var = vars[k];
    4674 }
    4675 else
    4676 {
    4678 var = SCIPvarGetNegationVar(vars[k]);
    4679 }
    4680
    4681 if( !SCIPhaveVarsCommonClique(scip, var1, value, var, (*cliquevalues)[k], TRUE) )
    4682 break;
    4683 }
    4684 }
    4685 }
    4686 /* don't decrease v because it might happen that the corresponding negated variable of var is next in
    4687 * usefulvars
    4688 */
    4689 --v1;
    4690 }
    4691
    4692 /* if k is smaller than 0 than the possible new variables is in the same clique with all variables of cons,
    4693 * so we add the new variable to clique constraint or fix some variables */
    4694 if( k < 0 )
    4695 {
    4696 ++(*nadded);
    4697
    4698 /* we found a variable which is the negated variable of another one in this clique so we can fix all
    4699 * other variable to zero and if it's a partitioning constraint we can also fix the variable of the
    4700 * negated to one and we can delete the constraint too */
    4701 if( nottocheck >= 0 )
    4702 {
    4703 assert(consdata == SCIPconsGetData(cons));
    4704 assert(nvars <= consdata->nvars);
    4705 assert(consdata->merged);
    4706
    4707 /* process all vars for possible fixing */
    4708 for( k = consdata->nvars - 1; k >= 0; --k )
    4709 {
    4710 if( SCIPvarGetUbLocal(vars[k]) > 0.5 )
    4711 {
    4712 /* there should no variables fixed to one occur in our constraint */
    4713 assert(SCIPvarGetLbLocal(vars[v]) < 0.5);
    4714
    4716
    4717 if( k != nottocheck )
    4718 {
    4719 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because we could lift a negated variable of another constraint variable\n", SCIPvarGetName(vars[k]));
    4720 /* fix variable to zero */
    4721 SCIP_CALL( SCIPfixVar(scip, vars[k], 0.0, cutoff, &fixed) );
    4722
    4723 if( *cutoff )
    4724 {
    4725 SCIPdebugMsg(scip, "fixing led to cutoff\n");
    4726
    4727 return SCIP_OKAY;
    4728 }
    4729
    4730 assert(fixed);
    4731
    4732 ++(*nfixedvars);
    4733 }
    4734 }
    4735 }
    4736 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING ) /*lint !e641*/
    4737 {
    4738 assert(SCIPvarIsActive(vars[nottocheck]) || (SCIPvarGetStatus(vars[nottocheck]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(vars[nottocheck]))));
    4739
    4740 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]));
    4741 /* fix the remaining variable to one, due to it's the only one left to satisfy the constraint */
    4742 SCIP_CALL( SCIPfixVar(scip, vars[nottocheck], 1.0, cutoff, &fixed) );
    4743 if( *cutoff )
    4744 {
    4745 SCIPdebugMsg(scip, "fixing led to cutoff\n");
    4746
    4747 return SCIP_OKAY;
    4748 }
    4749
    4750 assert(fixed);
    4751 ++(*nfixedvars);
    4752 }
    4753
    4754 /* delete constraint */
    4755 SCIPdebugMsg(scip, " -> deleting constraint <%s> number <%d> due to active and negated variable in the same clique constraint\n", SCIPconsGetName(cons), arraypos);
    4756 assert(SCIPconsIsActive(cons));
    4757 SCIP_CALL( SCIPdelCons(scip, cons) );
    4758 ++(*ndelconss);
    4759
    4760 break;
    4761 }
    4762 /* we found a variable which could be added to a partitioning constraint so we can fix it to zero */
    4763 else if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING ) /*lint !e641*/
    4764 {
    4765 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]));
    4766 /* fix variable to zero */
    4767 SCIP_CALL( SCIPfixVar(scip, usefulvars[v1 + 1], 0.0, cutoff, &fixed) );
    4768
    4769 if( *cutoff )
    4770 {
    4771 SCIPdebugMsg(scip, "fixing led to cutoff\n");
    4772
    4773 return SCIP_OKAY;
    4774 }
    4775
    4776 assert(fixed);
    4777
    4778 ++(*nfixedvars);
    4779 }
    4780 /* we have found a new variable for a set packing constraint cons, so add the found variable to the first constraint */
    4781 else
    4782 {
    4783 SCIP_VAR* addvar;
    4784
    4785 assert(SCIPconsIsActive(cons));
    4786
    4787 addvar = usefulvars[v1 + 1];
    4788
    4789 assert(SCIPvarGetLbLocal(addvar) < 0.5 && SCIPvarGetUbLocal(addvar) > 0.5);
    4790
    4791 /* add representative instead */
    4792 SCIPdebugMsg(scip, " -> adding variable <%s> to constraint <%s> number %d\n", SCIPvarGetName(usefulvars[v1 + 1]), SCIPconsGetName(cons), arraypos);
    4793 SCIP_CALL( addCoef(scip, cons, addvar) );
    4794 assert(consdata == SCIPconsGetData(cons));
    4795 /* we know that this constraint stays merged but later on we have to resort */
    4796 consdata->merged = TRUE;
    4797
    4798 /* second we add the constraint index to the list of indices where this variable occurs */
    4799 assert(SCIPhashmapExists(vartoindex, (void*) addvar));
    4800
    4801 /* correct local data structure, add constraint entry to variable data */
    4802 SCIP_CALL( addCliqueDataEntry(scip, addvar, arraypos, FALSE, usefulvars, nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs) );
    4803
    4804 /* we need the new pointer to the variables, because due to adding variables it is possible that we
    4805 * did reallocate the variables array inside the constraint, the index v should stay the same because the
    4806 * added variable was inserted at the end and we are decreasing v in our for loop
    4807 */
    4808 vars = consdata->vars;
    4809 nvars = consdata->nvars;
    4810
    4811 /* we need to update our data structure */
    4812
    4813 /* resize clique array if necessary, due to adding variables */
    4814 if( (*maxnvars) < nvars )
    4815 {
    4816 while( (*maxnvars) < nvars )
    4817 (*maxnvars) *= 2 ;
    4818 SCIP_CALL( SCIPreallocBufferArray(scip, cliquevalues, (*maxnvars)) );
    4819 }
    4820 (*cliquevalues)[nvars - 1] = SCIPvarIsActive(addvar) ? TRUE : FALSE;
    4821
    4822 (*chgcons) = TRUE;
    4823 }
    4824 }
    4825 }
    4826
    4827 if( !SCIPconsIsActive(cons) )
    4828 return SCIP_OKAY;
    4829
    4830 /* maybe we stopped because of cons(v reached -1) so try to add rest in usefulvars */
    4831 for( ; v1 >= 0; --v1)
    4832 {
    4833 if( SCIPvarGetLbLocal(usefulvars[v1]) > 0.5 || SCIPvarGetUbLocal(usefulvars[v1]) < 0.5 )
    4834 continue;
    4835
    4836 /* get active variable and clique value */
    4837 if( SCIPvarIsActive(usefulvars[v1]) )
    4838 {
    4839 var1 = usefulvars[v1];
    4840 value = TRUE;
    4841 }
    4842 else
    4843 {
    4844 assert(SCIPvarGetStatus(usefulvars[v1]) == SCIP_VARSTATUS_NEGATED && SCIPvarIsActive(SCIPvarGetNegationVar(usefulvars[v1])));
    4845 var1 = SCIPvarGetNegationVar(usefulvars[v1]);
    4846 value = FALSE;
    4847 }
    4848
    4849 assert(consdata == SCIPconsGetData(cons));
    4850 assert(nvars <= consdata->nvars);
    4851
    4852 /* check if every variable in the actual clique is in clique with the new variable */
    4853 for( k = nvars - 1; k >= 0; --k )
    4854 {
    4855 if( SCIPvarGetUbLocal(vars[k]) > 0.5 )
    4856 {
    4857 /* there should no variables fixed to one occur in our constraint */
    4858 assert(SCIPvarGetLbLocal(vars[k]) < 0.5);
    4859
    4861
    4862 if( (*cliquevalues)[k] )
    4863 {
    4864 assert(SCIPvarIsActive(vars[k]));
    4865 var = vars[k];
    4866 }
    4867 else
    4868 {
    4870 var = SCIPvarGetNegationVar(vars[k]);
    4871 }
    4872
    4873 if( !SCIPvarsHaveCommonClique(var1, value, var, (*cliquevalues)[k], TRUE) )
    4874 break;
    4875 }
    4876 }
    4877
    4878 /* add new variable to clique constraint or fix some variables */
    4879 if( k < 0 )
    4880 {
    4881 /* we found a variable which could be added to a partitioning constraint so we can fix it to zero */
    4882 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING ) /*lint !e641*/
    4883 {
    4884 SCIPdebugMsg(scip, "trying to fix <%s> to 0 because this variable is in the same clique with a set partition\n", SCIPvarGetName(usefulvars[v1]));
    4885
    4886 /* fix variable to zero */
    4887 SCIP_CALL( SCIPfixVar(scip, usefulvars[v1], 0.0, cutoff, &fixed) );
    4888 if( *cutoff )
    4889 {
    4890 SCIPdebugMsg(scip, "fixing led to cutoff\n");
    4891
    4892 return SCIP_OKAY;
    4893 }
    4894 assert(fixed);
    4895
    4896 ++(*nfixedvars);
    4897 ++(*nadded);
    4898 }
    4899 /* add the found variable to the first constraint */
    4900 else
    4901 {
    4902 SCIP_VAR* addvar;
    4903
    4904 assert(SCIPconsIsActive(cons));
    4905
    4906 addvar = usefulvars[v1];
    4907
    4908 assert(SCIPvarGetLbLocal(addvar) < 0.5 && SCIPvarGetUbLocal(addvar) > 0.5);
    4909
    4910 /* add representative instead */
    4911 SCIPdebugMsg(scip, " -> adding variable <%s> to constraint <%s> number %d\n", SCIPvarGetName(addvar), SCIPconsGetName(cons), arraypos);
    4912 SCIP_CALL( addCoef(scip, cons, addvar) );
    4913 assert(consdata == SCIPconsGetData(cons));
    4914 /* we know that this constraint stays merged but later on we have to resort */
    4915 consdata->merged = TRUE;
    4916
    4917 /* second we add the constraint index to the list of indices where this variable occurs */
    4918 assert(SCIPhashmapExists(vartoindex, (void*) addvar));
    4919
    4920 /* correct local data structure, add constraint entry to variable data */
    4921 SCIP_CALL( addCliqueDataEntry(scip, addvar, arraypos, FALSE, usefulvars, nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs) );
    4922
    4923 /* we need the new pointer to the variables, because due to adding variables it is possible that we
    4924 * did reallocate the variables array inside the constraint, the index v should stay the same because the
    4925 * added variable was inserted at the end and we are decreasing v in our for loop
    4926 */
    4927 vars = consdata->vars;
    4928 nvars = consdata->nvars;
    4929
    4930 /* we need to update our data structure */
    4931
    4932 /* resize clique array if necessary, due to adding variables */
    4933 if( (*maxnvars) < nvars )
    4934 {
    4935 while( (*maxnvars) < nvars )
    4936 (*maxnvars) *= 2 ;
    4937 SCIP_CALL( SCIPreallocBufferArray(scip, cliquevalues, (*maxnvars)) );
    4938 }
    4939 (*cliquevalues)[nvars - 1] = SCIPvarIsActive(addvar) ? TRUE : FALSE;
    4940
    4941 ++(*nadded);
    4942 (*chgcons) = TRUE;
    4943 }
    4944 }
    4945 }
    4946
    4947 return SCIP_OKAY;
    4948}
    4949
    4950/** perform all collected aggregations */
    4951static
    4953 SCIP*const scip, /**< SCIP data structure */
    4954 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    4955 SCIP_VAR**const undoneaggrvars, /**< aggregation variables storage */
    4956 SCIP_Bool*const undoneaggrtypes, /**< aggregation type storage, type FALSE means the aggregation is of the
    4957 * form x + y = 1; type TRUE means the aggregation is of the form x = y;
    4958 */
    4959 int const naggregations, /**< number of aggregations to performed */
    4960 int*const naggrvars, /**< pointer to count number of aggregated variables */
    4961 SCIP_Bool*const cutoff /**< pointer to store if the problem is infeasible due to a fixing */
    4962 )
    4963{ /*lint --e{715}*/
    4964 SCIP_VAR* var1;
    4965 SCIP_VAR* var2;
    4966 SCIP_Bool aggregated;
    4967 SCIP_Bool redundant;
    4968 int a;
    4969
    4970 assert(scip != NULL);
    4971 assert(conshdlrdata != NULL);
    4972 assert(undoneaggrvars != NULL);
    4973 assert(undoneaggrtypes != NULL);
    4974 assert(naggregations > 0);
    4975 assert(naggrvars != NULL);
    4976 assert(cutoff != NULL);
    4977
    4978 /* loop over all open aggregations and try to aggregate them */
    4979 for( a = 0; a < naggregations; ++a )
    4980 {
    4981 var1 = undoneaggrvars[2 * a];
    4982 var2 = undoneaggrvars[2 * a + 1];
    4983 assert(var1 != NULL);
    4984 assert(var2 != NULL);
    4985
    4986 SCIPdebugMsg(scip, "trying to aggregate <%s> %s <%s>%s\n", SCIPvarGetName(var1), undoneaggrtypes[a] ? "=" : "+", SCIPvarGetName(var2), undoneaggrtypes[a] ? "" : " = 1");
    4987
    4988#ifdef VARUSES
    4989 /* in order to not mess up the variable usage counting, we have to decrease usage counting, aggregate,
    4990 * and increase usage counting again
    4991 */
    4992 SCIP_CALL( conshdlrdataDecVaruses(scip, conshdlrdata, var1) );
    4993 SCIP_CALL( conshdlrdataDecVaruses(scip, conshdlrdata, var2) );
    4994#endif
    4995
    4996 /* aggregate last remaining variables in the set partitioning constraint */
    4997 if( undoneaggrtypes[a] )
    4998 {
    4999 SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, -1.0, 0.0, cutoff, &redundant, &aggregated) );
    5000 }
    5001 else
    5002 {
    5003 SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, 1.0, 1.0, cutoff, &redundant, &aggregated) );
    5004 }
    5005
    5006 if( *cutoff )
    5007 {
    5008 SCIPdebugMsg(scip, "aggregation was infeasible\n");
    5009
    5010 return SCIP_OKAY;
    5011 }
    5012 /* binary variables should always be aggregated, or due to fixation the aggregation is redundant */
    5013 assert(redundant);
    5014
    5015 if( aggregated )
    5016 ++(*naggrvars);
    5017
    5018#ifdef VARUSES
    5019 /* increase variable usage counting again */
    5020 SCIP_CALL( conshdlrdataIncVaruses(scip, conshdlrdata, var1) );
    5021 SCIP_CALL( conshdlrdataIncVaruses(scip, conshdlrdata, var2) );
    5022#endif
    5023 }
    5024
    5025 return SCIP_OKAY;
    5026}
    5027
    5028/** check whether we can combine or grow cliques so some constraints become redundant or we can fix variables */
    5029/** @todo try another variant, by building up the clique graph and delete unnecessary (transitive closure) edges and do
    5030 * a bfs search to search for common ancestors to get all possible lifting variables
    5031 */
    5032static
    5034 SCIP*const scip, /**< SCIP data structure */
    5035 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    5036 SCIP_CONS**const conss, /**< constraint set */
    5037 int const nconss, /**< number of constraints in constraint set */
    5038 int const nrounds, /**< actual presolving round */
    5039 int*const firstchange, /**< pointer to store first changed constraint */
    5040 int*const firstclique, /**< pointer to store first constraint to start adding clique again */
    5041 int*const lastclique, /**< pointer to store last constraint to add cliques again */
    5042 int*const nfixedvars, /**< pointer to count number of deleted variables */
    5043 int*const naggrvars, /**< pointer to count number of aggregated variables */
    5044 int*const ndelconss, /**< pointer to count number of deleted constraints */
    5045 int*const nchgcoefs, /**< pointer to count number of deleted coefficients */
    5046 SCIP_Bool*const cutoff /**< pointer to store if the problem is infeasible due to a fixing */
    5047 )
    5048{
    5049 /* extend cliques/constraints by checking whether some variables are in the same clique, no pairwise clique lifting
    5050 * which would be slower
    5051 */
    5052 SCIP_CONS** usefulconss; /* array with pointers of constraint of setpartitioning and setpacking type */
    5053 SCIP_VAR** usefulvars; /* array with pointers of variables in setpartitioning and setpacking constraints */
    5054 int** varconsidxs; /* array consisting of constraint indices in which the corresponding variable exists */
    5055 int* varnconss; /* array consisting of number of constraints the variable occurs */
    5056 int* maxnvarconsidx; /* maximal number of occurrences of a variable */
    5057 int* countofoverlapping = NULL; /* the amount of variables which are in another constraint */
    5058 SCIP_Bool* cliquevalues = NULL; /* values of clique-variables, either one if the variable is active or zero if the variable is negated */
    5059
    5060 SCIP_HASHMAP* vartoindex; /* mapping of SCIP variables to indices */
    5061 SCIP_CONSDATA* consdata;
    5062
    5063 SCIP_Bool chgcons0;
    5064 int nvars;
    5065 int c;
    5066 int v;
    5067 int nusefulconss;
    5068 int nusefulvars;
    5069 int susefulvars;
    5070 int maxnvars;
    5071 int varindex;
    5072
    5073 SCIP_VAR** undoneaggrvars; /* storage for not yet performed aggregations */
    5074 SCIP_Bool* undoneaggrtypes; /* storage for not yet performed aggregation type (x = y or x + y = 1) */
    5075 int saggregations;
    5076 int naggregations;
    5077 int startndelconss;
    5078
    5079 assert(scip != NULL);
    5080 assert(conshdlrdata != NULL);
    5081 assert(conss != NULL || nconss == 0);
    5082 assert(firstchange != NULL);
    5083 assert(firstclique != NULL);
    5084 assert(lastclique != NULL);
    5085 assert(nfixedvars != NULL);
    5086 assert(naggrvars != NULL);
    5087 assert(ndelconss != NULL);
    5088 assert(nchgcoefs != NULL);
    5089 assert(cutoff != NULL);
    5090
    5091 *cutoff = FALSE;
    5092
    5093 if( nconss == 0 )
    5094 return SCIP_OKAY;
    5095
    5096 nvars = SCIPgetNVars(scip);
    5097
    5098 if( nvars == 0 )
    5099 return SCIP_OKAY;
    5100
    5101 susefulvars = 2 * nvars; /* two times because of negated vars, maybe due to deleted variables we need to increase this */
    5102
    5103 /* a hashmap from varindex to postion in varconsidxs array, because above is still too small */
    5104 SCIP_CALL( SCIPhashmapCreate(&vartoindex, SCIPblkmem(scip), nvars) );
    5105
    5106 /* get temporary memory for the aggregation storage, to memorize aggregations which will be performed later, otherwise we would destroy our local data structures */
    5107 saggregations = nvars;
    5108 SCIP_CALL( SCIPallocBufferArray(scip, &undoneaggrvars, 2 * saggregations) );
    5109 SCIP_CALL( SCIPallocBufferArray(scip, &undoneaggrtypes, saggregations) );
    5110 BMSclearMemoryArray(undoneaggrtypes, saggregations);
    5111 naggregations = 0;
    5112
    5113 /* get temporary memory for all clique constraints, all appearing variables and the mapping from variables to constraints */
    5114 SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, nconss) );
    5115 SCIP_CALL( SCIPallocBufferArray(scip, &usefulvars, susefulvars) );
    5116 BMSclearMemoryArray(usefulvars, susefulvars);
    5117 SCIP_CALL( SCIPallocBufferArray(scip, &varnconss, susefulvars + 1) );
    5118 BMSclearMemoryArray(varnconss, susefulvars + 1);
    5119 SCIP_CALL( SCIPallocBufferArray(scip, &maxnvarconsidx, susefulvars + 1) );
    5120 SCIP_CALL( SCIPallocBufferArray(scip, &varconsidxs, susefulvars + 1) );
    5121 BMSclearMemoryArray(varconsidxs, susefulvars + 1);
    5122 nusefulvars = 0;
    5123 nusefulconss = 0;
    5124 maxnvars = 0;
    5125 startndelconss = *ndelconss;
    5126
    5127 /* @todo: check for round limit for adding extra clique constraints */
    5128 /* adding clique constraints which arises from global clique information */
    5129 if( conshdlrdata->nclqpresolve == 0 && conshdlrdata->addvariablesascliques )
    5130 {
    5131 SCIP_VAR** vars = SCIPgetVars(scip);
    5132 SCIP_VAR** binvars;
    5133 int* cliquepartition;
    5134 int ncliques;
    5135 int nbinvars;
    5136 int naddconss;
    5137
    5138 nbinvars = SCIPgetNBinVars(scip);
    5139 SCIP_CALL( SCIPduplicateBufferArray(scip, &binvars, vars, nbinvars) );
    5140 SCIP_CALL( SCIPallocBufferArray(scip, &cliquepartition, nbinvars) );
    5141
    5142 /* @todo: check for better permutations/don't permute the first round
    5143 * @todo: take binary variables which are not of vartype SCIP_VARTYPE_BINARY into account
    5144 */
    5145 SCIPrandomPermuteArray(conshdlrdata->randnumgen, (void**)binvars, 0, nbinvars);
    5146
    5147 /* try to create a clique-partition over all binary variables and create these cliques as new setppc constraints
    5148 * and add them to the usefulconss array and adjust all necessary data this will hopefully lead to faster
    5149 * detection of redundant constraints
    5150 */
    5151 SCIP_CALL( SCIPcalcCliquePartition(scip, binvars, nbinvars, &conshdlrdata->probtoidxmap, &conshdlrdata->probtoidxmapsize, cliquepartition, &ncliques) );
    5152
    5153 /* resize usefulconss array if necessary */
    5154 SCIP_CALL( SCIPreallocBufferArray(scip, &usefulconss, nconss + ncliques) );
    5155
    5156 naddconss = 0;
    5157
    5158 /* add extra clique constraints resulting from the cliquepartition calculation to SCIP and to the local data structure */
    5159 SCIP_CALL( addExtraCliques(scip, binvars, nbinvars, cliquepartition, ncliques, usefulconss, &nusefulconss,
    5160 nrounds, nfixedvars, &naddconss, ndelconss, nchgcoefs, cutoff) );
    5161
    5162 /* bad hack, we don't want to count these artificial created constraints if they got deleted, so ndelconss
    5163 * can become negative which will be change to zero at the end of this method if it's still negative
    5164 */
    5165 *ndelconss -= naddconss;
    5166
    5167 SCIPfreeBufferArray(scip, &cliquepartition);
    5168 SCIPfreeBufferArray(scip, &binvars);
    5169
    5170 if( *cutoff )
    5171 goto TERMINATE;
    5172 }
    5173
    5174 /* start to collect setpartitioning and setpacking constraints, and try to remove fixed variables and merged these
    5175 * constraints
    5176 */
    5177 SCIP_CALL( collectCliqueConss(scip, conss, nconss, usefulconss, &nusefulconss, nfixedvars, ndelconss, nchgcoefs, cutoff) );
    5178 /* @Note: Even after the call above some constraints can have fixed variables, because it might happen that caused by
    5179 * mergeMultiplies some variables were fixed which occurred already in previous constraints
    5180 */
    5181 if( *cutoff )
    5182 goto TERMINATE;
    5183
    5184 /* no usefulconss found */
    5185 if( nusefulconss <= 1 )
    5186 goto TERMINATE;
    5187
    5188 /* @todo: maybe sort them after biggest indices too, or another variant would be to restore the order as they were
    5189 * read in
    5190 */
    5191 /* sort constraints first after type (partitioning before packing) and second after number of variables such that the
    5192 * partitioning constraints have increasing number of variables and the packing constraints have decreasing number of
    5193 * variables, because we loop from back to front we sort them downwards, so they are the other way around
    5194 */
    5195 SCIPsortDownPtr((void**)usefulconss, setppcConssSort, nusefulconss);
    5196
    5197 /* creating all necessary data in array structure, collect all clique constraint variables and occurrences */
    5198 SCIP_CALL( collectCliqueData(scip, usefulconss, nusefulconss, usefulvars, &nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs, &maxnvars) );
    5199 assert(maxnvars > 0);
    5200
    5201 /* allocate temporary memory for actual clique */
    5202 SCIP_CALL( SCIPallocBufferArray(scip, &cliquevalues, maxnvars) );
    5203 /* allocate temporary memory for counting an overlap of variables */
    5204 SCIP_CALL( SCIPallocBufferArray(scip, &countofoverlapping, nusefulconss) );
    5205
    5206 /* sort usefulvars after indices of variables, negated and active counterparts will stand side by side */
    5207 SCIPsortDownPtr((void**)usefulvars, SCIPvarCompActiveAndNegated, nusefulvars);
    5208
    5209 /* extend cliques/constraints by checking whether some variables of a second constraint are in the same clique */
    5210 for( c = nusefulconss - 1; c >= 0 && !SCIPisStopped(scip); --c )
    5211 {
    5212 SCIP_VAR** cons0vars; /* these are the clique variables */
    5213 SCIP_CONS* cons0;
    5214 int ncons0vars;
    5215 SCIP_VAR* var0;
    5216 int v1;
    5217 int nadded; /* number of possible added variables to constraint */
    5218 int cons0fixedzeros;
    5219 int oldnchgcoefs;
    5220#ifndef NDEBUG
    5221 const int oldnaggrvars = *naggrvars;
    5222#endif
    5223 cons0 = usefulconss[c];
    5224
    5225 if( !SCIPconsIsActive(cons0) )
    5226 continue;
    5227
    5228 /* check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
    5229 * possible
    5230 */
    5231 SCIP_CALL( presolvePropagateCons(scip, cons0, FALSE, undoneaggrvars, undoneaggrtypes, &naggregations, &saggregations, nfixedvars, naggrvars, ndelconss, cutoff) );
    5232
    5233 if( *cutoff )
    5234 break;
    5235
    5236 /* we can't handle aggregated variables later on so we should have saved them for later */
    5237 assert(*naggrvars == oldnaggrvars);
    5238
    5239 if( !SCIPconsIsActive(cons0) )
    5240 continue;
    5241
    5242 /* we need to determine the cliquedata in each iteration because we eventual will change it later */
    5243 consdata = SCIPconsGetData(cons0);
    5244 assert(consdata != NULL);
    5245
    5246 cons0vars = consdata->vars;
    5247 ncons0vars = consdata->nvars;
    5248
    5249 /* sorting array after indices of variables, negated and active counterparts will stand side by side */
    5250 SCIPsortDownPtr((void**)cons0vars, SCIPvarCompActiveAndNegated, ncons0vars);
    5251 /* standard setppc-sorting now lost */
    5252 consdata->sorted = FALSE;
    5253
    5254 /* clique array should be long enough */
    5255 assert(maxnvars >= ncons0vars);
    5256
    5257 /* clear old entries in overlapping constraint */
    5258 BMSclearMemoryArray(countofoverlapping, nusefulconss);
    5259
    5260 /* calculate overlapping */
    5261 for( v = ncons0vars - 1; v >= 0 ; --v )
    5262 {
    5263 var0 = cons0vars[v];
    5264
    5265 /* fixed variables later to the count */
    5266 if( SCIPvarGetLbLocal(var0) > 0.5 || SCIPvarGetUbLocal(var0) < 0.5 )
    5267 continue;
    5268
    5269 assert(SCIPhashmapExists(vartoindex, (void*) var0));
    5270
    5271 varindex = SCIPhashmapGetImageInt(vartoindex, (void*) var0);
    5272 for( v1 = varnconss[varindex] - 1; v1 >= 0 ; --v1 )
    5273 ++(countofoverlapping[varconsidxs[varindex][v1]]);
    5274 }
    5275
    5276 oldnchgcoefs = *nchgcoefs;
    5277 cons0fixedzeros = consdata->nfixedzeros;
    5278
    5279 chgcons0 = FALSE;
    5280
    5281 /* check for overlapping constraint before starting lifting */
    5282 SCIP_CALL( checkForOverlapping(scip, cons0, c, c, usefulconss, nusefulconss, usefulvars, &nusefulvars, vartoindex,
    5283 varnconss, maxnvarconsidx, varconsidxs, countofoverlapping, conshdlrdata->cliqueshrinking, &chgcons0,
    5284 undoneaggrvars, undoneaggrtypes, &naggregations, &saggregations,
    5285 nfixedvars, naggrvars, nchgcoefs, ndelconss, cutoff) );
    5286
    5287 if( *cutoff )
    5288 break;
    5289
    5290 /* we can't handle aggregated variables later on so we should have saved them for later */
    5291 assert(*naggrvars == oldnaggrvars);
    5292
    5293 /* if cons0 changed, we need to reorder the variables */
    5294 if( chgcons0 && *nchgcoefs > oldnchgcoefs )
    5295 {
    5296 consdata = SCIPconsGetData(cons0);
    5297 assert(consdata != NULL);
    5298
    5299 cons0vars = consdata->vars;
    5300 ncons0vars = consdata->nvars;
    5301
    5302 /* sorting array after indices of variables, negated and active counterparts will stand side by side */
    5303 SCIPsortDownPtr((void**)cons0vars, SCIPvarCompActiveAndNegated, ncons0vars);
    5304 /* standard setppc-sorting now lost */
    5305 consdata->sorted = FALSE;
    5306 }
    5307
    5308 /* check cons0 again for redundancy/fixings, because due to fixings in all other constraints it might happen that cons0 is redundant now */
    5309 if( consdata->nfixedones > 0 || consdata->nfixedzeros > cons0fixedzeros )
    5310 {
    5311 /* check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
    5312 * possible
    5313 */
    5314 SCIP_CALL( presolvePropagateCons(scip, cons0, FALSE, undoneaggrvars, undoneaggrtypes, &naggregations, &saggregations, nfixedvars, naggrvars, ndelconss, cutoff) );
    5315
    5316 if( *cutoff )
    5317 break;
    5318
    5319 /* we can't handle aggregated variables later on so we should have saved them for later */
    5320 assert(*naggrvars == oldnaggrvars);
    5321
    5322 if( !SCIPconsIsActive(cons0) )
    5323 continue;
    5324 }
    5325
    5326 nadded = 0;
    5327
    5328 /* iterate over the cliques variables and all possible new clique variables at the "same" time, determine starting
    5329 * index
    5330 *
    5331 * @note: it might be better to start the first round with our computed v1, but maybe it's better to switch to
    5332 * trying to add all variables the second time for set packing constraints
    5333 */
    5334
    5335 /* we try to add all variables to the partitioning constraints, to try to fix as much as possible */
    5336 if( consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING ) /*lint !e641*/
    5337 v1 = nusefulvars - 1;
    5338 else
    5339 {
    5340 /* if we already ran a presolving round we want to try to add new variables */
    5341 if( conshdlrdata->nclqpresolve > 0 )
    5342 v1 = nusefulvars - 1;
    5343 else
    5344 {
    5345 /* find start position of variable which we will try to add to our constraint, so we will get better clique constraints */
    5346 (void) SCIPsortedvecFindDownPtr((void**)usefulvars, SCIPvarCompActiveAndNegated, (void*)cons0vars[ncons0vars - 1], nusefulvars, &v1);
    5347 assert(v1 >= 0 && v1 < nusefulvars);
    5348 /* if constraint is not merged and we found a variable which is negated the same as it's neighbour we have to
    5349 * increase v1 to make sure that we don't loose this important variable */
    5350 if( v1 + 1 < nusefulvars && ((SCIPvarIsNegated(usefulvars[v1 + 1]) && SCIPvarGetNegatedVar(usefulvars[v1 + 1]) == usefulvars[v1]) || (SCIPvarIsNegated(usefulvars[v1]) && SCIPvarGetNegatedVar(usefulvars[v1]) == usefulvars[v1 + 1])) )
    5351 ++v1;
    5352 }
    5353 }
    5354
    5355 assert(maxnvars >= ncons0vars);
    5356 /* initialize the cliquevalues array */
    5357 for( v = ncons0vars - 1; v >= 0; --v )
    5358 {
    5359 if( SCIPvarGetLbLocal(cons0vars[v]) < 0.5 && SCIPvarGetUbLocal(cons0vars[v]) > 0.5 )
    5360 {
    5361 /* variable has to be either active or a negated variable of an active one */
    5362 assert(SCIPvarIsActive(cons0vars[v]) || (SCIPvarGetStatus(cons0vars[v]) == SCIP_VARSTATUS_NEGATED &&
    5363 SCIPvarIsActive(SCIPvarGetNegationVar(cons0vars[v]))));
    5364 cliquevalues[v] = SCIPvarIsActive(cons0vars[v]) ? TRUE : FALSE;
    5365 }
    5366 }
    5367
    5368 chgcons0 = FALSE;
    5369
    5370 /* try to lift variables to cons0 */
    5371 SCIP_CALL( liftCliqueVariables(scip, cons0, c, usefulvars, &nusefulvars, v1, &cliquevalues, vartoindex, varnconss,
    5372 maxnvarconsidx, varconsidxs, &maxnvars, &nadded, &chgcons0, nfixedvars, ndelconss, cutoff) );
    5373
    5374 if( *cutoff )
    5375 break;
    5376
    5377 if( !SCIPconsIsActive(cons0) )
    5378 continue;
    5379
    5380 /* check for redundant constraints due to changing cons0 */
    5381 if( chgcons0 )
    5382 {
    5383 int i;
    5384
    5385 *firstchange = MIN(*firstchange, c);
    5386 *firstclique = MIN(*firstclique, c);
    5387 *lastclique = MAX(*lastclique, c);
    5388
    5389 /* variables array has changed due to lifting variables, so get new values */
    5390 assert(consdata == SCIPconsGetData(cons0));
    5391 cons0vars = consdata->vars;
    5392 ncons0vars = consdata->nvars;
    5393
    5394 /* resorting array, because we added new variables, in order of indices of variables, negated
    5395 * and active counterparts would stand side by side
    5396 */
    5397 SCIPsortDownPtr((void**)cons0vars, SCIPvarCompActiveAndNegated, ncons0vars);
    5398 /* standard setppc-sorting now lost */
    5399 consdata->sorted = FALSE;
    5400
    5401 /* clear old entries in overlapping constraint */
    5402 BMSclearMemoryArray(countofoverlapping, nusefulconss);
    5403
    5404 for( v = ncons0vars - 1; v >= 0 ; --v )
    5405 {
    5406 var0 = cons0vars[v];
    5407
    5408 /* fixed variables later to the count */
    5409 if( SCIPvarGetLbLocal(var0) > 0.5 || SCIPvarGetUbLocal(var0) < 0.5 )
    5410 continue;
    5411
    5412 assert(SCIPhashmapExists(vartoindex, (void*) var0));
    5413
    5414 varindex = SCIPhashmapGetImageInt(vartoindex, (void*) var0);
    5415 for( i = varnconss[varindex] - 1; i >= 0 ; --i )
    5416 ++(countofoverlapping[varconsidxs[varindex][i]]);
    5417 }
    5418
    5419 chgcons0 = FALSE;
    5420
    5421 /* check for overlapping constraint after lifting, in the first round we will only check up front */
    5422 SCIP_CALL( checkForOverlapping(scip, cons0, c, (conshdlrdata->nclqpresolve > 0) ? nusefulconss : c,
    5423 usefulconss, nusefulconss, usefulvars, &nusefulvars, vartoindex, varnconss, maxnvarconsidx, varconsidxs,
    5424 countofoverlapping, conshdlrdata->cliqueshrinking, &chgcons0,
    5425 undoneaggrvars, undoneaggrtypes, &naggregations, &saggregations,
    5426 nfixedvars, naggrvars, nchgcoefs, ndelconss, cutoff) );
    5427
    5428 if( *cutoff )
    5429 break;
    5430
    5431 /* we can't handle aggregated variables later on so we should have saved them for later */
    5432 assert(*naggrvars == oldnaggrvars);
    5433 }
    5434 }
    5435
    5436 TERMINATE:
    5437 SCIPfreeBufferArrayNull(scip, &countofoverlapping);
    5438 SCIPfreeBufferArrayNull(scip, &cliquevalues);
    5439
    5440 /* free temporary memory for constraints, variables and the mapping between them in reverse order as they were
    5441 * allocated
    5442 */
    5443 for( c = nusefulvars; c > 0; --c )
    5444 {
    5445 if( varconsidxs[c] != NULL )
    5446 {
    5447 SCIPfreeBufferArrayNull(scip, &(varconsidxs[c]));
    5448 }
    5449 }
    5450
    5451 SCIPfreeBufferArray(scip, &varconsidxs);
    5452 SCIPfreeBufferArray(scip, &maxnvarconsidx);
    5453 SCIPfreeBufferArray(scip, &varnconss);
    5454 SCIPfreeBufferArray(scip, &usefulvars);
    5455 SCIPfreeBufferArray(scip, &usefulconss);
    5456
    5457 /* perform all collected aggregations */
    5458 if( !*cutoff && naggregations > 0 && !SCIPdoNotAggr(scip) )
    5459 {
    5460 SCIP_CALL( performAggregations(scip, conshdlrdata, undoneaggrvars, undoneaggrtypes, naggregations, naggrvars, cutoff) );
    5461 }
    5462
    5463 /* free temporary memory for the aggregation storage */
    5464 SCIPfreeBufferArray(scip, &undoneaggrtypes);
    5465 SCIPfreeBufferArray(scip, &undoneaggrvars);
    5466
    5467 /* free hashmap */
    5468 SCIPhashmapFree(&vartoindex);
    5469
    5470 if( *ndelconss < startndelconss )
    5471 *ndelconss = startndelconss;
    5472
    5473 return SCIP_OKAY;
    5474}
    5475
    5476
    5477/** add cliques to SCIP */
    5478static
    5480 SCIP* scip, /**< SCIP data structure */
    5481 SCIP_CONS** conss, /**< constraint set */
    5482 int nconss, /**< number of constraints in constraint set */
    5483 int firstclique, /**< first constraint to start to add cliques */
    5484 int lastclique, /**< last constraint to start to add cliques */
    5485 int* naddconss, /**< pointer to count number of added constraints */
    5486 int* ndelconss, /**< pointer to count number of deleted constraints */
    5487 int* nchgbds, /**< pointer to count number of changed bounds */
    5488 SCIP_Bool* cutoff /**< pointer to store if the problem is infeasible due to a fixing */
    5489 )
    5490{
    5491 SCIP_CONS* cons;
    5492 SCIP_CONSDATA* consdata;
    5493 SCIP_Bool infeasible;
    5494 int nlocalbdchgs;
    5495 int c;
    5496
    5497 assert(scip != NULL);
    5498 assert(firstclique >= 0);
    5499 assert(lastclique <= nconss);
    5500 assert(conss != NULL || ((nconss == 0) && (lastclique == 0)));
    5501
    5502 /* add clique and implication information */
    5503 for( c = firstclique; c < lastclique; ++c )
    5504 {
    5505 cons = conss[c]; /*lint !e613*/
    5506 assert(cons != NULL);
    5507
    5508 /* ignore deleted constraints */
    5509 if( !SCIPconsIsActive(cons) )
    5510 continue;
    5511
    5512 nlocalbdchgs = 0;
    5513 SCIP_CALL( applyFixings(scip, cons, naddconss, ndelconss, &nlocalbdchgs, cutoff) );
    5514 *nchgbds += nlocalbdchgs;
    5515
    5516 if( *cutoff )
    5517 return SCIP_OKAY;
    5518
    5519 consdata = SCIPconsGetData(cons);
    5520 assert(consdata != NULL);
    5521
    5522 if( SCIPconsIsDeleted(cons) )
    5523 continue;
    5524
    5525 if( !consdata->cliqueadded && consdata->nvars >= 2 )
    5526 {
    5527 /* add a set partitioning / packing constraint as clique */
    5528 if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING || (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING )
    5529 {
    5530 SCIP_CALL( SCIPaddClique(scip, consdata->vars, NULL, consdata->nvars,
    5531 ((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING), &infeasible, &nlocalbdchgs) );
    5532 *nchgbds += nlocalbdchgs;
    5533
    5534 if( infeasible )
    5535 {
    5536 *cutoff = TRUE;
    5537 return SCIP_OKAY;
    5538 }
    5539 }
    5540 else if( consdata->nvars == 2 && !SCIPconsIsModifiable(cons) )
    5541 {
    5542 /* a two-variable set covering constraint x + y >= 1 yields the implication x == 0 -> y == 1 */
    5543 SCIP_CALL( SCIPaddVarImplication(scip, consdata->vars[0], FALSE, consdata->vars[1],
    5544 SCIP_BOUNDTYPE_LOWER, 1.0, &infeasible, &nlocalbdchgs) );
    5545 *nchgbds += nlocalbdchgs;
    5546
    5547 if( infeasible )
    5548 {
    5549 *cutoff = TRUE;
    5550 return SCIP_OKAY;
    5551 }
    5552 }
    5553 consdata->cliqueadded = TRUE;
    5554 }
    5555 }
    5556
    5557 return SCIP_OKAY;
    5558}
    5559
    5560/** perform multi-aggregation on variables resulting from a set-partitioning/-packing constraint */
    5561static
    5563 SCIP* scip, /**< SCIP data structure */
    5564 SCIP_Bool linearconshdlrexist,/**< does the linear constraint handler exist, necessary for multi-aggregations */
    5565 SCIP_VAR** vars, /**< all variables including the variable to which will be multi-aggregated */
    5566 int nvars, /**< number of all variables */
    5567 int pos, /**< position of variable for multi-aggregation */
    5568 SCIP_Bool* infeasible, /**< pointer to store infeasibility status of aggregation */
    5569 SCIP_Bool* aggregated /**< pointer to store aggregation status */
    5570 )
    5571{
    5572 SCIP_VAR** tmpvars;
    5574 int v;
    5575
    5576 assert(scip != NULL);
    5577 assert(vars != NULL);
    5578 assert(nvars >= 1);
    5579 assert(pos >= 0);
    5580 assert(pos < nvars);
    5581 assert(infeasible != NULL);
    5582 assert(aggregated != NULL);
    5583
    5584 if( !linearconshdlrexist && nvars > 2 )
    5585 {
    5586 *infeasible = FALSE;
    5587 *aggregated = FALSE;
    5588
    5589 return SCIP_OKAY;
    5590 }
    5591
    5592 /* if the first variable will be multi-aggregated, we do not need to copy the variables */
    5593 if( pos == 0 )
    5594 tmpvars = vars + 1;
    5595 /* if the last variable will be multi-aggregated, we do not need to copy the variables */
    5596 else if( pos == nvars - 1 )
    5597 tmpvars = vars;
    5598 /* copy variables for aggregation */
    5599 else
    5600 {
    5601 SCIP_CALL( SCIPduplicateBufferArray(scip, &tmpvars, vars, nvars - 1) );
    5602 tmpvars[pos] = vars[nvars - 1];
    5603 }
    5604
    5605 SCIP_CALL( SCIPallocBufferArray(scip, &scalars, nvars - 1) );
    5606
    5607 /* initialize scalars */
    5608 for( v = nvars - 2; v >= 0; --v )
    5609 scalars[v] = -1.0;
    5610
    5611 SCIPdebugMsg(scip, "multi-aggregating binary variable <%s> (locks: [%d,%d]; to %d variables)\n",
    5613 SCIPvarGetNLocksUpType(vars[pos], SCIP_LOCKTYPE_MODEL), nvars - 1);
    5614
    5615 /* perform multi-aggregation */
    5616 SCIP_CALL( SCIPmultiaggregateVar(scip, vars[pos], nvars - 1, tmpvars, scalars, 1.0, infeasible, aggregated) );
    5617 assert(!(*infeasible));
    5618
    5620
    5621 if( pos != 0 && pos != nvars - 1 )
    5622 {
    5623 assert(tmpvars != vars);
    5624 assert(tmpvars != vars + 1);
    5625 SCIPfreeBufferArray(scip, &tmpvars);
    5626 }
    5627
    5628 return SCIP_OKAY;
    5629}
    5630
    5631/** determine singleton variables in set-partitioning/-packing constraints, or doubleton variables (active and negated)
    5632 * in any combination of set-partitioning and set-packing constraints
    5633 *
    5634 * we can multi-aggregate the variable and either change the set-partitioning constraint to a set-packing constraint or
    5635 * even delete it
    5636 *
    5637 * 1. c1: x + y + z = 1, uplocks(x) = 1, downlocks(x) = 1 => x = 1 - y - z and change c1 to y + z <= 1
    5638 *
    5639 * 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
    5640 *
    5641 * 3. d1: x + y + z <= 1 and d2: ~x + u + v <= 1, uplocks(x) = 1, downlocks(x) = 1
    5642 * a) obj(x) <= 0 => x = 1 - y - z and delete d1
    5643 * b) obj(x) > 0 => ~x = 1 - u - v and delete d2
    5644 *
    5645 * 4. e1: x + y + z == 1 and e2: ~x + u + v (<= or ==) 1, uplocks(x) = (1 or 2), downlocks(x) = 2
    5646 * => x = 1 - y - z and delete e1
    5647 *
    5648 * we can also aggregate a variable in a set-packing constraint with only two variables when the uplocks are equal to
    5649 * one and then delete this constraint
    5650 *
    5651 * 5. f1: x + y <= 1, uplocks(x) = 1, obj(x) <= 0 => x = 1 - y and delete f1
    5652 *
    5653 * @todo might want to multi-aggregate variables even with more locks, when the fill in is still smaller or equal to
    5654 * the old number of non-zeros, e.g.
    5655 *
    5656 * x + y + z = 1
    5657 * ~x + u + v <=/= 1
    5658 * ~x + w <= 1
    5659 */
    5660static
    5662 SCIP* scip, /**< SCIP data structure */
    5663 SCIP_CONS** conss, /**< constraint set */
    5664 int nconss, /**< number of constraints in constraint set */
    5665 SCIP_Bool dualpresolvingenabled,/**< is dual presolving enabled */
    5666 SCIP_Bool linearconshdlrexist,/**< does the linear constraint handler exist, necessary for
    5667 * multi-aggregations
    5668 */
    5669 int* nfixedvars, /**< pointer to count number of deleted variables */
    5670 int* naggrvars, /**< pointer to count number of aggregated variables */
    5671 int* ndelconss, /**< pointer to count number of deleted constraints */
    5672 int* nchgcoefs, /**< pointer to count number of changed coefficients */
    5673 int* nchgsides, /**< pointer to count number of changed left hand sides */
    5674 SCIP_Bool* cutoff /**< pointer to store if a cut off was detected */
    5675 )
    5676{
    5677 SCIP_CONS** usefulconss;
    5678 SCIP_VAR** binvars;
    5679 SCIP_HASHMAP* vartoindex;
    5680 SCIP_Bool* chgtype;
    5681 int* considxs;
    5682 int* posincons;
    5683 SCIP_Bool infeasible;
    5684 SCIP_Bool aggregated;
    5685 SCIP_Bool donotaggr;
    5686 SCIP_Bool donotmultaggr;
    5687 SCIP_Bool mustcheck;
    5688 SCIP_Bool addcut;
    5689 int nposvars;
    5690 int ndecs;
    5691 int nbinvars;
    5692 int nposbinvars;
    5693 int nuplocks;
    5694 int ndownlocks;
    5695#ifndef NDEBUG
    5696 int posreplacements = 0;
    5697#endif
    5698 int nhashmapentries;
    5699 int nlocaladdconss;
    5700 int v;
    5701 int c;
    5702
    5703 assert(scip != NULL);
    5704 assert(conss != NULL);
    5705 assert(nconss > 0);
    5706 assert(nfixedvars != NULL);
    5707 assert(naggrvars != NULL);
    5708 assert(ndelconss != NULL);
    5709 assert(nchgcoefs != NULL);
    5710 assert(nchgsides != NULL);
    5711
    5712 nbinvars = SCIPgetNBinVars(scip);
    5713 nposbinvars = SCIPgetNVars(scip) - SCIPgetNContVars(scip);
    5714 assert(nbinvars + SCIPgetNIntVars(scip) + SCIPgetNImplVars(scip) == nposbinvars);
    5715
    5716 binvars = SCIPgetVars(scip);
    5717
    5718 /* determine number for possible multi-aggregations */
    5719 nposvars = 0;
    5720 for( v = nposbinvars - 1; v >= 0; --v )
    5721 {
    5722 assert(SCIPvarIsIntegral(binvars[v]));
    5723
    5724 if( v < nbinvars || SCIPvarIsBinary(binvars[v]) )
    5725 {
    5726 nuplocks = SCIPvarGetNLocksUpType(binvars[v], SCIP_LOCKTYPE_MODEL);
    5727 ndownlocks = SCIPvarGetNLocksDownType(binvars[v], SCIP_LOCKTYPE_MODEL);
    5728
    5729 if( (nuplocks == 1 && ndownlocks <= 1) || (nuplocks <= 1 && ndownlocks == 1) || (nuplocks <= 2 && ndownlocks <= 2 && SCIPvarGetNegatedVar(binvars[v]) != NULL) )
    5730 ++nposvars;
    5731 }
    5732 }
    5733
    5734 SCIPdebugMsg(scip, "found %d binary variables for possible multi-aggregation\n", nposvars);
    5735
    5736 if( nposvars == 0 )
    5737 return SCIP_OKAY;
    5738
    5739 /* a hashmap from var to index when found in a set-partitioning constraint */
    5740 SCIP_CALL( SCIPhashmapCreate(&vartoindex, SCIPblkmem(scip), nposvars) );
    5741
    5742 /* get temporary memory */
    5743 SCIP_CALL( SCIPallocBufferArray(scip, &chgtype, nconss) );
    5744 BMSclearMemoryArray(chgtype, nconss);
    5745
    5746 SCIP_CALL( SCIPallocBufferArray(scip, &considxs, nposbinvars) );
    5747 SCIP_CALL( SCIPallocBufferArray(scip, &posincons, nposbinvars) );
    5748
    5749 SCIP_CALL( SCIPduplicateBufferArray(scip, &usefulconss, conss, nconss) );
    5750 /* sort constraints */
    5751 SCIPsortPtr((void**)usefulconss, setppcConssSort2, nconss);
    5752
    5753 nhashmapentries = 0;
    5754 ndecs = 0;
    5755 donotaggr = SCIPdoNotAggr(scip);
    5756 donotmultaggr = SCIPdoNotMultaggr(scip);
    5757 assert(!donotaggr || !donotmultaggr);
    5758
    5759 /* determine singleton variables in set-partitioning/-packing constraints, or doubleton variables (active and
    5760 * negated) in any combination of set-partitioning and set-packing constraints
    5761 *
    5762 * we can multi-aggregate the variable and either change the set-partitioning constraint to a set-packing constraint
    5763 * or even delete it
    5764 */
    5765 for( c = 0; c < nconss; ++c )
    5766 {
    5767 SCIP_CONS* cons;
    5768 SCIP_CONSDATA* consdata;
    5769 SCIP_CONSDATA* aggrconsdata;
    5770 int oldnfixedvars;
    5771 int aggrconsindex;
    5772 int aggrallyindex;
    5773 nlocaladdconss = 0;
    5774
    5775 cons = usefulconss[c];
    5776 assert(cons != NULL);
    5777
    5778 if( SCIPconsIsDeleted(cons) )
    5779 continue;
    5780
    5781 consdata = SCIPconsGetData(cons);
    5782 assert(consdata != NULL);
    5783
    5784 /* if we cannot find any constraint to perform a useful multi-aggregation, stop */
    5785 if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_COVERING )
    5786 break;
    5787
    5788 if( !SCIPconsIsChecked(cons) )
    5789 continue;
    5790
    5791 if( SCIPconsIsModifiable(cons) )
    5792 continue;
    5793
    5794 /* update the variables */
    5795 SCIP_CALL( applyFixings(scip, cons, &nlocaladdconss, ndelconss, nfixedvars, cutoff) );
    5796
    5797 if( *cutoff )
    5798 break;
    5799
    5800 /* due to resolving multi-aggregations a constraint can become deleted */
    5801 if( SCIPconsIsDeleted(cons) )
    5802 continue;
    5803
    5804 SCIP_CALL( processFixings(scip, cons, cutoff, nfixedvars, &addcut, &mustcheck) );
    5805 assert(!addcut);
    5806
    5807 if( *cutoff )
    5808 break;
    5809
    5810 if( SCIPconsIsDeleted(cons) )
    5811 continue;
    5812
    5813 oldnfixedvars = *nfixedvars;
    5814
    5815 /* merging unmerged constraints */
    5816 SCIP_CALL( mergeMultiples(scip, cons, nfixedvars, ndelconss, nchgcoefs, cutoff) );
    5817
    5818 if( *cutoff )
    5819 break;
    5820
    5821 if( SCIPconsIsDeleted(cons) )
    5822 continue;
    5823
    5824 if( oldnfixedvars < *nfixedvars )
    5825 {
    5826 /* update the variables */
    5827 SCIP_CALL( applyFixings(scip, cons, &nlocaladdconss, ndelconss, nfixedvars, cutoff) );
    5828 assert(!SCIPconsIsDeleted(cons));
    5829 assert(nlocaladdconss == 0);
    5830 assert(!*cutoff);
    5831
    5832 if( SCIPconsIsDeleted(cons) )
    5833 continue;
    5834 }
    5835
    5836 /* if the constraint was not merged and consists of a variable with its negation, the constraint is redundant */
    5837 if( consdata->nvars < 2 )
    5838 {
    5839 /* deleting redundant set-packing constraint */
    5840 if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING )
    5841 {
    5842 SCIPdebugMsg(scip, "deleting redundant set-packing constraint <%s>\n", SCIPconsGetName(cons));
    5843
    5844 SCIP_CALL( SCIPdelCons(scip, cons) );
    5845 ++(*ndelconss);
    5846
    5847 continue;
    5848 }
    5849 else
    5850 {
    5851 SCIP_Bool fixed;
    5852
    5853 assert((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING);
    5854
    5855 if( consdata->nvars == 0 )
    5856 {
    5857 SCIPdebugMsg(scip, "empty set partition constraint <%s> led to infeasibility\n", SCIPconsGetName(cons));
    5858
    5859 *cutoff = TRUE;
    5860 break;
    5861 }
    5862
    5863 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));
    5864
    5865 SCIP_CALL( SCIPfixVar(scip, consdata->vars[0], 1.0, &infeasible, &fixed) );
    5866 assert(!infeasible);
    5867
    5868 if( fixed )
    5869 ++(*nfixedvars);
    5870
    5871 assert(SCIPvarGetLbGlobal(consdata->vars[0]) > 0.5);
    5872
    5873 SCIPdebugMsg(scip, "deleting redundant set-partition constraint <%s>\n", SCIPconsGetName(cons));
    5874
    5875 SCIP_CALL( SCIPdelCons(scip, cons) );
    5876 ++(*ndelconss);
    5877
    5878 continue;
    5879 }
    5880 }
    5881
    5882 /* perform dualpresolve on set-packing constraints with exactly two variables */
    5883 if( !donotaggr && consdata->nvars == 2 && dualpresolvingenabled && (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING )
    5884 {
    5885 SCIP_VAR* var;
    5886 SCIP_Real objval;
    5887 SCIP_Bool redundant;
    5888
    5889 var = consdata->vars[0];
    5890 assert(var != NULL);
    5892
    5893 SCIP_CALL( SCIPvarGetAggregatedObj(var, &objval) );
    5894
    5896
    5897 if( nuplocks == 1 && objval <= 0 )
    5898 {
    5899 /* perform aggregation on variables resulting from a set-packing constraint */
    5900 SCIP_CALL( SCIPaggregateVars(scip, var, consdata->vars[1], 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
    5901
    5902 if( infeasible )
    5903 {
    5904 *cutoff = TRUE;
    5905 break;
    5906 }
    5907
    5908 if( aggregated )
    5909 {
    5910 SCIPdebugMsg(scip, "dualpresolve, aggregated %s + %s = 1, in set-packing constraint %s\n", SCIPvarGetName(var), SCIPvarGetName(consdata->vars[1]), SCIPconsGetName(cons));
    5911 ++(*naggrvars);
    5912
    5913 SCIP_CALL( SCIPdelCons(scip, cons) );
    5914 ++(*ndelconss);
    5915 }
    5916
    5917 continue;
    5918 }
    5919 else
    5920 {
    5921 var = consdata->vars[1];
    5922 assert(var != NULL);
    5924
    5925 SCIP_CALL( SCIPvarGetAggregatedObj(var, &objval) );
    5926
    5928
    5929 if( nuplocks == 1 && objval <= 0 )
    5930 {
    5931 /* perform aggregation on variables resulting from a set-packing constraint */
    5932 SCIP_CALL( SCIPaggregateVars(scip, var, consdata->vars[0], 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
    5933
    5934 if( infeasible )
    5935 {
    5936 *cutoff = TRUE;
    5937 break;
    5938 }
    5939
    5940 if( aggregated )
    5941 {
    5942 SCIPdebugMsg(scip, "dualpresolve, aggregated %s + %s = 1, in set-packing constraint %s\n", SCIPvarGetName(var), SCIPvarGetName(consdata->vars[0]), SCIPconsGetName(cons));
    5943 ++(*naggrvars);
    5944
    5945 SCIP_CALL( SCIPdelCons(scip, cons) );
    5946 ++(*ndelconss);
    5947 }
    5948
    5949 continue;
    5950 }
    5951 }
    5952 }
    5953 else if( !donotaggr && consdata->nvars == 2 && (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING )
    5954 {
    5955 SCIP_Bool redundant;
    5956
    5957 /* perform aggregation on variables resulting from a set-partitioning constraint */
    5958 SCIP_CALL( SCIPaggregateVars(scip, consdata->vars[0], consdata->vars[1], 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
    5959
    5960 if( infeasible )
    5961 {
    5962 *cutoff = TRUE;
    5963 break;
    5964 }
    5965
    5966 if( aggregated )
    5967 {
    5968 SCIPdebugMsg(scip, "aggregated %s + %s = 1, in set-partition constraint %s\n", SCIPvarGetName(consdata->vars[0]), SCIPvarGetName(consdata->vars[1]), SCIPconsGetName(cons));
    5969 ++(*naggrvars);
    5970
    5971 SCIP_CALL( SCIPdelCons(scip, cons) );
    5972 ++(*ndelconss);
    5973 }
    5974
    5975 continue;
    5976 }
    5977
    5978 /* we already found all possible variables for multi-aggregation */
    5979 if( ndecs >= nposvars )
    5980 continue;
    5981
    5982 /* no multi aggregation is allowed, so we can continue */
    5983 if( donotmultaggr )
    5984 continue;
    5985
    5986 /* if the following condition does not hold, we have an unmerged constraint, and we might need to merge it first */
    5987 assert(nposbinvars >= consdata->nvars);
    5988
    5989 /* reset aggregation information */
    5990 aggregated = FALSE;
    5991 aggrconsindex = -1;
    5992 aggrallyindex = -1;
    5993
    5994 /* search for possible variables for multi-aggregation */
    5995 for( v = consdata->nvars - 1; v >= 0; --v )
    5996 {
    5997 SCIP_VAR* var = consdata->vars[v];
    5998
    5999 assert(var != NULL);
    6001 assert(!SCIPconsIsDeleted(cons));
    6002
    6005 assert(nuplocks >= 1 && ndownlocks >= 0); /* we are only treating set partitioning and set packing constraints, so every variable in there should have an uplock */
    6006
    6007 if( dualpresolvingenabled && (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING && nuplocks <= 1 && nuplocks + ndownlocks <= 2 )
    6008 {
    6009 assert(nuplocks == 1 && ndownlocks <= 1);
    6010
    6011 /* we found a redundant variable in a set-partitioning constraint */
    6012 if( ndownlocks == 0 )
    6013 {
    6014 SCIP_Real objval;
    6015 SCIP_Bool fixed;
    6016
    6017 SCIP_CALL( SCIPvarGetAggregatedObj(var, &objval) );
    6018
    6019 ++ndecs;
    6020
    6021 /* if the objective value is >= 0 the fixing is normally done by the dualfix presolver */
    6022 if( !SCIPisNegative(scip, objval) )
    6023 {
    6024 SCIPdebugMsg(scip, "dual-fixing of variable <%s> to 0.0\n", SCIPvarGetName(var));
    6025
    6026 SCIP_CALL( SCIPfixVar(scip, var, 0.0, &infeasible, &fixed) );
    6027 assert(!infeasible);
    6028 assert(fixed);
    6029
    6030 ++(*nfixedvars);
    6031 }
    6032 else
    6033 {
    6034 SCIPdebugMsg(scip, "multi-aggregating in set-packing constraint\n");
    6035
    6036 /* perform aggregation on variables resulting from a set-packing constraint */
    6037 SCIP_CALL( multiAggregateBinvar(scip, linearconshdlrexist, consdata->vars, consdata->nvars, v, &infeasible, &fixed) );
    6038
    6039 if( infeasible )
    6040 {
    6041 *cutoff = TRUE;
    6042 break;
    6043 }
    6044
    6045 if( fixed )
    6046 {
    6047 ++(*naggrvars);
    6048
    6049 SCIP_CALL( delCoefPos(scip, cons, v) );
    6050 ++(*nchgcoefs);
    6051 }
    6052 }
    6053 }
    6054 else if( ndownlocks == 1 && SCIPvarGetNegatedVar(var) != NULL )
    6055 {
    6056 SCIP_VAR* negvar = SCIPvarGetNegatedVar(var);
    6057 SCIP_VAR* activevar;
    6058 SCIP_Real objval;
    6059 int multaggridx;
    6060 int image;
    6061 int consindex;
    6062 int varindex;
    6063
    6064 assert(!SCIPhashmapExists(vartoindex, (void*) var));
    6065
    6066 /* if we found a new variable add it to the data */
    6067 if( !SCIPhashmapExists(vartoindex, (void*) negvar) )
    6068 {
    6069 ++nhashmapentries;
    6070 SCIP_CALL( SCIPhashmapInsertInt(vartoindex, (void*) var, nhashmapentries) );
    6071
    6072 considxs[nhashmapentries - 1] = c;
    6073 posincons[nhashmapentries - 1] = v;
    6074
    6075#ifndef NDEBUG
    6076 ++posreplacements;
    6077#endif
    6078 continue;
    6079 }
    6080
    6081 assert(SCIPhashmapExists(vartoindex, (void*) negvar));
    6082 image = SCIPhashmapGetImageInt(vartoindex, (void*) negvar);
    6083 assert(image > 0 && image <= nhashmapentries);
    6084
    6085 consindex = considxs[image - 1];
    6086 assert(0 <= consindex && consindex < nconss);
    6087
    6088 /* if the following assert fails, the constraint was not merged, or something really strange happened */
    6089 assert(consindex < c);
    6090
    6091 ++ndecs;
    6092#ifndef NDEBUG
    6093 --posreplacements;
    6094#endif
    6095 assert(posreplacements >= 0);
    6096
    6097 varindex = posincons[image - 1];
    6098 considxs[image - 1] = -1;
    6099 posincons[image - 1] = -1;
    6100 SCIP_CALL( SCIPhashmapRemove(vartoindex, (void*) negvar) );
    6101
    6102 /* this constraint can already be required for a multi-aggregation or the other constraint removed */
    6103 if( aggregated || SCIPconsIsDeleted(usefulconss[consindex]) )
    6104 continue;
    6105
    6106 aggrconsdata = SCIPconsGetData(usefulconss[consindex]);
    6107 assert(aggrconsdata != NULL);
    6108 assert((SCIP_SETPPCTYPE)aggrconsdata->setppctype == SCIP_SETPPCTYPE_PACKING);
    6109
    6110 /* determine active variable and constraint that corresponds to */
    6112 {
    6113 activevar = negvar;
    6114 multaggridx = consindex;
    6115 }
    6116 else
    6117 {
    6118 activevar = var;
    6119 multaggridx = c;
    6120 }
    6121 objval = SCIPvarGetObj(activevar);
    6122
    6123 SCIPdebugMsg(scip, "multi-aggregating in two set-packing constraint\n");
    6124
    6125 /* perform aggregation on variables resulting from a set-packing constraint */
    6126 if( (objval < 0.0) == (multaggridx == c) )
    6127 {
    6128 SCIP_CALL( multiAggregateBinvar(scip, linearconshdlrexist, consdata->vars, consdata->nvars, v, &infeasible, &aggregated) );
    6129 aggrconsindex = c;
    6130 aggrallyindex = consindex;
    6131 }
    6132 else
    6133 {
    6134 /* we need to find the variable again if other multi-aggregations invalidated the position */
    6135 assert(varindex >= 0);
    6136 if( varindex >= aggrconsdata->nvars || aggrconsdata->vars[varindex] != negvar )
    6137 {
    6138 int v2;
    6139
    6140 /* if the following assert is raised, then the constraint is redundant and we do not need to aggregate
    6141 * anymore and can delete this constraint
    6142 */
    6143 assert(aggrconsdata->nvars >= 2);
    6144
    6145 for( v2 = aggrconsdata->nvars - 1; v2 >= 0; --v2 )
    6146 {
    6147 if( aggrconsdata->vars[v2] == negvar )
    6148 break;
    6149 }
    6150 assert(v2 >= 0);
    6151
    6152 varindex = v2;
    6153 }
    6154 assert(varindex >= 0);
    6155 assert(varindex < aggrconsdata->nvars);
    6156 assert(aggrconsdata->vars[varindex] == negvar);
    6157
    6158 SCIP_CALL( multiAggregateBinvar(scip, linearconshdlrexist, aggrconsdata->vars, aggrconsdata->nvars, varindex, &infeasible, &aggregated) );
    6159 aggrconsindex = consindex;
    6160 aggrallyindex = c;
    6161 }
    6162
    6163 if( infeasible )
    6164 {
    6165 *cutoff = TRUE;
    6166 break;
    6167 }
    6168 }
    6169 }
    6170 /* we found a redundant variable in a set-partitioning constraint */
    6171 else if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING && nuplocks == 1 && ndownlocks == 1 )
    6172 {
    6173 /* this constraint can already be required for a multi-aggregation */
    6174 if( aggregated )
    6175 continue;
    6176
    6177 SCIPdebugMsg(scip, "multi-aggregating in set-partitioning constraint\n");
    6178
    6179 /* perform aggregation on variables resulting from a set-partitioning constraint */
    6180 SCIP_CALL( multiAggregateBinvar(scip, linearconshdlrexist, consdata->vars, consdata->nvars, v, &infeasible, &aggregated) );
    6181
    6182 ++ndecs;
    6183
    6184 if( infeasible )
    6185 {
    6186 *cutoff = TRUE;
    6187 break;
    6188 }
    6189
    6190 if( aggregated )
    6191 {
    6192 ++(*naggrvars);
    6193
    6194 SCIP_CALL( delCoefPos(scip, cons, v) );
    6195 ++(*nchgcoefs);
    6196
    6197 SCIPdebugMsg(scip, "changing constraint <%s> from set-partitioning to set-packing, due to multi-aggregation\n", SCIPconsGetName(cons));
    6198
    6200 ++(*nchgsides);
    6201 chgtype[c] = TRUE;
    6202
    6203 aggregated = FALSE;
    6204 break;
    6205 }
    6206 }
    6207 /* we might have found a redundant variable */
    6208 else if( ndownlocks <= 2 && nuplocks <= 2 && SCIPvarGetNegatedVar(var) != NULL )
    6209 {
    6210 SCIP_VAR* negvar = SCIPvarGetNegatedVar(var);
    6211 int image;
    6212 int consindex;
    6213 int varindex;
    6214
    6215 /* if we have two times the same variable in a set-partitioning constraint, we cannot aggregate this */
    6216 if( SCIPhashmapExists(vartoindex, (void*) var) )
    6217 {
    6218 image = SCIPhashmapGetImageInt(vartoindex, (void*) var);
    6219 assert(image > 0 && image <= nhashmapentries);
    6220
    6221 assert(0 <= considxs[image - 1] && considxs[image - 1] < nconss);
    6222 assert(SCIPconsIsDeleted(usefulconss[considxs[image - 1]]) || chgtype[considxs[image - 1]] || (0 <= posincons[image - 1] && posincons[image - 1] < SCIPconsGetData(usefulconss[considxs[image - 1]])->nvars));
    6223
    6224 considxs[image - 1] = -1;
    6225 posincons[image - 1] = -1;
    6226
    6227 SCIP_CALL( SCIPhashmapRemove(vartoindex, (void*) var) );
    6228
    6229#ifndef NDEBUG
    6230 --posreplacements;
    6231#endif
    6232 assert(posreplacements >= 0);
    6233
    6234 continue;
    6235 }
    6236 else if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING )
    6237 {
    6238 /* if we found a new variable add it to the data */
    6239 if( !SCIPhashmapExists(vartoindex, (void*) negvar) )
    6240 {
    6241 assert(!SCIPhashmapExists(vartoindex, (void*) var));
    6242
    6243 ++nhashmapentries;
    6244 SCIP_CALL( SCIPhashmapInsertInt(vartoindex, (void*) var, nhashmapentries) );
    6245
    6246 considxs[nhashmapentries - 1] = c;
    6247 posincons[nhashmapentries - 1] = v;
    6248
    6249#ifndef NDEBUG
    6250 ++posreplacements;
    6251#endif
    6252 continue;
    6253 }
    6254 }
    6255 else
    6256 {
    6257 assert((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING);
    6258
    6259 /* if the negated variable occurs in an additional packing constraint,
    6260 * then we are no longer in a doubleton or singleton case;
    6261 * this case of two packing and one partitioning constraint (thus,
    6262 * 2 down- and 2 uplocks) cannot be handled by this routine, so the
    6263 * variable cannot be aggregated, see also #3752 and !3832;
    6264 * this situation is characterized by having 2 downlocks (one from the
    6265 * partitioning constraint, one from the negated variable in the other
    6266 * packing constraint; the current packing constraint (cons) does not
    6267 * contribute a downlock)
    6268 */
    6269 if( ndownlocks >= 2 )
    6270 continue;
    6271
    6272 /* if the negated variable did not occur in a set partitioning constraint
    6273 * (those will be iterated over first), we cannot aggregate this variable
    6274 */
    6275 if( !SCIPhashmapExists(vartoindex, (void*) negvar) )
    6276 continue;
    6277 }
    6278
    6279 assert(!chgtype[c]);
    6280 assert(SCIPhashmapExists(vartoindex, (void*) negvar));
    6281 image = SCIPhashmapGetImageInt(vartoindex, (void*) negvar);
    6282 assert(image > 0 && image <= nhashmapentries);
    6283
    6284 consindex = considxs[image - 1];
    6285 assert(0 <= consindex && consindex < nconss);
    6286
    6287 /* if the following assert fails, the constraint was not merged, or something really strange happened */
    6288 assert(consindex < c);
    6289
    6290 ++ndecs;
    6291#ifndef NDEBUG
    6292 --posreplacements;
    6293#endif
    6294 assert(posreplacements >= 0);
    6295
    6296 varindex = posincons[image - 1];
    6297 considxs[image - 1] = -1;
    6298 posincons[image - 1] = -1;
    6299 SCIP_CALL( SCIPhashmapRemove(vartoindex, (void*) negvar) );
    6300
    6301 /* this constraint can already be required for a multi-aggregation or the other constraint removed */
    6302 if( aggregated || SCIPconsIsDeleted(usefulconss[consindex]) )
    6303 continue;
    6304
    6305 aggrconsdata = SCIPconsGetData(usefulconss[consindex]);
    6306 assert(aggrconsdata != NULL);
    6307
    6308 /* must not multi-aggregate variables that are locked more then twice by all setppc constraints */
    6309 if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PACKING &&
    6310 (SCIP_SETPPCTYPE)aggrconsdata->setppctype == SCIP_SETPPCTYPE_PACKING )
    6311 {
    6312 assert(!dualpresolvingenabled || nuplocks + ndownlocks > 2);
    6313 continue;
    6314 }
    6315
    6316 assert((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING ||
    6317 (SCIP_SETPPCTYPE)aggrconsdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING);
    6318
    6319 /* perform aggregation on variables resulting from a set-partitioning constraint */
    6320 if( chgtype[consindex] )
    6321 {
    6322#ifndef NDEBUG
    6323 int v2;
    6324
    6325 assert((SCIP_SETPPCTYPE)aggrconsdata->setppctype == SCIP_SETPPCTYPE_PACKING);
    6326
    6327 /* negated variables needs to be still in the upgraded set-packing constraint */
    6328 for( v2 = aggrconsdata->nvars - 1; v2 >= 0; --v2 )
    6329 {
    6330 if( aggrconsdata->vars[v2] == negvar )
    6331 break;
    6332 }
    6333 assert(v2 >= 0);
    6334#endif
    6335 assert((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING);
    6336
    6337 SCIPdebugMsg(scip, "multi-aggregating in one set-partitioning or one set-packing constraint\n");
    6338
    6339 SCIP_CALL( multiAggregateBinvar(scip, linearconshdlrexist, consdata->vars, consdata->nvars, v, &infeasible, &aggregated) );
    6340 aggrconsindex = c;
    6341 aggrallyindex = consindex;
    6342 }
    6343 else
    6344 {
    6345 /* @note it might have happened that we have a variable at hand which exists actually in a set-packing
    6346 * constraint and due to some other aggregation we increased the number of locks and reached this
    6347 * part of the code, where we would expect only set-partitioning constraints in general, so in
    6348 * such a strange case we cannot aggregate anything
    6349 */
    6350 if( (SCIP_SETPPCTYPE)aggrconsdata->setppctype != SCIP_SETPPCTYPE_PARTITIONING )
    6351 continue;
    6352
    6353 SCIPdebugMsg(scip, "multi-aggregating in two set-partitioning or one set-partitioning and -packing constraint\n");
    6354
    6355 /* we need to find the variable again if other multi-aggregations invalidated the position */
    6356 assert(varindex >= 0);
    6357 if( varindex >= aggrconsdata->nvars || aggrconsdata->vars[varindex] != negvar )
    6358 {
    6359 int v2;
    6360
    6361 /* if the following assert is raised, then the constraint is redundant and we do not need to aggregate
    6362 * anymore and can delete this constraint
    6363 */
    6364 assert(aggrconsdata->nvars >= 2);
    6365
    6366 for( v2 = aggrconsdata->nvars - 1; v2 >= 0; --v2 )
    6367 {
    6368 if( aggrconsdata->vars[v2] == negvar )
    6369 break;
    6370 }
    6371 assert(v2 >= 0);
    6372
    6373 varindex = v2;
    6374 }
    6375 assert(varindex >= 0);
    6376 assert(varindex < aggrconsdata->nvars);
    6377 assert(aggrconsdata->vars[varindex] == negvar);
    6378
    6379 SCIP_CALL( multiAggregateBinvar(scip, linearconshdlrexist, aggrconsdata->vars, aggrconsdata->nvars, varindex, &infeasible, &aggregated) );
    6380 aggrconsindex = consindex;
    6381 aggrallyindex = c;
    6382 }
    6383
    6384 if( infeasible )
    6385 {
    6386 *cutoff = TRUE;
    6387 break;
    6388 }
    6389 }
    6390 }
    6391
    6392 if( *cutoff )
    6393 break;
    6394
    6395 if( aggregated )
    6396 {
    6397 ++(*naggrvars);
    6398
    6399 assert(aggrconsindex >= 0);
    6400 assert(aggrconsindex <= c);
    6401 assert(aggrallyindex >= 0);
    6402 assert(aggrallyindex <= c);
    6403 cons = usefulconss[aggrallyindex];
    6404
    6405 /* update the variables */
    6406 SCIP_CALL( applyFixings(scip, cons, &nlocaladdconss, ndelconss, nfixedvars, cutoff) );
    6407
    6408 if( *cutoff )
    6409 break;
    6410
    6411 /* merging unmerged constraints */
    6412 SCIP_CALL( mergeMultiples(scip, cons, nfixedvars, ndelconss, nchgcoefs, cutoff) );
    6413
    6414 if( *cutoff )
    6415 break;
    6416
    6417 /* update hashmap information */
    6418 if( !SCIPconsIsDeleted(cons) )
    6419 {
    6420 aggrconsdata = SCIPconsGetData(usefulconss[aggrconsindex]);
    6421 assert(aggrconsdata != NULL);
    6422
    6423 for( v = aggrconsdata->nvars - 1; v >= 0; --v )
    6424 {
    6425 SCIP_VAR* var = aggrconsdata->vars[v];
    6426
    6427 if( SCIPhashmapExists(vartoindex, (void*)var) )
    6428 {
    6429 /* variable moved to ally constraint to unknown value position */
    6430 int image = SCIPhashmapGetImageInt(vartoindex, (void*)var);
    6431 considxs[image - 1] = aggrallyindex;
    6432 posincons[image - 1] = 0;
    6433 }
    6434 }
    6435 }
    6436
    6437 SCIPdebugMsg(scip, "deleting redundant constraint <%s>, due to multi-aggregation\n", SCIPconsGetName(usefulconss[aggrconsindex]));
    6438 SCIPdebugPrintCons(scip, usefulconss[aggrconsindex], NULL);
    6439
    6440 assert(!SCIPconsIsDeleted(usefulconss[aggrconsindex]));
    6441 SCIP_CALL( SCIPdelCons(scip, usefulconss[aggrconsindex]) );
    6442 ++(*ndelconss);
    6443 }
    6444 }
    6445
    6446 /* free temporary memory */
    6447 SCIPfreeBufferArray(scip, &usefulconss);
    6448 SCIPfreeBufferArray(scip, &posincons);
    6449 SCIPfreeBufferArray(scip, &considxs);
    6450 SCIPfreeBufferArray(scip, &chgtype);
    6451
    6452 /* free hashmap */
    6453 SCIPhashmapFree(&vartoindex);
    6454
    6455 return SCIP_OKAY;
    6456}
    6457
    6458
    6459/** compares each constraint with all other constraints for possible redundancy and removes or changes constraint
    6460 * accordingly; in contrast to removeRedundantConstraints(), it uses a hash table
    6461 */
    6462static
    6464 SCIP* scip, /**< SCIP data structure */
    6465 BMS_BLKMEM* blkmem, /**< block memory */
    6466 SCIP_CONS** conss, /**< constraint set */
    6467 int nconss, /**< number of constraints in constraint set */
    6468 int* firstchange, /**< pointer to store first changed constraint */
    6469 int* ndelconss, /**< pointer to count number of deleted constraints */
    6470 int* nchgsides /**< pointer to count number of changed left/right hand sides */
    6471 )
    6472{
    6473 SCIP_HASHTABLE* hashtable;
    6474 int hashtablesize;
    6475 int c;
    6476
    6477 assert(scip != NULL);
    6478 assert(blkmem != NULL);
    6479 assert(conss != NULL || nconss == 0);
    6480 assert(firstchange != NULL);
    6481 assert(ndelconss != NULL);
    6482 assert(nchgsides != NULL);
    6483
    6484 if( nconss == 0 )
    6485 return SCIP_OKAY;
    6486
    6487 assert(conss != NULL);
    6488
    6489 /* create a hash table for the constraint set */
    6490 hashtablesize = nconss;
    6491 hashtablesize = MAX(hashtablesize, HASHSIZE_SETPPCCONS);
    6492 SCIP_CALL( SCIPhashtableCreate(&hashtable, blkmem, hashtablesize,
    6493 hashGetKeySetppccons, hashKeyEqSetppccons, hashKeyValSetppccons, (void*) scip) );
    6494
    6495 /* check all constraints in the given set for redundancy */
    6496 for( c = 0; c < nconss; ++c )
    6497 {
    6498 SCIP_CONS* cons0;
    6499 SCIP_CONS* cons1;
    6500
    6501 cons0 = conss[c];
    6502
    6503 if( !SCIPconsIsActive(cons0) || SCIPconsIsModifiable(cons0) )
    6504 continue;
    6505
    6506 /* get constraint from current hash table with same variables as cons0 and with coefficients either equal or negated
    6507 * to the ones of cons0 */
    6508 cons1 = (SCIP_CONS*)(SCIPhashtableRetrieve(hashtable, (void*)cons0));
    6509
    6510 if( cons1 != NULL )
    6511 {
    6512 SCIP_CONSDATA* consdata0;
    6513 SCIP_CONSDATA* consdata1;
    6514
    6515 assert(SCIPconsIsActive(cons1));
    6516 assert(!SCIPconsIsModifiable(cons1));
    6517
    6518 /* constraint found: create a new constraint with same coefficients and best left and right hand side;
    6519 * delete old constraints afterwards
    6520 */
    6521 consdata0 = SCIPconsGetData(cons0);
    6522 consdata1 = SCIPconsGetData(cons1);
    6523
    6524 assert(consdata0 != NULL && consdata1 != NULL);
    6525 assert(consdata0->nvars >= 1 && consdata0->nvars == consdata1->nvars);
    6526
    6527 assert(consdata0->sorted && consdata1->sorted);
    6528 assert(consdata0->vars[0] == consdata1->vars[0]);
    6529
    6530 SCIPdebugMsg(scip, "setppc constraints <%s> and <%s> have identical variable sets\n",
    6531 SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    6532 SCIPdebugPrintCons(scip, cons0, NULL);
    6533 SCIPdebugPrintCons(scip, cons1, NULL);
    6534
    6535 /* if necessary change type of setppc constraint */
    6536 if( consdata1->setppctype != SCIP_SETPPCTYPE_PARTITIONING && consdata0->setppctype != consdata1->setppctype ) /*lint !e641*/
    6537 {
    6538 /* change the type of cons0 */
    6540 (*nchgsides)++;
    6541 }
    6542
    6543 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    6544 /* coverity[swapped_arguments] */
    6545 SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
    6546
    6547 /* delete cons0 */
    6548 SCIP_CALL( SCIPdelCons(scip, cons0) );
    6549 (*ndelconss)++;
    6550
    6551 /* update the first changed constraint to begin the next aggregation round with */
    6552 if( consdata0->changed && SCIPconsGetPos(cons1) < *firstchange )
    6553 *firstchange = SCIPconsGetPos(cons1);
    6554
    6555 assert(SCIPconsIsActive(cons1));
    6556 }
    6557 else
    6558 {
    6559 /* no such constraint in current hash table: insert cons0 into hash table */
    6560 SCIP_CALL( SCIPhashtableInsert(hashtable, (void*) cons0) );
    6561 }
    6562 }
    6563
    6564 /* free hash table */
    6565 SCIPhashtableFree(&hashtable);
    6566
    6567 return SCIP_OKAY;
    6568}
    6569
    6570/** removes the redundant second constraint and updates the flags of the first one */
    6571static
    6573 SCIP* scip, /**< SCIP data structure */
    6574 SCIP_CONS* cons0, /**< constraint that should stay */
    6575 SCIP_CONS* cons1, /**< constraint that should be deleted */
    6576 int* ndelconss /**< pointer to count number of deleted constraints */
    6577 )
    6578{
    6579 assert(ndelconss != NULL);
    6580
    6581 SCIPdebugMsg(scip, " -> removing setppc constraint <%s> which is redundant to <%s>\n",
    6582 SCIPconsGetName(cons1), SCIPconsGetName(cons0));
    6583 SCIPdebugPrintCons(scip, cons0, NULL);
    6584 SCIPdebugPrintCons(scip, cons1, NULL);
    6585
    6586 /* update flags of cons0 */
    6587 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
    6588
    6589 /* delete cons1 */
    6590 SCIP_CALL( SCIPdelCons(scip, cons1) );
    6591 (*ndelconss)++;
    6592
    6593 return SCIP_OKAY;
    6594}
    6595
    6596/** for cons0 contained in cons1, fixes variables of cons1 that are not in cons0 to zero */
    6597static
    6599 SCIP* scip, /**< SCIP data structure */
    6600 SCIP_CONS* cons0, /**< constraint that is contained in the other */
    6601 SCIP_CONS* cons1, /**< constraint that is a superset of the other */
    6602 SCIP_Bool* cutoff, /**< pointer to store whether a cutoff was found */
    6603 int* nfixedvars /**< pointer to count number of fixed variables */
    6604 )
    6605{
    6606 SCIP_CONSDATA* consdata0;
    6607 SCIP_CONSDATA* consdata1;
    6608 int v0;
    6609 int v1;
    6610
    6611 assert(cutoff != NULL);
    6612 assert(nfixedvars != NULL);
    6613
    6614 *cutoff = FALSE;
    6615
    6616 /* get constraint data */
    6617 consdata0 = SCIPconsGetData(cons0);
    6618 consdata1 = SCIPconsGetData(cons1);
    6619 assert(consdata0 != NULL);
    6620 assert(consdata1 != NULL);
    6621 assert(consdata0->nvars < consdata1->nvars);
    6622 assert(consdata0->sorted);
    6623 assert(consdata1->sorted);
    6624
    6625 /* fix variables in the range of cons0 */
    6626 for( v0 = 0, v1 = 0; v0 < consdata0->nvars && !(*cutoff); ++v0, ++v1 )
    6627 {
    6628 int index0;
    6629
    6630 assert(v1 < consdata1->nvars);
    6631 index0 = SCIPvarGetIndex(consdata0->vars[v0]);
    6632 for( ; SCIPvarGetIndex(consdata1->vars[v1]) < index0 && !(*cutoff); ++v1 ) /*lint !e445*/
    6633 {
    6634 SCIP_Bool fixed;
    6635
    6636 /* fix variable to zero */
    6637 SCIP_CALL( SCIPfixVar(scip, consdata1->vars[v1], 0.0, cutoff, &fixed) );
    6638 if( fixed )
    6639 {
    6640 SCIPdebugMsg(scip, " -> fixed <%s> == 0\n", SCIPvarGetName(consdata1->vars[v1]));
    6641 (*nfixedvars)++;
    6642 }
    6643 assert(v1 < consdata1->nvars-1);
    6644 }
    6645 assert(SCIPvarGetIndex(consdata1->vars[v1]) == index0 || *cutoff);
    6646 }
    6647
    6648 /* fix remaining variables of cons1 */
    6649 for( ; v1 < consdata1->nvars && !(*cutoff); ++v1 )
    6650 {
    6651 SCIP_Bool fixed;
    6652
    6653 assert(consdata0->nvars == 0
    6654 || SCIPvarGetIndex(consdata1->vars[v1]) > SCIPvarGetIndex(consdata0->vars[consdata0->nvars-1]));
    6655
    6656 /* fix variable to zero */
    6657 SCIP_CALL( SCIPfixVar(scip, consdata1->vars[v1], 0.0, cutoff, &fixed) );
    6658 if( fixed )
    6659 {
    6660 SCIPdebugMsg(scip, " -> fixed <%s> == 0\n", SCIPvarGetName(consdata1->vars[v1]));
    6661 (*nfixedvars)++;
    6662 }
    6663 }
    6664
    6665 return SCIP_OKAY;
    6666}
    6667
    6668/** applies reductions for cons0 being contained in cons1 */
    6669static
    6671 SCIP* scip, /**< SCIP data structure */
    6672 SCIP_CONS* cons0, /**< constraint that is contained in the other */
    6673 SCIP_CONS* cons1, /**< constraint that is a superset of the other */
    6674 SCIP_Bool* cutoff, /**< pointer to store whether a cutoff was found */
    6675 int* nfixedvars, /**< pointer to count number of fixed variables */
    6676 int* ndelconss, /**< pointer to count number of deleted constraints */
    6677 int* nchgsides /**< pointer to count number of changed left/right hand sides */
    6678 )
    6679{
    6680 SCIP_CONSDATA* consdata0;
    6681 SCIP_CONSDATA* consdata1;
    6682
    6683 assert(cutoff != NULL);
    6684 assert(nfixedvars != NULL);
    6685 assert(ndelconss != NULL);
    6686 assert(nchgsides != NULL);
    6687
    6688 *cutoff = FALSE;
    6689
    6690 /* get constraint data */
    6691 consdata0 = SCIPconsGetData(cons0);
    6692 consdata1 = SCIPconsGetData(cons1);
    6693 assert(consdata0 != NULL);
    6694 assert(consdata1 != NULL);
    6695 assert(consdata0->nvars < consdata1->nvars);
    6696 assert(consdata0->sorted);
    6697 assert(consdata1->sorted);
    6698
    6699 switch( consdata0->setppctype )
    6700 {
    6702 switch( consdata1->setppctype )
    6703 {
    6706 /* cons0: partitioning, cons1: partitioning or packing
    6707 * -> fix additional variables in cons1 to zero, remove cons1
    6708 */
    6709 SCIP_CALL( fixAdditionalVars(scip, cons0, cons1, cutoff, nfixedvars) );
    6710 SCIP_CALL( removeRedundantCons(scip, cons0, cons1, ndelconss) );
    6711 break;
    6712
    6714 /* cons0: partitioning, cons1: covering
    6715 * -> remove cons1
    6716 */
    6717 SCIP_CALL( removeRedundantCons(scip, cons0, cons1, ndelconss) );
    6718 break;
    6719
    6720 default:
    6721 SCIPerrorMessage("invalid setppc type <%d> of constraint <%s>\n", consdata1->setppctype, SCIPconsGetName(cons1));
    6722 return SCIP_INVALIDDATA;
    6723 }
    6724 break;
    6725
    6727 switch( consdata1->setppctype )
    6728 {
    6731 /* cons0: packing, cons1: partitioning or packing
    6732 * -> remove cons0
    6733 */
    6734 SCIP_CALL( removeRedundantCons(scip, cons1, cons0, ndelconss) );
    6735 break;
    6736
    6738 /* cons0: packing, cons1: covering
    6739 * -> nothing can be deduced
    6740 */
    6741 break;
    6742
    6743 default:
    6744 SCIPerrorMessage("invalid setppc type <%d> of constraint <%s>\n", consdata1->setppctype, SCIPconsGetName(cons1));
    6745 return SCIP_INVALIDDATA;
    6746 }
    6747 break;
    6748
    6750 switch( consdata1->setppctype )
    6751 {
    6754 /* cons0: covering, cons1: partitioning or packing
    6755 * -> fix additional variables in cons1 to zero, remove cons1, convert cons0 into partitioning
    6756 */
    6757 SCIP_CALL( fixAdditionalVars(scip, cons0, cons1, cutoff, nfixedvars) );
    6759 SCIP_CALL( removeRedundantCons(scip, cons0, cons1, ndelconss) );
    6760 (*nchgsides)++;
    6761 break;
    6762
    6764 /* cons0: covering, cons1: covering
    6765 * -> remove cons1
    6766 */
    6767 SCIP_CALL( removeRedundantCons(scip, cons0, cons1, ndelconss) );
    6768 break;
    6769
    6770 default:
    6771 SCIPerrorMessage("invalid setppc type <%d> of constraint <%s>\n", consdata1->setppctype, SCIPconsGetName(cons1));
    6772 return SCIP_INVALIDDATA;
    6773 }
    6774 break;
    6775
    6776 default:
    6777 SCIPerrorMessage("invalid setppc type <%d> of constraint <%s>\n", consdata0->setppctype, SCIPconsGetName(cons0));
    6778 return SCIP_INVALIDDATA;
    6779 }
    6780
    6781 return SCIP_OKAY;
    6782}
    6783
    6784/** deletes redundant constraints */
    6785static
    6787 SCIP* scip, /**< SCIP data structure */
    6788 SCIP_CONS** conss, /**< constraint set */
    6789 int firstchange, /**< first constraint that changed since last pair preprocessing round */
    6790 int chkind, /**< index of constraint to check against all prior indices up to startind */
    6791 SCIP_Bool* cutoff, /**< pointer to store whether a cutoff was found */
    6792 int* nfixedvars, /**< pointer to count number of fixed variables */
    6793 int* ndelconss, /**< pointer to count number of deleted constraints */
    6794 int* nchgsides /**< pointer to count number of changed left/right hand sides */
    6795 )
    6796{
    6797 SCIP_CONS* cons0;
    6798 SCIP_CONSDATA* consdata0;
    6799 uint64_t signature0;
    6800 SCIP_Bool cons0changed;
    6801 int c;
    6802
    6803 assert(scip != NULL);
    6804 assert(conss != NULL);
    6805 assert(cutoff != NULL);
    6806 assert(nfixedvars != NULL);
    6807 assert(ndelconss != NULL);
    6808 assert(nchgsides != NULL);
    6809
    6810 *cutoff = FALSE;
    6811
    6812 /* get the constraint to be checked against all prior constraints */
    6813 cons0 = conss[chkind];
    6814 assert(SCIPconsIsActive(cons0));
    6815 assert(!SCIPconsIsModifiable(cons0));
    6816
    6817 consdata0 = SCIPconsGetData(cons0);
    6818 assert(consdata0 != NULL);
    6819 assert(consdata0->nvars >= 1);
    6820
    6821 /* sort the constraint cons0 */
    6822 consdataSort(consdata0);
    6823
    6824 /* get the bit signature of the constraint */
    6825 signature0 = consdataGetSignature(consdata0);
    6826
    6827 /* check constraint against all prior constraints */
    6828 cons0changed = consdata0->changed;
    6829 consdata0->changed = FALSE;
    6830 for( c = (cons0changed ? 0 : firstchange); c < chkind && !(*cutoff) && SCIPconsIsActive(cons0); ++c )
    6831 {
    6832 SCIP_CONS* cons1;
    6833 SCIP_CONSDATA* consdata1;
    6834 uint64_t signature1;
    6835 uint64_t jointsignature;
    6836 SCIP_Bool cons0iscontained;
    6837 SCIP_Bool cons1iscontained;
    6838 int v0;
    6839 int v1;
    6840
    6841 cons1 = conss[c];
    6842
    6843 /* ignore inactive and modifiable constraints */
    6844 if( !SCIPconsIsActive(cons1) || SCIPconsIsModifiable(cons1) )
    6845 continue;
    6846
    6847 consdata1 = SCIPconsGetData(cons1);
    6848 assert(consdata1 != NULL);
    6849
    6850 /* sort the constraint cons1 */
    6851 consdataSort(consdata1);
    6852
    6853 /* get the bit signature of cons1 */
    6854 signature1 = consdataGetSignature(consdata1);
    6855
    6856 /* check (based on signature) if the two constraints are not included in each other */
    6857 jointsignature = (signature0 | signature1);
    6858 if( jointsignature != signature0 && jointsignature != signature1 )
    6859 continue;
    6860
    6861 /* check whether one constraint is really a subset of the other */
    6862 cons0iscontained = (consdata0->nvars <= consdata1->nvars);
    6863 cons1iscontained = (consdata1->nvars <= consdata0->nvars);
    6864 v0 = 0;
    6865 v1 = 0;
    6866 while( v0 < consdata0->nvars && v1 < consdata1->nvars )
    6867 {
    6868 int index0;
    6869 int index1;
    6870
    6871 index0 = SCIPvarGetIndex(consdata0->vars[v0]);
    6872 index1 = SCIPvarGetIndex(consdata1->vars[v1]);
    6873 if( index0 < index1 )
    6874 {
    6875 cons0iscontained = FALSE;
    6876 if( !cons1iscontained )
    6877 break;
    6878 for( v0++; v0 < consdata0->nvars && SCIPvarGetIndex(consdata0->vars[v0]) < index1; v0++ )
    6879 {}
    6880 }
    6881 else if( index1 < index0 )
    6882 {
    6883 cons1iscontained = FALSE;
    6884 if( !cons0iscontained )
    6885 break;
    6886 for( v1++; v1 < consdata1->nvars && SCIPvarGetIndex(consdata1->vars[v1]) < index0; v1++ )
    6887 {}
    6888 }
    6889 else
    6890 {
    6891 v0++;
    6892 v1++;
    6893 }
    6894 }
    6895 cons0iscontained = cons0iscontained && (v0 == consdata0->nvars);
    6896 cons1iscontained = cons1iscontained && (v1 == consdata1->nvars);
    6897
    6898 if( cons0iscontained && cons1iscontained )
    6899 {
    6900 SCIPdebugMsg(scip, "setppc constraints <%s> and <%s> have identical variable sets\n",
    6901 SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    6902 SCIPdebugPrintCons(scip, cons0, NULL);
    6903 SCIPdebugPrintCons(scip, cons1, NULL);
    6904
    6905 /* both constraints consists of the same variables */
    6906 if( consdata0->setppctype == consdata1->setppctype )
    6907 {
    6908 /* both constraints are equal: update flags in cons0 and delete cons1 */
    6909 SCIP_CALL( removeRedundantCons(scip, cons0, cons1, ndelconss) );
    6910 }
    6911 else if( consdata0->setppctype == SCIP_SETPPCTYPE_PARTITIONING ) /*lint !e641*/
    6912 {
    6913 /* the set partitioning constraint is stronger: remove the other one */
    6914 SCIP_CALL( removeRedundantCons(scip, cons0, cons1, ndelconss) );
    6915 }
    6916 else if( consdata1->setppctype == SCIP_SETPPCTYPE_PARTITIONING ) /*lint !e641*/
    6917 {
    6918 /* the set partitioning constraint is stronger: remove the other one */
    6919 SCIP_CALL( removeRedundantCons(scip, cons1, cons0, ndelconss) );
    6920 }
    6921 else
    6922 {
    6923 /* one is a covering, the other one a packing constraint: replace them by a single partitioning constraint */
    6924 assert((consdata0->setppctype == SCIP_SETPPCTYPE_COVERING && consdata1->setppctype == SCIP_SETPPCTYPE_PACKING)
    6925 || (consdata1->setppctype == SCIP_SETPPCTYPE_COVERING && consdata0->setppctype == SCIP_SETPPCTYPE_PACKING)); /*lint !e641*/
    6926
    6927 /* change the type of cons0 */
    6929 (*nchgsides)++;
    6930
    6931 /* delete cons1 */
    6932 SCIP_CALL( removeRedundantCons(scip, cons0, cons1, ndelconss) );
    6933 }
    6934 }
    6935 else if( cons0iscontained )
    6936 {
    6937 /* cons0 is contained in cons1 */
    6938 SCIPdebugMsg(scip, "setppc constraint <%s> is contained in <%s>\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    6939 SCIPdebugPrintCons(scip, cons0, NULL);
    6940 SCIPdebugPrintCons(scip, cons1, NULL);
    6941 SCIP_CALL( processContainedCons(scip, cons0, cons1, cutoff, nfixedvars, ndelconss, nchgsides) );
    6942 }
    6943 else if( cons1iscontained )
    6944 {
    6945 /* cons1 is contained in cons1 */
    6946 SCIPdebugMsg(scip, "setppc constraint <%s> is contained in <%s>\n", SCIPconsGetName(cons1), SCIPconsGetName(cons0));
    6947 SCIPdebugPrintCons(scip, cons0, NULL);
    6948 SCIPdebugPrintCons(scip, cons1, NULL);
    6949 SCIP_CALL( processContainedCons(scip, cons1, cons0, cutoff, nfixedvars, ndelconss, nchgsides) );
    6950 }
    6951 }
    6952
    6953 return SCIP_OKAY;
    6954}
    6955
    6956/* perform deletion of variables in all constraints of the constraint handler */
    6957static
    6959 SCIP* scip, /**< SCIP data structure */
    6960 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    6961 SCIP_CONS** conss, /**< array of constraints */
    6962 int nconss /**< number of constraints */
    6963 )
    6964{
    6965 SCIP_CONSDATA* consdata;
    6966 int i;
    6967 int v;
    6968
    6969 assert(scip != NULL);
    6970 assert(conshdlr != NULL);
    6971 assert(conss != NULL);
    6972 assert(nconss >= 0);
    6973 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    6974
    6975 /* iterate over all constraints */
    6976 for( i = 0; i < nconss; i++ )
    6977 {
    6978 consdata = SCIPconsGetData(conss[i]);
    6979
    6980 /* constraint is marked, that some of its variables were deleted */
    6981 if( consdata->varsdeleted )
    6982 {
    6983 /* iterate over all variables of the constraint and delete marked variables */
    6984 for( v = consdata->nvars - 1; v >= 0; v-- )
    6985 {
    6986 if( SCIPvarIsDeleted(consdata->vars[v]) )
    6987 {
    6988 SCIP_CALL( delCoefPos(scip, conss[i], v) );
    6989 }
    6990 }
    6991 consdata->varsdeleted = FALSE;
    6992 }
    6993 }
    6994
    6995 return SCIP_OKAY;
    6996}
    6997
    6998/** helper function to enforce constraints */
    6999static
    7001 SCIP* scip, /**< SCIP data structure */
    7002 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    7003 SCIP_CONS** conss, /**< constraints to process */
    7004 int nconss, /**< number of constraints */
    7005 int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
    7006 SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
    7007 SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
    7008 )
    7009{
    7010 SCIP_Bool cutoff;
    7011 SCIP_Bool separated;
    7012 SCIP_Bool reduceddom;
    7013 int c;
    7014
    7015 assert(conshdlr != NULL);
    7016 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    7017 assert(nconss == 0 || conss != NULL);
    7018 assert(result != NULL);
    7019
    7020 SCIPdebugMsg(scip, "Enforcing %d set partitioning / packing / covering constraints for %s solution\n", nconss,
    7021 sol == NULL ? "LP" : "relaxation");
    7022
    7023 *result = SCIP_FEASIBLE;
    7024
    7025 cutoff = FALSE;
    7026 separated = FALSE;
    7027 reduceddom = FALSE;
    7028
    7029 /* check all useful set partitioning / packing / covering constraints for feasibility */
    7030 for( c = 0; c < nusefulconss && !cutoff && !reduceddom; ++c )
    7031 {
    7032 SCIP_CALL( separateCons(scip, conss[c], sol, TRUE, &cutoff, &separated, &reduceddom) );
    7033 }
    7034
    7035 /* check all obsolete set partitioning / packing / covering constraints for feasibility */
    7036 for( c = nusefulconss; c < nconss && !cutoff && !separated && !reduceddom; ++c )
    7037 {
    7038 SCIP_CALL( separateCons(scip, conss[c], sol, TRUE, &cutoff, &separated, &reduceddom) );
    7039 }
    7040
    7041#ifdef VARUSES
    7042#ifdef BRANCHLP
    7043 /* @todo also branch on relaxation solution */
    7044 if( (sol == NULL) && !cutoff && !separated && !reduceddom )
    7045 {
    7046 /* if solution is not integral, choose a variable set to branch on */
    7047 SCIP_CALL( branchLP(scip, conshdlr, result) );
    7048 if( *result != SCIP_FEASIBLE )
    7049 return SCIP_OKAY;
    7050 }
    7051#endif
    7052#endif
    7053
    7054 /* return the correct result */
    7055 if( cutoff )
    7056 *result = SCIP_CUTOFF;
    7057 else if( separated )
    7058 *result = SCIP_SEPARATED;
    7059 else if( reduceddom )
    7060 *result = SCIP_REDUCEDDOM;
    7061
    7062 return SCIP_OKAY;
    7063}
    7064
    7065/*
    7066 * upgrading of linear constraints
    7067 */
    7068
    7069
    7070/** creates and captures a set partitioning / packing / covering constraint */
    7071static
    7073 SCIP* scip, /**< SCIP data structure */
    7074 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    7075 const char* name, /**< name of constraint */
    7076 int nvars, /**< number of variables in the constraint */
    7077 SCIP_VAR** vars, /**< array with variables of constraint entries */
    7078 SCIP_SETPPCTYPE setppctype, /**< type of constraint: set partitioning, packing, or covering constraint */
    7079 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    7080 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    7081 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    7082 * Usually set to TRUE. */
    7083 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    7084 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    7085 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    7086 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    7087 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    7088 * Usually set to TRUE. */
    7089 SCIP_Bool local, /**< is constraint only valid locally?
    7090 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    7091 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    7092 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    7093 * adds coefficients to this constraint. */
    7094 SCIP_Bool dynamic, /**< is constraint subject to aging?
    7095 * Usually set to FALSE. Set to TRUE for own cuts which
    7096 * are separated as constraints. */
    7097 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    7098 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    7099 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    7100 * if it may be moved to a more global node?
    7101 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    7102 )
    7103{
    7104 SCIP_CONSHDLR* conshdlr;
    7105 SCIP_CONSDATA* consdata;
    7106 SCIP_CONSHDLRDATA* conshdlrdata;
    7107 int i;
    7108
    7109 assert(scip != NULL);
    7110
    7111 /* find the set partitioning constraint handler */
    7112 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    7113 if( conshdlr == NULL )
    7114 {
    7115 SCIPerrorMessage("set partitioning / packing / covering constraint handler not found\n");
    7116 return SCIP_INVALIDCALL;
    7117 }
    7118
    7119 /* check whether all variables are binary */
    7120 assert(vars != NULL || nvars == 0);
    7121 for( i = 0; i < nvars; ++i )
    7122 {
    7123 if( !SCIPvarIsBinary(vars[i]) )
    7124 {
    7125 SCIPerrorMessage("operand <%s> is not binary\n", SCIPvarGetName(vars[i]));
    7126 return SCIP_INVALIDDATA;
    7127 }
    7128 }
    7129
    7130 /* create the constraint specific data */
    7132 {
    7133 /* create constraint in original problem */
    7134 SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, setppctype) );
    7135 }
    7136 else
    7137 {
    7138 /* create constraint in transformed problem */
    7139 SCIP_CALL( consdataCreateTransformed(scip, &consdata, nvars, vars, setppctype) );
    7140 }
    7141
    7142 /* create constraint */
    7143 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
    7144 local, modifiable, dynamic, removable, stickingatnode) );
    7145
    7146 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    7147 assert(conshdlrdata != NULL);
    7148
    7150 {
    7151 ++(conshdlrdata->nsetpart);
    7152 assert(conshdlrdata->nsetpart >= 0);
    7153 }
    7154
    7156 {
    7157 /* get event handler */
    7158 assert(conshdlrdata->eventhdlr != NULL);
    7159
    7160 /* catch bound change events of variables */
    7161 SCIP_CALL( catchAllEvents(scip, *cons, conshdlrdata->eventhdlr) );
    7162 }
    7163
    7164 return SCIP_OKAY;
    7165}
    7166
    7167/** creates and captures a normalized (with all coefficients +1) setppc constraint */
    7168static
    7170 SCIP* scip, /**< SCIP data structure */
    7171 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    7172 const char* name, /**< name of constraint */
    7173 int nvars, /**< number of variables in the constraint */
    7174 SCIP_VAR** vars, /**< array with variables of constraint entries */
    7175 SCIP_Real* vals, /**< array with coefficients (+1.0 or -1.0) */
    7176 int mult, /**< multiplier on the coefficients(+1 or -1) */
    7177 SCIP_SETPPCTYPE setppctype, /**< type of constraint: set partitioning, packing, or covering constraint */
    7178 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    7179 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    7180 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    7181 * Usually set to TRUE. */
    7182 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    7183 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    7184 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    7185 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    7186 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    7187 * Usually set to TRUE. */
    7188 SCIP_Bool local, /**< is constraint only valid locally?
    7189 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    7190 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    7191 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    7192 * adds coefficients to this constraint. */
    7193 SCIP_Bool dynamic, /**< is constraint subject to aging?
    7194 * Usually set to FALSE. Set to TRUE for own cuts which
    7195 * are separated as constraints. */
    7196 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    7197 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    7198 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    7199 * if it may be moved to a more global node?
    7200 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    7201 )
    7202{
    7203 SCIP_VAR** transvars;
    7204 int v;
    7205
    7206 assert(nvars == 0 || vars != NULL);
    7207 assert(nvars == 0 || vals != NULL);
    7208 assert(mult == +1 || mult == -1);
    7209
    7210 /* get temporary memory */
    7211 SCIP_CALL( SCIPallocBufferArray(scip, &transvars, nvars) );
    7212
    7213 /* negate positive or negative variables */
    7214 for( v = 0; v < nvars; ++v )
    7215 {
    7216 if( mult * vals[v] > 0.0 )
    7217 transvars[v] = vars[v];
    7218 else
    7219 {
    7220 SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &transvars[v]) );
    7221 }
    7222 assert(transvars[v] != NULL);
    7223 }
    7224
    7225 /* create the constraint */
    7226 SCIP_CALL( createConsSetppc(scip, cons, name, nvars, transvars, setppctype,
    7227 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    7228
    7229 /* release temporary memory */
    7230 SCIPfreeBufferArray(scip, &transvars);
    7231
    7232 return SCIP_OKAY;
    7233}
    7234
    7235/** check, if linear constraint can be upgraded to set partitioning, packing, or covering constraint */
    7236static
    7237SCIP_DECL_LINCONSUPGD(linconsUpgdSetppc)
    7238{ /*lint --e{715}*/
    7239 assert(upgdcons != NULL);
    7240 assert( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), "linear") == 0 );
    7241
    7242 /* check, if linear constraint can be upgraded to set partitioning, packing, or covering constraint
    7243 * - all set partitioning / packing / covering constraints consist only of binary variables with a
    7244 * coefficient of +1.0 or -1.0 (variables with -1.0 coefficients can be negated):
    7245 * lhs <= x1 + ... + xp - y1 - ... - yn <= rhs
    7246 * - negating all variables y = (1-Y) with negative coefficients gives:
    7247 * lhs + n <= x1 + ... + xp + Y1 + ... + Yn <= rhs + n
    7248 * - negating all variables x = (1-X) with positive coefficients and multiplying with -1 gives:
    7249 * p - rhs <= X1 + ... + Xp + y1 + ... + yn <= p - lhs
    7250 * - a set partitioning constraint has left hand side of +1.0, and right hand side of +1.0 : x(S) == 1.0
    7251 * -> without negations: lhs == rhs == 1 - n or lhs == rhs == p - 1
    7252 * - a set packing constraint has left hand side of -infinity, and right hand side of +1.0 : x(S) <= 1.0
    7253 * -> without negations: (lhs == -inf and rhs == 1 - n) or (lhs == p - 1 and rhs = +inf)
    7254 * - a set covering constraint has left hand side of +1.0, and right hand side of +infinity: x(S) >= 1.0
    7255 * -> without negations: (lhs == 1 - n and rhs == +inf) or (lhs == -inf and rhs = p - 1)
    7256 */
    7257 if( nposbin + nnegbin + nposimplbin + nnegimplbin == nvars && ncoeffspone + ncoeffsnone == nvars )
    7258 {
    7259 int mult;
    7260
    7261 if( SCIPisEQ(scip, lhs, rhs) && (SCIPisEQ(scip, lhs, 1.0 - ncoeffsnone) || SCIPisEQ(scip, lhs, ncoeffspone - 1.0)) )
    7262 {
    7263 SCIPdebugMsg(scip, "upgrading constraint <%s> to set partitioning constraint\n", SCIPconsGetName(cons));
    7264
    7265 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
    7266 mult = SCIPisEQ(scip, lhs, 1.0 - ncoeffsnone) ? +1 : -1;
    7267
    7268 /* create the set partitioning constraint (an automatically upgraded constraint is always unmodifiable) */
    7269 assert(!SCIPconsIsModifiable(cons));
    7270 SCIP_CALL( createNormalizedSetppc(scip, upgdcons, SCIPconsGetName(cons), nvars, vars, vals, mult,
    7276 }
    7277 else if( (SCIPisInfinity(scip, -lhs) && SCIPisEQ(scip, rhs, 1.0 - ncoeffsnone))
    7278 || (SCIPisEQ(scip, lhs, ncoeffspone - 1.0) && SCIPisInfinity(scip, rhs)) )
    7279 {
    7280 SCIPdebugMsg(scip, "upgrading constraint <%s> to set packing constraint\n", SCIPconsGetName(cons));
    7281
    7282 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
    7283 mult = SCIPisInfinity(scip, -lhs) ? +1 : -1;
    7284
    7285 /* create the set packing constraint (an automatically upgraded constraint is always unmodifiable) */
    7286 assert(!SCIPconsIsModifiable(cons));
    7287 SCIP_CALL( createNormalizedSetppc(scip, upgdcons, SCIPconsGetName(cons), nvars, vars, vals, mult,
    7293 }
    7294 else if( (SCIPisEQ(scip, lhs, 1.0 - ncoeffsnone) && SCIPisInfinity(scip, rhs))
    7295 || (SCIPisInfinity(scip, -lhs) && SCIPisEQ(scip, rhs, ncoeffspone - 1.0)) )
    7296 {
    7297 SCIPdebugMsg(scip, "upgrading constraint <%s> to set covering constraint\n", SCIPconsGetName(cons));
    7298
    7299 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
    7300 mult = SCIPisInfinity(scip, rhs) ? +1 : -1;
    7301
    7302 /* create the set covering constraint (an automatically upgraded constraint is always unmodifiable) */
    7303 assert(!SCIPconsIsModifiable(cons));
    7304 SCIP_CALL( createNormalizedSetppc(scip, upgdcons, SCIPconsGetName(cons), nvars, vars, vals, mult,
    7310 }
    7311 }
    7312
    7313 return SCIP_OKAY;
    7314}
    7315
    7316/** tries to upgrade a nonlinear constraint to a setpacking constraint */
    7317static
    7319{
    7320 SCIP_Bool isquadratic;
    7321 SCIP_EXPR* expr;
    7322 SCIP_EXPR* expr1;
    7323 SCIP_EXPR* expr2;
    7324 SCIP_VAR* bilinvars[2];
    7325 SCIP_VAR* vars[2];
    7326 SCIP_Real bilincoef;
    7327 SCIP_Real constant;
    7328 SCIP_Real lincoef;
    7329 SCIP_Real sqrcoef;
    7330 SCIP_Real coefx;
    7331 SCIP_Real coefy;
    7332 SCIP_Real rhs;
    7333 int nbilinexprterms;
    7334 int nquadexprs;
    7335 int nlinexprs;
    7336
    7337 assert(scip != NULL);
    7338 assert(cons != NULL);
    7339 assert(nupgdconss != NULL);
    7340 assert(upgdconss != NULL);
    7341 assert(! SCIPconsIsModifiable(cons));
    7342 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), "nonlinear") == 0);
    7343
    7344 *nupgdconss = 0;
    7345
    7346 SCIPdebugMsg(scip, "try to upgrade nonlinear constraint <%s> to setpacking constraint ...\n", SCIPconsGetName(cons));
    7348
    7349 /* need exactly two variables */
    7350 if( nvarexprs != 2 )
    7351 return SCIP_OKAY;
    7352
    7353 /* left and right hand side need to be equal
    7354 * @todo we could also handle inequalities
    7355 */
    7356 rhs = SCIPgetRhsNonlinear(cons);
    7357 if( SCIPisInfinity(scip, rhs) || !SCIPisEQ(scip, SCIPgetLhsNonlinear(cons), rhs) )
    7358 return SCIP_OKAY;
    7359
    7360 /* check whether constraint is quadratic */
    7361 SCIP_CALL( SCIPcheckQuadraticNonlinear(scip, cons, &isquadratic) );
    7362 if( !isquadratic )
    7363 return SCIP_OKAY;
    7364
    7365 expr = SCIPgetExprNonlinear(cons);
    7366 SCIPexprGetQuadraticData(expr, &constant, &nlinexprs, NULL, NULL, &nquadexprs, &nbilinexprterms, NULL, NULL);
    7367
    7368 /* adjust rhs */
    7369 rhs -= constant;
    7370
    7371 /* cannot currently handle linear part */
    7372 if( nlinexprs > 0 )
    7373 return SCIP_OKAY;
    7374
    7375 /* need only one bilinear term */
    7376 if( nbilinexprterms != 1 )
    7377 return SCIP_OKAY;
    7378
    7379 /* need exactly two quadratic variables */
    7380 if( nquadexprs != 2 )
    7381 return SCIP_OKAY;
    7382
    7383 /* get bilinear term */
    7384 SCIPexprGetQuadraticBilinTerm(expr, 0, &expr1, &expr2, &bilincoef, NULL, NULL);
    7385 bilinvars[0] = SCIPgetVarExprVar(expr1);
    7386 bilinvars[1] = SCIPgetVarExprVar(expr2);
    7387
    7388 if( SCIPisZero(scip, bilincoef) )
    7389 return SCIP_OKAY;
    7390
    7391 /* check variable types */
    7392 if( SCIPvarGetType(bilinvars[0]) != SCIP_VARTYPE_BINARY || SCIPvarIsImpliedIntegral(bilinvars[0])
    7393 || SCIPvarGetType(bilinvars[1]) != SCIP_VARTYPE_BINARY || SCIPvarIsImpliedIntegral(bilinvars[1]) )
    7394 return SCIP_OKAY;
    7395
    7396 /* get data of quadratic terms */
    7397 SCIPexprGetQuadraticQuadTerm(expr, 0, &expr1, &lincoef, &sqrcoef, NULL, NULL, NULL);
    7398 coefx = lincoef + sqrcoef; /* for binary variables, we can treat sqr coef as lin coef */
    7399
    7400 SCIPexprGetQuadraticQuadTerm(expr, 1, &expr2, &lincoef, &sqrcoef, NULL, NULL, NULL);
    7401 coefy = lincoef + sqrcoef; /* for binary variables, we can treat sqr coef as lin coef */
    7402
    7403 /* divide constraint by coefficient of x*y */
    7404 coefx /= bilincoef;
    7405 coefy /= bilincoef;
    7406 rhs /= bilincoef;
    7407
    7408 /* constraint is now of the form coefx * x + coefy * y + x * y == rhs
    7409 * we can rewrite as (x + coefy) * (y + coefx) == rhs + coefx * coefy
    7410 */
    7411
    7412 /* we can only upgrade if coefx and coefy are 0 or -1 and rhs == -coefx * coefy */
    7413 if( !SCIPisZero(scip, coefx) && !SCIPisEQ(scip, coefx, -1.0) )
    7414 return SCIP_OKAY;
    7415 if( !SCIPisZero(scip, coefy) && !SCIPisEQ(scip, coefy, -1.0) )
    7416 return SCIP_OKAY;
    7417 if( !SCIPisEQ(scip, rhs, -coefx * coefy) )
    7418 return SCIP_OKAY;
    7419
    7420 if( SCIPisZero(scip, coefy) )
    7421 {
    7422 vars[0] = SCIPgetVarExprVar(expr1);
    7423 }
    7424 else
    7425 {
    7426 assert(SCIPisEQ(scip, coefy, -1.0));
    7427 /* x - 1 = -(1-x) = -(~x) */
    7428 SCIP_CALL( SCIPgetNegatedVar(scip, SCIPgetVarExprVar(expr1), &vars[0]) );
    7429 }
    7430 if( SCIPisZero(scip, coefx) )
    7431 {
    7432 vars[1] = SCIPgetVarExprVar(expr2);
    7433 }
    7434 else
    7435 {
    7436 assert(SCIPisEQ(scip, coefx, -1.0));
    7437 /* y - 1 = -(1 - y) = -(~y) */
    7438 SCIP_CALL( SCIPgetNegatedVar(scip, SCIPgetVarExprVar(expr2), &vars[1]) );
    7439 }
    7440
    7441 /* constraint is now of the form vars[0] * vars[1] == 0 */
    7442
    7443 SCIPdebugMsg(scip, "constraint <%s> can be upgraded ...\n", SCIPconsGetName(cons));
    7444
    7445 /* vars[0] + vars[1] <= 1 */
    7446 SCIP_CALL( SCIPcreateConsSetpack(scip, &upgdconss[0], SCIPconsGetName(cons), 2, vars,
    7450 SCIPdebugPrintCons(scip, upgdconss[0], NULL);
    7451
    7452 ++(*nupgdconss);
    7453
    7454 return SCIP_OKAY;
    7455} /*lint !e715*/
    7456
    7457/** adds symmetry information of constraint to a symmetry detection graph */
    7458static
    7460 SCIP* scip, /**< SCIP pointer */
    7461 SYM_SYMTYPE symtype, /**< type of symmetries that need to be added */
    7462 SCIP_CONS* cons, /**< constraint */
    7463 SYM_GRAPH* graph, /**< symmetry detection graph */
    7464 SCIP_Bool* success /**< pointer to store whether symmetry information could be added */
    7465 )
    7466{
    7467 SCIP_CONSDATA* consdata;
    7468 SCIP_VAR** vars;
    7469 SCIP_Real* vals;
    7470 SCIP_Real constant = 0.0;
    7471 SCIP_Real lhs;
    7472 SCIP_Real rhs;
    7473 int nlocvars;
    7474 int nvars;
    7475 int i;
    7476
    7477 assert(scip != NULL);
    7478 assert(cons != NULL);
    7479 assert(graph != NULL);
    7480 assert(success != NULL);
    7481
    7482 consdata = SCIPconsGetData(cons);
    7483 assert(consdata != NULL);
    7484
    7485 /* get active variables of the constraint */
    7486 nvars = SCIPgetNVars(scip);
    7487 nlocvars = consdata->nvars;
    7488
    7489 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
    7490 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
    7491
    7492 for( i = 0; i < consdata->nvars; ++i )
    7493 {
    7494 vars[i] = consdata->vars[i];
    7495 vals[i] = 1.0;
    7496 }
    7497
    7498 SCIP_CALL( SCIPgetSymActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant, SCIPisTransformed(scip)) );
    7499
    7500 lhs = -SCIPinfinity(scip);
    7501 rhs = SCIPinfinity(scip);
    7502 if ( consdata->setppctype == (unsigned) SCIP_SETPPCTYPE_PACKING ) /*lint !e641*/
    7503 rhs = 1.0 - constant;
    7504 else if ( consdata->setppctype == (unsigned) SCIP_SETPPCTYPE_COVERING ) /*lint !e641*/
    7505 lhs = 1.0 - constant;
    7506 else
    7507 {
    7508 assert(consdata->setppctype == (unsigned) SCIP_SETPPCTYPE_PARTITIONING); /*lint !e641*/
    7509
    7510 rhs = 1.0 - constant;
    7511 lhs = 1.0 - constant;
    7512 }
    7513
    7514 SCIP_CALL( SCIPextendPermsymDetectionGraphLinear(scip, graph, vars, vals, nlocvars,
    7515 cons, lhs, rhs, success) );
    7516
    7517 SCIPfreeBufferArray(scip, &vals);
    7518 SCIPfreeBufferArray(scip, &vars);
    7519
    7520 return SCIP_OKAY;
    7521}
    7522
    7523/*
    7524 * Callback methods of constraint handler
    7525 */
    7526
    7527/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    7528static
    7529SCIP_DECL_CONSHDLRCOPY(conshdlrCopySetppc)
    7530{ /*lint --e{715}*/
    7531 assert(scip != NULL);
    7532 assert(conshdlr != NULL);
    7533 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    7534
    7535 /* call inclusion method of constraint handler */
    7537
    7538 *valid = TRUE;
    7539
    7540 return SCIP_OKAY;
    7541}
    7542
    7543/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
    7544static
    7545SCIP_DECL_CONSFREE(consFreeSetppc)
    7546{ /*lint --e{715}*/
    7547 SCIP_CONSHDLRDATA* conshdlrdata;
    7548
    7549 assert(conshdlr != NULL);
    7550 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    7551 assert(scip != NULL);
    7552
    7553 /* free constraint handler data */
    7554 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    7555 assert(conshdlrdata != NULL);
    7556 SCIP_CALL( conshdlrdataFree(scip, &conshdlrdata) );
    7557
    7558 SCIPconshdlrSetData(conshdlr, NULL);
    7559
    7560 return SCIP_OKAY;
    7561}
    7562
    7563
    7564/** initialization method of constraint handler (called after problem was transformed) */
    7565static
    7566SCIP_DECL_CONSINIT(consInitSetppc)
    7567{ /*lint --e{715}*/
    7568 SCIP_CONSHDLRDATA* conshdlrdata;
    7569
    7570 assert(conshdlr != NULL);
    7571 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    7572 assert(scip != NULL);
    7573
    7574 /* free constraint handler data */
    7575 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    7576 assert(conshdlrdata != NULL);
    7577
    7578 conshdlrdata->noldfixedvars = 0;
    7579 conshdlrdata->noldimpls = 0;
    7580 conshdlrdata->noldcliques = 0;
    7581 conshdlrdata->noldupgrs = 0;
    7582 conshdlrdata->nclqpresolve = 0;
    7583 conshdlrdata->updatedsetppctype = FALSE;
    7584 conshdlrdata->enablecliquelifting = TRUE;
    7585
    7586 return SCIP_OKAY;
    7587}
    7588
    7589
    7590/** presolving deinitialization method of constraint handler (called after presolving has been finished) */
    7591static
    7592SCIP_DECL_CONSEXITPRE(consExitpreSetppc)
    7593{ /*lint --e{715}*/
    7594 int c;
    7595
    7596 assert(scip != NULL);
    7597 assert(conshdlr != NULL);
    7598
    7599 for( c = 0; c < nconss; ++c )
    7600 {
    7601 if( !SCIPconsIsDeleted(conss[c]) )
    7602 {
    7603 /* we are not allowed to detect infeasibility in the exitpre stage */
    7604 SCIP_CALL( applyFixings(scip, conss[c], NULL, NULL, NULL, NULL) );
    7605 }
    7606 }
    7607
    7608 return SCIP_OKAY;
    7609}
    7610
    7611/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
    7612static
    7613SCIP_DECL_CONSINITSOL(consInitsolSetppc)
    7614{ /*lint --e{715}*/
    7615 /* add nlrow representation to NLP, if NLP had been constructed */
    7617 {
    7618 int c;
    7619 for( c = 0; c < nconss; ++c )
    7620 {
    7621 SCIP_CALL( addNlrow(scip, conss[c]) );
    7622 }
    7623 }
    7624
    7625 return SCIP_OKAY;
    7626}
    7627
    7628/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
    7629static
    7630SCIP_DECL_CONSEXITSOL(consExitsolSetppc)
    7631{ /*lint --e{715}*/
    7632 SCIP_CONSDATA* consdata;
    7633 int c;
    7634
    7635 /* release the rows and nlrows of all constraints */
    7636 for( c = 0; c < nconss; ++c )
    7637 {
    7638 consdata = SCIPconsGetData(conss[c]);
    7639 assert(consdata != NULL);
    7640
    7641 if( consdata->row != NULL )
    7642 {
    7643 SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
    7644 }
    7645
    7646 if( consdata->nlrow != NULL )
    7647 {
    7648 SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow) );
    7649 }
    7650 }
    7651
    7652 return SCIP_OKAY;
    7653}
    7654
    7655
    7656/** frees specific constraint data */
    7657static
    7658SCIP_DECL_CONSDELETE(consDeleteSetppc)
    7659{ /*lint --e{715}*/
    7660 SCIP_CONSHDLRDATA* conshdlrdata;
    7661
    7662 assert(conshdlr != NULL);
    7663 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    7664
    7665 /* get event handler */
    7666 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    7667 assert(conshdlrdata != NULL);
    7668 assert(conshdlrdata->eventhdlr != NULL);
    7669
    7670 if( SCIPisTransformed(scip) )
    7671 {
    7672 if( (SCIP_SETPPCTYPE)((*consdata)->setppctype) == SCIP_SETPPCTYPE_PARTITIONING )
    7673 {
    7674 --(conshdlrdata->nsetpart);
    7675 assert(conshdlrdata->nsetpart >= 0);
    7676 }
    7677 }
    7678
    7679 /* if constraint belongs to transformed problem space, drop bound change events on variables */
    7680 if( (*consdata)->nvars > 0 && SCIPvarIsTransformed((*consdata)->vars[0]) )
    7681 {
    7682 SCIP_CALL( dropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    7683 }
    7684
    7685 /* free setppc constraint data */
    7686 SCIP_CALL( consdataFree(scip, consdata) );
    7687
    7688 return SCIP_OKAY;
    7689}
    7690
    7691
    7692/** transforms constraint data into data belonging to the transformed problem */
    7693static
    7694SCIP_DECL_CONSTRANS(consTransSetppc)
    7695{ /*lint --e{715}*/
    7696 SCIP_CONSHDLRDATA* conshdlrdata;
    7697 SCIP_CONSDATA* sourcedata;
    7698 SCIP_CONSDATA* targetdata;
    7699
    7700 /*debugMsg(scip, "Trans method of setppc constraints\n");*/
    7701
    7702 assert(conshdlr != NULL);
    7703 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    7705 assert(sourcecons != NULL);
    7706 assert(targetcons != NULL);
    7707
    7708 /* get event handler */
    7709 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    7710 assert(conshdlrdata != NULL);
    7711 assert(conshdlrdata->eventhdlr != NULL);
    7712
    7713 sourcedata = SCIPconsGetData(sourcecons);
    7714 assert(sourcedata != NULL);
    7715 assert(sourcedata->row == NULL); /* in original problem, there cannot be LP rows */
    7716
    7717 /* create constraint data for target constraint */
    7718 SCIP_CALL( consdataCreateTransformed(scip, &targetdata, sourcedata->nvars, sourcedata->vars,
    7719 (SCIP_SETPPCTYPE)sourcedata->setppctype) );
    7720
    7721 /* create target constraint */
    7722 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
    7723 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    7724 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
    7725 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
    7726 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
    7727
    7728 if( (SCIP_SETPPCTYPE)sourcedata->setppctype == SCIP_SETPPCTYPE_PARTITIONING )
    7729 {
    7730 ++(conshdlrdata->nsetpart);
    7731 assert(conshdlrdata->nsetpart >= 0);
    7732 }
    7733
    7734 /* catch bound change events of variables */
    7735 SCIP_CALL( catchAllEvents(scip, *targetcons, conshdlrdata->eventhdlr) );
    7736
    7737 return SCIP_OKAY;
    7738}
    7739
    7740
    7741/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
    7742static
    7743SCIP_DECL_CONSINITLP(consInitlpSetppc)
    7744{ /*lint --e{715}*/
    7745 int c;
    7746
    7747 *infeasible = FALSE;
    7748
    7749 for( c = 0; c < nconss && !(*infeasible); ++c )
    7750 {
    7751 assert(SCIPconsIsInitial(conss[c]));
    7752 SCIP_CALL( addCut(scip, conss[c], infeasible) );
    7753 }
    7754
    7755 return SCIP_OKAY;
    7756}
    7757
    7758
    7759/** separation method of constraint handler for LP solutions */
    7760static
    7761SCIP_DECL_CONSSEPALP(consSepalpSetppc)
    7762{ /*lint --e{715}*/
    7763 SCIP_Bool cutoff;
    7764 SCIP_Bool separated;
    7765 SCIP_Bool reduceddom;
    7766 int c;
    7767
    7768 assert(conshdlr != NULL);
    7769 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    7770 assert(nconss == 0 || conss != NULL);
    7771 assert(result != NULL);
    7772
    7773 SCIPdebugMsg(scip, "separating %d/%d set partitioning / packing / covering constraints\n", nusefulconss, nconss);
    7774
    7775 *result = SCIP_DIDNOTFIND;
    7776
    7777 cutoff = FALSE;
    7778 separated = FALSE;
    7779 reduceddom = FALSE;
    7780
    7781 /* check all useful set partitioning / packing / covering constraints for feasibility */
    7782 for( c = 0; c < nusefulconss && !cutoff; ++c )
    7783 {
    7784 SCIP_CALL( separateCons(scip, conss[c], NULL, TRUE, &cutoff, &separated, &reduceddom) );
    7785 }
    7786
    7787 /* combine set partitioning / packing / covering constraints to get more cuts */
    7788 /**@todo further cuts of set partitioning / packing / covering constraints */
    7789
    7790 /* return the correct result */
    7791 if( cutoff )
    7792 *result = SCIP_CUTOFF;
    7793 else if( reduceddom )
    7794 *result = SCIP_REDUCEDDOM;
    7795 else if( separated )
    7796 *result = SCIP_SEPARATED;
    7797
    7798 return SCIP_OKAY;
    7799}
    7800
    7801
    7802/** separation method of constraint handler for arbitrary primal solutions */
    7803static
    7804SCIP_DECL_CONSSEPASOL(consSepasolSetppc)
    7805{ /*lint --e{715}*/
    7806 SCIP_Bool cutoff;
    7807 SCIP_Bool separated;
    7808 SCIP_Bool reduceddom;
    7809 int c;
    7810
    7811 assert(conshdlr != NULL);
    7812 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    7813 assert(nconss == 0 || conss != NULL);
    7814 assert(result != NULL);
    7815
    7816 SCIPdebugMsg(scip, "separating %d/%d set partitioning / packing / covering constraints\n", nusefulconss, nconss);
    7817
    7818 *result = SCIP_DIDNOTFIND;
    7819
    7820 cutoff = FALSE;
    7821 separated = FALSE;
    7822 reduceddom = FALSE;
    7823
    7824 /* check all useful set partitioning / packing / covering constraints for feasibility */
    7825 for( c = 0; c < nusefulconss && !cutoff; ++c )
    7826 {
    7827 SCIP_CALL( separateCons(scip, conss[c], sol, FALSE, &cutoff, &separated, &reduceddom) );
    7828 }
    7829
    7830 /* combine set partitioning / packing / covering constraints to get more cuts */
    7831 /**@todo further cuts of set partitioning / packing / covering constraints */
    7832
    7833 /* return the correct result */
    7834 if( cutoff )
    7835 *result = SCIP_CUTOFF;
    7836 else if( reduceddom )
    7837 *result = SCIP_REDUCEDDOM;
    7838 else if( separated )
    7839 *result = SCIP_SEPARATED;
    7840
    7841 return SCIP_OKAY;
    7842}
    7843
    7844
    7845#ifdef VARUSES
    7846#ifdef BRANCHLP
    7847/** if fractional variables exist, chooses a set S of them and branches on (i) x(S) == 0, and (ii) x(S) >= 1 */
    7848static
    7849SCIP_RETCODE branchLP(
    7850 SCIP* scip, /**< SCIP data structure */
    7851 SCIP_CONSHDLR* conshdlr, /**< set partitioning / packing / covering constraint handler */
    7852 SCIP_RESULT* result /**< pointer to store the result SCIP_BRANCHED, if branching was applied */
    7853 )
    7854{
    7855 SCIP_CONSHDLRDATA* conshdlrdata;
    7856 SCIP_INTARRAY* varuses;
    7857 SCIP_VAR** lpcands;
    7858 SCIP_VAR** sortcands;
    7859 SCIP_VAR* var;
    7860 SCIP_Real branchweight;
    7861 SCIP_Real solval;
    7862 int* uses;
    7863 int nlpcands;
    7864 int nsortcands;
    7865 int nselcands;
    7866 int numuses;
    7867 int i;
    7868 int j;
    7869
    7870 /**@todo use a better set partitioning / packing / covering branching on LP solution (use SOS branching) */
    7871
    7872 assert(conshdlr != NULL);
    7873 assert(result != NULL);
    7874
    7875 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    7876 assert(conshdlrdata != NULL);
    7877
    7878 varuses = conshdlrdata->varuses;
    7879 assert(varuses != NULL);
    7880
    7881 /* get fractional variables */
    7882 SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, NULL, NULL, &nlpcands, NULL, NULL) );
    7883 if( nlpcands == 0 )
    7884 return SCIP_OKAY;
    7885
    7886 assert(MINBRANCHWEIGHT <= MAXBRANCHWEIGHT);
    7887
    7888 /* get temporary memory */
    7889 SCIP_CALL( SCIPallocBufferArray(scip, &sortcands, nlpcands) );
    7890 SCIP_CALL( SCIPallocBufferArray(scip, &uses, nlpcands) );
    7891
    7892 /* sort fractional variables by number of uses in enabled set partitioning / packing / covering constraints */
    7893 nsortcands = 0;
    7894 for( i = 0; i < nlpcands; ++i )
    7895 {
    7896 var = lpcands[i];
    7897 numuses = SCIPgetIntarrayVal(scip, varuses, SCIPvarGetIndex(var));
    7898 if( numuses > 0 )
    7899 {
    7900 for( j = nsortcands; j > 0 && numuses > uses[j-1]; --j )
    7901 {
    7902 sortcands[j] = sortcands[j-1];
    7903 uses[j] = uses[j-1];
    7904 }
    7905 assert(0 <= j && j <= nsortcands);
    7906 sortcands[j] = var;
    7907 uses[j] = numuses;
    7908 nsortcands++;
    7909 }
    7910 }
    7911 assert(nsortcands <= nlpcands);
    7912
    7913 /* if none of the fractional variables is member of a set partitioning / packing / covering constraint,
    7914 * we are not responsible for doing the branching
    7915 */
    7916 if( nsortcands > 0 )
    7917 {
    7918 SCIP_Real cumprio = 0.0;
    7919 SCIP_Real minprio = SCIP_INVALID;
    7920 SCIP_Real minestzero = SCIP_INVALID;
    7921 SCIP_Real minestone = SCIP_INVALID;
    7922 SCIP_Real tmp;
    7923
    7924 /* select the first variables from the sorted candidate list, until MAXBRANCHWEIGHT is reached;
    7925 * then choose one less
    7926 */
    7927 branchweight = 0.0;
    7928 solval = 0.0;
    7929 for( nselcands = 0; nselcands < nsortcands; ++nselcands )
    7930 {
    7931 solval = SCIPgetVarSol(scip, sortcands[nselcands]);
    7932 assert(SCIPisFeasGE(scip, solval, 0.0) && SCIPisFeasLE(scip, solval, 1.0));
    7933 branchweight += solval;
    7934
    7935 /* did we exceed the maximal weight */
    7936 if( branchweight > MAXBRANCHWEIGHT )
    7937 break;
    7938
    7939 /* @todo instead of taking the minimum into account try other variants like the maximum and the average */
    7940 /* calculate priorities and estimates by adding up/taking the minimum of all single priorities/estimates */
    7941 cumprio += SCIPcalcNodeselPriority(scip, sortcands[nselcands], SCIP_BRANCHDIR_DOWNWARDS, 0.0);
    7942 tmp = SCIPcalcNodeselPriority(scip, sortcands[nselcands], SCIP_BRANCHDIR_UPWARDS, 1.0);
    7943 minprio = MIN(minprio, tmp);
    7944 tmp = SCIPcalcChildEstimate(scip, sortcands[nselcands], 0.0);;
    7945 minestzero = MIN(minestzero, tmp);
    7946 tmp = SCIPcalcChildEstimate(scip, sortcands[nselcands], 1.0);;
    7947 minestone = MIN(minestone, tmp);
    7948 }
    7949 assert(minestzero != SCIP_INVALID); /*lint !e777*/
    7950 assert(minestone != SCIP_INVALID); /*lint !e777*/
    7951 assert(minprio != SCIP_INVALID); /*lint !e777*/
    7952 assert(nselcands > 0);
    7953 branchweight -= solval;
    7954
    7955 /* check, if we accumulated at least MIN and at most MAXBRANCHWEIGHT weight */
    7956 if( MINBRANCHWEIGHT <= branchweight && branchweight <= MAXBRANCHWEIGHT )
    7957 {
    7958 SCIP_NODE* node;
    7959
    7960 /* perform the binary set branching on the selected variables */
    7961 assert(1 <= nselcands && nselcands <= nlpcands);
    7962
    7963 /* create left child, fix x_i = 0 for all i \in S */
    7964 SCIP_CALL( SCIPcreateChild(scip, &node, cumprio, minestzero) );
    7965 for( i = 0; i < nselcands; ++i )
    7966 {
    7967 SCIP_CALL( SCIPchgVarUbNode(scip, node, sortcands[i], 0.0) );
    7968 }
    7969
    7970 /* create right child: add constraint x(S) >= 1 */
    7971 SCIP_CALL( SCIPcreateChild(scip, &node, minprio, minestone) );
    7972 if( nselcands == 1 )
    7973 {
    7974 /* only one candidate selected: fix it to 1.0 */
    7975 SCIPdebugMsg(scip, "fixing variable <%s> to 1.0 in right child node\n", SCIPvarGetName(sortcands[0]));
    7976 SCIP_CALL( SCIPchgVarLbNode(scip, node, sortcands[0], 1.0) );
    7977 }
    7978 else
    7979 {
    7980 SCIP_CONS* newcons;
    7981 char name[SCIP_MAXSTRLEN];
    7982
    7983 /* add set covering constraint x(S) >= 1 */
    7985
    7986 SCIP_CALL( SCIPcreateConsSetcover(scip, &newcons, name, nselcands, sortcands,
    7988 SCIP_CALL( SCIPaddConsNode(scip, node, newcons, NULL) );
    7989 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    7990 }
    7991
    7992 *result = SCIP_BRANCHED;
    7993
    7994#ifdef SCIP_DEBUG
    7995 SCIPdebugMsg(scip, "binary set branching: nselcands=%d/%d, weight(S)=%g, A={", nselcands, nlpcands, branchweight);
    7996 for( i = 0; i < nselcands; ++i )
    7997 SCIPdebugMsgPrint(scip, " %s[%g]", SCIPvarGetName(sortcands[i]), SCIPgetSolVal(scip, NULL, sortcands[i]));
    7998 SCIPdebugMsgPrint(scip, " }\n");
    7999#endif
    8000 }
    8001 }
    8002
    8003 /* free temporary memory */
    8004 SCIPfreeBufferArray(scip, &uses);
    8005 SCIPfreeBufferArray(scip, &sortcands);
    8006
    8007 return SCIP_OKAY;
    8008}
    8009#endif
    8010
    8011/** if unfixed variables exist, chooses a set S of them and creates |S|+1 child nodes:
    8012 * - for each variable i from S, create child node with x_0 = ... = x_i-1 = 0, x_i = 1
    8013 * - create an additional child node x_0 = ... = x_n-1 = 0
    8014 */
    8015static
    8016SCIP_RETCODE branchPseudo(
    8017 SCIP* scip, /**< SCIP data structure */
    8018 SCIP_CONSHDLR* conshdlr, /**< set partitioning / packing / covering constraint handler */
    8019 SCIP_RESULT* result /**< pointer to store the result SCIP_BRANCHED, if branching was applied */
    8020 )
    8021{
    8022 SCIP_CONSHDLRDATA* conshdlrdata;
    8023 SCIP_INTARRAY* varuses;
    8024 SCIP_VAR** pseudocands;
    8025 SCIP_VAR** branchcands;
    8026 SCIP_VAR* var;
    8027 SCIP_NODE* node;
    8028 int* canduses;
    8029 int npseudocands;
    8030 int maxnbranchcands;
    8031 int nbranchcands;
    8032 int uses;
    8033 int i;
    8034 int j;
    8035
    8036 /**@todo use a better set partitioning / packing / covering branching on pseudo solution (use SOS branching) */
    8037
    8038 assert(conshdlr != NULL);
    8039 assert(result != NULL);
    8040
    8041 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    8042 assert(conshdlrdata != NULL);
    8043
    8044 /* check, if pseudo branching is disabled */
    8045 if( conshdlrdata->npseudobranches <= 1 )
    8046 return SCIP_OKAY;
    8047
    8048 /* get fractional variables */
    8049 SCIP_CALL( SCIPgetPseudoBranchCands(scip, &pseudocands, NULL, &npseudocands) );
    8050 if( npseudocands == 0 )
    8051 return SCIP_OKAY;
    8052
    8053 varuses = conshdlrdata->varuses;
    8054 assert(varuses != NULL);
    8055
    8056 /* choose the maximal number of branching variables */
    8057 maxnbranchcands = conshdlrdata->npseudobranches-1;
    8058 assert(maxnbranchcands >= 1);
    8059
    8060 /* get temporary memory */
    8061 SCIP_CALL( SCIPallocBufferArray(scip, &branchcands, maxnbranchcands) );
    8062 SCIP_CALL( SCIPallocBufferArray(scip, &canduses, maxnbranchcands) );
    8063
    8064 /* sort unfixed variables by number of uses in enabled set partitioning / packing / covering constraints */
    8065 nbranchcands = 0;
    8066 for( i = 0; i < npseudocands; ++i )
    8067 {
    8068 var = pseudocands[i];
    8069 uses = SCIPgetIntarrayVal(scip, varuses, SCIPvarGetIndex(var));
    8070 if( uses > 0 )
    8071 {
    8072 if( nbranchcands < maxnbranchcands || uses > canduses[nbranchcands-1] )
    8073 {
    8074 for( j = MIN(nbranchcands, maxnbranchcands-1); j > 0 && uses > canduses[j-1]; --j )
    8075 {
    8076 branchcands[j] = branchcands[j-1];
    8077 canduses[j] = canduses[j-1];
    8078 }
    8079 assert(0 <= j && j <= nbranchcands && j < maxnbranchcands);
    8080 branchcands[j] = var;
    8081 canduses[j] = uses;
    8082 if( nbranchcands < maxnbranchcands )
    8083 nbranchcands++;
    8084 }
    8085 }
    8086 }
    8087 assert(nbranchcands <= maxnbranchcands);
    8088
    8089 /* if none of the unfixed variables is member of a set partitioning / packing / covering constraint,
    8090 * we are not responsible for doing the branching
    8091 */
    8092 if( nbranchcands > 0 )
    8093 {
    8094 SCIP_Real* estone;
    8095 SCIP_Real minestzero = SCIP_INVALID;
    8096 SCIP_Real tmp;
    8097
    8098 SCIP_CALL( SCIPallocBufferArray(scip, &estone, nbranchcands) );
    8099
    8100 /* @todo instead of taking the minimum into account try other variants like the maximum and the average */
    8101 /* @todo calculate priorities instead of setting it to the number of branching candidates */
    8102 /* calculate estimates by taking the minimum over all single estimates */
    8103 for( i = 0; i < nbranchcands; ++i )
    8104 {
    8105 tmp = SCIPcalcChildEstimate(scip, branchcands[i], 0.0);;
    8106 minestzero = MIN(minestzero, tmp);
    8107 estone[i] = SCIPcalcChildEstimate(scip, branchcands[i], 1.0);
    8108 }
    8109 assert(minestzero != SCIP_INVALID); /*lint !e777*/
    8110
    8111 /* branch on the first part of the sorted candidates:
    8112 * - for each of these variables i, create a child node x_0 = ... = x_i-1 = 0, x_i = 1
    8113 * - create an additional child node x_0 = ... = x_n-1 = 0
    8114 */
    8115 for( i = 0; i < nbranchcands; ++i )
    8116 {
    8117 /* create child with x_0 = ... = x_i-1 = 0, x_i = 1 */
    8118 SCIP_CALL( SCIPcreateChild(scip, &node, (SCIP_Real)nbranchcands, MIN(minestzero, estone[i])) );
    8119 for( j = 0; j < i; ++j )
    8120 {
    8121 SCIP_CALL( SCIPchgVarUbNode(scip, node, branchcands[j], 0.0) );
    8122 }
    8123 SCIP_CALL( SCIPchgVarLbNode(scip, node, branchcands[i], 1.0) );
    8124 }
    8125 /* create child with x_0 = ... = x_n = 0 */
    8126 SCIP_CALL( SCIPcreateChild(scip, &node, (SCIP_Real)nbranchcands, minestzero) );
    8127 for( i = 0; i < nbranchcands; ++i )
    8128 {
    8129 SCIP_CALL( SCIPchgVarUbNode(scip, node, branchcands[i], 0.0) );
    8130 }
    8131
    8132 *result = SCIP_BRANCHED;
    8133
    8134 SCIPfreeBufferArray(scip, &estone);
    8135
    8136#ifdef SCIP_DEBUG
    8137 {
    8138 int nchildren;
    8139 SCIP_CALL( SCIPgetChildren(scip, NULL, &nchildren) );
    8140 SCIPdebugMsg(scip, "branched on pseudo solution: %d children\n", nchildren);
    8141 }
    8142#endif
    8143 }
    8144
    8145 /* free temporary memory */
    8146 SCIPfreeBufferArray(scip, &canduses);
    8147 SCIPfreeBufferArray(scip, &branchcands);
    8148
    8149 return SCIP_OKAY;
    8150}
    8151#endif
    8152
    8153
    8154/** constraint enforcing method of constraint handler for LP solutions */
    8155static
    8156SCIP_DECL_CONSENFOLP(consEnfolpSetppc)
    8157{ /*lint --e{715}*/
    8158 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
    8159
    8160 return SCIP_OKAY;
    8161}
    8162
    8163
    8164/** constraint enforcing method of constraint handler for relaxation solutions */
    8165static
    8166SCIP_DECL_CONSENFORELAX(consEnforelaxSetppc)
    8167{ /*lint --e{715}*/
    8168 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
    8169
    8170 return SCIP_OKAY;
    8171}
    8172
    8173
    8174/** constraint enforcing method of constraint handler for pseudo solutions */
    8175static
    8176SCIP_DECL_CONSENFOPS(consEnfopsSetppc)
    8177{ /*lint --e{715}*/
    8178 SCIP_Bool cutoff;
    8179 SCIP_Bool infeasible;
    8180 SCIP_Bool reduceddom;
    8181 SCIP_Bool solvelp;
    8182 int c;
    8183
    8184 assert(conshdlr != NULL);
    8185 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    8186 assert(nconss == 0 || conss != NULL);
    8187 assert(result != NULL);
    8188
    8189 /* if the solution is infeasible anyway due to objective value, skip the constraint processing and branch directly */
    8190#ifdef VARUSES
    8191 if( objinfeasible )
    8192 {
    8193 *result = SCIP_DIDNOTRUN;
    8194 SCIP_CALL( branchPseudo(scip, conshdlr, result) );
    8195 return SCIP_OKAY;
    8196 }
    8197#endif
    8198
    8199 SCIPdebugMsg(scip, "pseudo enforcing %d set partitioning / packing / covering constraints\n", nconss);
    8200
    8201 *result = SCIP_FEASIBLE;
    8202
    8203 cutoff = FALSE;
    8204 infeasible = FALSE;
    8205 reduceddom = FALSE;
    8206 solvelp = FALSE;
    8207
    8208 /* check all set partitioning / packing / covering constraints for feasibility */
    8209 for( c = 0; c < nconss && !cutoff && !reduceddom && !solvelp; ++c )
    8210 {
    8211 SCIP_CALL( enforcePseudo(scip, conss[c], &cutoff, &infeasible, &reduceddom, &solvelp) );
    8212 }
    8213
    8214 if( cutoff )
    8215 *result = SCIP_CUTOFF;
    8216 else if( reduceddom )
    8217 *result = SCIP_REDUCEDDOM;
    8218 else if( solvelp )
    8219 *result = SCIP_SOLVELP;
    8220 else if( infeasible )
    8221 {
    8222 *result = SCIP_INFEASIBLE;
    8223
    8224#ifdef VARUSES
    8225 /* at least one constraint is violated by pseudo solution and we didn't find a better way to resolve this:
    8226 * -> branch on pseudo solution
    8227 */
    8228 SCIP_CALL( branchPseudo(scip, conshdlr, result) );
    8229#endif
    8230 }
    8231
    8232 return SCIP_OKAY;
    8233}
    8234
    8235
    8236/** feasibility check method of constraint handler for integral solutions */
    8237static
    8238SCIP_DECL_CONSCHECK(consCheckSetppc)
    8239{ /*lint --e{715}*/
    8240 SCIP_CONS* cons;
    8241 SCIP_CONSDATA* consdata;
    8242 int c;
    8243
    8244 assert(conshdlr != NULL);
    8245 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    8246 assert(nconss == 0 || conss != NULL);
    8247 assert(result != NULL);
    8248
    8249 *result = SCIP_FEASIBLE;
    8250
    8251 /* check all set partitioning / packing / covering constraints for feasibility */
    8252 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
    8253 {
    8254 cons = conss[c];
    8255 consdata = SCIPconsGetData(cons);
    8256 assert(consdata != NULL);
    8257 if( checklprows || consdata->row == NULL || !SCIProwIsInLP(consdata->row) )
    8258 {
    8259 if( !checkCons(scip, consdata, sol) )
    8260 {
    8261 /* constraint is violated */
    8262 *result = SCIP_INFEASIBLE;
    8263
    8264 if( printreason )
    8265 {
    8266 SCIP_Real sum = 0.0;
    8267 int v;
    8268
    8269 SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
    8270
    8271 for( v = 0; v < consdata->nvars; ++v )
    8272 {
    8273 assert(SCIPvarIsBinary(consdata->vars[v]));
    8274
    8275 sum += SCIPgetSolVal(scip, sol, consdata->vars[v]);
    8276 }
    8277 SCIPinfoMessage(scip, NULL, ";\n");
    8278 SCIPinfoMessage(scip, NULL, "violation: the right hand side is violated by by %.15g\n", ABS(sum - 1));
    8279 }
    8280 }
    8281 }
    8282 }
    8283
    8284 return SCIP_OKAY;
    8285}
    8286
    8287/** domain propagation method of constraint handler */
    8288static
    8289SCIP_DECL_CONSPROP(consPropSetppc)
    8290{ /*lint --e{715}*/
    8291 SCIP_Bool cutoff;
    8292 SCIP_Bool addcut;
    8293 SCIP_Bool mustcheck;
    8294 SCIP_Bool inpresolve;
    8295 int nfixedvars = 0;
    8296 int c;
    8297
    8298 assert(conshdlr != NULL);
    8299 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    8300 assert(nconss == 0 || conss != NULL);
    8301 assert(result != NULL);
    8302
    8303 *result = SCIP_DIDNOTFIND;
    8304
    8305 SCIPdebugMsg(scip, "propagating %d/%d set partitioning / packing / covering constraints\n", nmarkedconss, nconss);
    8306
    8307 cutoff = FALSE;
    8308 inpresolve = (SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE);
    8309
    8310 /* propagate all marked set partitioning / packing / covering constraints */
    8311 for( c = nmarkedconss - 1; c >= 0 && !cutoff; --c )
    8312 {
    8313 assert(SCIPconsGetData(conss[c]) != NULL);
    8314
    8315 /* during presolving, we do not want to propagate constraints with multiaggregated variables. After presolving,
    8316 * we want to resolve the multiaggregation to have a clean data structure; All initial constraints should not
    8317 * have multiaggregated variables, but this is not true for constraints that were introduced during solving
    8318 */
    8319 if( SCIPconsGetData(conss[c])->existmultaggr )
    8320 {
    8321 int naddconss, ndelconss;
    8322
    8323 if( inpresolve )
    8324 continue;
    8325
    8326 naddconss = ndelconss = 0;
    8327 SCIP_CALL( applyFixings(scip, conss[c], &naddconss, &ndelconss, &nfixedvars, &cutoff) );
    8328
    8329 if( cutoff )
    8330 break;
    8331 }
    8332
    8333 /* all multiaggregations should be resolved at here */
    8334 assert(inpresolve || ! SCIPconsGetData(conss[c])->existmultaggr);
    8335
    8336 SCIP_CALL( processFixings(scip, conss[c], &cutoff, &nfixedvars, &addcut, &mustcheck) );
    8337
    8339 }
    8340
    8341 /* return the correct result */
    8342 if( cutoff )
    8343 *result = SCIP_CUTOFF;
    8344 else if( nfixedvars > 0 )
    8345 *result = SCIP_REDUCEDDOM;
    8346
    8347 return SCIP_OKAY; /*lint !e438*/
    8348}
    8349
    8350
    8351/** presolving method of constraint handler */
    8352static
    8353SCIP_DECL_CONSPRESOL(consPresolSetppc)
    8354{ /*lint --e{715}*/
    8355 SCIP_CONSHDLRDATA* conshdlrdata;
    8356 int oldnfixedvars;
    8357 int oldnaggrvars;
    8358 int oldndelconss;
    8359 int oldnchgcoefs;
    8360 int firstchange;
    8361 int firstclique;
    8362 int lastclique;
    8363 int startdelconss;
    8364 int c;
    8365 SCIP_Bool cutoff;
    8366
    8367 assert(conshdlr != NULL);
    8368 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    8369 assert(scip != NULL);
    8370 assert(result != NULL);
    8371
    8372 *result = SCIP_DIDNOTFIND;
    8373 oldnfixedvars = *nfixedvars;
    8374 oldndelconss = *ndelconss;
    8375 oldnaggrvars = *naggrvars;
    8376 oldnchgcoefs = *nchgcoefs;
    8377 cutoff = FALSE;
    8378
    8379 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    8380 assert(conshdlrdata != NULL);
    8381
    8382 /* determine whether we want to run the clique lifting procedure */
    8383 conshdlrdata->enablecliquelifting = conshdlrdata->enablecliquelifting || conshdlrdata->updatedsetppctype
    8384 || conshdlrdata->noldfixedvars != SCIPgetNFixedVars(scip) || conshdlrdata->noldimpls != SCIPgetNImplications(scip)
    8385 || conshdlrdata->noldcliques != SCIPgetNCliques(scip) || conshdlrdata->noldupgrs != nconss;
    8386
    8387 /* remember old values */
    8388 startdelconss = *ndelconss;
    8389 conshdlrdata->noldimpls = SCIPgetNImplications(scip);
    8390 conshdlrdata->noldcliques = SCIPgetNCliques(scip);
    8391 conshdlrdata->updatedsetppctype = FALSE;
    8392
    8393 /* process constraints */
    8394 firstchange = INT_MAX;
    8395 firstclique = INT_MAX;
    8396 lastclique = -1;
    8397 for( c = 0; c < nconss && !SCIPisStopped(scip); ++c )
    8398 {
    8399 SCIP_CONS* cons;
    8400 SCIP_CONSDATA* consdata;
    8401
    8402 assert(*result != SCIP_CUTOFF);
    8403
    8404 cons = conss[c];
    8405 assert(cons != NULL);
    8406 consdata = SCIPconsGetData(cons);
    8407 assert(consdata != NULL);
    8408
    8409 /*SCIPdebugMsg(scip, "presolving set partitioning / packing / covering constraint <%s>\n", SCIPconsGetName(cons));*/
    8410
    8411 /* remove all variables that are fixed to zero and replace all aggregated variables */
    8412 if( consdata->nfixedzeros > 0 || nnewaggrvars > 0 || nnewaddconss > 0 || nnewupgdconss > 0
    8413 || *naggrvars > oldnaggrvars || (nrounds == 0 && SCIPgetNRuns(scip) > 1) )
    8414 {
    8415 SCIP_CALL( applyFixings(scip, cons, naddconss, ndelconss, nfixedvars, &cutoff) );
    8416
    8417 if( cutoff )
    8418 {
    8419 *result = SCIP_CUTOFF;
    8420 return SCIP_OKAY;
    8421 }
    8422
    8423 if( SCIPconsIsDeleted(cons) )
    8424 continue;
    8425 }
    8426
    8427 /* find pairs of negated variables in constraint:
    8428 * partitioning/packing: all other variables must be zero, constraint is redundant
    8429 * covering: constraint is redundant
    8430 *
    8431 * find sets of equal variables in constraint:
    8432 * partitioning/packing: variable must be zero
    8433 * covering: multiple entries of variable can be replaced by single entry
    8434 */
    8435 SCIP_CALL( mergeMultiples(scip, cons, nfixedvars, ndelconss, nchgcoefs, &cutoff) );
    8436
    8437 if( cutoff )
    8438 {
    8439 *result = SCIP_CUTOFF;
    8440 return SCIP_OKAY;
    8441 }
    8442
    8443 /* if constraint was deleted while merging, go to the next constraint */
    8444 if( !SCIPconsIsActive(cons) )
    8445 continue;
    8446
    8447 /* remove fixings found by merging */
    8448 if( consdata->nfixedzeros > 0 )
    8449 {
    8450 SCIP_CALL( applyFixings(scip, cons, naddconss, ndelconss, nfixedvars, &cutoff) );
    8451
    8452 if( cutoff )
    8453 {
    8454 *result = SCIP_CUTOFF;
    8455 return SCIP_OKAY;
    8456 }
    8457
    8458 if( SCIPconsIsDeleted(cons) )
    8459 continue;
    8460 }
    8461
    8462 /* check if constraint is already redundant or infeasible due to fixings, fix or aggregate left over variables if
    8463 * possible
    8464 */
    8465 SCIP_CALL( presolvePropagateCons(scip, cons, TRUE, NULL, NULL, NULL, NULL, nfixedvars, naggrvars, ndelconss, &cutoff) );
    8466
    8467 if( cutoff )
    8468 {
    8469 *result = SCIP_CUTOFF;
    8470 return SCIP_OKAY;
    8471 }
    8472
    8473 /* if constraint was deleted while propagation, go to the next constraint */
    8474 if( !SCIPconsIsActive(cons) )
    8475 continue;
    8476
    8477 /* remove fixings found by presolvePropagateCons() */
    8478 if( consdata->nfixedzeros > 0 )
    8479 {
    8480 SCIP_CALL( applyFixings(scip, cons, naddconss, ndelconss, nfixedvars, &cutoff) );
    8481
    8482 if( cutoff )
    8483 {
    8484 *result = SCIP_CUTOFF;
    8485 return SCIP_OKAY;
    8486 }
    8487
    8488 if( SCIPconsIsDeleted(cons) )
    8489 continue;
    8490 }
    8491
    8492 /* perform dual reductions */
    8493 if( conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) )
    8494 {
    8495 SCIP_CALL( dualPresolving(scip, cons, nfixedvars, ndelconss, naggrvars, result) );
    8496
    8497 /* if dual reduction deleted the constraint we take the next */
    8498 if( !SCIPconsIsActive(cons) )
    8499 continue;
    8500 }
    8501
    8502 /* remember the first changed constraint to begin the next redundancy round with */
    8503 if( firstchange == INT_MAX && consdata->changed )
    8504 firstchange = c;
    8505
    8506 /* remember the first and last constraints for which we have to add the clique information */
    8507 if( !consdata->cliqueadded && consdata->nvars >= 2 )
    8508 {
    8509 if( firstclique == INT_MAX )
    8510 firstclique = c;
    8511 lastclique = c;
    8512 }
    8513 }
    8514
    8515 /* update result pointer */
    8516 if( oldnfixedvars < *nfixedvars || oldnaggrvars < *naggrvars || oldndelconss < *ndelconss || oldnchgcoefs < *nchgcoefs )
    8517 *result = SCIP_SUCCESS;
    8518
    8519 if( firstchange < nconss && conshdlrdata->presolusehashing )
    8520 {
    8521 /* detect redundant constraints; fast version with hash table instead of pairwise comparison */
    8522 SCIP_CALL( detectRedundantConstraints(scip, SCIPblkmem(scip), conss, nconss, &firstchange, ndelconss, nchgsides) );
    8523 if( oldndelconss < *ndelconss )
    8524 *result = SCIP_SUCCESS;
    8525 }
    8526
    8527 /* determine singleton variables in set-partitioning/-packing constraints, or doubleton variables (active and
    8528 * negated) in any combination of set-partitioning and set-packing constraints
    8529 */
    8530 if( nconss > 1 && (presoltiming & SCIP_PRESOLTIMING_MEDIUM) != 0
    8531 && ((conshdlrdata->nsetpart > 0 && !SCIPdoNotMultaggr(scip) && conshdlrdata->conshdlrlinear != NULL)
    8532 || (conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip)
    8533 && conshdlrdata->nsetpart < nconss && !SCIPdoNotAggr(scip))) )
    8534 {
    8535 SCIP_CALL( removeDoubleAndSingletonsAndPerformDualpresolve(scip, conss, nconss, conshdlrdata->dualpresolving
    8536 && SCIPallowStrongDualReds(scip), conshdlrdata->conshdlrlinear != NULL, nfixedvars,
    8537 naggrvars, ndelconss, nchgcoefs, nchgsides, &cutoff) );
    8538
    8539 if( cutoff )
    8540 {
    8541 *result = SCIP_CUTOFF;
    8542 return SCIP_OKAY;
    8543 }
    8544 else if( oldnfixedvars < *nfixedvars || oldnaggrvars < *naggrvars || oldndelconss < *ndelconss )
    8545 *result = SCIP_SUCCESS;
    8546 }
    8547
    8548 /* clique lifting */
    8549 if( conshdlrdata->cliquelifting && conshdlrdata->enablecliquelifting && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 )
    8550 {
    8551 /* add cliques first before lifting variables */
    8552 SCIP_CALL( addCliques(scip, conss, nconss, firstclique, lastclique, naddconss, ndelconss, nchgbds, &cutoff) );
    8553
    8554 if( cutoff )
    8555 {
    8556 *result = SCIP_CUTOFF;
    8557 return SCIP_OKAY;
    8558 }
    8559
    8560 firstclique = nconss;
    8561 lastclique = -1;
    8562
    8563 /* lift variables and check for fixings due to clique information */
    8564 SCIP_CALL( preprocessCliques(scip, conshdlrdata, conss, nconss, nrounds, &firstchange, &firstclique,
    8565 &lastclique, nfixedvars, naggrvars, ndelconss, nchgcoefs, &cutoff) );
    8566 ++(conshdlrdata->nclqpresolve);
    8567
    8568 if( cutoff )
    8569 {
    8570 *result = SCIP_CUTOFF;
    8571 return SCIP_OKAY;
    8572 }
    8573 else if( oldnfixedvars < *nfixedvars || oldnaggrvars < *naggrvars || oldndelconss < *ndelconss || oldnchgcoefs < *nchgcoefs )
    8574 *result = SCIP_SUCCESS;
    8575
    8576 /* remember the number of fixings */
    8577 conshdlrdata->noldfixedvars = *nfixedvars + *naggrvars;
    8578 conshdlrdata->enablecliquelifting = FALSE;
    8579 }
    8580
    8581 if( oldndelconss == *ndelconss && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 )
    8582 {
    8583 /* check constraints for redundancy */
    8584 if( conshdlrdata->presolpairwise )
    8585 {
    8586 SCIP_Longint npaircomparisons = 0;
    8587
    8588 oldnfixedvars = *nfixedvars;
    8589
    8590 for( c = firstchange; c < nconss && !SCIPisStopped(scip); ++c )
    8591 {
    8592 assert(*result != SCIP_CUTOFF);
    8593
    8594 if( SCIPconsIsActive(conss[c]) && !SCIPconsIsModifiable(conss[c]) )
    8595 {
    8596 npaircomparisons += (SCIPconsGetData(conss[c])->changed) ? (SCIP_Longint) c : ((SCIP_Longint) c - (SCIP_Longint) firstchange);
    8597
    8598 SCIP_CALL( removeRedundantConstraints(scip, conss, firstchange, c, &cutoff, nfixedvars, ndelconss, nchgsides) );
    8599 if( cutoff )
    8600 {
    8601 *result = SCIP_CUTOFF;
    8602 return SCIP_OKAY;
    8603 }
    8604
    8605 if( npaircomparisons > NMINCOMPARISONS )
    8606 {
    8607 if( (*ndelconss - oldndelconss + *nfixedvars - oldnfixedvars) / ((SCIP_Real)npaircomparisons) < MINGAINPERNMINCOMPARISONS )
    8608 break;
    8609 oldndelconss = *ndelconss;
    8610 oldnfixedvars = *nfixedvars;
    8611 npaircomparisons = 0;
    8612 *result = SCIP_SUCCESS;
    8613 }
    8614 }
    8615 }
    8616 }
    8617 }
    8618
    8619 /* add cliques after lifting variables */
    8620 SCIP_CALL( addCliques(scip, conss, nconss, MIN(firstclique, nconss), MIN(lastclique, nconss), naddconss, ndelconss,
    8621 nchgbds, &cutoff) );
    8622
    8623 if( cutoff )
    8624 *result = SCIP_CUTOFF;
    8625
    8626 conshdlrdata->noldupgrs = nconss - (*ndelconss - startdelconss);
    8627
    8628 return SCIP_OKAY;
    8629}
    8630
    8631
    8632/** propagation conflict resolving method of constraint handler */
    8633static
    8634SCIP_DECL_CONSRESPROP(consRespropSetppc)
    8635{ /*lint --e{715}*/
    8636 SCIP_CONSDATA* consdata;
    8637 int v;
    8638
    8639 assert(conshdlr != NULL);
    8640 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    8641 assert(cons != NULL);
    8642 assert(infervar != NULL);
    8643 assert(result != NULL);
    8644
    8645 consdata = SCIPconsGetData(cons);
    8646 assert(consdata != NULL);
    8647
    8648 SCIPdebugMsg(scip, "conflict resolving method of set partitioning / packing / covering constraint handler\n");
    8649
    8650 if( (SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_COVERING
    8651 || ((SCIP_SETPPCTYPE)consdata->setppctype == SCIP_SETPPCTYPE_PARTITIONING
    8652 && SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) > 0.5) )
    8653 {
    8654#ifndef NDEBUG
    8655 SCIP_Bool confvarfound;
    8656#endif
    8657
    8658 /* the inference constraint is a set partitioning or covering constraint with the inference variable inferred to 1.0:
    8659 * the reason for the deduction is the assignment of 0.0 to all other variables
    8660 */
    8661#ifndef NDEBUG
    8662 confvarfound = FALSE;
    8663#endif
    8664 for( v = 0; v < consdata->nvars; ++v )
    8665 {
    8666 if( consdata->vars[v] != infervar )
    8667 {
    8668 /* the reason variable must be assigned to zero */
    8669 assert(SCIPgetVarUbAtIndex(scip, consdata->vars[v], bdchgidx, FALSE) < 0.5);
    8670 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->vars[v]) );
    8671 }
    8672#ifndef NDEBUG
    8673 else
    8674 {
    8675 assert(!confvarfound);
    8676 confvarfound = TRUE;
    8677 }
    8678#endif
    8679 }
    8680 assert(confvarfound);
    8681 }
    8682 else
    8683 {
    8684 /* the inference constraint is a set partitioning or packing constraint with the inference variable inferred to 0.0:
    8685 * the reason for the deduction is the assignment of 1.0 to a single variable
    8686 */
    8687 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
    8688
    8689 if( inferinfo >= 0 )
    8690 {
    8691 assert(SCIPgetVarLbAtIndex(scip, consdata->vars[inferinfo], bdchgidx, FALSE) > 0.5);
    8692 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->vars[inferinfo]) );
    8693 }
    8694 else
    8695 {
    8696 for( v = 0; v < consdata->nvars; ++v )
    8697 {
    8698 if( SCIPgetVarLbAtIndex(scip, consdata->vars[v], bdchgidx, FALSE) > 0.5 )
    8699 {
    8700 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->vars[v]) );
    8701 break;
    8702 }
    8703 }
    8704 assert(v < consdata->nvars);
    8705 }
    8706 }
    8707
    8708 *result = SCIP_SUCCESS;
    8709
    8710 return SCIP_OKAY;
    8711}
    8712
    8713
    8714/** variable rounding lock method of constraint handler */
    8715static
    8716SCIP_DECL_CONSLOCK(consLockSetppc)
    8717{ /*lint --e{715}*/
    8718 SCIP_CONSDATA* consdata;
    8719 int nlocksdown;
    8720 int nlocksup;
    8721 int i;
    8722
    8723 consdata = SCIPconsGetData(cons);
    8724 assert(consdata != NULL);
    8725
    8726 switch( consdata->setppctype )
    8727 {
    8729 nlocksdown = nlockspos + nlocksneg;
    8730 nlocksup = nlockspos + nlocksneg;
    8731 break;
    8733 nlocksdown = nlocksneg;
    8734 nlocksup = nlockspos;
    8735 break;
    8737 nlocksdown = nlockspos;
    8738 nlocksup = nlocksneg;
    8739 break;
    8740 default:
    8741 SCIPerrorMessage("unknown setppc type\n");
    8742 return SCIP_INVALIDDATA;
    8743 }
    8744
    8745 for( i = 0; i < consdata->nvars; ++i )
    8746 {
    8747 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksdown, nlocksup) );
    8748 }
    8749
    8750 return SCIP_OKAY;
    8751}
    8752
    8753
    8754/** constraint activation notification method of constraint handler */
    8755static
    8756SCIP_DECL_CONSACTIVE(consActiveSetppc)
    8757{ /*lint --e{715}*/
    8758 assert(cons != NULL);
    8759 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    8760 assert(SCIPconsIsTransformed(cons));
    8761
    8762 SCIPdebugMsg(scip, "activation information for set partitioning / packing / covering constraint <%s>\n",
    8763 SCIPconsGetName(cons));
    8764
    8765 /* we only might add the constraint to the propagation list, when we are not activating it in probing mode */
    8767 {
    8768 SCIP_CONSDATA* consdata = SCIPconsGetData(cons);
    8769 assert(consdata != NULL);
    8770
    8771 if( consdata->nfixedones >= 1 || consdata->nfixedzeros >= consdata->nvars - 1 )
    8772 {
    8774 }
    8775 }
    8776
    8777#ifdef VARUSES
    8778 /* increase the number of uses for each variable in the constraint */
    8779 SCIP_CALL( consdataIncVaruses(scip, SCIPconshdlrGetData(conshdlr), SCIPconsGetData(cons)) );
    8780#endif
    8781
    8783 {
    8784 SCIP_CALL( addNlrow(scip, cons) );
    8785 }
    8786
    8787 return SCIP_OKAY;
    8788}
    8789
    8790
    8791/** constraint deactivation notification method of constraint handler */
    8792static
    8793SCIP_DECL_CONSDEACTIVE(consDeactiveSetppc)
    8794{ /*lint --e{715}*/
    8795 SCIP_CONSDATA* consdata;
    8796
    8797 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    8798 assert(SCIPconsIsTransformed(cons));
    8799
    8800 SCIPdebugMsg(scip, "deactivation information for set partitioning / packing / covering constraint <%s>\n",
    8801 SCIPconsGetName(cons));
    8802
    8803 /* get constraint data */
    8804 consdata = SCIPconsGetData(cons);
    8805 assert(consdata != NULL);
    8806
    8807#ifdef VARUSES
    8808 /* decrease the number of uses for each variable in the constraint */
    8809 SCIP_CALL( consdataDecVaruses(scip, SCIPconshdlrGetData(conshdlr), condata) );
    8810#endif
    8811
    8812 if( SCIPconsIsDeleted(cons) )
    8813 {
    8814 SCIP_CONSHDLRDATA* conshdlrdata;
    8815
    8816 /* get event handler */
    8817 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    8818 assert(conshdlrdata != NULL);
    8819 assert(conshdlrdata->eventhdlr != NULL);
    8820
    8821 /* if constraint belongs to transformed problem space, drop bound change events on variables */
    8822 if( consdata->nvars > 0 && SCIPvarIsTransformed(consdata->vars[0]) )
    8823 {
    8824 SCIP_CALL( dropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    8825 }
    8826 }
    8827
    8828 /* remove row from NLP, if still in solving
    8829 * if we are in exitsolve, the whole NLP will be freed anyway
    8830 */
    8831 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && consdata->nlrow != NULL )
    8832 {
    8833 SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow) );
    8834 }
    8835
    8836 return SCIP_OKAY;
    8837}
    8838
    8839/** variable deletion method of constraint handler */
    8840static
    8841SCIP_DECL_CONSDELVARS(consDelvarsSetppc)
    8842{
    8843 assert( scip != NULL );
    8844 assert( conshdlr != NULL );
    8845 assert( conss != NULL || nconss == 0 );
    8846
    8847 if( nconss > 0 )
    8848 {
    8849 SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
    8850 }
    8851
    8852 return SCIP_OKAY;
    8853}
    8854
    8855
    8856
    8857/** constraint display method of constraint handler */
    8858static
    8859SCIP_DECL_CONSPRINT(consPrintSetppc)
    8860{ /*lint --e{715}*/
    8861 assert( scip != NULL );
    8862 assert( conshdlr != NULL );
    8863 assert( cons != NULL );
    8864
    8866
    8867 return SCIP_OKAY;
    8868}
    8869
    8870/** constraint copying method of constraint handler */
    8871static
    8872SCIP_DECL_CONSCOPY(consCopySetppc)
    8873{ /*lint --e{715}*/
    8874 SCIP_VAR** sourcevars;
    8875 const char* consname;
    8876 SCIP_Real lhs;
    8877 SCIP_Real rhs;
    8878 int nvars;
    8879 SCIP_SETPPCTYPE type;
    8880
    8881 /* get variables and coefficients of the source constraint */
    8882 sourcevars = SCIPgetVarsSetppc(sourcescip, sourcecons);
    8883 nvars = SCIPgetNVarsSetppc(sourcescip, sourcecons);
    8884
    8885 /* get setppc type */
    8886 type = SCIPgetTypeSetppc(sourcescip, sourcecons);
    8887 lhs = -SCIPinfinity(scip);
    8888 rhs = SCIPinfinity(scip);
    8889
    8890 switch( type )
    8891 {
    8893 lhs = 1.0;
    8894 rhs = 1.0;
    8895 break;
    8897 rhs = 1.0;
    8898 break;
    8900 lhs = 1.0;
    8901 break;
    8902 default:
    8903 SCIPerrorMessage("unknown setppc type\n");
    8904 return SCIP_INVALIDDATA;
    8905 }
    8906
    8907 if( name != NULL )
    8908 consname = name;
    8909 else
    8910 consname = SCIPconsGetName(sourcecons);
    8911
    8912 /* copy the logic using the linear constraint copy method */
    8913 SCIP_CALL( SCIPcopyConsLinear(scip, cons, sourcescip, consname, nvars, sourcevars, NULL,
    8914 lhs, rhs, varmap, consmap,
    8915 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
    8916 assert(cons != NULL);
    8917
    8918 return SCIP_OKAY;
    8919}
    8920
    8921/** constraint parsing method of constraint handler */
    8922static
    8923SCIP_DECL_CONSPARSE(consParseSetppc)
    8924{ /*lint --e{715}*/
    8925 SCIP_VAR** vars;
    8926 int nvars;
    8927
    8928 assert(scip != NULL);
    8929 assert(success != NULL);
    8930 assert(str != NULL);
    8931 assert(name != NULL);
    8932 assert(cons != NULL);
    8933
    8934 *success = TRUE;
    8935
    8936 nvars = 0;
    8937 vars = NULL;
    8938
    8939 /* check if lhs is just 0 */
    8940 if( str[0] == '0' )
    8941 {
    8942 assert(str[1] == ' ');
    8943 str += 2;
    8944 }
    8945 else
    8946 {
    8947 SCIP_Real* coefs;
    8948 char* endptr;
    8949 int coefssize;
    8950 int requsize;
    8951
    8952 /* initialize buffers for storing the coefficients */
    8953 coefssize = 100;
    8954 SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
    8955 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, coefssize) );
    8956
    8957 /* parse linear sum to get variables and coefficients */
    8958 SCIP_CALL( SCIPparseVarsLinearsum(scip, str, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
    8959
    8960 if( *success && requsize > coefssize )
    8961 {
    8962 /* realloc buffers and try again */
    8963 coefssize = requsize;
    8964 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, coefssize) );
    8965 SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, coefssize) );
    8966
    8967 SCIP_CALL( SCIPparseVarsLinearsum(scip, str, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
    8968 assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
    8969 }
    8970
    8971 if( !*success )
    8972 {
    8973 SCIPerrorMessage("no luck in parsing linear sum '%s'\n", str);
    8974 }
    8975 else
    8976 str = endptr;
    8977
    8978 /* free coefficient array */
    8979 SCIPfreeBufferArray(scip, &coefs);
    8980 }
    8981
    8982 /* remove white spaces */
    8983 SCIP_CALL( SCIPskipSpace((char**)&str) );
    8984
    8985 if( *success )
    8986 {
    8987 switch( *str )
    8988 {
    8989 case '=' :
    8990 SCIP_CALL( SCIPcreateConsSetpart(scip, cons, name, nvars, vars,
    8991 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    8992 break;
    8993 case '<' :
    8994 SCIP_CALL( SCIPcreateConsSetpack(scip, cons, name, nvars, vars,
    8995 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    8996 break;
    8997 case '>' :
    8998 SCIP_CALL( SCIPcreateConsSetcover(scip, cons, name, nvars, vars,
    8999 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    9000 break;
    9001 default:
    9002 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "error parsing setppc type\n");
    9003 *success = FALSE;
    9004 break;
    9005 }
    9006 }
    9007
    9008 /* free variable array */
    9010
    9011 return SCIP_OKAY;
    9012}
    9013
    9014/** constraint method of constraint handler which returns the variables (if possible) */
    9015static
    9016SCIP_DECL_CONSGETVARS(consGetVarsSetppc)
    9017{ /*lint --e{715}*/
    9018 SCIP_CONSDATA* consdata;
    9019
    9020 consdata = SCIPconsGetData(cons);
    9021 assert(consdata != NULL);
    9022
    9023 if( varssize < consdata->nvars )
    9024 (*success) = FALSE;
    9025 else
    9026 {
    9027 assert(vars != NULL);
    9028
    9029 BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
    9030 (*success) = TRUE;
    9031 }
    9032
    9033 return SCIP_OKAY;
    9034}
    9035
    9036/** constraint method of constraint handler which returns the number of variables (if possible) */
    9037static
    9038SCIP_DECL_CONSGETNVARS(consGetNVarsSetppc)
    9039{ /*lint --e{715}*/
    9040 SCIP_CONSDATA* consdata;
    9041
    9042 consdata = SCIPconsGetData(cons);
    9043 assert(consdata != NULL);
    9044
    9045 (*nvars) = consdata->nvars;
    9046 (*success) = TRUE;
    9047
    9048 return SCIP_OKAY;
    9049}
    9050
    9051/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
    9052static
    9053SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphSetppc)
    9054{ /*lint --e{715}*/
    9055 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_PERM, cons, graph, success) );
    9056
    9057 return SCIP_OKAY;
    9058}
    9059
    9060/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
    9061static
    9062SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphSetppc)
    9063{ /*lint --e{715}*/
    9064 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_SIGNPERM, cons, graph, success) );
    9065
    9066 return SCIP_OKAY;
    9067}
    9068
    9069/*
    9070 * Callback methods of event handler
    9071 */
    9072
    9073static
    9074SCIP_DECL_EVENTEXEC(eventExecSetppc)
    9075{ /*lint --e{715}*/
    9076 SCIP_CONS* cons;
    9077 SCIP_CONSDATA* consdata;
    9078 SCIP_EVENTTYPE eventtype;
    9079
    9080 assert(eventhdlr != NULL);
    9081 assert(eventdata != NULL);
    9082 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    9083 assert(event != NULL);
    9084
    9085 /*debugMsg(scip, "Exec method of bound change event handler for set partitioning / packing / covering constraints\n");*/
    9086
    9087 cons = (SCIP_CONS*)eventdata;
    9088 assert(cons != NULL);
    9089
    9090 consdata = SCIPconsGetData(cons);
    9091 assert(consdata != NULL);
    9092
    9093 eventtype = SCIPeventGetType(event);
    9094
    9095 switch( eventtype )
    9096 {
    9098 consdata->nfixedones++;
    9099 break;
    9101 consdata->nfixedones--;
    9102 break;
    9104 consdata->nfixedzeros++;
    9105 break;
    9107 consdata->nfixedzeros--;
    9108 break;
    9110 consdata->varsdeleted = TRUE;
    9111 break;
    9113 if( consdata->merged )
    9114 {
    9115 SCIP_VAR* var = SCIPeventGetVar(event);
    9116
    9117 /* this event should only arise during the presolving stage */
    9119 assert(var != NULL);
    9120
    9121 /* one variable was changed to a negated or aggregated variable, so maybe we can merge again */
    9122 if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_FIXED && SCIPvarGetLbGlobal(var) < 0.5 && SCIPvarGetUbGlobal(var) > 0.5 )
    9123 consdata->merged = FALSE;
    9124 }
    9125
    9126 if( !consdata->existmultaggr )
    9127 {
    9128 SCIP_VAR* var = SCIPeventGetVar(event);
    9129 assert(var != NULL);
    9130
    9132 consdata->existmultaggr = TRUE;
    9133 }
    9134 break;
    9135 default:
    9136 SCIPerrorMessage("invalid event type\n");
    9137 return SCIP_INVALIDDATA;
    9138 }
    9139 assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nvars);
    9140 assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nvars);
    9141
    9142 if( eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED )
    9143 {
    9144 if( consdata->nfixedones >= 1 || consdata->nfixedzeros >= consdata->nvars - 1 )
    9145 {
    9146 consdata->presolpropagated = FALSE;
    9148 }
    9149 else if( (SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE) && (consdata->nfixedzeros >= consdata->nvars - 2) )
    9150 {
    9151 consdata->presolpropagated = FALSE;
    9152 }
    9153 }
    9154
    9155 /*debugMsg(scip, " -> constraint has %d zero-fixed and %d one-fixed of %d variables\n",
    9156 consdata->nfixedzeros, consdata->nfixedones, consdata->nvars);*/
    9157
    9158 return SCIP_OKAY;
    9159}
    9160
    9161
    9162
    9163
    9164/*
    9165 * Callback methods of conflict handler
    9166 */
    9167
    9168/** conflict processing method of conflict handler (called when conflict was found) */
    9169static
    9170SCIP_DECL_CONFLICTEXEC(conflictExecSetppc)
    9171{ /*lint --e{715}*/
    9172 SCIP_VAR** vars;
    9173 int i;
    9174
    9175 assert(conflicthdlr != NULL);
    9176 assert(strcmp(SCIPconflicthdlrGetName(conflicthdlr), CONFLICTHDLR_NAME) == 0);
    9177 assert(bdchginfos != NULL || nbdchginfos == 0);
    9178 assert(result != NULL);
    9179
    9180 /* don't process already resolved conflicts */
    9181 if( resolved )
    9182 {
    9183 *result = SCIP_DIDNOTRUN;
    9184 return SCIP_OKAY;
    9185 }
    9186
    9187 *result = SCIP_DIDNOTFIND;
    9188
    9189 /* for two (binary) variables we will create a set packing constraint and add the clique information of the conflict is global */
    9190 if( nbdchginfos == 2 )
    9191 {
    9192 SCIP_CONS* cons;
    9193 char consname[SCIP_MAXSTRLEN];
    9194 SCIP_VAR* twovars[2];
    9195
    9196 assert(bdchginfos != NULL);
    9197
    9198 twovars[0] = SCIPbdchginfoGetVar(bdchginfos[0]);
    9199
    9200 /* we can only treat binary variables */
    9201 if( !SCIPvarIsBinary(twovars[0]) )
    9202 return SCIP_OKAY;
    9203
    9204 /* if the variable is fixed to zero in the conflict set, we have to use its negation */
    9205 if( SCIPbdchginfoGetNewbound(bdchginfos[0]) < 0.5 )
    9206 {
    9207 SCIP_CALL( SCIPgetNegatedVar(scip, twovars[0], &twovars[0]) );
    9208 }
    9209
    9210 twovars[1] = SCIPbdchginfoGetVar(bdchginfos[1]);
    9211
    9212 /* we can only treat binary variables */
    9213 if( !SCIPvarIsBinary(twovars[1]) )
    9214 return SCIP_OKAY;
    9215
    9216 /* if the variable is fixed to zero in the conflict set, we have to use its negation */
    9217 if( SCIPbdchginfoGetNewbound(bdchginfos[1]) < 0.5 )
    9218 {
    9219 SCIP_CALL( SCIPgetNegatedVar(scip, twovars[1], &twovars[1]) );
    9220 }
    9221
    9222 /* create a constraint out of the conflict set */
    9224 SCIP_CALL( SCIPcreateConsSetpack(scip, &cons, consname, 2, twovars,
    9225 FALSE, separate, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
    9226
    9227 /* if the constraint gets globally added, we also add the clique information */
    9228 if( !SCIPconsIsLocal(cons) )
    9229 {
    9230 SCIP_Bool infeasible;
    9231 int ncliquebdchgs;
    9232
    9233 SCIP_CALL( SCIPaddClique(scip, twovars, NULL, 2, FALSE, &infeasible, &ncliquebdchgs) );
    9234
    9235 SCIPdebugMsg(scip, "new clique of conflict constraint %s led to %d fixings\n", consname, ncliquebdchgs);
    9236
    9237 if( infeasible )
    9238 {
    9239 SCIPdebugMsg(scip, "new clique of conflict constraint %s led to infeasibility\n", consname);
    9240 }
    9241 }
    9242
    9243 /* add conflict to SCIP */
    9244 SCIP_CALL( SCIPaddConflict(scip, node, &cons, validnode, conftype, cutoffinvolved) );
    9245
    9246 *result = SCIP_CONSADDED;
    9247
    9248 return SCIP_OKAY;
    9249 }
    9250
    9251 /* create array of variables in conflict constraint */
    9252 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
    9253 for( i = 0; i < nbdchginfos; ++i )
    9254 {
    9255 assert(bdchginfos != NULL);
    9256
    9257 vars[i] = SCIPbdchginfoGetVar(bdchginfos[i]);
    9258
    9259 /* we can only treat binary variables */
    9260 if( !SCIPvarIsBinary(vars[i]) )
    9261 break;
    9262
    9263 /* if the variable is fixed to one in the conflict set, we have to use its negation */
    9264 if( SCIPbdchginfoGetNewbound(bdchginfos[i]) > 0.5 )
    9265 {
    9266 SCIP_CALL( SCIPgetNegatedVar(scip, vars[i], &vars[i]) );
    9267 }
    9268 }
    9269
    9270 if( i == nbdchginfos )
    9271 {
    9272 SCIP_CONS* cons;
    9273 char consname[SCIP_MAXSTRLEN];
    9274
    9275 /* create a constraint out of the conflict set */
    9277 SCIP_CALL( SCIPcreateConsSetcover(scip, &cons, consname, nbdchginfos, vars,
    9278 FALSE, separate, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
    9279 SCIP_CALL( SCIPaddConsNode(scip, node, cons, validnode) );
    9280 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    9281
    9282 *result = SCIP_CONSADDED;
    9283 }
    9284
    9285 /* free temporary memory */
    9286 SCIPfreeBufferArray(scip, &vars);
    9287
    9288 return SCIP_OKAY;
    9289}
    9290
    9291
    9292
    9293
    9294/*
    9295 * constraint specific interface methods
    9296 */
    9297
    9298/** creates the handler for set partitioning / packing / covering constraints and includes it in SCIP */
    9300 SCIP* scip /**< SCIP data structure */
    9301 )
    9302{
    9303 SCIP_CONSHDLRDATA* conshdlrdata;
    9304 SCIP_CONSHDLR* conshdlr;
    9305 SCIP_EVENTHDLR* eventhdlr;
    9306
    9307 /* create event handler for bound change events */
    9309 eventExecSetppc, NULL) );
    9310
    9311 /* create conflict handler for setppc constraints */
    9313 conflictExecSetppc, NULL) );
    9314
    9315 /* create constraint handler data */
    9316 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
    9317
    9318 /* include constraint handler */
    9321 consEnfolpSetppc, consEnfopsSetppc, consCheckSetppc, consLockSetppc,
    9322 conshdlrdata) );
    9323 assert(conshdlr != NULL);
    9324
    9325 /* set non-fundamental callbacks via specific setter functions */
    9326 SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveSetppc) );
    9327 SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveSetppc) );
    9328 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopySetppc, consCopySetppc) );
    9329 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteSetppc) );
    9330 SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsSetppc) );
    9331 SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreSetppc) );
    9332 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolSetppc) );
    9333 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolSetppc) );
    9334 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeSetppc) );
    9335 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsSetppc) );
    9336 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsSetppc) );
    9337 SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitSetppc) );
    9338 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpSetppc) );
    9339 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseSetppc) );
    9341 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintSetppc) );
    9344 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropSetppc) );
    9345 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpSetppc, consSepasolSetppc, CONSHDLR_SEPAFREQ,
    9347 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransSetppc) );
    9348 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxSetppc) );
    9349 SCIP_CALL( SCIPsetConshdlrGetPermsymGraph(scip, conshdlr, consGetPermsymGraphSetppc) );
    9350 SCIP_CALL( SCIPsetConshdlrGetSignedPermsymGraph(scip, conshdlr, consGetSignedPermsymGraphSetppc) );
    9351
    9352 conshdlrdata->conshdlrlinear = SCIPfindConshdlr(scip,"linear");
    9353
    9354 if( conshdlrdata->conshdlrlinear != NULL )
    9355 {
    9356 /* include the linear constraint to setppc constraint upgrade in the linear constraint handler */
    9358 }
    9359 if( SCIPfindConshdlr(scip, "nonlinear") != NULL )
    9360 {
    9361 /* notify function that upgrades quadratic constraint to setpacking */
    9363 }
    9364
    9365 /* set partitioning constraint handler parameters */
    9367 "constraints/" CONSHDLR_NAME "/npseudobranches",
    9368 "number of children created in pseudo branching (0: disable pseudo branching)",
    9369 &conshdlrdata->npseudobranches, TRUE, DEFAULT_NPSEUDOBRANCHES, 0, INT_MAX, NULL, NULL) );
    9371 "constraints/" CONSHDLR_NAME "/presolpairwise",
    9372 "should pairwise constraint comparison be performed in presolving?",
    9373 &conshdlrdata->presolpairwise, TRUE, DEFAULT_PRESOLPAIRWISE, NULL, NULL) );
    9375 "constraints/" CONSHDLR_NAME "/presolusehashing",
    9376 "should hash table be used for detecting redundant constraints in advance",
    9377 &conshdlrdata->presolusehashing, TRUE, DEFAULT_PRESOLUSEHASHING, NULL, NULL) );
    9379 "constraints/" CONSHDLR_NAME "/dualpresolving",
    9380 "should dual presolving steps be performed?",
    9381 &conshdlrdata->dualpresolving, TRUE, DEFAULT_DUALPRESOLVING, NULL, NULL) );
    9383 "constraints/" CONSHDLR_NAME "/cliquelifting",
    9384 " should we try to lift variables into other clique constraints, fix variables, aggregate them, and also shrink the amount of variables in clique constraints",
    9385 &conshdlrdata->cliquelifting, TRUE, DEFAULT_CLIQUELIFTING, NULL, NULL) );
    9387 "constraints/" CONSHDLR_NAME "/addvariablesascliques",
    9388 "should we try to generate extra cliques out of all binary variables to maybe fasten redundant constraint detection",
    9389 &conshdlrdata->addvariablesascliques, TRUE, DEFAULT_ADDVARIABLESASCLIQUES, NULL, NULL) );
    9391 "constraints/" CONSHDLR_NAME "/cliqueshrinking",
    9392 "should we try to shrink the number of variables in a clique constraints, by replacing more than one variable by only one",
    9393 &conshdlrdata->cliqueshrinking, TRUE, DEFAULT_CLIQUESHRINKING, NULL, NULL) );
    9394
    9395 return SCIP_OKAY;
    9396}
    9397
    9398/** creates and captures a set partitioning constraint
    9399 *
    9400 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    9401 */
    9403 SCIP* scip, /**< SCIP data structure */
    9404 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    9405 const char* name, /**< name of constraint */
    9406 int nvars, /**< number of variables in the constraint */
    9407 SCIP_VAR** vars, /**< array with variables of constraint entries */
    9408 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    9409 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    9410 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    9411 * Usually set to TRUE. */
    9412 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    9413 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    9414 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    9415 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    9416 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    9417 * Usually set to TRUE. */
    9418 SCIP_Bool local, /**< is constraint only valid locally?
    9419 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    9420 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    9421 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    9422 * adds coefficients to this constraint. */
    9423 SCIP_Bool dynamic, /**< is constraint subject to aging?
    9424 * Usually set to FALSE. Set to TRUE for own cuts which
    9425 * are separated as constraints. */
    9426 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    9427 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    9428 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    9429 * if it may be moved to a more global node?
    9430 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    9431 )
    9432{
    9433 return createConsSetppc(scip, cons, name, nvars, vars, SCIP_SETPPCTYPE_PARTITIONING,
    9434 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode);
    9435}
    9436
    9437/** creates and captures a set partitioning constraint with all constraint flags set
    9438 * to their default values
    9439 *
    9440 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    9441 */
    9443 SCIP* scip, /**< SCIP data structure */
    9444 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    9445 const char* name, /**< name of constraint */
    9446 int nvars, /**< number of variables in the constraint */
    9447 SCIP_VAR** vars /**< array with variables of constraint entries */
    9448 )
    9449{
    9450 SCIP_CALL( SCIPcreateConsSetpart(scip, cons, name, nvars, vars,
    9452
    9453 return SCIP_OKAY;
    9454}
    9455
    9456/** creates and captures a set packing constraint
    9457 *
    9458 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    9459 */
    9461 SCIP* scip, /**< SCIP data structure */
    9462 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    9463 const char* name, /**< name of constraint */
    9464 int nvars, /**< number of variables in the constraint */
    9465 SCIP_VAR** vars, /**< array with variables of constraint entries */
    9466 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    9467 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    9468 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    9469 * Usually set to TRUE. */
    9470 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    9471 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    9472 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    9473 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    9474 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    9475 * Usually set to TRUE. */
    9476 SCIP_Bool local, /**< is constraint only valid locally?
    9477 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    9478 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    9479 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    9480 * adds coefficients to this constraint. */
    9481 SCIP_Bool dynamic, /**< is constraint subject to aging?
    9482 * Usually set to FALSE. Set to TRUE for own cuts which
    9483 * are separated as constraints. */
    9484 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    9485 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    9486 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    9487 * if it may be moved to a more global node?
    9488 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    9489 )
    9490{
    9491 return createConsSetppc(scip, cons, name, nvars, vars, SCIP_SETPPCTYPE_PACKING,
    9492 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode);
    9493}
    9494
    9495/** creates and captures a set packing constraint with all constraint flags set
    9496 * to their default values
    9497 *
    9498 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    9499 */
    9501 SCIP* scip, /**< SCIP data structure */
    9502 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    9503 const char* name, /**< name of constraint */
    9504 int nvars, /**< number of variables in the constraint */
    9505 SCIP_VAR** vars /**< array with variables of constraint entries */
    9506 )
    9507{
    9508 SCIP_CALL( SCIPcreateConsSetpack(scip, cons, name, nvars, vars,
    9510
    9511 return SCIP_OKAY;
    9512}
    9513
    9514/** creates and captures a set covering constraint
    9515 *
    9516 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    9517 */
    9519 SCIP* scip, /**< SCIP data structure */
    9520 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    9521 const char* name, /**< name of constraint */
    9522 int nvars, /**< number of variables in the constraint */
    9523 SCIP_VAR** vars, /**< array with variables of constraint entries */
    9524 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    9525 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    9526 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    9527 * Usually set to TRUE. */
    9528 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    9529 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    9530 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    9531 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    9532 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    9533 * Usually set to TRUE. */
    9534 SCIP_Bool local, /**< is constraint only valid locally?
    9535 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    9536 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    9537 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    9538 * adds coefficients to this constraint. */
    9539 SCIP_Bool dynamic, /**< is constraint subject to aging?
    9540 * Usually set to FALSE. Set to TRUE for own cuts which
    9541 * are separated as constraints. */
    9542 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    9543 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    9544 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    9545 * if it may be moved to a more global node?
    9546 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    9547 )
    9548{
    9549 return createConsSetppc(scip, cons, name, nvars, vars, SCIP_SETPPCTYPE_COVERING,
    9550 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode);
    9551}
    9552
    9553/** creates and captures a set covering constraint with all constraint flags set
    9554 * to their default values
    9555 *
    9556 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    9557 */
    9559 SCIP* scip, /**< SCIP data structure */
    9560 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    9561 const char* name, /**< name of constraint */
    9562 int nvars, /**< number of variables in the constraint */
    9563 SCIP_VAR** vars /**< array with variables of constraint entries */
    9564 )
    9565{
    9566 SCIP_CALL( SCIPcreateConsSetcover(scip, cons, name, nvars, vars,
    9568
    9569 return SCIP_OKAY;
    9570}
    9571
    9572/** adds coefficient in set partitioning / packing / covering constraint */
    9574 SCIP* scip, /**< SCIP data structure */
    9575 SCIP_CONS* cons, /**< constraint data */
    9576 SCIP_VAR* var /**< variable to add to the constraint */
    9577 )
    9578{
    9579 assert(var != NULL);
    9580
    9581 /*debugMsg(scip, "adding variable <%s> to setppc constraint <%s>\n",
    9582 SCIPvarGetName(var), SCIPconsGetName(cons));*/
    9583
    9584 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    9585 {
    9586 SCIPerrorMessage("constraint is not a set partitioning / packing / covering constraint\n");
    9587 return SCIP_INVALIDDATA;
    9588 }
    9589
    9590 SCIP_CALL( addCoef(scip, cons, var) );
    9591
    9592 return SCIP_OKAY;
    9593}
    9594
    9595/** gets number of variables in set partitioning / packing / covering constraint */
    9597 SCIP* scip, /**< SCIP data structure */
    9598 SCIP_CONS* cons /**< constraint data */
    9599 )
    9600{
    9601 SCIP_CONSDATA* consdata;
    9602
    9603 assert(scip != NULL);
    9604
    9605 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    9606 {
    9607 SCIPerrorMessage("constraint is not a set partitioning / packing / covering constraint\n");
    9608 SCIPABORT();
    9609 return -1; /*lint !e527*/
    9610 }
    9611
    9612 consdata = SCIPconsGetData(cons);
    9613 assert(consdata != NULL);
    9614
    9615 return consdata->nvars;
    9616}
    9617
    9618/** gets array of variables in set partitioning / packing / covering constraint */
    9620 SCIP* scip, /**< SCIP data structure */
    9621 SCIP_CONS* cons /**< constraint data */
    9622 )
    9623{
    9624 SCIP_CONSDATA* consdata;
    9625
    9626 assert(scip != NULL);
    9627
    9628 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    9629 {
    9630 SCIPerrorMessage("constraint is not a set partitioning / packing / covering constraint\n");
    9631 SCIPABORT();
    9632 return NULL; /*lint !e527*/
    9633 }
    9634
    9635 consdata = SCIPconsGetData(cons);
    9636 assert(consdata != NULL);
    9637
    9638 return consdata->vars;
    9639}
    9640
    9641/** gets type of set partitioning / packing / covering constraint */
    9643 SCIP* scip, /**< SCIP data structure */
    9644 SCIP_CONS* cons /**< constraint data */
    9645 )
    9646{
    9647 SCIP_CONSDATA* consdata;
    9648
    9649 assert(scip != NULL);
    9650
    9651 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    9652 {
    9653 SCIPerrorMessage("constraint is not a set partitioning / packing / covering constraint\n");
    9654 SCIPABORT();
    9655 }
    9656
    9657 consdata = SCIPconsGetData(cons);
    9658 assert(consdata != NULL);
    9659
    9660 return (SCIP_SETPPCTYPE)(consdata->setppctype);
    9661}
    9662
    9663/** gets the dual solution of the set partitioning / packing / covering constraint in the current LP */
    9665 SCIP* scip, /**< SCIP data structure */
    9666 SCIP_CONS* cons /**< constraint data */
    9667 )
    9668{
    9669 SCIP_CONSDATA* consdata;
    9670
    9671 assert(scip != NULL);
    9672
    9673 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    9674 {
    9675 SCIPerrorMessage("constraint is not a set partitioning / packing / covering constraint\n");
    9676 SCIPABORT();
    9677 return SCIP_INVALID; /*lint !e527*/
    9678 }
    9679
    9680 consdata = SCIPconsGetData(cons);
    9681 assert(consdata != NULL);
    9682
    9683 if( consdata->row != NULL )
    9684 return SCIProwGetDualsol(consdata->row);
    9685 else
    9686 return 0.0;
    9687}
    9688
    9689/** gets the dual Farkas value of the set partitioning / packing / covering constraint in the current infeasible LP */
    9691 SCIP* scip, /**< SCIP data structure */
    9692 SCIP_CONS* cons /**< constraint data */
    9693 )
    9694{
    9695 SCIP_CONSDATA* consdata;
    9696
    9697 assert(scip != NULL);
    9698
    9699 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    9700 {
    9701 SCIPerrorMessage("constraint is not a set partitioning / packing / covering constraint\n");
    9702 SCIPABORT();
    9703 return SCIP_INVALID; /*lint !e527*/
    9704 }
    9705
    9706 consdata = SCIPconsGetData(cons);
    9707 assert(consdata != NULL);
    9708
    9709 if( consdata->row != NULL )
    9710 return SCIProwGetDualfarkas(consdata->row);
    9711 else
    9712 return 0.0;
    9713}
    9714
    9715/** returns the linear relaxation of the given set partitioning / packing / covering constraint; may return NULL if no
    9716 * LP row was yet created; the user must not modify the row!
    9717 */
    9719 SCIP* scip, /**< SCIP data structure */
    9720 SCIP_CONS* cons /**< constraint data */
    9721 )
    9722{
    9723 SCIP_CONSDATA* consdata;
    9724
    9725 assert(scip != NULL);
    9726
    9727 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    9728 {
    9729 SCIPerrorMessage("constraint is not a set partitioning / packing / covering constraint\n");
    9730 SCIPABORT();
    9731 return NULL; /*lint !e527*/
    9732 }
    9733
    9734 consdata = SCIPconsGetData(cons);
    9735 assert(consdata != NULL);
    9736
    9737 return consdata->row;
    9738}
    9739
    9740/** creates and returns the row of the given set partitioning / packing / covering constraint */
    9742 SCIP* scip, /**< SCIP data structure */
    9743 SCIP_CONS* cons /**< constraint data */
    9744 )
    9745{
    9746 SCIP_CONSDATA* consdata;
    9747
    9748 SCIP_Real lhs;
    9749 SCIP_Real rhs;
    9750
    9751 assert(scip != NULL);
    9752
    9753 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    9754 {
    9755 SCIPerrorMessage("constraint is not a set partitioning / packing / covering constraint\n");
    9756 SCIPABORT();
    9757 return SCIP_ERROR; /*lint !e527*/
    9758 }
    9759
    9760 consdata = SCIPconsGetData(cons);
    9761 assert(consdata != NULL);
    9762 assert(consdata->row == NULL);
    9763
    9764 switch( consdata->setppctype )
    9765 {
    9767 lhs = 1.0;
    9768 rhs = 1.0;
    9769 break;
    9771 lhs = -SCIPinfinity(scip);
    9772 rhs = 1.0;
    9773 break;
    9775 lhs = 1.0;
    9776 rhs = SCIPinfinity(scip);
    9777 break;
    9778 default:
    9779 SCIPerrorMessage("unknown setppc type\n");
    9780 return SCIP_ERROR;
    9781 }
    9782
    9783 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, cons, SCIPconsGetName(cons), lhs, rhs,
    9785
    9786 SCIP_CALL( SCIPaddVarsToRowSameCoef(scip, consdata->row, consdata->nvars, consdata->vars, 1.0) );
    9787
    9788 return SCIP_OKAY;
    9789}
    9790
    9791/** returns current number of variables fixed to one in the constraint */
    9793 SCIP* scip, /**< SCIP data structure */
    9794 SCIP_CONS* cons /**< constraint data */
    9795 )
    9796{
    9797 SCIP_CONSDATA* consdata;
    9798
    9799 assert(scip != NULL);
    9800
    9801 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    9802 {
    9803 SCIPerrorMessage("constraint is not a set partitioning / packing / covering constraint\n");
    9804 SCIPABORT();
    9805 return -1; /*lint !e527*/
    9806 }
    9807
    9808 consdata = SCIPconsGetData(cons);
    9809 assert(consdata != NULL);
    9810
    9811 return consdata->nfixedones;
    9812}
    9813
    9814
    9815/** returns current number of variables fixed to zero in the constraint */
    9817 SCIP* scip, /**< SCIP data structure */
    9818 SCIP_CONS* cons /**< constraint data */
    9819 )
    9820{
    9821 SCIP_CONSDATA* consdata;
    9822
    9823 assert(scip != NULL);
    9824
    9825 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    9826 {
    9827 SCIPerrorMessage("constraint is not a set partitioning / packing / covering constraint\n");
    9828 SCIPABORT();
    9829 return -1; /*lint !e527*/
    9830 }
    9831
    9832 consdata = SCIPconsGetData(cons);
    9833 assert(consdata != NULL);
    9834
    9835 return consdata->nfixedzeros;
    9836}
    9837
    9838/** cleans up (multi-)aggregations and fixings from setppc constraints */
    9840 SCIP* scip, /**< SCIP data structure */
    9841 SCIP_Bool onlychecked, /**< should only checked constraints be cleaned up? */
    9842 SCIP_Bool* infeasible, /**< pointer to return whether problem was detected to be infeasible */
    9843 int* naddconss, /**< pointer to count number of added (linear) constraints */
    9844 int* ndelconss, /**< pointer to count number of deleted (setppc) constraints */
    9845 int* nchgcoefs, /**< pointer to count number of changed coefficients */
    9846 int* nfixedvars /**< pointer to count number of fixed variables */
    9847 )
    9848{
    9849 SCIP_CONSHDLR* conshdlr;
    9850 SCIP_CONS** conss;
    9851 int nconss;
    9852 int i;
    9853
    9854 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    9855 if( conshdlr == NULL )
    9856 return SCIP_OKAY;
    9857
    9858 assert(naddconss != NULL);
    9859 assert(ndelconss != NULL);
    9860 assert(nfixedvars != NULL);
    9861 assert(infeasible != NULL);
    9862 *infeasible = FALSE;
    9863
    9864 nconss = onlychecked ? SCIPconshdlrGetNCheckConss(conshdlr) : SCIPconshdlrGetNActiveConss(conshdlr);
    9865 conss = onlychecked ? SCIPconshdlrGetCheckConss(conshdlr) : SCIPconshdlrGetConss(conshdlr);
    9866
    9867 /* loop backwards since then deleted constraints do not interfere with the loop */
    9868 for( i = nconss - 1; i >= 0; --i )
    9869 {
    9870 SCIP_CONS* cons = conss[i];
    9871
    9872 SCIP_CALL( applyFixings(scip, cons, naddconss, ndelconss, nfixedvars, infeasible) );
    9873
    9874 if( *infeasible )
    9875 break;
    9876
    9877 if( SCIPconsIsDeleted(cons) )
    9878 continue;
    9879
    9880 /* merging unmerged constraints */
    9881 SCIP_CALL( mergeMultiples(scip, cons, nfixedvars, ndelconss, nchgcoefs, infeasible) );
    9882
    9883 if( *infeasible )
    9884 break;
    9885 }
    9886
    9887 return SCIP_OKAY;
    9888}
    SCIP_VAR * a
    Definition: circlepacking.c:66
    Constraint handler for linear constraints in their most general form, .
    constraint handler for nonlinear constraints specified by algebraic expressions
    static SCIP_DECL_CONSPRINT(consPrintSetppc)
    Definition: cons_setppc.c:8859
    static int setppcCompare(SCIP_CONS *const cons1, SCIP_CONS *const cons2)
    Definition: cons_setppc.c:201
    static SCIP_DECL_CONSFREE(consFreeSetppc)
    Definition: cons_setppc.c:7545
    static SCIP_RETCODE collectCliqueConss(SCIP *const scip, SCIP_CONS **const conss, int const nconss, SCIP_CONS **const usefulconss, int *const nusefulconss, int *const nfixedvars, int *const ndelconss, int *const nchgcoefs, SCIP_Bool *const cutoff)
    Definition: cons_setppc.c:2958
    static SCIP_DECL_CONSGETVARS(consGetVarsSetppc)
    Definition: cons_setppc.c:9016
    static SCIP_RETCODE conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
    Definition: cons_setppc.c:409
    static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
    Definition: cons_setppc.c:1075
    static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
    Definition: cons_setppc.c:750
    static SCIP_DECL_CONSGETNVARS(consGetNVarsSetppc)
    Definition: cons_setppc.c:9038
    #define DEFAULT_DUALPRESOLVING
    Definition: cons_setppc.c:111
    static SCIP_RETCODE dropEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
    Definition: cons_setppc.c:983
    #define CONSHDLR_NEEDSCONS
    Definition: cons_setppc.c:80
    #define CONSHDLR_SEPAFREQ
    Definition: cons_setppc.c:73
    #define CONFLICTHDLR_PRIORITY
    Definition: cons_setppc.c:93
    #define CONFLICTHDLR_NAME
    Definition: cons_setppc.c:91
    static SCIP_RETCODE addCut(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff)
    Definition: cons_setppc.c:2512
    #define CONSHDLR_CHECKPRIORITY
    Definition: cons_setppc.c:72
    static SCIP_RETCODE mergeMultiples(SCIP *scip, SCIP_CONS *cons, int *nfixedvars, int *ndelconss, int *nchgcoefs, SCIP_Bool *cutoff)
    Definition: cons_setppc.c:1636
    static SCIP_RETCODE liftCliqueVariables(SCIP *const scip, SCIP_CONS *const cons, int const arraypos, SCIP_VAR **const usefulvars, int *const nusefulvars, int const endidx, SCIP_Bool **cliquevalues, SCIP_HASHMAP *const vartoindex, int *const varnconss, int *const maxnvarconsidx, int **const varconsidxs, int *const maxnvars, int *const nadded, SCIP_Bool *const chgcons, int *const nfixedvars, int *const ndelconss, SCIP_Bool *const cutoff)
    Definition: cons_setppc.c:4478
    static SCIP_RETCODE createConsSetppc(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_SETPPCTYPE setppctype, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_setppc.c:7072
    #define CONSHDLR_DESC
    Definition: cons_setppc.c:69
    static SCIP_RETCODE createRow(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:2470
    #define DEFAULT_NPSEUDOBRANCHES
    Definition: cons_setppc.c:110
    static SCIP_DECL_CONSENFORELAX(consEnforelaxSetppc)
    Definition: cons_setppc.c:8166
    #define CONSHDLR_PROP_TIMING
    Definition: cons_setppc.c:83
    static SCIP_DECL_CONSACTIVE(consActiveSetppc)
    Definition: cons_setppc.c:8756
    #define HASHSIZE_SETPPCCONS
    Definition: cons_setppc.c:97
    #define CONFLICTHDLR_DESC
    Definition: cons_setppc.c:92
    static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
    Definition: cons_setppc.c:346
    static SCIP_RETCODE createNormalizedSetppc(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, int mult, SCIP_SETPPCTYPE setppctype, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_setppc.c:7169
    static SCIP_RETCODE addCliqueDataEntry(SCIP *const scip, SCIP_VAR *const addvar, int const considx, SCIP_Bool const maybenew, SCIP_VAR **const usefulvars, int *const nusefulvars, SCIP_HASHMAP *const vartoindex, int *const varnconss, int *const maxnvarconsidx, int **const varconsidxs)
    Definition: cons_setppc.c:3200
    static SCIP_DECL_CONSSEPALP(consSepalpSetppc)
    Definition: cons_setppc.c:7761
    static SCIP_RETCODE addExtraCliques(SCIP *const scip, SCIP_VAR **const binvars, int const nbinvars, int *const cliquepartition, int const ncliques, SCIP_CONS **const usefulconss, int *const nusefulconss, int const nrounds, int *const nfixedvars, int *const naddconss, int *const ndelconss, int *const nchgcoefs, SCIP_Bool *const cutoff)
    Definition: cons_setppc.c:2838
    static SCIP_DECL_CONSSEPASOL(consSepasolSetppc)
    Definition: cons_setppc.c:7804
    static SCIP_DECL_CONFLICTEXEC(conflictExecSetppc)
    Definition: cons_setppc.c:9170
    #define CONSHDLR_MAXPREROUNDS
    Definition: cons_setppc.c:77
    static SCIP_DECL_CONSCOPY(consCopySetppc)
    Definition: cons_setppc.c:8872
    static SCIP_RETCODE performAggregations(SCIP *const scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_VAR **const undoneaggrvars, SCIP_Bool *const undoneaggrtypes, int const naggregations, int *const naggrvars, SCIP_Bool *const cutoff)
    Definition: cons_setppc.c:4952
    static SCIP_DECL_HASHKEYEQ(hashKeyEqSetppccons)
    Definition: cons_setppc.c:2765
    static SCIP_DECL_HASHKEYVAL(hashKeyValSetppccons)
    Definition: cons_setppc.c:2808
    static SCIP_DECL_CONSRESPROP(consRespropSetppc)
    Definition: cons_setppc.c:8634
    #define DEFAULT_PRESOLPAIRWISE
    Definition: cons_setppc.c:95
    static SCIP_RETCODE performVarDeletions(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss)
    Definition: cons_setppc.c:6958
    static SCIP_RETCODE dualPresolving(SCIP *scip, SCIP_CONS *cons, int *nfixedvars, int *ndelconss, int *naggrvars, SCIP_RESULT *result)
    Definition: cons_setppc.c:1289
    #define CONSHDLR_SEPAPRIORITY
    Definition: cons_setppc.c:70
    static SCIP_Bool checkCons(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
    Definition: cons_setppc.c:2405
    static SCIP_DECL_HASHGETKEY(hashGetKeySetppccons)
    Definition: cons_setppc.c:2757
    static SCIP_DECL_CONSINITSOL(consInitsolSetppc)
    Definition: cons_setppc.c:7613
    static SCIP_RETCODE consdataCreateTransformed(SCIP *scip, SCIP_CONSDATA **consdata, int nvars, SCIP_VAR **vars, SCIP_SETPPCTYPE setppctype)
    Definition: cons_setppc.c:691
    #define DEFAULT_CLIQUELIFTING
    Definition: cons_setppc.c:113
    static SCIP_RETCODE setSetppcType(SCIP *scip, SCIP_CONS *cons, SCIP_SETPPCTYPE setppctype)
    Definition: cons_setppc.c:840
    static SCIP_RETCODE analyzeConflictOne(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:2129
    static int setppcCompare2(SCIP_CONS *const cons1, SCIP_CONS *const cons2)
    Definition: cons_setppc.c:257
    static SCIP_RETCODE collectCliqueData(SCIP *const scip, SCIP_CONS **const usefulconss, int const nusefulconss, SCIP_VAR **const usefulvars, int *const nusefulvars, SCIP_HASHMAP *const vartoindex, int *const varnconss, int *const maxnvarconsidx, int **const varconsidxs, int *const maxnvars)
    Definition: cons_setppc.c:3050
    static SCIP_DECL_CONSPRESOL(consPresolSetppc)
    Definition: cons_setppc.c:8353
    static SCIP_RETCODE addSymmetryInformation(SCIP *scip, SYM_SYMTYPE symtype, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
    Definition: cons_setppc.c:7459
    static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
    Definition: cons_setppc.c:314
    static SCIP_RETCODE preprocessCliques(SCIP *const scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONS **const conss, int const nconss, int const nrounds, int *const firstchange, int *const firstclique, int *const lastclique, int *const nfixedvars, int *const naggrvars, int *const ndelconss, int *const nchgcoefs, SCIP_Bool *const cutoff)
    Definition: cons_setppc.c:5033
    static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
    Definition: cons_setppc.c:550
    static SCIP_DECL_CONSENFOPS(consEnfopsSetppc)
    Definition: cons_setppc.c:8176
    #define DEFAULT_ADDVARIABLESASCLIQUES
    Definition: cons_setppc.c:117
    #define NONLINCONSUPGD_PRIORITY
    Definition: cons_setppc.c:86
    static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool lpfeas, SCIP_Bool *cutoff, SCIP_Bool *separated, SCIP_Bool *reduceddom)
    Definition: cons_setppc.c:2610
    static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, int *naddconss, int *ndelconss, int *nfixedvars, SCIP_Bool *cutoff)
    Definition: cons_setppc.c:1780
    static SCIP_DECL_CONSTRANS(consTransSetppc)
    Definition: cons_setppc.c:7694
    static SCIP_RETCODE removeDoubleAndSingletonsAndPerformDualpresolve(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool dualpresolvingenabled, SCIP_Bool linearconshdlrexist, int *nfixedvars, int *naggrvars, int *ndelconss, int *nchgcoefs, int *nchgsides, SCIP_Bool *cutoff)
    Definition: cons_setppc.c:5661
    #define DEFAULT_PRESOLUSEHASHING
    Definition: cons_setppc.c:98
    static SCIP_DECL_CONSENFOLP(consEnfolpSetppc)
    Definition: cons_setppc.c:8156
    static SCIP_DECL_CONSDELETE(consDeleteSetppc)
    Definition: cons_setppc.c:7658
    static void deleteCliqueDataEntry(SCIP_VAR *const var, int const considx, SCIP_HASHMAP *const vartoindex, int *const varnconss, int **const varconsidxs)
    Definition: cons_setppc.c:3158
    static uint64_t consdataGetSignature(SCIP_CONSDATA *consdata)
    Definition: cons_setppc.c:787
    static SCIP_DECL_CONSPARSE(consParseSetppc)
    Definition: cons_setppc.c:8923
    static SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphSetppc)
    Definition: cons_setppc.c:9053
    static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, int pos)
    Definition: cons_setppc.c:1159
    #define MINGAINPERNMINCOMPARISONS
    Definition: cons_setppc.c:100
    static SCIP_RETCODE analyzeConflictZero(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:2094
    static SCIP_DECL_EVENTEXEC(eventExecSetppc)
    Definition: cons_setppc.c:9074
    static SCIP_RETCODE multiAggregateBinvar(SCIP *scip, SCIP_Bool linearconshdlrexist, SCIP_VAR **vars, int nvars, int pos, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
    Definition: cons_setppc.c:5562
    static SCIP_DECL_SORTPTRCOMP(setppcConssSort)
    Definition: cons_setppc.c:241
    static SCIP_DECL_CONSEXITPRE(consExitpreSetppc)
    Definition: cons_setppc.c:7592
    #define CONSHDLR_PROPFREQ
    Definition: cons_setppc.c:74
    static SCIP_DECL_CONSEXITSOL(consExitsolSetppc)
    Definition: cons_setppc.c:7630
    static SCIP_DECL_LINCONSUPGD(linconsUpgdSetppc)
    Definition: cons_setppc.c:7237
    static SCIP_DECL_CONSDEACTIVE(consDeactiveSetppc)
    Definition: cons_setppc.c:8793
    #define NMINCOMPARISONS
    Definition: cons_setppc.c:99
    #define DEFAULT_RANDSEED
    Definition: cons_setppc.c:102
    #define CONSHDLR_PRESOLTIMING
    Definition: cons_setppc.c:82
    static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result)
    Definition: cons_setppc.c:7000
    static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
    Definition: cons_setppc.c:713
    static SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphSetppc)
    Definition: cons_setppc.c:9062
    static void consdataSort(SCIP_CONSDATA *consdata)
    Definition: cons_setppc.c:808
    static SCIP_RETCODE addNlrow(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:2545
    static SCIP_DECL_CONSDELVARS(consDelvarsSetppc)
    Definition: cons_setppc.c:8841
    #define CONSHDLR_EAGERFREQ
    Definition: cons_setppc.c:75
    static SCIP_DECL_CONSINIT(consInitSetppc)
    Definition: cons_setppc.c:7566
    static SCIP_RETCODE enforcePseudo(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, SCIP_Bool *infeasible, SCIP_Bool *reduceddom, SCIP_Bool *solvelp)
    Definition: cons_setppc.c:2696
    static SCIP_DECL_CONSINITLP(consInitlpSetppc)
    Definition: cons_setppc.c:7743
    #define EVENTHDLR_DESC
    Definition: cons_setppc.c:89
    static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
    Definition: cons_setppc.c:378
    static SCIP_DECL_NONLINCONSUPGD(nonlinUpgdSetppc)
    Definition: cons_setppc.c:7318
    static SCIP_RETCODE checkForOverlapping(SCIP *const scip, SCIP_CONS *const cons, int const considx, int const endidx, SCIP_CONS **const usefulconss, int const nusefulconss, SCIP_VAR **const usefulvars, int *const nusefulvars, SCIP_HASHMAP *const vartoindex, int *const varnconss, int *const maxnvarconsidx, int **const varconsidxs, int *const countofoverlapping, SCIP_Bool const shrinking, SCIP_Bool *const chgcons, SCIP_VAR **undoneaggrvars, SCIP_Bool *undoneaggrtypes, int *const naggregations, int *const saggregations, int *const nfixedvars, int *const naggrvars, int *const nchgcoefs, int *const ndelconss, SCIP_Bool *const cutoff)
    Definition: cons_setppc.c:3612
    static SCIP_RETCODE processFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, SCIP_Bool *addcut, SCIP_Bool *mustcheck)
    Definition: cons_setppc.c:2169
    #define CONSHDLR_ENFOPRIORITY
    Definition: cons_setppc.c:71
    static SCIP_RETCODE processContainedCons(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1, SCIP_Bool *cutoff, int *nfixedvars, int *ndelconss, int *nchgsides)
    Definition: cons_setppc.c:6670
    static SCIP_DECL_CONSCHECK(consCheckSetppc)
    Definition: cons_setppc.c:8238
    static SCIP_RETCODE dropAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
    Definition: cons_setppc.c:1047
    #define DEFAULT_CLIQUESHRINKING
    Definition: cons_setppc.c:120
    static SCIP_DECL_CONSHDLRCOPY(conshdlrCopySetppc)
    Definition: cons_setppc.c:7529
    static SCIP_RETCODE catchAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
    Definition: cons_setppc.c:1019
    #define LINCONSUPGD_PRIORITY
    Definition: cons_setppc.c:85
    static SCIP_DECL_CONSPROP(consPropSetppc)
    Definition: cons_setppc.c:8289
    #define CONSHDLR_DELAYSEPA
    Definition: cons_setppc.c:78
    static SCIP_RETCODE detectRedundantConstraints(SCIP *scip, BMS_BLKMEM *blkmem, SCIP_CONS **conss, int nconss, int *firstchange, int *ndelconss, int *nchgsides)
    Definition: cons_setppc.c:6463
    #define CONSHDLR_NAME
    Definition: cons_setppc.c:68
    static SCIP_RETCODE addCliques(SCIP *scip, SCIP_CONS **conss, int nconss, int firstclique, int lastclique, int *naddconss, int *ndelconss, int *nchgbds, SCIP_Bool *cutoff)
    Definition: cons_setppc.c:5479
    #define EVENTHDLR_NAME
    Definition: cons_setppc.c:88
    static SCIP_DECL_CONSLOCK(consLockSetppc)
    Definition: cons_setppc.c:8716
    static SCIP_RETCODE removeRedundantCons(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1, int *ndelconss)
    Definition: cons_setppc.c:6572
    static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, int nvars, SCIP_VAR **vars, SCIP_SETPPCTYPE setppctype)
    Definition: cons_setppc.c:574
    static SCIP_RETCODE fixAdditionalVars(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1, SCIP_Bool *cutoff, int *nfixedvars)
    Definition: cons_setppc.c:6598
    static SCIP_RETCODE presolvePropagateCons(SCIP *const scip, SCIP_CONS *const cons, SCIP_Bool const aggregate, SCIP_VAR **undoneaggrvars, SCIP_Bool *undoneaggrtypes, int *const naggregations, int *const saggregations, int *const nfixedvars, int *const naggrvars, int *const ndelconss, SCIP_Bool *const cutoff)
    Definition: cons_setppc.c:3269
    #define CONSHDLR_DELAYPROP
    Definition: cons_setppc.c:79
    static SCIP_RETCODE catchEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
    Definition: cons_setppc.c:913
    static SCIP_RETCODE removeRedundantConstraints(SCIP *scip, SCIP_CONS **conss, int firstchange, int chkind, SCIP_Bool *cutoff, int *nfixedvars, int *ndelconss, int *nchgsides)
    Definition: cons_setppc.c:6786
    Constraint handler for the set partitioning / packing / covering constraints .
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define ABS(x)
    Definition: def.h:216
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define SCIPABORT()
    Definition: def.h:327
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPcheckQuadraticNonlinear(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *isquadratic)
    SCIP_RETCODE SCIPincludeLinconsUpgrade(SCIP *scip, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority, const char *conshdlrname)
    SCIP_RETCODE SCIPcleanupConssSetppc(SCIP *scip, SCIP_Bool onlychecked, SCIP_Bool *infeasible, int *naddconss, int *ndelconss, int *nchgcoefs, int *nfixedvars)
    Definition: cons_setppc.c:9839
    SCIP_RETCODE SCIPcreateConsBasicSetpart(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars)
    Definition: cons_setppc.c:9442
    SCIP_RETCODE SCIPincludeConsUpgradeNonlinear(SCIP *scip, SCIP_DECL_NONLINCONSUPGD((*nlconsupgd)), int priority, SCIP_Bool active, const char *conshdlrname)
    int SCIPgetNFixedzerosSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9816
    SCIP_ROW * SCIPgetRowSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9718
    int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9596
    SCIP_RETCODE SCIPcreateConsSetpack(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_setppc.c:9460
    SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9619
    SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
    int SCIPgetNFixedonesSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9792
    SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsBasicSetcover(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars)
    Definition: cons_setppc.c:9558
    SCIP_RETCODE SCIPaddCoefSetppc(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
    Definition: cons_setppc.c:9573
    enum SCIP_SetppcType SCIP_SETPPCTYPE
    Definition: cons_setppc.h:91
    SCIP_RETCODE SCIPcopyConsLinear(SCIP *scip, SCIP_CONS **cons, SCIP *sourcescip, const char *name, int nvars, SCIP_VAR **sourcevars, SCIP_Real *sourcecoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool global, SCIP_Bool *valid)
    SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9642
    SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_RETCODE SCIPcreateConsSetpart(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_setppc.c:9402
    SCIP_RETCODE SCIPcreateConsSetcover(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_setppc.c:9518
    SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
    SCIP_Real SCIPgetDualsolSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9664
    SCIP_RETCODE SCIPcreateConsBasicSetpack(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars)
    Definition: cons_setppc.c:9500
    SCIP_RETCODE SCIPcreateRowSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9741
    SCIP_Real SCIPgetDualfarkasSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9690
    @ SCIP_SETPPCTYPE_PARTITIONING
    Definition: cons_setppc.h:87
    @ SCIP_SETPPCTYPE_COVERING
    Definition: cons_setppc.h:89
    @ SCIP_SETPPCTYPE_PACKING
    Definition: cons_setppc.h:88
    SCIP_RETCODE SCIPincludeConshdlrSetppc(SCIP *scip)
    Definition: cons_setppc.c:9299
    SCIP_Bool SCIPisConsCompressionEnabled(SCIP *scip)
    Definition: scip_copy.c:662
    SCIP_Bool SCIPisTransformed(SCIP *scip)
    Definition: scip_general.c:647
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:759
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    int SCIPgetNImplVars(SCIP *scip)
    Definition: scip_prob.c:2387
    int SCIPgetNContVars(SCIP *scip)
    Definition: scip_prob.c:2569
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3420
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNFixedVars(SCIP *scip)
    Definition: scip_prob.c:2705
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3304
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3466
    SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
    Definition: misc.c:3179
    SCIP_RETCODE SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3482
    void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
    Definition: misc.c:2348
    #define SCIPhashFour(a, b, c, d)
    Definition: pub_misc.h:573
    SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
    Definition: misc.c:2298
    void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
    Definition: misc.c:2596
    SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2535
    #define SCIPhashSignature64(a)
    Definition: pub_misc.h:566
    SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:4067
    SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
    Definition: scip_prob.c:3901
    SCIP_RETCODE SCIPaddConflict(SCIP *scip, SCIP_NODE *node, SCIP_CONS **cons, SCIP_NODE *validnode, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
    Definition: scip_prob.c:3806
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsgPrint
    Definition: scip_message.h:79
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
    Definition: misc.c:11162
    SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    void SCIPrandomPermuteArray(SCIP_RANDNUMGEN *randnumgen, void **array, int begin, int end)
    Definition: misc.c:10294
    SCIP_Real SCIPcalcNodeselPriority(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdir, SCIP_Real targetvalue)
    Definition: scip_branch.c:928
    SCIP_Real SCIPcalcChildEstimate(SCIP *scip, SCIP_VAR *var, SCIP_Real targetvalue)
    Definition: scip_branch.c:955
    SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
    Definition: scip_branch.c:402
    SCIP_RETCODE SCIPgetPseudoBranchCands(SCIP *scip, SCIP_VAR ***pseudocands, int *npseudocands, int *npriopseudocands)
    Definition: scip_branch.c:741
    SCIP_RETCODE SCIPcreateChild(SCIP *scip, SCIP_NODE **node, SCIP_Real nodeselprio, SCIP_Real estimate)
    Definition: scip_branch.c:1025
    SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
    const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
    SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
    SCIP_RETCODE SCIPaddConflictBinvar(SCIP *scip, SCIP_VAR *var)
    SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
    SCIP_RETCODE SCIPincludeConflicthdlrBasic(SCIP *scip, SCIP_CONFLICTHDLR **conflicthdlrptr, const char *name, const char *desc, int priority, SCIP_DECL_CONFLICTEXEC((*conflictexec)), SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
    int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4798
    SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
    Definition: scip_cons.c:808
    void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: cons.c:4346
    SCIP_CONS ** SCIPconshdlrGetCheckConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4755
    SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
    Definition: scip_cons.c:540
    SCIP_RETCODE SCIPsetConshdlrInit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINIT((*consinit)))
    Definition: scip_cons.c:396
    SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
    Definition: scip_cons.c:831
    SCIP_RETCODE SCIPsetConshdlrSepa(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSSEPALP((*conssepalp)), SCIP_DECL_CONSSEPASOL((*conssepasol)), int sepafreq, int sepapriority, SCIP_Bool delaysepa)
    Definition: scip_cons.c:235
    SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
    Definition: scip_cons.c:281
    SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: scip_cons.c:181
    SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
    Definition: scip_cons.c:693
    SCIP_RETCODE SCIPsetConshdlrGetPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETPERMSYMGRAPH((*consgetpermsymgraph)))
    Definition: scip_cons.c:900
    SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
    Definition: scip_cons.c:578
    SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
    Definition: scip_cons.c:372
    SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
    Definition: scip_cons.c:323
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
    Definition: scip_cons.c:516
    SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
    Definition: scip_cons.c:347
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_RETCODE SCIPsetConshdlrGetSignedPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH((*consgetsignedpermsymgraph)))
    Definition: scip_cons.c:924
    SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
    Definition: scip_cons.c:468
    SCIP_RETCODE SCIPsetConshdlrDelvars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELVARS((*consdelvars)))
    Definition: scip_cons.c:762
    SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
    Definition: scip_cons.c:624
    SCIP_RETCODE SCIPsetConshdlrInitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITSOL((*consinitsol)))
    Definition: scip_cons.c:444
    SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4336
    SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
    Definition: scip_cons.c:601
    SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
    Definition: scip_cons.c:647
    int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4812
    SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
    Definition: scip_cons.c:854
    SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4735
    SCIP_RETCODE SCIPsetConshdlrActive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSACTIVE((*consactive)))
    Definition: scip_cons.c:670
    SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
    Definition: scip_cons.c:785
    SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
    Definition: cons.c:8419
    int SCIPconsGetPos(SCIP_CONS *cons)
    Definition: cons.c:8399
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8648
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8558
    SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
    Definition: scip_cons.c:2536
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8588
    SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
    Definition: cons.c:8518
    SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
    Definition: cons.c:8698
    SCIP_Bool SCIPconsIsLockedType(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
    Definition: cons.c:8782
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8578
    SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:2042
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8450
    SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: scip_cons.c:997
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8608
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8628
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1812
    SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:2014
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8638
    SCIP_Bool SCIPconsIsAdded(SCIP_CONS *cons)
    Definition: cons.c:8818
    SCIP_RETCODE SCIPupdateConsFlags(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1)
    Definition: scip_cons.c:1524
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8668
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8568
    SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1784
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8658
    SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
    Definition: scip_cut.c:225
    int SCIPgetIntarrayVal(SCIP *scip, SCIP_INTARRAY *intarray, int idx)
    SCIP_RETCODE SCIPcreateIntarray(SCIP *scip, SCIP_INTARRAY **intarray)
    SCIP_RETCODE SCIPincIntarrayVal(SCIP *scip, SCIP_INTARRAY *intarray, int idx, int incval)
    SCIP_RETCODE SCIPfreeIntarray(SCIP *scip, SCIP_INTARRAY **intarray)
    SCIP_RETCODE SCIPsetIntarrayVal(SCIP *scip, SCIP_INTARRAY *intarray, int idx, int val)
    SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: scip_event.c:111
    const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:396
    SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
    Definition: event.c:1194
    SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: scip_event.c:367
    SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: scip_event.c:413
    SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
    Definition: event.c:1217
    void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
    Definition: expr.c:4226
    void SCIPexprGetQuadraticData(SCIP_EXPR *expr, SCIP_Real *constant, int *nlinexprs, SCIP_EXPR ***linexprs, SCIP_Real **lincoefs, int *nquadexprs, int *nbilinexprs, SCIP_Real **eigenvalues, SCIP_Real **eigenvectors)
    Definition: expr.c:4141
    SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
    Definition: expr_var.c:424
    void SCIPexprGetQuadraticQuadTerm(SCIP_EXPR *quadexpr, int termidx, SCIP_EXPR **expr, SCIP_Real *lincoef, SCIP_Real *sqrcoef, int *nadjbilin, int **adjbilin, SCIP_EXPR **sqrexpr)
    Definition: expr.c:4186
    SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
    Definition: scip_lp.c:87
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPfreeBufferArrayNull(scip, ptr)
    Definition: scip_mem.h:137
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    SCIP_RETCODE SCIPdelNlRow(SCIP *scip, SCIP_NLROW *nlrow)
    Definition: scip_nlp.c:424
    SCIP_RETCODE SCIPaddNlRow(SCIP *scip, SCIP_NLROW *nlrow)
    Definition: scip_nlp.c:396
    SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
    Definition: scip_nlp.c:110
    SCIP_RETCODE SCIPreleaseNlRow(SCIP *scip, SCIP_NLROW **nlrow)
    Definition: scip_nlp.c:1058
    SCIP_Bool SCIPnlrowIsInNLP(SCIP_NLROW *nlrow)
    Definition: nlp.c:1953
    SCIP_RETCODE SCIPcreateNlRow(SCIP *scip, SCIP_NLROW **nlrow, const char *name, SCIP_Real constant, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_EXPRCURV curvature)
    Definition: scip_nlp.c:954
    SCIP_Bool SCIPinProbing(SCIP *scip)
    Definition: scip_probing.c:98
    SCIP_RETCODE SCIPaddVarsToRowSameCoef(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real val)
    Definition: scip_lp.c:1718
    SCIP_RETCODE SCIPcreateEmptyRowCons(SCIP *scip, SCIP_ROW **row, SCIP_CONS *cons, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
    Definition: scip_lp.c:1398
    SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_lp.c:1646
    SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
    Definition: scip_lp.c:2131
    SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
    Definition: scip_lp.c:1508
    SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
    Definition: lp.c:17719
    SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
    Definition: lp.c:17917
    SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
    Definition: lp.c:17706
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    void SCIPupdateSolLPConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
    Definition: scip_sol.c:469
    int SCIPgetNImplications(SCIP *scip)
    SCIP_Longint SCIPgetNTotalNodes(SCIP *scip)
    int SCIPgetNRuns(SCIP *scip)
    SCIP_Longint SCIPgetNConflictConssApplied(SCIP *scip)
    SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfeastol(SCIP *scip)
    SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_RETCODE SCIPgetChildren(SCIP *scip, SCIP_NODE ***children, int *nchildren)
    Definition: scip_tree.c:164
    int SCIPvarCompareActiveAndNegated(SCIP_VAR *var1, SCIP_VAR *var2)
    Definition: var.c:17236
    SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
    Definition: var.c:23534
    SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5210
    SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23868
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8882
    SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
    Definition: scip_var.c:2119
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4386
    SCIP_Bool SCIPdoNotAggr(SCIP *scip)
    Definition: scip_var.c:10909
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23498
    SCIP_RETCODE SCIPvarGetAggregatedObj(SCIP_VAR *var, SCIP_Real *aggrobj)
    Definition: var.c:23944
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
    Definition: var.c:23430
    SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
    Definition: scip_var.c:10550
    SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6088
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
    Definition: var.c:17550
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23652
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5296
    SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2872
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPcalcCliquePartition(SCIP *scip, SCIP_VAR **vars, int nvars, int **probtoidxmap, int *probtoidxmapsize, int *cliquepartition, int *ncliques)
    Definition: scip_var.c:9330
    SCIP_RETCODE SCIPmultiaggregateVar(SCIP *scip, SCIP_VAR *var, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
    Definition: scip_var.c:10834
    SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24929
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_Bool SCIPdoNotMultaggr(SCIP *scip)
    Definition: scip_var.c:10919
    SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
    Definition: scip_var.c:899
    SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
    Definition: scip_var.c:2378
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:3051
    SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
    Definition: scip_var.c:2166
    SCIP_Bool SCIPhaveVarsCommonClique(SCIP *scip, SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
    Definition: scip_var.c:9596
    SCIP_RETCODE SCIPaddVarImplication(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8740
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
    Definition: var.c:23443
    SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
    Definition: var.c:23878
    int SCIPgetNCliques(SCIP *scip)
    Definition: scip_var.c:9512
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
    Definition: scip_var.c:10318
    SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2736
    int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
    Definition: var.c:17274
    SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6044
    SCIP_RETCODE SCIPvarGetProbvarBinary(SCIP_VAR **var, SCIP_Bool *negated)
    Definition: var.c:17642
    SCIP_RETCODE SCIPinferBinvarCons(SCIP *scip, SCIP_VAR *var, SCIP_Bool fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:7412
    SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
    Definition: scip_var.c:2236
    SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
    Definition: scip_var.c:474
    SCIP_Bool SCIPvarsHaveCommonClique(SCIP_VAR *var1, SCIP_Bool value1, SCIP_VAR *var2, SCIP_Bool value2, SCIP_Bool regardimplics)
    Definition: var.c:16807
    SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24919
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4328
    SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
    Definition: scip_var.c:2078
    SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
    Definition: scip_var.c:10984
    void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
    SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
    void SCIPsortPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
    void SCIPsortDownPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
    SCIP_Bool SCIPsortedvecFindDownPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), void *val, int len, int *pos)
    void SCIPsortedvecInsertDownPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), void *keyval, int *len, int *pos)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    SCIP_RETCODE SCIPskipSpace(char **s)
    Definition: misc.c:10816
    SCIP_RETCODE SCIPgetSymActiveVariables(SCIP *scip, SYM_SYMTYPE symtype, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
    SCIP_RETCODE SCIPextendPermsymDetectionGraphLinear(SCIP *scip, SYM_GRAPH *graph, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_CONS *cons, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool *success)
    static const SCIP_Real scalars[]
    Definition: lp.c:5959
    memory allocation routines
    #define BMScopyMemoryArray(ptr, source, num)
    Definition: memory.h:134
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    public methods for conflict analysis handlers
    public methods for managing constraints
    public methods for managing events
    public methods for LP management
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugPrintCons(x, y, z)
    Definition: pub_message.h:102
    public data structures and miscellaneous methods
    methods for sorting joint arrays of various types
    public methods for problem variables
    public methods for conflict handler plugins and conflict analysis
    public methods for constraint handler plugins and constraints
    public methods for cuts and aggregation rows
    public methods for event handler plugins and event handlers
    general public methods
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for message handling
    public methods for nonlinear relaxation
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for the probing mode
    public methods for random numbers
    public methods for solutions
    public methods for querying solving statistics
    public methods for SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1221
    structs for symmetry computations
    methods for dealing with symmetry detection graphs
    @ SCIP_CONFTYPE_PROPAGATION
    Definition: type_conflict.h:62
    struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
    Definition: type_cons.h:64
    struct SCIP_ConsData SCIP_CONSDATA
    Definition: type_cons.h:65
    #define SCIP_EVENTTYPE_BOUNDCHANGED
    Definition: type_event.h:127
    struct SCIP_EventData SCIP_EVENTDATA
    Definition: type_event.h:179
    #define SCIP_EVENTTYPE_UBTIGHTENED
    Definition: type_event.h:79
    #define SCIP_EVENTTYPE_VARFIXED
    Definition: type_event.h:72
    #define SCIP_EVENTTYPE_VARDELETED
    Definition: type_event.h:71
    #define SCIP_EVENTTYPE_LBRELAXED
    Definition: type_event.h:78
    uint64_t SCIP_EVENTTYPE
    Definition: type_event.h:156
    #define SCIP_EVENTTYPE_BOUNDTIGHTENED
    Definition: type_event.h:125
    #define SCIP_EVENTTYPE_LBTIGHTENED
    Definition: type_event.h:77
    #define SCIP_EVENTTYPE_UBRELAXED
    Definition: type_event.h:80
    @ SCIP_EXPRCURV_LINEAR
    Definition: type_expr.h:65
    @ SCIP_BRANCHDIR_DOWNWARDS
    Definition: type_history.h:43
    @ SCIP_BRANCHDIR_UPWARDS
    Definition: type_history.h:44
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    @ SCIP_VERBLEVEL_MINIMAL
    Definition: type_message.h:59
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_FEASIBLE
    Definition: type_result.h:45
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_SOLVELP
    Definition: type_result.h:55
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_INFEASIBLE
    Definition: type_result.h:46
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_PROBLEM
    Definition: type_set.h:45
    @ SCIP_STAGE_PRESOLVING
    Definition: type_set.h:49
    @ SCIP_STAGE_INITSOLVE
    Definition: type_set.h:52
    @ SCIP_STAGE_SOLVING
    Definition: type_set.h:53
    @ SCIP_STAGE_TRANSFORMING
    Definition: type_set.h:46
    enum SYM_Symtype SYM_SYMTYPE
    Definition: type_symmetry.h:64
    @ SYM_SYMTYPE_SIGNPERM
    Definition: type_symmetry.h:62
    @ SYM_SYMTYPE_PERM
    Definition: type_symmetry.h:61
    #define SCIP_PRESOLTIMING_MEDIUM
    Definition: type_timing.h:53
    #define SCIP_PRESOLTIMING_EXHAUSTIVE
    Definition: type_timing.h:54
    #define NLOCKTYPES
    Definition: type_var.h:138
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    @ SCIP_VARSTATUS_NEGATED
    Definition: type_var.h:57
    @ SCIP_VARSTATUS_LOOSE
    Definition: type_var.h:52
    enum SCIP_LockType SCIP_LOCKTYPE
    Definition: type_var.h:144
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141