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