Scippy

    SCIP

    Solving Constraint Integer Programs

    cons_linking.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file cons_linking.c
    26 * @ingroup DEFPLUGINS_CONS
    27 * @brief constraint handler for linking constraints
    28 * @author Stefan Heinz
    29 * @author Jens Schulz
    30 *
    31 * The constraints handler stores linking constraints between a linking variable (integer or continuous) and an array of binary variables. Such
    32 * a linking constraint has the form:
    33 *
    34 * linkvar = sum_{i=1}^n {vals[i] * binvars[i]}
    35 *
    36 * with the additional side condition that exactly one binary variable has to be one (set partitioning condition).
    37 *
    38 * This constraint can be created only with the linking variable if it is an integer variable. In this case the binary variables are only created on
    39 * demand. That is, whenever someone asks for the binary variables. Therefore, such constraints can be used to get a
    40 * "binary representation" of the domain of the linking variable which will be dynamically created.
    41 *
    42 *
    43 * @todo add pairwise comparison of constraints in presolving (fast hash table version and complete pairwise comparison)
    44 * @todo in case the integer variable is set to lower or upper bound it follows that only the corresponding binary
    45 * variable has a positive value which is one, this can be used to fasten the checking routine
    46 */
    47
    48/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    49
    51#include "scip/cons_linear.h"
    52#include "scip/cons_linking.h"
    53#include "scip/cons_setppc.h"
    54#include "scip/pub_cons.h"
    55#include "scip/pub_event.h"
    56#include "scip/pub_lp.h"
    57#include "scip/pub_message.h"
    58#include "scip/pub_misc.h"
    59#include "scip/pub_misc_sort.h"
    60#include "scip/pub_var.h"
    61#include "scip/scip_conflict.h"
    62#include "scip/scip_cons.h"
    63#include "scip/scip_copy.h"
    64#include "scip/scip_cut.h"
    65#include "scip/scip_event.h"
    66#include "scip/scip_general.h"
    67#include "scip/scip_lp.h"
    68#include "scip/scip_mem.h"
    69#include "scip/scip_message.h"
    70#include "scip/scip_nlp.h"
    71#include "scip/scip_numerics.h"
    72#include "scip/scip_param.h"
    73#include "scip/scip_prob.h"
    74#include "scip/scip_probing.h"
    75#include "scip/scip_sol.h"
    76#include "scip/scip_tree.h"
    77#include "scip/scip_var.h"
    78#include "scip/symmetry_graph.h"
    80#include <ctype.h>
    81#include <string.h>
    82
    83/* constraint handler properties */
    84#define CONSHDLR_NAME "linking"
    85#define CONSHDLR_DESC "linking constraint x = sum_{i=1}^{n} c_i*y_i, y1+...+yn = 1, x real, y's binary"
    86
    87#define EVENTHDLR_NAME "linking"
    88#define EVENTHDLR_DESC "event handler for linking constraints"
    89
    90#define CONSHDLR_SEPAPRIORITY 750000 /**< priority of the constraint handler for separation */
    91#define CONSHDLR_ENFOPRIORITY -2050000 /**< priority of the constraint handler for constraint enforcing */
    92#define CONSHDLR_CHECKPRIORITY -750000 /**< priority of the constraint handler for checking feasibility */
    93#define CONSHDLR_SEPAFREQ 1 /**< frequency for separating cuts; zero means to separate only in the root node */
    94#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
    95#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation, propagation and enforcement, -1 for no eager evaluations, 0 for first only */
    96#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
    97#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
    98#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    99#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
    100
    101#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP /**< propagation timing mask of the constraint handler */
    102#define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
    103
    104
    105#define HASHSIZE_BINVARSCONS 500 /**< minimal size of hash table in linking constraint handler */
    106#define DEFAULT_LINEARIZE FALSE /**< should the linking constraint be linearize after the binary variable are created */
    107
    108/*
    109 * Data structures
    110 */
    111
    112/** constraint data for linking constraints */
    113struct SCIP_ConsData
    114{
    115 SCIP_VAR* linkvar; /**< continuous variable which is linked */
    116 SCIP_VAR** binvars; /**< binary variables */
    117 SCIP_Real* vals; /**< coefficients */
    118 SCIP_ROW* row1; /**< LP row for the linking itself */
    119 SCIP_ROW* row2; /**< LP row ensuring the set partitioning condition of the binary variables */
    120 SCIP_NLROW* nlrow1; /**< NLP row for the linking itself */
    121 SCIP_NLROW* nlrow2; /**< NLP row ensuring the set partitioning condition of the binary variables */
    122 int nbinvars; /**< number of binary variables */
    123 int sizebinvars; /**< size of the binary variable array */
    124 int nfixedzeros; /**< current number of variables fixed to zero in the constraint */
    125 int nfixedones; /**< current number of variables fixed to one in the constraint */
    126 int firstnonfixed; /**< index of first locally non-fixed binary variable in binvars array */
    127 int lastnonfixed; /**< index of last locally non-fixed binary variable in binvars array */
    128 unsigned int cliqueadded:1; /**< was the set partitioning condition already added as clique? */
    129 unsigned int sorted:1; /**< are the coefficients of the binary variables are sorted in non-decreasing order */
    130};
    131
    132/** constraint handler data */
    133struct SCIP_ConshdlrData
    134{
    135 SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events on binary variables */
    136 SCIP_HASHMAP* varmap; /**< hash map mapping a linking variable to its linking constraint */
    137 SCIP_Bool linearize; /**< should the linking constraint be linearize after the binary variable are created */
    138};
    139
    140/*
    141 * Local methods
    142 */
    143
    144/** returns for a given linking variable the corresponding hash map key */
    145static
    147 SCIP_VAR* var /**< variable to get the hash map key for */
    148 )
    149{
    150 /* return the unique variable index + 1 */
    151 return (void*)(size_t)(SCIPvarGetIndex(var) + 1); /*lint !e571 !e776*/
    152}
    153
    154/* sort binary variable in non-decreasing order w.r.t. coefficients */
    155static
    157 SCIP_CONSDATA* consdata /**< linking constraint data */
    158 )
    159{
    160 if( consdata->sorted )
    161 return;
    162
    163 /* sort binary variable in non-decreasing order w.r.t. coefficients */
    164 SCIPsortRealPtr(consdata->vals, (void**)consdata->binvars, consdata->nbinvars);
    165
    166 consdata->sorted = TRUE;
    167}
    168
    169
    170/** installs rounding locks for the binary variables in the given linking constraint */
    171static
    173 SCIP* scip, /**< SCIP data structure */
    174 SCIP_CONS* cons, /**< linking constraint */
    175 SCIP_VAR** binvars, /**< binary variables */
    176 int nbinvars /**< number of binary variables */
    177 )
    178{
    179 int b;
    180
    181 for( b = 0; b < nbinvars; ++b )
    182 {
    183 SCIP_CALL( SCIPlockVarCons(scip, binvars[b], cons, TRUE, TRUE) );
    184 }
    185
    186 return SCIP_OKAY;
    187}
    188
    189/** creates constraint handler data for the linking constraint handler */
    190static
    192 SCIP* scip, /**< SCIP data structure */
    193 SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
    194 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    195 )
    196{
    197 assert(scip != NULL);
    198 assert(conshdlrdata != NULL);
    199 assert(eventhdlr != NULL);
    200
    201 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
    202
    203 /* create hash map */
    204 (*conshdlrdata)->varmap = NULL;
    205
    206 /* set event handler for bound change events on binary variables */
    207 (*conshdlrdata)->eventhdlr = eventhdlr;
    208
    209 return SCIP_OKAY;
    210}
    211
    212/** frees constraint handler data for linking constraint handler */
    213static
    215 SCIP* scip, /**< SCIP data structure */
    216 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
    217 )
    218{
    219 assert(conshdlrdata != NULL);
    220 assert(*conshdlrdata != NULL);
    221
    222 /* free hash map */
    223 if( (*conshdlrdata)->varmap != NULL )
    224 SCIPhashmapFree(&(*conshdlrdata)->varmap);
    225
    226 /* free memory of constraint handler data */
    227 SCIPfreeBlockMemory(scip, conshdlrdata);
    228}
    229
    230/** prints linking constraint to file stream */
    231static
    233 SCIP* scip, /**< SCIP data structure */
    234 SCIP_CONSDATA* consdata, /**< linking constraint data */
    235 FILE* file /**< output file (or NULL for standard output) */
    236 )
    237{
    238 SCIP_VAR** binvars;
    239 SCIP_VAR* linkvar;
    240 int nbinvars;
    241
    242 assert(scip != NULL);
    243 assert(consdata != NULL);
    244
    245 linkvar = consdata->linkvar;
    246 binvars = consdata->binvars;
    247 nbinvars = consdata->nbinvars;
    248
    249 assert(linkvar != NULL);
    250 assert(binvars != NULL || nbinvars == 0);
    251
    252 /* print linking variable */
    253 SCIP_CALL( SCIPwriteVarName(scip, file, linkvar, FALSE) );
    254
    255 SCIPinfoMessage(scip, file, " = ");
    256
    257 if( nbinvars == 0 )
    258 {
    259 SCIPinfoMessage(scip, file, " no binary variables yet");
    260 }
    261 else
    262 {
    263 assert(binvars != NULL);
    264
    265 SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, binvars, consdata->vals, nbinvars, FALSE) );
    266 }
    267
    268 return SCIP_OKAY;
    269}
    270
    271/** catches events for variable at given position */
    272static
    274 SCIP* scip, /**< SCIP data structure */
    275 SCIP_CONSDATA* consdata, /**< linking constraint data */
    276 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    277 int pos /**< array position of variable to catch bound change events for */
    278 )
    279{
    280 SCIP_VAR* var;
    281
    282 assert(consdata != NULL);
    283 assert(eventhdlr != NULL);
    284 assert(0 <= pos && pos < consdata->nbinvars);
    285 assert(consdata->binvars != NULL);
    286
    287 var = consdata->binvars[pos];
    288 assert(var != NULL);
    289
    290 /* catch bound change events on variable */
    291 /**@todo do we have to add the event SCIP_EVENTTYPE_VARFIXED? */
    293
    294 /* update the fixed variables counters for this variable */
    295 if( SCIPisEQ(scip, SCIPvarGetUbLocal(var), 0.0) )
    296 consdata->nfixedzeros++;
    297 else if( SCIPisEQ(scip, SCIPvarGetLbLocal(var), 1.0) )
    298 consdata->nfixedones++;
    299
    300 return SCIP_OKAY;
    301}
    302
    303/** drops events for variable at given position */
    304static
    306 SCIP* scip, /**< SCIP data structure */
    307 SCIP_CONSDATA* consdata, /**< linking constraint data */
    308 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    309 int pos /**< array position of variable to catch bound change events for */
    310 )
    311{
    312 SCIP_VAR* var;
    313
    314 assert(consdata != NULL);
    315 assert(eventhdlr != NULL);
    316 assert(0 <= pos && pos < consdata->nbinvars);
    317 assert(consdata->binvars != NULL);
    318
    319 var = consdata->binvars[pos];
    320 assert(var != NULL);
    321
    322 /* drop events on variable */
    323 SCIP_CALL( SCIPdropVarEvent(scip, var, SCIP_EVENTTYPE_BOUNDCHANGED, eventhdlr, (SCIP_EVENTDATA*)consdata, -1) );
    324
    325 /* update the fixed variables counters for this variable */
    326 if( SCIPisEQ(scip, SCIPvarGetUbLocal(var), 0.0) )
    327 consdata->nfixedzeros--;
    328 else if( SCIPisEQ(scip, SCIPvarGetLbLocal(var), 1.0) )
    329 consdata->nfixedones--;
    330
    331 return SCIP_OKAY;
    332}
    333
    334/** catches bound change events for all variables in transformed linking constraint */
    335static
    337 SCIP* scip, /**< SCIP data structure */
    338 SCIP_CONSDATA* consdata, /**< linking constraint data */
    339 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
    340 )
    341{
    342 int i;
    343
    344 assert(consdata != NULL);
    345
    346 /* author bzfhende
    347 *
    348 * TODO should we catch events even in the trivial case of only 1 binary variable
    349 */
    350
    351 /* catch event for every single variable */
    352 for( i = 0; i < consdata->nbinvars; ++i )
    353 {
    354 SCIP_CALL( catchEvent(scip, consdata, eventhdlr, i) );
    355 }
    356
    357 return SCIP_OKAY;
    358}
    359
    360/** drops bound change events for all variables in transformed linking constraint */
    361static
    363 SCIP* scip, /**< SCIP data structure */
    364 SCIP_CONSDATA* consdata, /**< linking constraint data */
    365 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
    366 )
    367{
    368 int i;
    369
    370 assert(consdata != NULL);
    371
    372 /* author bzfhende
    373 *
    374 * TODO drop the events even in the trivial case nbinvars == 1?
    375 */
    376
    377 /* drop event of every single variable */
    378 for( i = 0; i < consdata->nbinvars; ++i )
    379 {
    380 SCIP_CALL( dropEvent(scip, consdata, eventhdlr, i) );
    381 }
    382
    383 return SCIP_OKAY;
    384}
    385
    386/** linearize the given linking constraint into a set partitioning constraint for the binary variables and a linear
    387 * constraint for the linking between the linking variable and the binary variables */
    388static
    390 SCIP* scip, /**< SCIP data structure */
    391 SCIP_CONS* cons, /**< linking constraint */
    392 SCIP_CONSDATA* consdata /**< linking constraint data */
    393 )
    394{
    395 SCIP_CONS* lincons;
    396 int b;
    397
    398 SCIPdebugMsg(scip, "linearized linking constraint <%s>\n", SCIPconsGetName(cons));
    399
    400 /* create set partitioning constraint for the binary variables */
    401 SCIP_CALL( SCIPcreateConsSetpart(scip, &lincons, SCIPconsGetName(cons), consdata->nbinvars, consdata->binvars,
    405 SCIP_CALL( SCIPaddCons(scip, lincons) );
    406 SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
    407
    408 /* create linear constraint for the linking between the binary variables and the linking variable */
    409 SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, SCIPconsGetName(cons), 0, NULL, NULL, 0.0, 0.0,
    413
    414 for( b = 0; b < consdata->nbinvars; ++b )
    415 {
    416 SCIP_CALL( SCIPaddCoefLinear(scip, lincons, consdata->binvars[b], consdata->vals[b]) );
    417 }
    418 SCIP_CALL( SCIPaddCoefLinear(scip, lincons, consdata->linkvar, -1.0) );
    419
    420 SCIP_CALL( SCIPaddCons(scip, lincons) );
    421 SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
    422
    423 return SCIP_OKAY;
    424}
    425
    426/** creates the binary variables */
    427static
    429 SCIP* scip, /**< SCIP data structure */
    430 SCIP_CONS* cons, /**< linking constraint */
    431 SCIP_CONSDATA* consdata, /**< linking constraint data */
    432 SCIP_EVENTHDLR* eventhdlr, /**< event handler for bound change events on binary variables */
    433 SCIP_Bool linearize /**< should the linking constraint be linearized */
    434 )
    435{
    436 SCIP_VAR* linkvar;
    437 SCIP_VAR* binvar;
    438 int lb;
    439 int ub;
    440 char name[SCIP_MAXSTRLEN];
    441 int nbinvars;
    442 int b;
    443
    444 assert(scip != NULL);
    445 assert(consdata != NULL);
    446 assert(consdata->nbinvars == 0);
    447 assert(consdata->binvars == NULL);
    448 assert(SCIPvarIsIntegral(consdata->linkvar));
    449 assert(!SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->linkvar)));
    450 assert(!SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->linkvar)));
    451
    452 SCIPdebugMsg(scip, "create binary variables for linking variable <%s>\n", SCIPvarGetName(consdata->linkvar));
    453
    454 linkvar = consdata->linkvar;
    457
    458 nbinvars = ub - lb + 1;
    459 assert(nbinvars > 0);
    460
    461 /* allocate block memory for the binary variables */
    462 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->binvars, nbinvars) );
    463 /* allocate block memory for the binary variables */
    464 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->vals, nbinvars) );
    465 consdata->sizebinvars = nbinvars;
    466
    467 /* check if the linking variable is fixed */
    468 if( nbinvars == 1 )
    469 {
    470 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s[%d]", SCIPvarGetName(linkvar), lb);
    471
    472 /* creates and captures a fixed binary variables */
    473 SCIP_CALL( SCIPcreateVar(scip, &binvar, name, 1.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
    474 FALSE, TRUE, NULL, NULL, NULL, NULL, NULL) );
    475 SCIP_CALL( SCIPaddVar(scip, binvar) );
    476
    477 consdata->binvars[0] = binvar;
    478 consdata->vals[0] = lb;
    479 }
    480 else
    481 {
    482 for( b = 0; b < nbinvars; ++b)
    483 {
    484 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s[%d]", SCIPvarGetName(linkvar), lb + b);
    485
    486 /* creates and captures variables */
    487 SCIP_CALL( SCIPcreateVar(scip, &binvar, name, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
    488 TRUE, TRUE, NULL, NULL, NULL, NULL, NULL) );
    489
    490 /* add variable to the problem */
    491 SCIP_CALL( SCIPaddVar(scip, binvar) );
    492 consdata->binvars[b] = binvar;
    493 consdata->vals[b] = lb + b;
    494 }
    495 }
    496
    497 consdata->nbinvars = nbinvars;
    498 consdata->lastnonfixed = nbinvars - 1;
    499
    500 assert(consdata->nfixedzeros == 0);
    501 assert(consdata->nfixedones == 0);
    502
    504 {
    505 /* (rounding) lock binary variable */
    506 SCIP_CALL( lockRounding(scip, cons, consdata->binvars, consdata->nbinvars) );
    507
    508 /* catch bound change events of variables */
    509 SCIP_CALL( catchAllEvents(scip, consdata, eventhdlr) );
    510
    511 if( nbinvars > 1 )
    512 {
    513 if( linearize )
    514 {
    515 SCIP_CALL( consdataLinearize(scip, cons, consdata) );
    516 }
    517 else
    518 {
    519 /* enable constraint */
    520 SCIP_CALL( SCIPenableCons(scip, cons) );
    521 }
    522 }
    523 }
    524
    525 return SCIP_OKAY;
    526}
    527
    528/** creates consdata */
    529static
    531 SCIP* scip, /**< SCIP data structure */
    532 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    533 SCIP_CONSDATA** consdata, /**< pointer to constraint data */
    534 SCIP_VAR* linkvar, /**< linking variable which is linked */
    535 SCIP_VAR** binvars, /**< binary variables */
    536 SCIP_Real* vals, /**< coefficients of the binary variables */
    537 int nbinvars /**< number of binary starting variables */
    538 )
    539{
    540 int v;
    541
    542 assert(scip!= NULL);
    543 assert(consdata != NULL);
    544 assert(linkvar != NULL);
    545 assert(binvars != NULL || nbinvars == 0);
    546 assert(SCIPvarIsIntegral(linkvar) || nbinvars > 0);
    547
    548 /* allocate memory for consdata */
    549 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
    550
    551 (*consdata)->linkvar = linkvar;
    552 (*consdata)->nbinvars = nbinvars;
    553 (*consdata)->sizebinvars = nbinvars;
    554 (*consdata)->row1 = NULL;
    555 (*consdata)->row2 = NULL;
    556 (*consdata)->nlrow1 = NULL;
    557 (*consdata)->nlrow2 = NULL;
    558 (*consdata)->cliqueadded = FALSE;
    559
    560 /* initialize constraint state */
    561 (*consdata)->sorted = FALSE;
    562 (*consdata)->firstnonfixed = 0;
    563 (*consdata)->lastnonfixed = nbinvars - 1;
    564 (*consdata)->nfixedzeros = 0;
    565 (*consdata)->nfixedones = 0;
    566
    567 if( nbinvars == 0 )
    568 {
    569 (*consdata)->binvars = NULL;
    570 (*consdata)->vals = NULL;
    571 }
    572 else
    573 {
    574 /* copy binary variable array */
    575 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->binvars, binvars, nbinvars) );
    576
    577 /* copy coefficients */
    578 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, vals, nbinvars) );
    579 }
    580
    581 /* get transformed variable, if we are in the transformed problem */
    583 {
    584 if( nbinvars > 0 )
    585 {
    586 SCIP_CALL( SCIPgetTransformedVars(scip, nbinvars, (*consdata)->binvars, (*consdata)->binvars) );
    587
    588 /* catch bound change events of variables */
    589 SCIP_CALL( catchAllEvents(scip, *consdata, eventhdlr) );
    590 }
    591
    592 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->linkvar, &(*consdata)->linkvar) );
    593 }
    594
    595 /* author bzfhende
    596 *
    597 * TODO do we need to forbid multi-aggregations? This was only needed if we substitute and resubstitute linking
    598 * variables into linear constraints.
    599 */
    600
    601 /* capture variables */
    602 for( v = 0; v < nbinvars; ++v )
    603 {
    604 assert((*consdata)->binvars[v] != NULL);
    605 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->binvars[v]) );
    606 }
    607 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->linkvar) );
    608
    609 return SCIP_OKAY;
    610}
    611
    612
    613/** free consdata */
    614static
    616 SCIP* scip, /**< SCIP data structure */
    617 SCIP_CONSDATA** consdata /**< pointer to consdata */
    618 )
    619{
    620 int v;
    621
    622 assert(consdata != NULL);
    623 assert(*consdata != NULL);
    624 assert((*consdata)->nbinvars == 0 || (*consdata)->binvars != NULL);
    625
    626 /* release the rows */
    627 if( (*consdata)->row1 != NULL )
    628 {
    629 assert((*consdata)->row2 != NULL);
    630
    631 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row1) );
    632 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row2) );
    633 }
    634
    635 /* release the nlrows */
    636 if( (*consdata)->nlrow1 != NULL )
    637 {
    638 assert((*consdata)->nlrow2 != NULL);
    639
    640 SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow1) );
    641 SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow2) );
    642 }
    643
    644 /* capture variables */
    645 for( v = 0; v < (*consdata)->nbinvars; ++v )
    646 {
    647 assert((*consdata)->binvars[v] != NULL);
    648 SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->binvars[v]) );
    649 }
    650 SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->linkvar) );
    651
    652 /* free binary variable array */
    653 if( (*consdata)->sizebinvars > 0 )
    654 {
    655 /* if constraint belongs to transformed problem space, drop bound change events on variables */
    656 SCIPfreeBlockMemoryArray(scip, &(*consdata)->vals, (*consdata)->sizebinvars);
    657 SCIPfreeBlockMemoryArray(scip, &(*consdata)->binvars, (*consdata)->sizebinvars);
    658 }
    659
    660 /* check if the fixed counters are reset */
    661 assert((*consdata)->nfixedzeros == 0);
    662 assert((*consdata)->nfixedones == 0);
    663
    664 /* free constraint data */
    665 SCIPfreeBlockMemory(scip, consdata);
    666
    667 return SCIP_OKAY;
    668}
    669
    670
    671/** analyzes conflicting assignment on given constraint where reason comes from the linking variable lower or upper
    672 * bound
    673 */
    674static
    676 SCIP* scip, /**< SCIP data structure */
    677 SCIP_CONS* cons, /**< linking constraint to be processed */
    678 SCIP_VAR* linkvar, /**< linking variable */
    679 SCIP_VAR* binvar, /**< binary variable is the reason */
    680 SCIP_Bool lblinkvar, /**< lower bound of linking variable is the reason */
    681 SCIP_Bool ublinkvar /**< upper bound of linking variable is the reason */
    682 )
    683{
    684 assert(scip != NULL);
    685
    686 /* conflict analysis can only be applied in solving stage and if it is turned on */
    688 return SCIP_OKAY;
    689
    690 /* initialize conflict analysis, and add all variables of infeasible constraint to conflict candidate queue */
    692
    693 if( lblinkvar )
    694 {
    695 assert(linkvar != NULL);
    696 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, NULL) );
    697 }
    698
    699 if( ublinkvar )
    700 {
    701 assert(linkvar != NULL);
    702 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, NULL) );
    703 }
    704
    705 if( binvar != NULL )
    706 {
    708 }
    709
    710 /* analyze the conflict */
    712
    713 return SCIP_OKAY;
    714}
    715
    716/* author bzfhende
    717 *
    718 * TODO check if the method below produces valid results even if the variable is continuous
    719 */
    720
    721/** fix linking variable to the value of the binary variable at pos */
    722static
    724 SCIP* scip, /**< SCIP data structure */
    725 SCIP_CONS* cons, /**< linking constraint to be processed */
    726 int pos, /**< position of binary variable */
    727 SCIP_Bool* cutoff /**< pointer to store TRUE, if the node can be cut off */
    728 )
    729{
    730 SCIP_CONSDATA* consdata;
    731 SCIP_VAR* linkvar;
    732 SCIP_Bool infeasible;
    733 SCIP_Bool tightened;
    734 SCIP_Real coef;
    735
    736 consdata = SCIPconsGetData(cons);
    737 assert(consdata != NULL);
    738
    739 linkvar = consdata->linkvar;
    740 coef = consdata->vals[pos];
    741
    742 /* change lower bound of the linking variable */
    743 SCIP_CALL( SCIPinferVarLbCons(scip, linkvar, coef, cons, pos, TRUE, &infeasible, &tightened) );
    744
    745 if( infeasible )
    746 {
    747 assert(coef > SCIPvarGetUbLocal(linkvar));
    748 assert(coef >= SCIPvarGetLbLocal(linkvar));
    749
    750 SCIP_CALL( analyzeConflict(scip, cons, linkvar, consdata->binvars[pos], FALSE, TRUE) );
    751
    752 *cutoff = TRUE;
    753 return SCIP_OKAY;
    754 }
    755 assert(SCIPisFeasLE(scip, coef, SCIPvarGetUbLocal(linkvar)));
    756
    757 /* change upper bound of the integer variable */
    758 SCIP_CALL( SCIPinferVarUbCons(scip, linkvar, coef, cons, pos, TRUE, &infeasible, &tightened) );
    759
    760 if( infeasible )
    761 {
    762 assert(coef < SCIPvarGetLbLocal(linkvar));
    763 assert(coef <= SCIPvarGetUbLocal(linkvar));
    764
    765 SCIP_CALL( analyzeConflict(scip, cons, linkvar, consdata->binvars[pos], TRUE, FALSE) );
    766
    767 *cutoff = TRUE;
    768 return SCIP_OKAY;
    769 }
    770
    771 assert(SCIPisFeasEQ(scip, SCIPvarGetUbLocal(linkvar), SCIPvarGetLbLocal(linkvar)));
    772
    773 return SCIP_OKAY;
    774}
    775
    776/** checks constraint for violation from the local bound of the linking variable, applies fixings to the binary
    777 * variables if possible
    778 */
    779static
    781 SCIP* scip, /**< SCIP data structure */
    782 SCIP_CONS* cons, /**< linking constraint to be processed */
    783 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    784 int* nchgbds, /**< pointer to store the number of changes (foxed) variable bounds */
    785 SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
    786 )
    787{
    788 SCIP_CONSDATA* consdata;
    789 SCIP_VAR** binvars;
    790 SCIP_VAR* linkvar;
    791 SCIP_Real* vals;
    792 SCIP_Real lb;
    793 SCIP_Real ub;
    794 int nbinvars;
    795 int b;
    796 SCIP_Bool infeasible;
    797 SCIP_Bool tightened;
    798
    799 assert(cons != NULL);
    800 assert(SCIPconsGetHdlr(cons) != NULL);
    801 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
    802 assert(cutoff != NULL);
    803 assert(nchgbds != NULL);
    804 assert(mustcheck != NULL);
    805
    806 consdata = SCIPconsGetData(cons);
    807 assert(consdata != NULL);
    808
    809 /* ensure that the binary variables are sorted in non-decreasing order w.r.t. their coefficients */
    810 consdataSort(consdata);
    811
    812 nbinvars = consdata->nbinvars;
    813
    814 /* in case there is only at most one binary variables, the constraints should already be disabled */
    815 assert(nbinvars > 1);
    816
    817 /* if more than one binary variable is fixed to one or at least nbinvars minus one variable are fixed to zero */
    818 if( consdata->nfixedones > 0 || consdata->nfixedzeros >= nbinvars-1 )
    819 return SCIP_OKAY;
    820
    821 linkvar = consdata->linkvar;
    822 assert(linkvar != NULL);
    823
    824 binvars = consdata->binvars;
    825 vals = consdata->vals;
    826
    827 lb = SCIPvarGetLbLocal(linkvar);
    828 ub = SCIPvarGetUbLocal(linkvar);
    829
    830 assert(lb <= ub);
    831
    832#ifndef NDEBUG
    833 /* check that the first variable are locally fixed to zero */
    834 for( b = 0; b < consdata->firstnonfixed; ++b )
    835 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
    836
    837 /* check that the last variable are locally fixed to zero */
    838 for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
    839 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
    840#endif
    841
    842 for( b = consdata->firstnonfixed; b < nbinvars; ++b )
    843 {
    844 if( SCIPisLT(scip, vals[b], lb) )
    845 {
    846 SCIP_VAR* var;
    847
    848 var = binvars[b];
    849 assert(var != NULL);
    850
    851 SCIPdebugMsg(scip, "fix variable <%s> to zero due to the lower bound of the linking variable <%s> [%g,%g]\n",
    852 SCIPvarGetName(var), SCIPvarGetName(linkvar), lb, ub);
    853
    854 SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -2, &infeasible, &tightened) );
    855
    856 if( infeasible )
    857 {
    858 SCIP_CALL( analyzeConflict(scip, cons, linkvar, var, TRUE, FALSE) );
    859 *cutoff = TRUE;
    860 return SCIP_OKAY;
    861 }
    862
    863 if( tightened )
    864 (*nchgbds)++;
    865
    866 /* adjust constraint state */
    867 consdata->firstnonfixed++;
    868 }
    869 else
    870 break;
    871 }
    872
    873 /* fix binary variables to zero if not yet fixed, from local upper bound + 1*/
    874 for( b = consdata->lastnonfixed; b >= 0; --b )
    875 {
    876 if( SCIPisGT(scip, vals[b], ub) )
    877 {
    878 SCIP_VAR* var;
    879
    880 var = binvars[b];
    881 assert(var != NULL);
    882
    883 SCIPdebugMsg(scip, "fix variable <%s> to zero due to the upper bound of the linking variable <%s> [%g,%g]\n",
    884 SCIPvarGetName(var), SCIPvarGetName(linkvar), lb, ub);
    885
    886 SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -3, &infeasible, &tightened) );
    887
    888 if( infeasible )
    889 {
    890 SCIP_CALL( analyzeConflict(scip, cons, linkvar, var, FALSE, TRUE) );
    891 *cutoff = TRUE;
    892 return SCIP_OKAY;
    893 }
    894
    895 if( tightened )
    896 (*nchgbds)++;
    897
    898 /* adjust constraint state */
    899 consdata->lastnonfixed--;
    900 }
    901 else
    902 break;
    903 }
    904
    905 if( consdata->firstnonfixed > consdata->lastnonfixed )
    906 {
    907 *cutoff = TRUE;
    908 return SCIP_OKAY;
    909 }
    910
    911 *mustcheck = (*nchgbds) == 0;
    912
    913 /* if linking variable is fixed, create for the binary variables which have a coefficient equal to the fixed value a
    914 * set partitioning constraint
    915 */
    916 if( SCIPisEQ(scip, lb, ub) )
    917 {
    918 if( consdata->firstnonfixed == consdata->lastnonfixed )
    919 {
    920 SCIP_VAR* var;
    921
    922 var = binvars[consdata->firstnonfixed];
    923
    924 SCIPdebugMsg(scip, "fix variable <%s> to one due to the fixed linking variable <%s> [%g,%g]\n",
    925 SCIPvarGetName(var), SCIPvarGetName(linkvar), lb, ub);
    926
    927 /* TODO can the forbidden cases be covered more elegantly? */
    929 return SCIP_OKAY;
    930
    934 return SCIP_OKAY;
    935
    936 SCIP_CALL( SCIPinferBinvarCons(scip, var, TRUE, cons, -6, &infeasible, &tightened) );
    937
    938 if( infeasible )
    939 {
    940 SCIP_CALL( analyzeConflict(scip, cons, linkvar, var, TRUE, TRUE) );
    941 *cutoff = TRUE;
    942 return SCIP_OKAY;
    943 }
    944
    945 if( tightened )
    946 (*nchgbds)++;
    947
    948 SCIPdebugMsg(scip, " -> disabling linking constraint <%s>\n", SCIPconsGetName(cons));
    950
    951 *mustcheck = FALSE;
    952 }
    953 else if( SCIPgetDepth(scip) <= 0 )
    954 {
    955 SCIP_CONS* setppc;
    956 SCIP_VAR** vars;
    957 int nvars;
    958
    959 /* get sub array of variables which have the same coefficient */
    960 vars = &consdata->binvars[consdata->firstnonfixed];
    961 nvars = consdata->lastnonfixed - consdata->firstnonfixed + 1;
    962
    963 SCIP_CALL( SCIPcreateConsSetpart(scip, &setppc, SCIPconsGetName(cons), nvars, vars,
    967
    968 SCIP_CALL( SCIPaddCons(scip, setppc) );
    969 SCIP_CALL( SCIPreleaseCons(scip, &setppc) );
    970
    972 }
    973 }
    974
    975 return SCIP_OKAY;
    976}
    977
    978/** deletes coefficient at given position from the binary variable array */
    979static
    981 SCIP* scip, /**< SCIP data structure */
    982 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    983 SCIP_CONS* cons, /**< linking constraint */
    984 int pos /**< position of coefficient to delete */
    985 )
    986{
    987 SCIP_CONSDATA* consdata;
    988 SCIP_VAR* var;
    989
    990 assert(scip != NULL);
    991 assert(eventhdlr != NULL);
    992
    993 consdata = SCIPconsGetData(cons);
    994 assert(consdata != NULL);
    995 assert(0 <= pos && pos < consdata->nbinvars);
    996
    997 var = consdata->binvars[pos];
    998 assert(var != NULL);
    999 assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
    1000
    1001 /* remove the rounding locks for the deleted variable */
    1002 SCIP_CALL( SCIPunlockVarCons(scip, var, cons, TRUE, TRUE) );
    1003
    1004 /* if we are in transformed problem, delete the event data of the variable */
    1005 if( SCIPconsIsTransformed(cons) )
    1006 {
    1007 SCIP_CONSHDLR* conshdlr;
    1008 SCIP_CONSHDLRDATA* conshdlrdata;
    1009
    1010 /* get event handler */
    1011 conshdlr = SCIPconsGetHdlr(cons);
    1012 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    1013 assert(conshdlrdata != NULL);
    1014 assert(conshdlrdata->eventhdlr != NULL);
    1015
    1016 /* drop bound change events of variable */
    1017 SCIP_CALL( dropEvent(scip, consdata, conshdlrdata->eventhdlr, pos) );
    1018 }
    1019
    1020 /* move the last variable to the free slot */
    1021 if( pos != consdata->nbinvars - 1 )
    1022 {
    1023 consdata->binvars[pos] = consdata->binvars[consdata->nbinvars-1];
    1024 consdata->vals[pos] = consdata->vals[consdata->nbinvars-1];
    1025 consdata->sorted = FALSE;
    1026 }
    1027
    1028 consdata->nbinvars--;
    1029
    1030 /* release variable */
    1031 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    1032
    1033 return SCIP_OKAY;
    1034}
    1035
    1036/** remove the trailing and leading binary variables that are fixed to zero */
    1037static
    1039 SCIP* scip, /**< SCIP data structure */
    1040 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    1041 SCIP_CONS* cons /**< linking constraint */
    1042 )
    1043{
    1044 SCIP_CONSDATA* consdata;
    1045 int nbinvars;
    1046 int b;
    1047
    1048 consdata = SCIPconsGetData(cons);
    1049 assert(consdata != NULL);
    1050 assert(consdata->sorted);
    1051
    1053 assert(!SCIPinProbing(scip));
    1054 assert(!SCIPinRepropagation(scip));
    1055
    1056 nbinvars = consdata->nbinvars;
    1057
    1058 for( b = nbinvars - 1; b > consdata->lastnonfixed; --b )
    1059 {
    1060 SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
    1061 }
    1062
    1063 for( b = consdata->firstnonfixed - 1; b >= 0; --b )
    1064 {
    1065 SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
    1066 }
    1067
    1068 for( b = consdata->nbinvars - 1; b >= 0; --b )
    1069 {
    1070 if( SCIPvarGetUbLocal(consdata->binvars[b]) < 0.5 )
    1071 {
    1072 SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
    1073 }
    1074 }
    1075
    1076 /* set the constraint state */
    1077 consdata->firstnonfixed = 0;
    1078 consdata->lastnonfixed = consdata->nbinvars - 1;
    1079
    1080 return SCIP_OKAY;
    1081}
    1082
    1083/** tightened the linking variable due to binary variables which are fixed to zero */
    1084static
    1086 SCIP* scip, /**< SCIP data structure */
    1087 SCIP_CONS* cons, /**< linking constraint to be processed */
    1088 SCIP_CONSDATA* consdata, /**< linking constraint to be processed */
    1089 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    1090 int* nchgbds /**< pointer to store the number of changed variable bounds */
    1091 )
    1092{
    1093 SCIP_VAR** binvars;
    1094 SCIP_VAR* linkvar;
    1095 SCIP_Real* vals;
    1096
    1097 SCIP_Bool infeasible;
    1098 SCIP_Bool tightened;
    1099 int nbinvars;
    1100 int b;
    1101
    1102 /* if more than one binary variable is fixed to one or at least nbinvars minus one variable are fixed to zero return */
    1103 if( consdata->nfixedones > 1 || consdata->nfixedzeros >= consdata->nbinvars-1 )
    1104 return SCIP_OKAY;
    1105
    1106 if( *cutoff )
    1107 return SCIP_OKAY;
    1108
    1109 assert(consdata->sorted);
    1110
    1111 linkvar = consdata->linkvar;
    1112 binvars = consdata->binvars;
    1113 vals = consdata->vals;
    1114 nbinvars = consdata->nbinvars;
    1115
    1116#ifndef NDEBUG
    1117 /* check that the first variable are locally fixed to zero */
    1118 for( b = 0; b < consdata->firstnonfixed; ++b )
    1119 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
    1120#endif
    1121
    1122 assert(consdata->firstnonfixed < nbinvars);
    1123 assert(consdata->lastnonfixed < nbinvars);
    1124
    1125 /* find first non fixed binary variable */
    1126 for( b = consdata->firstnonfixed; b < nbinvars; ++b )
    1127 {
    1128 if( SCIPvarGetUbLocal(binvars[b]) > 0.5 )
    1129 break;
    1130
    1131 consdata->firstnonfixed++;
    1132 }
    1133
    1134 SCIP_CALL( SCIPinferVarLbCons(scip, linkvar, vals[b], cons, -4, TRUE, &infeasible, &tightened) );
    1135
    1136 /* start conflict analysis if infeasible */
    1137 if( infeasible )
    1138 {
    1139 /* analyze the cutoff if if SOLVING stage and conflict analysis is turned on */
    1141 {
    1142 SCIPdebugMsg(scip, "conflict at <%s> due to bounds and fixed binvars: [lb,ub] = [%g,%g]; b= %d; coef = %g \n",
    1143 SCIPvarGetName(linkvar), SCIPvarGetLbLocal(linkvar), SCIPvarGetUbLocal(linkvar), b, vals[b]);
    1144
    1146
    1147 /* ??????????? use resolve method and only add binvars which are needed to exceed the upper bound */
    1148
    1149 /* add conflicting variables */
    1150 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, NULL) );
    1151
    1152 for( b = 0; b < consdata->firstnonfixed; ++b )
    1153 {
    1154 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
    1155 }
    1156
    1157 /* analyze the conflict */
    1159 }
    1160
    1161 *cutoff = TRUE;
    1162 return SCIP_OKAY;
    1163 }
    1164
    1165 if( tightened )
    1166 (*nchgbds)++;
    1167
    1168#ifndef NDEBUG
    1169 /* check that the last variable are locally fixed to zero */
    1170 for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
    1171 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
    1172#endif
    1173
    1174 /* find last non fixed variable */
    1175 for( b = consdata->lastnonfixed; b >= 0; --b )
    1176 {
    1177 if( SCIPvarGetUbLocal(binvars[b]) > 0.5 )
    1178 break;
    1179
    1180 consdata->lastnonfixed--;
    1181 }
    1182
    1184 SCIP_CALL( SCIPinferVarUbCons(scip, linkvar, (SCIP_Real)vals[b], cons, -5, TRUE, &infeasible, &tightened) );
    1185
    1186 if( infeasible )
    1187 {
    1188 /* conflict analysis can only be applied in solving stage and if conflict analysis is turned on */
    1190 {
    1191 SCIPdebugMsg(scip, "conflict at <%s> due to bounds and fixed binvars: [lb,ub] = [%g,%g]; b = %d; coef = %g,\n",
    1192 SCIPvarGetName(linkvar), SCIPvarGetLbLocal(linkvar), SCIPvarGetUbLocal(linkvar), b, vals[b]);
    1193
    1195
    1196 /* ??????????? use resolve method and only add binvars which are needed to fall below the lower bound */
    1197
    1198 /* add conflicting variables */
    1199 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, NULL) );
    1200
    1201 for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
    1202 {
    1203 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
    1204 }
    1205
    1206 /* analyze the conflict */
    1208 }
    1209
    1210 *cutoff = TRUE;
    1211 return SCIP_OKAY;
    1212 }
    1213
    1214 if( tightened )
    1215 (*nchgbds)++;
    1216
    1217 return SCIP_OKAY;
    1218}
    1219
    1220/** checks constraint for violation only looking at the fixed binary variables, applies further fixings if possible */
    1221static
    1223 SCIP* scip, /**< SCIP data structure */
    1224 SCIP_CONS* cons, /**< linking constraint to be processed */
    1225 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    1226 int* nchgbds, /**< pointer to store the number of changed variable bounds */
    1227 SCIP_Bool* addcut, /**< pointer to store whether this constraint must be added as a cut */
    1228 SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
    1229 )
    1230{
    1231 SCIP_CONSDATA* consdata;
    1232 SCIP_Bool infeasible;
    1233 SCIP_Bool tightened;
    1234
    1235 assert(cons != NULL);
    1236 assert(SCIPconsGetHdlr(cons) != NULL);
    1237 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
    1238 assert(cutoff != NULL);
    1239 assert(nchgbds != NULL);
    1240 assert(addcut != NULL);
    1241 assert(mustcheck != NULL);
    1242
    1243 consdata = SCIPconsGetData(cons);
    1244 assert(consdata != NULL);
    1245 assert(consdata->nbinvars == 0 || consdata->binvars != NULL);
    1246 assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nbinvars);
    1247 assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nbinvars);
    1248
    1249 /* ensure that the binary variables are sorted in non-decreasing order w.r.t. their coefficients */
    1250 consdataSort(consdata);
    1251
    1252 /* in case there is only at most one binary variables, the constraints should already be disabled */
    1253 assert(consdata->nbinvars > 1);
    1254
    1255 if( *cutoff )
    1256 return SCIP_OKAY;
    1257
    1258 if( consdata->nfixedones == 1 )
    1259 {
    1260 /* exactly one variable is fixed to 1:
    1261 * - all other binary variables in a set partitioning must be zero
    1262 * - linking variable is fixed to that binary variable
    1263 */
    1264 if( consdata->nfixedzeros < consdata->nbinvars - 1 ||
    1265 SCIPisLT(scip, SCIPvarGetLbLocal(consdata->linkvar), SCIPvarGetUbLocal(consdata->linkvar)) )
    1266 {
    1267 SCIP_VAR** vars;
    1268 SCIP_VAR* var;
    1269#ifndef NDEBUG
    1270 SCIP_Bool fixedonefound;
    1271#endif
    1272 int nvars;
    1273 int v;
    1274
    1275 SCIPdebugMsg(scip, " -> fixing all other variables to zero due to the set partitioning condition <%s>\n",
    1276 SCIPconsGetName(cons));
    1277
    1278 /* unfixed variables exist: fix them to zero;
    1279 * this could result in additional variables fixed to one due to aggregations; in this case, the
    1280 * constraint is infeasible in local bounds
    1281 */
    1282 vars = consdata->binvars;
    1283 nvars = consdata->nbinvars;
    1284#ifndef NDEBUG
    1285 fixedonefound = FALSE;
    1286#endif
    1287
    1288 for( v = 0; v < nvars && consdata->nfixedones == 1 && !(*cutoff); ++v )
    1289 {
    1290 var = vars[v];
    1291 assert(SCIPvarIsBinary(var));
    1292 /* TODO can this be handled more elegantly? */
    1294 continue;
    1295
    1299 continue;
    1300
    1301 if( SCIPvarGetLbLocal(var) < 0.5 )
    1302 {
    1303 SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -1, &infeasible, &tightened) );
    1304 assert(!infeasible);
    1305 SCIPdebugMsg(scip, " -> fixed <%s> to zero (tightened=%u)\n", SCIPvarGetName(var), tightened);
    1306 }
    1307 else
    1308 {
    1309#ifndef NDEBUG
    1310 fixedonefound = TRUE;
    1311#endif
    1312 /* fix linking variable */
    1313 /* TODO check if variable status allows fixing (probably in consFixLinkvar) */
    1314 SCIP_CALL( consFixLinkvar(scip, cons, v, cutoff) );
    1315 }
    1316 }
    1317 if( !(*cutoff) )
    1318 {
    1319 /* the fixed to one variable must have been found, and at least one variable must have been fixed */
    1320 assert(consdata->nfixedones >= 1 || fixedonefound);
    1321
    1323 (*nchgbds)++;
    1324 }
    1325 }
    1326
    1327 /* now all other variables are fixed to zero:
    1328 * the constraint is feasible, and if it's not modifiable, it is redundant
    1329 */
    1330 if( !SCIPconsIsModifiable(cons) && consdata->nfixedones == 1 )
    1331 {
    1332 SCIPdebugMsg(scip, " -> disabling set linking constraint <%s>\n", SCIPconsGetName(cons));
    1334 }
    1335 }
    1336 else if( consdata->nfixedones >= 2 )
    1337 {
    1338 /* at least two variables are fixed to 1:
    1339 * - the set partitioning condition is violated
    1340 */
    1341 SCIPdebugMsg(scip, " -> conflict on " CONSHDLR_NAME " constraint <%s> due to the set partitioning condition\n", SCIPconsGetName(cons));
    1342
    1344
    1345 /* conflict analysis can only be applied in solving stage and if it is applicable */
    1347 {
    1348 SCIP_VAR** vars;
    1349 int nvars;
    1350 int n;
    1351 int v;
    1352
    1353 vars = consdata->binvars;
    1354 nvars = consdata->nbinvars;
    1355
    1356 /* initialize conflict analysis, and add the two variables assigned to one to conflict candidate queue */
    1358
    1359 n = 0;
    1360
    1361 for( v = 0; v < nvars && n < 2; ++v )
    1362 {
    1363 if( SCIPvarGetLbLocal(vars[v]) > 0.5 )
    1364 {
    1366 n++;
    1367 }
    1368 }
    1369 assert(n == 2);
    1370
    1371 /* analyze the conflict */
    1373 }
    1374
    1375 *cutoff = TRUE;
    1376 }
    1377 else if( consdata->nfixedzeros == consdata->nbinvars )
    1378 {
    1379 /* all variables are fixed to zero:
    1380 * - the set partitioning condition is violated, and if it's unmodifiable, the node
    1381 * can be cut off -- otherwise, the constraint must be added as a cut and further pricing must
    1382 * be performed
    1383 */
    1384 assert(consdata->nfixedones == 0);
    1385
    1386 SCIPdebugMsg(scip, " -> " CONSHDLR_NAME " constraint <%s> is infeasible due to the set partitioning condition\n",
    1387 SCIPconsGetName(cons));
    1388
    1390 if( SCIPconsIsModifiable(cons) )
    1391 *addcut = TRUE;
    1392 else
    1393 {
    1394 /* conflict analysis can only be applied in solving stage and if it is applicable */
    1396 {
    1397 SCIP_VAR** vars;
    1398 int nvars;
    1399 int v;
    1400
    1401 vars = consdata->binvars;
    1402 nvars = consdata->nbinvars;
    1403
    1404 /* initialize conflict analysis, add all variables of infeasible constraint to conflict candidate queue */
    1406
    1407 for( v = 0; v < nvars; ++v )
    1408 {
    1409 assert(SCIPvarGetUbLocal(vars[v]) < 0.5);
    1411 }
    1412
    1413 /* analyze the conflict */
    1415 }
    1416 *cutoff = TRUE;
    1417 }
    1418 }
    1419 else if( consdata->nfixedzeros == consdata->nbinvars - 1 )
    1420 {
    1421 /* all variables except one are fixed to zero:
    1422 * - an unmodifiable set partitioning constraint is feasible and can be disabled after the
    1423 * remaining variable is fixed to one
    1424 * - a modifiable set partitioning constraint must be checked manually
    1425 */
    1426 assert(consdata->nfixedones == 0);
    1427
    1428 if( !SCIPconsIsModifiable(cons) )
    1429 {
    1430 SCIP_VAR** vars;
    1431 SCIP_VAR* var;
    1432 int nvars;
    1433 int v;
    1434
    1435 /* search the single variable that can be fixed */
    1436 vars = consdata->binvars;
    1437 nvars = consdata->nbinvars;
    1438 for( v = 0; v < nvars && !(*cutoff); ++v )
    1439 {
    1440 var = vars[v];
    1441 assert(SCIPisFeasZero(scip, SCIPvarGetLbLocal(var)));
    1443
    1444 if( SCIPvarGetUbLocal(var) > 0.5 )
    1445 {
    1446 assert(SCIPvarGetLbLocal(var) < 0.5);
    1447 SCIPdebugMsg(scip, " -> fixing remaining binary variable <%s> to one in " CONSHDLR_NAME " constraint <%s>\n",
    1448 SCIPvarGetName(var), SCIPconsGetName(cons));
    1449
    1451 {
    1452 SCIP_CALL( SCIPinferBinvarCons(scip, var, TRUE, cons, -1, &infeasible, &tightened) );
    1453 assert(!infeasible);
    1454 assert(tightened);
    1455 }
    1456
    1457 /* fix linking variable */
    1458 /* TODO check if variable status allows fixing (probably in consFixLinkvar)*/
    1459 SCIP_CALL( consFixLinkvar(scip, cons, v, cutoff) );
    1460 break;
    1461 }
    1462 }
    1463 assert(v < nvars);
    1464 assert(consdata->nfixedzeros == consdata->nbinvars - 1);
    1465 assert(consdata->nfixedones == 1);
    1466
    1468 (*nchgbds)++;
    1469 }
    1470 }
    1471 else
    1472 {
    1473 SCIP_CALL( tightenedLinkvar(scip, cons, consdata, cutoff, nchgbds) );
    1474 }
    1475
    1476 *mustcheck = (*nchgbds) == 0;
    1477
    1478 assert(consdata->nfixedzeros + consdata->nfixedones <= consdata->nbinvars);
    1479
    1480 return SCIP_OKAY;
    1481}
    1482
    1483/** returns whether the given solution is feasible for the given linking constraint */
    1484static
    1486 SCIP* scip, /**< SCIP data structure */
    1487 SCIP_CONS* cons, /**< linking constraint to be checked */
    1488 SCIP_SOL* sol /**< primal solution, or NULL for current LP/pseudo solution */
    1489 )
    1490{
    1491 SCIP_CONSDATA* consdata;
    1492 SCIP_VAR** binvars;
    1493 SCIP_Real* vals;
    1494 SCIP_Real solval;
    1495 SCIP_Real linksum;
    1496 SCIP_Real linkvarval;
    1497 SCIP_Real setpartsum;
    1498 SCIP_Real setpartsumbound;
    1499 SCIP_Real absviol;
    1500 SCIP_Real relviol;
    1501 int nbinvars;
    1502 int b;
    1503
    1504 assert(scip != NULL);
    1505 assert(cons != NULL);
    1506
    1507 SCIPdebugMsg(scip, "checking linking constraint <%s> for feasibility of solution %p\n", SCIPconsGetName(cons), (void*)sol);
    1508
    1509 consdata = SCIPconsGetData(cons);
    1510 assert(consdata != NULL);
    1511 assert(consdata->binvars != NULL || consdata->nbinvars == 0);
    1512
    1513 /* in case there is only at most one binary variables, the constraints should already be disabled */
    1514 assert(consdata->nbinvars > 1);
    1515
    1516 /* calculate the constraint's activity for the linking part and the set partitioning part */
    1517 binvars = consdata->binvars;
    1518 vals = consdata->vals;
    1519 nbinvars = consdata->nbinvars;
    1520
    1521 linksum = 0.0;
    1522 setpartsum = 0.0;
    1523 setpartsumbound = 1.0 + 2*SCIPfeastol(scip);
    1524
    1525 for( b = 0; b < nbinvars && setpartsum < setpartsumbound; ++b ) /* if sum >= sumbound, the feasibility is clearly decided */
    1526 {
    1527 assert(SCIPvarIsBinary(binvars[b]));
    1528
    1529 solval = SCIPgetSolVal(scip, sol, binvars[b]);
    1530 assert(SCIPisFeasGE(scip, solval, 0.0) && SCIPisFeasLE(scip, solval, 1.0));
    1531
    1532 linksum += vals[b] * solval;
    1533 setpartsum += solval;
    1534 }
    1535
    1536 /* calculate and update absolute and relative violation of the equality constraint */
    1537 linkvarval = SCIPgetSolVal(scip, sol, consdata->linkvar);
    1538 absviol = REALABS(linksum - linkvarval);
    1539 relviol = REALABS(SCIPrelDiff(linksum, linkvarval));
    1540 if( sol != NULL )
    1541 SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
    1542
    1543 /* calculate and update absolute and relative violation of the set partitioning constraint */
    1544 absviol = REALABS(setpartsum - 1.0);
    1545 relviol = REALABS(SCIPrelDiff(setpartsum, 1.0));
    1546 if( sol != NULL )
    1547 SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
    1548
    1549 /* check if the fixed binary variable match with the linking variable */
    1550 return SCIPisFeasEQ(scip, linksum, linkvarval) && SCIPisFeasEQ(scip, setpartsum, 1.0);
    1551}
    1552
    1553#ifdef SCIP_DISABLED_CODE
    1554/* The following should work, but does not seem to be tested well. */
    1555
    1556/** transfer aggregated integer variables to the corresponding binary variables */
    1557static
    1559 SCIP* scip, /**< SCIP data structure */
    1560 SCIP_HASHMAP* varmap, /**< hash map mapping a integer variables to its linking constraint */
    1561 SCIP_CONS** conss, /**< array of linking constraint */
    1562 int nconss, /**< number of linking constraints */
    1563 int* naggrvars, /**< pointer to store the number of aggregate variables */
    1564 SCIP_Bool* cutoff /**< pointer to store if a cutoff was detected */
    1565 )
    1566{
    1567 SCIP_CONS* aggrcons;
    1568 SCIP_CONSDATA* aggrconsdata;
    1569 SCIP_CONSDATA* consdata;
    1570 SCIP_VAR** binvars;
    1571 SCIP_VAR** aggrbinvars;
    1572 SCIP_VAR* linkvar;
    1573 SCIP_VAR* aggrvar;
    1574 SCIP_Real aggrconst;
    1575 SCIP_Real aggrscalar;
    1576 SCIP_Bool infeasible;
    1577 SCIP_Bool redundant;
    1578 SCIP_Bool aggregated;
    1579 int offset;
    1580 int aggroffset;
    1581 int nbinvars;
    1582 int shift;
    1583 int b;
    1584 int c;
    1585
    1586 assert(varmap != NULL);
    1587
    1588 for( c = 0; c < nconss; ++c )
    1589 {
    1590 consdata = SCIPconsGetData(conss[c]);
    1591 assert(consdata != NULL);
    1592
    1593 linkvar = consdata->linkvar;
    1594 assert(linkvar != NULL);
    1595
    1597 {
    1598 aggrvar = SCIPvarGetAggrVar(linkvar);
    1599 aggrcons = (SCIP_CONS*) SCIPhashmapGetImage(varmap, getHashmapKey(aggrvar));
    1600
    1601 /* check if the aggregate variable belongs to a linking constraint */
    1602 if( aggrcons != NULL )
    1603 {
    1604 aggrconsdata = SCIPconsGetData(aggrcons);
    1605 assert(aggrconsdata != NULL);
    1606
    1607 aggrconst = SCIPvarGetAggrConstant(linkvar);
    1608 aggrscalar = SCIPvarGetAggrScalar(linkvar);
    1609
    1610 /**@todo extend the aggregation for those cases were the aggrscalar is not equal to 1.0 */
    1611 if( SCIPisEQ(scip, aggrscalar, 1.0 ) )
    1612 {
    1613 /* since both variables are integer variable and the aggrscalar is 1.0 the aggrconst should
    1614 * integral
    1615 */
    1616 assert(SCIPisIntegral(scip, aggrconst));
    1617 shift = SCIPconvertRealToInt(scip, aggrconst);
    1618
    1619 offset = consdata->offset;
    1620 binvars = consdata->binvars;
    1621 aggroffset = aggrconsdata->offset;
    1622 aggrbinvars = aggrconsdata->binvars;
    1623
    1624 nbinvars = MIN(consdata->nbinvars + offset, aggrconsdata->nbinvars + shift + aggroffset);
    1625
    1626 for( b = MAX(offset, aggroffset-shift); b < nbinvars; ++b )
    1627 {
    1628 assert(b - offset >= 0);
    1629 assert(b + shift - aggroffset >= 0);
    1630 assert(b < consdata->nbinvars);
    1631 assert(b < aggrconsdata->nbinvars - shift);
    1632
    1633 /* add aggregation x - y = 0.0 */
    1634 SCIP_CALL( SCIPaggregateVars(scip, binvars[b-offset], aggrbinvars[b+shift-aggroffset], 1.0, -1.0, 0.0,
    1635 &infeasible, &redundant, &aggregated) );
    1636
    1637 if( infeasible )
    1638 {
    1639 (*cutoff) = TRUE;
    1640 return SCIP_OKAY;
    1641 }
    1642
    1643 if( aggregated )
    1644 (*naggrvars)++;
    1645 }
    1646 }
    1647 }
    1648 }
    1649 }
    1650 return SCIP_OKAY;
    1651}
    1652#endif
    1653
    1654/** create two rows for the linking constraint
    1655 *
    1656 * - row1: {sum_{b=1}^n-1 vals[b] * binvars[b]} - linkvar = 0
    1657 * - row2: {sum_{b=0}^n-1 binvars[b]} = 1.0
    1658 */
    1659static
    1661 SCIP* scip, /**< SCIP data structure */
    1662 SCIP_CONS* cons /**< linking constraint */
    1663 )
    1664{
    1665 SCIP_CONSDATA* consdata;
    1666 char rowname[SCIP_MAXSTRLEN];
    1667 int b;
    1668
    1669 assert( cons != NULL);
    1670
    1671 /* get constraint data */
    1672 consdata = SCIPconsGetData(cons);
    1673 assert(consdata != NULL);
    1674 assert(consdata->row1 == NULL);
    1675 assert(consdata->row2 == NULL);
    1676 assert(consdata->nbinvars > 1);
    1677
    1678 /* create the LP row which captures the linking between the real and binary variables */
    1679 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[link]", SCIPconsGetName(cons));
    1680
    1681 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row1, cons, rowname, 0.0, 0.0,
    1683
    1684 /* add linking variable to the row */
    1685 assert(consdata->linkvar != NULL);
    1686 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row1, consdata->linkvar, -1.0) );
    1687
    1688 /* adding binary variables to the row */
    1689 assert(consdata->binvars != NULL);
    1690 for( b = 0; b < consdata->nbinvars; ++b )
    1691 {
    1692 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row1, consdata->binvars[b], consdata->vals[b]) );
    1693 }
    1694
    1695 /* create the LP row which captures the set partitioning condition of the binary variables */
    1696 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[setppc]", SCIPconsGetName(cons));
    1697 assert( consdata->nbinvars > 0 );
    1698
    1699 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row2, cons, rowname, 1.0, 1.0,
    1701
    1702 SCIP_CALL( SCIPaddVarsToRowSameCoef(scip, consdata->row2, consdata->nbinvars, consdata->binvars, 1.0) );
    1703
    1704 return SCIP_OKAY;
    1705}
    1706
    1707
    1708/** adds linking constraint as cut to the LP */
    1709static
    1711 SCIP* scip, /**< SCIP data structure */
    1712 SCIP_CONS* cons, /**< linking constraint */
    1713 SCIP_Bool* cutoff /**< whether a cutoff has been detected */
    1714 )
    1715{
    1716 SCIP_CONSDATA* consdata;
    1717
    1718 assert( cutoff != NULL );
    1719 *cutoff = FALSE;
    1720
    1721 consdata = SCIPconsGetData(cons);
    1722 assert(consdata != NULL);
    1723
    1724 /* in case there is only at most one binary variables, the constraints should already be disabled */
    1725 assert(consdata->nbinvars > 1);
    1726
    1727 if( consdata->row1 == NULL )
    1728 {
    1729 assert(consdata->row2 == NULL);
    1730
    1731 /* convert linking data into LP rows */
    1732 SCIP_CALL( createRows(scip, cons) );
    1733 }
    1734 assert(consdata->row1 != NULL);
    1735 assert(consdata->row2 != NULL);
    1736
    1737 /* insert LP linking row as cut */
    1738 if( !SCIProwIsInLP(consdata->row1) )
    1739 {
    1740 SCIPdebugMsg(scip, "adding linking row of constraint <%s> as cut to the LP\n", SCIPconsGetName(cons));
    1741 SCIP_CALL( SCIPaddRow(scip, consdata->row1, TRUE/*FALSE*/, cutoff) );
    1742 }
    1743
    1744 /* insert LP set partitioning row as cut */
    1745 if( !SCIProwIsInLP(consdata->row2) )
    1746 {
    1747 SCIPdebugMsg(scip, "adding set partitioning row of constraint <%s> as cut to the LP\n", SCIPconsGetName(cons));
    1748 SCIP_CALL( SCIPaddRow(scip, consdata->row2, TRUE/*FALSE*/, cutoff) );
    1749 }
    1750
    1751 return SCIP_OKAY;
    1752}
    1753
    1754/** adds linking constraint as rows to the NLP, if not added yet */
    1755static
    1757 SCIP* scip, /**< SCIP data structure */
    1758 SCIP_CONS* cons /**< linking constraint */
    1759 )
    1760{
    1761 SCIP_CONSDATA* consdata;
    1762
    1763 assert(SCIPisNLPConstructed(scip));
    1764
    1765 /* skip deactivated, redundant, or local constraints (the NLP does not allow for local rows at the moment) */
    1766 if( !SCIPconsIsActive(cons) || !SCIPconsIsChecked(cons) || SCIPconsIsLocal(cons) )
    1767 return SCIP_OKAY;
    1768
    1769 consdata = SCIPconsGetData(cons);
    1770 assert(consdata != NULL);
    1771
    1772 if( consdata->nlrow1 == NULL )
    1773 {
    1774 char rowname[SCIP_MAXSTRLEN];
    1775 SCIP_Real* coefs;
    1776 int i;
    1777
    1778 assert(consdata->nlrow2 == NULL);
    1779
    1780 /* create the NLP row which captures the linking between the real and binary variables */
    1781 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[link]", SCIPconsGetName(cons));
    1782
    1783 /* create nlrow1 with binary variables */
    1784 SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow1, rowname,
    1785 0.0, consdata->nbinvars, consdata->binvars, consdata->vals, NULL, 0.0, 0.0, SCIP_EXPRCURV_LINEAR) );
    1786 /* add linking variable to the row */
    1787 SCIP_CALL( SCIPaddLinearCoefToNlRow(scip, consdata->nlrow1, consdata->linkvar, -1.0) );
    1788
    1789 /* create the NLP row which captures the set partitioning condition of the binary variables */
    1790 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[setppc]", SCIPconsGetName(cons));
    1791
    1792 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, consdata->nbinvars) );
    1793 for( i = 0; i < consdata->nbinvars; ++i )
    1794 coefs[i] = 1.0;
    1795
    1796 SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow2, rowname,
    1797 0.0, consdata->nbinvars, consdata->binvars, coefs, NULL, 1.0, 1.0, SCIP_EXPRCURV_LINEAR) );
    1798
    1799 SCIPfreeBufferArray(scip, &coefs);
    1800 }
    1801
    1802 assert(SCIPnlrowIsInNLP(consdata->nlrow1) == SCIPnlrowIsInNLP(consdata->nlrow2));
    1803 if( !SCIPnlrowIsInNLP(consdata->nlrow1) )
    1804 {
    1805 SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow1) );
    1806 SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow2) );
    1807 }
    1808
    1809 return SCIP_OKAY;
    1810}
    1811
    1812/** checks constraint for violation, and adds it as a cuts if possible */
    1813static
    1815 SCIP* scip, /**< SCIP data structure */
    1816 SCIP_CONS* cons, /**< linking constraint to be separated */
    1817 SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
    1818 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    1819 SCIP_Bool* separated, /**< pointer to store TRUE, if a cut was found */
    1820 int* nchgbds /**< pointer to store the number of changed variables bounds */
    1821 )
    1822{
    1823 SCIP_CONSDATA* consdata;
    1824 SCIP_Bool addcut;
    1825 SCIP_Bool mustcheck;
    1826
    1827 assert(cons != NULL);
    1828 assert(SCIPconsGetHdlr(cons) != NULL);
    1829 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
    1830 assert(cutoff != NULL);
    1831 assert(separated != NULL);
    1832 assert(nchgbds != NULL);
    1833
    1834 consdata = SCIPconsGetData(cons);
    1835 assert(consdata != NULL);
    1836
    1837 /* in case there is only at most one binary variables, the constraints should already be disabled */
    1838 assert(consdata->nbinvars > 1);
    1839
    1840 SCIPdebugMsg(scip, "separating constraint <%s>\n", SCIPconsGetName(cons));
    1841
    1842 *cutoff = FALSE;
    1843 addcut = FALSE;
    1844 mustcheck = TRUE;
    1845
    1846 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
    1847 if( sol == NULL )
    1848 {
    1849 SCIP_CALL( processRealBoundChg(scip, cons, cutoff, nchgbds, &mustcheck) );
    1850 }
    1851
    1852 if( mustcheck && !(*cutoff) )
    1853 {
    1854 /* variable's fixings didn't give us any information -> we have to check the constraint */
    1855 if( sol == NULL && consdata->row1 != NULL )
    1856 {
    1857 SCIP_Real feasibility;
    1858 SCIP_Real tmp;
    1859
    1860 assert(consdata->row2 != NULL);
    1861
    1862 /* skip constraints already in the LP */
    1863 if( SCIProwIsInLP(consdata->row1) && SCIProwIsInLP(consdata->row2))
    1864 return SCIP_OKAY;
    1865
    1866 feasibility = 1.0;
    1867
    1868 /* check first row (linking) for feasibility */
    1869 if( !SCIProwIsInLP(consdata->row1) )
    1870 {
    1871 tmp = SCIPgetRowLPFeasibility(scip, consdata->row1);
    1872 feasibility = MIN(feasibility, tmp);
    1873 }
    1874
    1875 /* check second row (setppc) for feasibility */
    1876 if( !SCIProwIsInLP(consdata->row2) )
    1877 {
    1878 tmp = SCIPgetRowLPFeasibility(scip, consdata->row2);
    1879 feasibility = MIN(feasibility, tmp);
    1880 }
    1881 addcut = SCIPisFeasNegative(scip, feasibility);
    1882 }
    1883 else
    1884 addcut = !checkCons(scip, cons, sol);
    1885
    1886 if( !addcut )
    1887 {
    1888 /* constraint was feasible -> increase age */
    1889 SCIP_CALL( SCIPincConsAge(scip, cons) );
    1890 }
    1891 }
    1892
    1893 if( addcut )
    1894 {
    1895 /* insert LP row as cut */
    1896 assert(!(*cutoff));
    1897 SCIP_CALL( addCuts(scip, cons, cutoff) );
    1899 *separated = TRUE;
    1900 }
    1901
    1902 return SCIP_OKAY;
    1903}
    1904
    1905/** enforces the pseudo solution on the given constraint */
    1906static
    1908 SCIP* scip, /**< SCIP data structure */
    1909 SCIP_CONS* cons, /**< linking constraint to be separated */
    1910 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    1911 SCIP_Bool* infeasible, /**< pointer to store TRUE, if the constraint was infeasible */
    1912 int* nchgbds, /**< pointer to store the number of changed variable bounds */
    1913 SCIP_Bool* solvelp /**< pointer to store TRUE, if the LP has to be solved */
    1914 )
    1915{
    1916 SCIP_Bool addcut;
    1917 SCIP_Bool mustcheck;
    1918
    1919 assert(!SCIPhasCurrentNodeLP(scip));
    1920 assert(cons != NULL);
    1921 assert(SCIPconsGetHdlr(cons) != NULL);
    1922 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
    1923 assert(cutoff != NULL);
    1924 assert(infeasible != NULL);
    1925 assert(nchgbds != NULL);
    1926 assert(solvelp != NULL);
    1927
    1928 addcut = FALSE;
    1929 mustcheck = TRUE;
    1930
    1931 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
    1932 SCIP_CALL( processRealBoundChg(scip, cons, cutoff, nchgbds, &mustcheck) );
    1933 SCIP_CALL( processBinvarFixings(scip, cons, cutoff, nchgbds, &addcut, &mustcheck) );
    1934
    1935 if( mustcheck )
    1936 {
    1937 assert(!addcut);
    1938
    1939 if( checkCons(scip, cons, NULL) )
    1940 {
    1941 /* constraint was feasible -> increase age */
    1942 SCIP_CALL( SCIPincConsAge(scip, cons) );
    1943 }
    1944 else
    1945 {
    1946 /* constraint was infeasible -> reset age */
    1948 *infeasible = TRUE;
    1949 }
    1950 }
    1951
    1952 if( addcut )
    1953 {
    1954 assert(!(*cutoff));
    1955 /* a cut must be added to the LP -> we have to solve the LP immediately */
    1957 *solvelp = TRUE;
    1958 }
    1959
    1960 return SCIP_OKAY;
    1961}
    1962
    1963/** helper function to enforce constraints */
    1964static
    1966 SCIP* scip, /**< SCIP data structure */
    1967 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    1968 SCIP_CONS** conss, /**< constraints to process */
    1969 int nconss, /**< number of constraints */
    1970 int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
    1971 SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
    1972 SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
    1973 )
    1974{
    1975 SCIP_Bool cutoff;
    1976 SCIP_Bool separated;
    1977 int nchgbds;
    1978 int c;
    1979
    1980 assert(conshdlr != NULL);
    1981 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    1982 assert(nconss == 0 || conss != NULL);
    1983 assert(result != NULL);
    1984
    1985 SCIPdebugMsg(scip, "Enforcing %d linking constraints for %s solution\n", nconss, sol == NULL ? "LP" : "relaxation");
    1986
    1987 cutoff = FALSE;
    1988 separated = FALSE;
    1989 nchgbds = 0;
    1990
    1991 /* check all useful linking constraints for feasibility */
    1992 for( c = 0; c < nusefulconss && !cutoff && nchgbds == 0; ++c )
    1993 {
    1994 SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
    1995 }
    1996
    1997 /* check all obsolete linking constraints for feasibility */
    1998 for( c = nusefulconss; c < nconss && !cutoff && !separated && nchgbds == 0; ++c )
    1999 {
    2000 SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
    2001 }
    2002
    2003 /* return the correct result */
    2004 if( cutoff )
    2005 *result = SCIP_CUTOFF;
    2006 else if( nchgbds > 0 )
    2007 *result = SCIP_REDUCEDDOM;
    2008 else if( separated )
    2009 *result = SCIP_SEPARATED;
    2010 else
    2011 *result = SCIP_FEASIBLE;
    2012
    2013 return SCIP_OKAY;
    2014}
    2015
    2016/** adds symmetry information of constraint to a symmetry detection graph */
    2017static
    2019 SCIP* scip, /**< SCIP pointer */
    2020 SYM_SYMTYPE symtype, /**< type of symmetries that need to be added */
    2021 SCIP_CONS* cons, /**< constraint */
    2022 SYM_GRAPH* graph, /**< symmetry detection graph */
    2023 SCIP_Bool* success /**< pointer to store whether symmetry information could be added */
    2024 )
    2025{
    2026 SCIP_CONSDATA* consdata;
    2027 SCIP_VAR** vars;
    2028 SCIP_Real* vals;
    2029 SCIP_Real constant = 0.0;
    2030 int nlocvars;
    2031 int nvars;
    2032 int i;
    2033
    2034 assert(scip != NULL);
    2035 assert(cons != NULL);
    2036 assert(graph != NULL);
    2037 assert(success != NULL);
    2038
    2039 consdata = SCIPconsGetData(cons);
    2040 assert(consdata != NULL);
    2041
    2042 /* get active variables of the constraint */
    2043 nvars = SCIPgetNVars(scip);
    2044 nlocvars = consdata->nbinvars + 1;
    2045
    2046 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
    2047 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
    2048
    2049 /* get binary variables */
    2050 for( i = 0; i < consdata->nbinvars; ++i )
    2051 {
    2052 vars[i] = consdata->binvars[i];
    2053 vals[i] = consdata->vals[i];
    2054 }
    2055
    2056 /* get linking variable */
    2057 vars[consdata->nbinvars] = consdata->linkvar;
    2058 vals[consdata->nbinvars] = -1.0;
    2059
    2060 SCIP_CALL( SCIPgetSymActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant, SCIPisTransformed(scip)) );
    2061
    2062 SCIP_CALL( SCIPextendPermsymDetectionGraphLinear(scip, graph, vars, vals, nlocvars,
    2063 cons, -constant, -constant, success) );
    2064
    2065 SCIPfreeBufferArray(scip, &vals);
    2066 SCIPfreeBufferArray(scip, &vars);
    2067
    2068 return SCIP_OKAY;
    2069}
    2070
    2071/*
    2072 * Callback methods of constraint handler
    2073 */
    2074
    2075/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    2076static
    2077SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinking)
    2078{ /*lint --e{715}*/
    2079 assert(scip != NULL);
    2080 assert(conshdlr != NULL);
    2081 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    2082
    2083 /* call inclusion method of constraint handler */
    2085
    2086 *valid = TRUE;
    2087
    2088 return SCIP_OKAY;
    2089}
    2090
    2091/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
    2092static
    2093SCIP_DECL_CONSFREE(consFreeLinking)
    2094{
    2095 SCIP_CONSHDLRDATA* conshdlrdata;
    2096
    2097 assert(conshdlr != NULL);
    2098 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    2099 assert(scip != NULL);
    2100
    2101 /* free constraint handler data */
    2102 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2103 assert(conshdlrdata != NULL);
    2104
    2105 conshdlrdataFree(scip, &conshdlrdata);
    2106
    2107 return SCIP_OKAY;
    2108}
    2109
    2110
    2111/** presolving initialization method of constraint handler (called when presolving is about to begin) */
    2112static
    2113SCIP_DECL_CONSINITPRE(consInitpreLinking)
    2114{ /*lint --e{715}*/
    2115 SCIP_CONSHDLRDATA* conshdlrdata;
    2116 SCIP_CONSDATA* consdata;
    2117 int c;
    2118
    2119 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2120 assert(conshdlrdata != NULL);
    2121
    2122 /* disable all linking constraints which contain at most one binary variable */
    2123 for( c = 0; c < nconss; ++c )
    2124 {
    2125 consdata = SCIPconsGetData(conss[c]);
    2126 assert(consdata != NULL);
    2127
    2128 /* skip constraints which are not added */
    2129 if( !SCIPconsIsAdded(conss[c]) )
    2130 continue;
    2131
    2132 if( consdata->nbinvars <= 1 )
    2133 {
    2134 SCIP_CALL( SCIPdisableCons(scip, conss[c]) );
    2135 assert(consdata->nbinvars == 0 || SCIPvarGetLbGlobal(consdata->binvars[0]) > 0.5);
    2136 }
    2137 else if( conshdlrdata->linearize )
    2138 {
    2139 SCIP_CALL( consdataLinearize(scip, conss[c], consdata) );
    2140 SCIP_CALL( SCIPdelCons(scip, conss[c]) );
    2141 }
    2142 }
    2143
    2144 return SCIP_OKAY;
    2145}
    2146
    2147/** solving process initialization method of constraint handler */
    2148static
    2149SCIP_DECL_CONSINITSOL(consInitsolLinking)
    2150{ /*lint --e{715}*/
    2151 /* add nlrow representations to NLP, if NLP had been constructed */
    2153 {
    2154 int c;
    2155 for( c = 0; c < nconss; ++c )
    2156 {
    2157 SCIP_CALL( addNlrow(scip, conss[c]) );
    2158 }
    2159 }
    2160
    2161 return SCIP_OKAY;
    2162}
    2163
    2164/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
    2165static
    2166SCIP_DECL_CONSEXITSOL(consExitsolLinking)
    2167{ /*lint --e{715}*/
    2168 SCIP_CONSDATA* consdata;
    2169 int c;
    2170
    2171 for( c = 0; c < nconss; ++c )
    2172 {
    2173 consdata = SCIPconsGetData(conss[c]);
    2174 assert(consdata != NULL);
    2175
    2176 /* release the rows and nlrows of all constraints */
    2177 if( consdata->row1 != NULL )
    2178 {
    2179 assert(consdata->row2 != NULL);
    2180
    2181 SCIP_CALL( SCIPreleaseRow(scip, &consdata->row1) );
    2182 SCIP_CALL( SCIPreleaseRow(scip, &consdata->row2) );
    2183 }
    2184
    2185 if( consdata->nlrow1 != NULL )
    2186 {
    2187 assert(consdata->nlrow2 != NULL);
    2188
    2189 SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow1) );
    2190 SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow2) );
    2191 }
    2192 }
    2193
    2194 return SCIP_OKAY;
    2195}
    2196
    2197
    2198/** frees specific constraint data */
    2199static
    2200SCIP_DECL_CONSDELETE(consDeleteLinking)
    2201{ /*lint --e{715}*/
    2202 SCIP_CONSHDLRDATA* conshdlrdata;
    2203
    2204 assert(conshdlr != NULL);
    2205 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    2206 assert(consdata != NULL);
    2207 assert(*consdata != NULL);
    2208
    2209 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2210 assert(conshdlrdata != NULL);
    2211 assert(conshdlrdata->eventhdlr != NULL);
    2212
    2213 /* remove linking constraint form variable hash map */
    2214 assert(conshdlrdata->varmap != NULL);
    2215 assert(SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey((*consdata)->linkvar)));
    2216 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->varmap, getHashmapKey((*consdata)->linkvar)) );
    2217
    2218 if( (*consdata)->nbinvars > 0 && SCIPisTransformed(scip) )
    2219 {
    2220 SCIP_CALL( dropAllEvents(scip, *consdata, conshdlrdata->eventhdlr) );
    2221 }
    2222
    2223 /* free consdata */
    2224 SCIP_CALL( consdataFree(scip, consdata) );
    2225
    2226 return SCIP_OKAY;
    2227}
    2228
    2229
    2230/** transforms constraint data into data belonging to the transformed problem */
    2231static
    2232SCIP_DECL_CONSTRANS(consTransLinking)
    2233{ /*lint --e{715}*/
    2234 SCIP_CONSDATA* sourcedata;
    2235 SCIP_CONSDATA* targetdata;
    2236 SCIP_CONSHDLRDATA* conshdlrdata;
    2237
    2238 assert(conshdlr != NULL);
    2239 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    2241 assert(sourcecons != NULL);
    2242 assert(targetcons != NULL);
    2243
    2244 /* free constraint handler data */
    2245 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2246 assert(conshdlrdata != NULL);
    2247 assert(conshdlrdata->eventhdlr != NULL);
    2248
    2249 sourcedata = SCIPconsGetData(sourcecons);
    2250 assert(sourcedata != NULL);
    2251 assert(sourcedata->row1 == NULL); /* in original problem, there cannot be LP rows */
    2252 assert(sourcedata->row2 == NULL); /* in original problem, there cannot be LP rows */
    2253
    2254 SCIPdebugMsg(scip, "transform linking constraint for variable <%s>\n", SCIPvarGetName(sourcedata->linkvar));
    2255
    2256 /* create constraint data for target constraint */
    2257 SCIP_CALL( consdataCreate(scip, conshdlrdata->eventhdlr, &targetdata,
    2258 sourcedata->linkvar, sourcedata->binvars, sourcedata->vals, sourcedata->nbinvars) );
    2259
    2260 /* create target constraint */
    2261 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
    2262 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    2263 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
    2264 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
    2265 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
    2266
    2267 /* insert (transformed) linking constraint into the hash map */
    2268 assert(conshdlrdata->varmap != NULL);
    2269 SCIP_CALL( SCIPhashmapInsert(conshdlrdata->varmap, getHashmapKey(targetdata->linkvar), *targetcons) );
    2270
    2271 return SCIP_OKAY;
    2272}
    2273
    2274/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
    2275static
    2276SCIP_DECL_CONSINITLP(consInitlpLinking)
    2277{ /*lint --e{715}*/
    2278 SCIP_CONSDATA* consdata;
    2279 int c;
    2280
    2281 *infeasible = FALSE;
    2282
    2283 for( c = 0; c < nconss && !(*infeasible); ++c )
    2284 {
    2285 assert(SCIPconsIsInitial(conss[c]));
    2286
    2287 consdata = SCIPconsGetData(conss[c]);
    2288 assert(consdata != NULL);
    2289
    2290 if( consdata->nbinvars <= 1 )
    2291 continue;
    2292
    2293 SCIP_CALL( addCuts(scip, conss[c], infeasible) );
    2294 }
    2295
    2296 return SCIP_OKAY;
    2297}
    2298
    2299
    2300/** separation method of constraint handler for LP solutions */
    2301static
    2302SCIP_DECL_CONSSEPALP(consSepalpLinking)
    2303{ /*lint --e{715}*/
    2304 SCIP_Bool cutoff;
    2305 SCIP_Bool separated;
    2306 int nchgbds;
    2307 int c;
    2308
    2309 assert(conshdlr != NULL);
    2310 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    2311 assert(nconss == 0 || conss != NULL);
    2312 assert(result != NULL);
    2313
    2314 SCIPdebugMsg(scip, "separating %d/%d linking constraints\n", nusefulconss, nconss);
    2315
    2316 cutoff = FALSE;
    2317 separated = FALSE;
    2318 nchgbds = 0;
    2319
    2320 /* check all useful linking constraints for feasibility */
    2321 for( c = 0; c < nusefulconss && !cutoff; ++c )
    2322 {
    2323 SCIP_CALL( separateCons(scip, conss[c], NULL, &cutoff, &separated, &nchgbds) );
    2324 }
    2325
    2326 /* return the correct result */
    2327 if( cutoff )
    2328 *result = SCIP_CUTOFF;
    2329 else if( nchgbds > 0 )
    2330 *result = SCIP_REDUCEDDOM;
    2331 else if( separated )
    2332 *result = SCIP_SEPARATED;
    2333 else
    2334 *result = SCIP_DIDNOTFIND;
    2335
    2336 return SCIP_OKAY;
    2337}
    2338
    2339
    2340/** separation method of constraint handler for arbitrary primal solutions */
    2341static
    2342SCIP_DECL_CONSSEPASOL(consSepasolLinking)
    2343{ /*lint --e{715}*/
    2344 SCIP_Bool cutoff;
    2345 SCIP_Bool separated;
    2346 int nchgbds;
    2347 int c;
    2348
    2349 assert(conshdlr != NULL);
    2350 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    2351 assert(nconss == 0 || conss != NULL);
    2352 assert(result != NULL);
    2353
    2354 SCIPdebugMsg(scip, "separating %d/%d " CONSHDLR_NAME " constraints\n", nusefulconss, nconss);
    2355
    2356 cutoff = FALSE;
    2357 separated = FALSE;
    2358 nchgbds = 0;
    2359
    2360 /* check all useful set partitioning / packing / covering constraints for feasibility */
    2361 for( c = 0; c < nusefulconss && !cutoff; ++c )
    2362 {
    2363 SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
    2364 }
    2365
    2366 /* return the correct result */
    2367 if( cutoff )
    2368 *result = SCIP_CUTOFF;
    2369 else if( nchgbds > 0 )
    2370 *result = SCIP_REDUCEDDOM;
    2371 else if( separated )
    2372 *result = SCIP_SEPARATED;
    2373 else
    2374 *result = SCIP_DIDNOTFIND;
    2375
    2376 return SCIP_OKAY;
    2377}
    2378
    2379
    2380/** constraint enforcing method of constraint handler for LP solutions */
    2381static
    2382SCIP_DECL_CONSENFOLP(consEnfolpLinking)
    2383{ /*lint --e{715}*/
    2384 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
    2385
    2386 return SCIP_OKAY;
    2387}
    2388
    2389
    2390/** constraint enforcing method of constraint handler for relaxation solutions */
    2391static
    2392SCIP_DECL_CONSENFORELAX(consEnforelaxLinking)
    2393{ /*lint --e{715}*/
    2394 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
    2395
    2396 return SCIP_OKAY;
    2397}
    2398
    2399
    2400/** constraint enforcing method of constraint handler for pseudo solutions */
    2401static
    2402SCIP_DECL_CONSENFOPS(consEnfopsLinking)
    2403{ /*lint --e{715}*/
    2404 SCIP_Bool cutoff;
    2405 SCIP_Bool infeasible;
    2406 int nchgbds;
    2407 SCIP_Bool solvelp;
    2408 int c;
    2409
    2410 assert(conshdlr != NULL);
    2411 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    2412 assert(nconss == 0 || conss != NULL);
    2413 assert(result != NULL);
    2414
    2415 SCIPdebugMsg(scip, "pseudo enforcing %d " CONSHDLR_NAME " constraints\n", nconss);
    2416
    2417 if( objinfeasible )
    2418 {
    2419 *result = SCIP_DIDNOTRUN;
    2420 return SCIP_OKAY;
    2421 }
    2422
    2423 cutoff = FALSE;
    2424 infeasible = FALSE;
    2425 nchgbds = 0;
    2426 solvelp = FALSE;
    2427
    2428 /* check all linking constraint for domain reductions and feasibility */
    2429 for( c = 0; c < nconss && !cutoff && !solvelp; ++c )
    2430 {
    2431 SCIP_CALL( enforcePseudo(scip, conss[c], &cutoff, &infeasible, &nchgbds, &solvelp) );
    2432 }
    2433
    2434 if( cutoff )
    2435 *result = SCIP_CUTOFF;
    2436 else if( nchgbds > 0 )
    2437 *result = SCIP_REDUCEDDOM;
    2438 else if( solvelp )
    2439 *result = SCIP_SOLVELP;
    2440 else if( infeasible )
    2441 *result = SCIP_INFEASIBLE;
    2442 else
    2443 *result = SCIP_FEASIBLE;
    2444
    2445 return SCIP_OKAY;
    2446}
    2447
    2448
    2449/** feasibility check method of constraint handler for integral solutions */
    2450static
    2451SCIP_DECL_CONSCHECK(consCheckLinking)
    2452{ /*lint --e{715}*/
    2453 SCIP_CONS* cons;
    2454 SCIP_CONSDATA* consdata;
    2455 int c;
    2456
    2457 assert(conshdlr != NULL);
    2458 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    2459 assert(nconss == 0 || conss != NULL);
    2460 assert(result != NULL);
    2461
    2462 *result = SCIP_FEASIBLE;
    2463
    2464 /* check all linking constraints for feasibility */
    2465 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
    2466 {
    2467 cons = conss[c];
    2468 consdata = SCIPconsGetData(cons);
    2469 assert(consdata != NULL);
    2470
    2471 if( consdata->nbinvars > 1 && (checklprows || consdata->row1 == NULL || !SCIProwIsInLP(consdata->row1)) )
    2472 {
    2473 if( !checkCons(scip, cons, sol) )
    2474 {
    2475 /* constraint is violated */
    2476 *result = SCIP_INFEASIBLE;
    2477
    2478 if( printreason )
    2479 {
    2480 int pos;
    2481 int b;
    2482
    2483 pos = -1;
    2484
    2485#ifndef NDEBUG
    2486 for( b = 0; b < consdata->nbinvars; ++b )
    2487 {
    2488 assert(consdata->binvars[b] != NULL);
    2489 assert(SCIPvarIsBinary(consdata->binvars[b]));
    2490 }
    2491#endif
    2492
    2493 SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
    2494 SCIPinfoMessage(scip, NULL, ";\n");
    2495
    2496 /* check that at most one binary variable is fixed */
    2497 for( b = 0; b < consdata->nbinvars; ++b )
    2498 {
    2499 assert( SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, sol, consdata->binvars[b])) );
    2500
    2501 /* check if binary variable is fixed */
    2502 if( SCIPgetSolVal(scip, sol, consdata->binvars[b]) > 0.5 )
    2503 {
    2504 if( pos != -1 )
    2505 {
    2506 SCIPinfoMessage(scip, NULL, "violation: more than one binary variable is set to one");
    2507 break;
    2508 }
    2509 pos = b ;
    2510 }
    2511 }
    2512
    2513 /* check that at least one binary variable is fixed */
    2514 if( pos == -1 )
    2515 {
    2516 SCIPinfoMessage(scip, NULL, "violation: none of the binary variables is set to one\n");
    2517 }
    2518 else if( !SCIPisFeasEQ(scip, consdata->vals[pos], SCIPgetSolVal(scip, sol, consdata->linkvar)) )
    2519 {
    2520 /* check if the fixed binary variable match with the linking variable */
    2521 SCIPinfoMessage(scip, NULL, "violation: <%s> = <%g> and <%s> is one\n",
    2522 SCIPvarGetName(consdata->linkvar), SCIPgetSolVal(scip, sol, consdata->linkvar),
    2523 SCIPvarGetName(consdata->binvars[pos]) );
    2524 }
    2525 }
    2526 }
    2527 }
    2528 }
    2529
    2530 return SCIP_OKAY;
    2531}
    2532
    2533/** domain propagation method of constraint handler */
    2534static
    2535SCIP_DECL_CONSPROP(consPropLinking)
    2536{ /*lint --e{715}*/
    2537 SCIP_Bool cutoff = FALSE;
    2538 int nchgbds = 0;
    2539 int c;
    2540
    2541 assert(conshdlr != NULL);
    2542 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    2543 assert(nconss == 0 || conss != NULL);
    2544 assert(result != NULL);
    2545
    2546 SCIPdebugMsg(scip, "propagating %d/%d " CONSHDLR_NAME " constraints\n", nusefulconss, nconss);
    2547
    2548 /* propagate all useful set partitioning / packing / covering constraints */
    2549 for( c = 0; c < nusefulconss && !cutoff; ++c )
    2550 {
    2551 SCIP_Bool addcut;
    2552 SCIP_Bool mustcheck;
    2553
    2554 SCIP_CALL( processRealBoundChg(scip, conss[c], &cutoff, &nchgbds, &mustcheck) );
    2555 SCIP_CALL( processBinvarFixings(scip, conss[c], &cutoff, &nchgbds, &addcut, &mustcheck) );
    2556 } /*lint !e438*/
    2557
    2558 /* return the correct result */
    2559 if( cutoff )
    2560 *result = SCIP_CUTOFF;
    2561 else if( nchgbds > 0 )
    2562 *result = SCIP_REDUCEDDOM;
    2563 else
    2564 *result = SCIP_DIDNOTFIND;
    2565
    2566 return SCIP_OKAY;
    2567}
    2568
    2569
    2570/** presolving method of constraint handler */
    2571static
    2572SCIP_DECL_CONSPRESOL(consPresolLinking)
    2573{ /*lint --e{715}*/
    2574 SCIP_CONSHDLRDATA* conshdlrdata;
    2575 int oldnfixedvars;
    2576 int oldnchgbds;
    2577 int oldnaggrvars;
    2578 int oldndelconss;
    2579 int firstchange;
    2580 int firstclique;
    2581 int lastclique;
    2582 int c;
    2583 SCIP_Bool fixed;
    2584 SCIP_Bool cutoff;
    2585 SCIP_Bool infeasible;
    2586 SCIP_Bool mustcheck;
    2587
    2588 assert(conshdlr != NULL);
    2589 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    2590 assert(scip != NULL);
    2591 assert(result != NULL);
    2592
    2593 SCIPdebugMsg(scip, "presolve %d linking constraints\n", nconss);
    2594
    2595 (*result) = SCIP_DIDNOTFIND;
    2596
    2597 oldnchgbds = *nchgbds;
    2598 oldnaggrvars = *naggrvars;
    2599 oldnfixedvars = *nfixedvars;
    2600 oldndelconss = *ndelconss;
    2601 cutoff = FALSE;
    2602
    2603 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2604 assert(conshdlrdata != NULL);
    2605
    2606 /* process constraints */
    2607 firstchange = INT_MAX;
    2608 firstclique = INT_MAX;
    2609 lastclique = -1;
    2610
    2611 /* check for each linking constraint the set partitioning condition */
    2612 for( c = 0; c < nconss && !SCIPisStopped(scip); ++c )
    2613 {
    2614 SCIP_CONS* cons;
    2615 SCIP_CONSDATA* consdata;
    2616
    2617 assert(*result != SCIP_CUTOFF);
    2618
    2619 cons = conss[c];
    2620 assert(cons != NULL);
    2621 assert(!SCIPconsIsModifiable(cons));
    2622
    2623 SCIPdebugMsg(scip, "presolve linking constraints <%s>\n", SCIPconsGetName(cons));
    2624
    2625 consdata = SCIPconsGetData(cons);
    2626 assert(consdata != NULL);
    2627
    2628 if( !SCIPconsIsEnabled(cons) /* || consdata->nbinvars <= 1 */ )
    2629 continue;
    2630
    2631 /* in case there is only at most one binary variables, the constraints should already be disabled */
    2632 assert(consdata->nbinvars > 1);
    2633
    2634 /*SCIPdebugMsg(scip, "presolving set partitioning / packing / covering constraint <%s>\n", SCIPconsGetName(cons));*/
    2635 if( consdata->nfixedones >= 2 )
    2636 {
    2637 /* at least two variables are fixed to 1:
    2638 * - a linking constraint is infeasible due to the set partitioning condition
    2639 */
    2640 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> is infeasible\n", SCIPconsGetName(cons));
    2641 *result = SCIP_CUTOFF;
    2642 return SCIP_OKAY;
    2643 }
    2644
    2645 if( consdata->nfixedones == 1 )
    2646 {
    2647 /* exactly one variable is fixed to 1:
    2648 * - all other binary variables must be zero due to the set partitioning condition
    2649 * - linking variable has to be fixed to corresponding binary variable which is fixed to one
    2650 * - if constraint is not modifiable it can be removed
    2651 */
    2652 SCIP_VAR* var;
    2653 int v;
    2654
    2655 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> has a binary variable fixed to 1.0\n", SCIPconsGetName(cons));
    2656
    2657 for( v = 0; v < consdata->nbinvars; ++v )
    2658 {
    2659 var = consdata->binvars[v];
    2660 assert(var != NULL);
    2661
    2662 if( SCIPvarGetLbGlobal(var) < 0.5 && SCIPvarGetUbGlobal(var) > 0.5 )
    2663 {
    2664 SCIP_CALL( SCIPfixVar(scip, var, 0.0, &infeasible, &fixed) );
    2665
    2666 if( infeasible )
    2667 {
    2668 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == 0\n",
    2669 SCIPconsGetName(cons), SCIPvarGetName(var));
    2670
    2671 *result = SCIP_CUTOFF;
    2672 return SCIP_OKAY;
    2673 }
    2674 assert(fixed);
    2675 (*nfixedvars)++;
    2676 }
    2677 else if( SCIPvarGetLbGlobal(var) > 0.5 )
    2678 {
    2679 /* fix linking variable */
    2680 assert(SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_LOOSE
    2681 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_AGGREGATED
    2682 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_COLUMN
    2683 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_FIXED
    2684 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_NEGATED);
    2685 SCIP_CALL( SCIPfixVar(scip, consdata->linkvar, consdata->vals[v], &infeasible, &fixed) );
    2686
    2687 if( infeasible )
    2688 {
    2689 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == %g\n",
    2690 SCIPconsGetName(cons), SCIPvarGetName(consdata->linkvar), consdata->vals[v]);
    2691
    2692 *result = SCIP_CUTOFF;
    2693 return SCIP_OKAY;
    2694 }
    2695
    2696 if( fixed )
    2697 (*nfixedvars)++;
    2698 }
    2699 }
    2700
    2701 /* now all other variables are fixed to zero:
    2702 * the constraint is feasible, and if it's not modifiable, it is redundant
    2703 */
    2704 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> is redundant\n", SCIPconsGetName(cons));
    2705 SCIP_CALL( SCIPdelCons(scip, cons) );
    2706 (*ndelconss)++;
    2707 continue;
    2708 }
    2709
    2710 if( consdata->nfixedzeros == consdata->nbinvars )
    2711 {
    2712 /* all variables are fixed to zero:
    2713 * - a linking constraint is infeasible due the set partitioning condition
    2714 */
    2715 assert(consdata->nfixedones == 0);
    2716
    2717 SCIPdebugMsg(scip, "linking constraint <%s> is infeasible due to set partitioning condition\n", SCIPconsGetName(cons));
    2718 *result = SCIP_CUTOFF;
    2719 return SCIP_OKAY;
    2720 }
    2721
    2722 if( consdata->nfixedzeros == consdata->nbinvars - 1 )
    2723 {
    2724 /* all variables except one are fixed to zero:
    2725 * - a linking constraint is feasible due the set partitioning condition
    2726 * - the remaining binary variable can be fixed to one
    2727 * - linking variable has to be fixed to corresponding binary variable which is fixed to one
    2728 * - constraint can be deleted since it is not modifiable
    2729 */
    2730 SCIP_VAR* var;
    2731 int v;
    2732
    2733 assert(consdata->nfixedones == 0);
    2734
    2735 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> has only one binary variable not fixed to zero\n",
    2736 SCIPconsGetName(cons));
    2737
    2738 /* search unfixed variable */
    2739 /* intentional empty for loop to increment counter to proper position */
    2740 /* TODO speed up loop by considering only variables between firstnonfixed and lastnonfixed */
    2741 for( v = 0; v < consdata->nbinvars && SCIPvarGetUbGlobal(consdata->binvars[v]) < 0.5; ++v ); /*lint !e722*/
    2742 assert(v < consdata->nbinvars);
    2743 var = consdata->binvars[v];
    2744
    2745 /* fix remaining binary variable */
    2746 SCIP_CALL( SCIPfixVar(scip, var, 1.0, &infeasible, &fixed) );
    2747 if( infeasible )
    2748 {
    2749 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == 1\n",
    2750 SCIPconsGetName(cons), SCIPvarGetName(var));
    2751 *result = SCIP_CUTOFF;
    2752 return SCIP_OKAY;
    2753 }
    2754 assert(fixed);
    2755 (*nfixedvars)++;
    2756
    2757 /* fix linking variable */
    2758 assert(SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_LOOSE
    2759 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_AGGREGATED
    2760 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_COLUMN
    2761 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_FIXED
    2762 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_NEGATED);
    2763 SCIP_CALL( SCIPfixVar(scip, consdata->linkvar, consdata->vals[v], &infeasible, &fixed) );
    2764
    2765 if( infeasible )
    2766 {
    2767 SCIPdebugMsg(scip, CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == %g\n",
    2768 SCIPconsGetName(cons), SCIPvarGetName(consdata->linkvar), consdata->vals[v]);
    2769
    2770 *result = SCIP_CUTOFF;
    2771 return SCIP_OKAY;
    2772 }
    2773 assert(!SCIPvarIsActive(consdata->linkvar) || fixed);
    2774 if( fixed )
    2775 (*nfixedvars)++;
    2776
    2777 /* delete constraint from problem */
    2778 SCIP_CALL( SCIPdelCons(scip, cons) );
    2779 (*ndelconss)++;
    2780 continue;
    2781 }
    2782
    2783 if( consdata->nfixedzeros == consdata->nbinvars - 2 ) /*lint !e641*/
    2784 {
    2785 SCIP_VAR* var;
    2786 SCIP_VAR* var1;
    2787 SCIP_VAR* var2;
    2788 SCIP_Bool redundant;
    2789 SCIP_Bool aggregated;
    2790 int v;
    2791
    2792 /* aggregate variable, if set partitioning condition consists only of two
    2793 * non-fixed variables
    2794 */
    2795
    2796 /* search unfixed variable */
    2797 var1 = NULL;
    2798 var2 = NULL;
    2799 for( v = 0; v < consdata->nbinvars && var2 == NULL; ++v )
    2800 {
    2801 var = consdata->binvars[v];
    2802 if( SCIPvarGetUbGlobal(var) > 0.5 )
    2803 {
    2804 if( var1 == NULL )
    2805 var1 = var;
    2806 else
    2807 var2 = var;
    2808 }
    2809 }
    2810 assert(var1 != NULL && var2 != NULL);
    2811
    2812 /* aggregate binary equality var1 + var2 == 1 */
    2813 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: aggregate <%s> + <%s> == 1\n",
    2814 SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
    2815 SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
    2816
    2817 /* evaluate aggregation result */
    2818 if( infeasible )
    2819 {
    2820 SCIPdebugMsg(scip, "linking constraint <%s>: infeasible aggregation <%s> + <%s> == 1\n",
    2821 SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
    2822 *result = SCIP_CUTOFF;
    2823 return SCIP_OKAY;
    2824 }
    2825 if( aggregated )
    2826 (*naggrvars)++;
    2827 }
    2828
    2829 /* apply real bound to binary variables */
    2830 SCIP_CALL( processRealBoundChg(scip, cons, &cutoff, nchgbds, &mustcheck) );
    2831
    2832 /* tightened linking variable */
    2833 SCIP_CALL( tightenedLinkvar(scip, cons, consdata, &cutoff, nchgbds) );
    2834
    2835 /* remove the trailing and leeading binary variable which are fixed to zero */
    2836 SCIP_CALL( removeFixedBinvars(scip, conshdlrdata->eventhdlr, cons) );
    2837
    2838 /* fix the linking variable to the only remaining value and the corresponding binary variable to 1.0 */
    2839 if( ! cutoff && consdata->nbinvars == 1 )
    2840 {
    2841 SCIP_VAR* linkvar;
    2842 SCIP_VAR* binvar;
    2843 SCIP_Real val;
    2844
    2845 linkvar = consdata->linkvar;
    2846 binvar = consdata->binvars[0];
    2847 val = consdata->vals[0];
    2848
    2849 SCIPdebugMsg(scip, "linking constraint <%s>: fix <%s> to %16.9g as only one binary variable remains",
    2850 SCIPconsGetName(cons), SCIPvarGetName(linkvar), val);
    2851
    2852 SCIP_CALL( SCIPfixVar(scip, binvar, 1.0, &infeasible, &fixed) );
    2853 assert(fixed);
    2854 ++(*nfixedvars);
    2855
    2856 if( ! infeasible )
    2857 {
    2858 SCIP_CALL( SCIPfixVar(scip, linkvar, val, &infeasible, &fixed) );
    2859 assert(fixed);
    2860 ++(*nfixedvars);
    2861 }
    2862 cutoff = infeasible;
    2863
    2864 SCIP_CALL( SCIPdelCons(scip, cons) );
    2865 ++(*ndelconss);
    2866 }
    2867
    2868 if( cutoff )
    2869 {
    2870 *result = SCIP_CUTOFF;
    2871 return SCIP_OKAY;
    2872 }
    2873
    2874 /* remember the first changed constraint to begin the next redundancy round with */
    2875 if( firstchange == INT_MAX )
    2876 firstchange = c;
    2877
    2878 /* remember the first and last constraints for which we have to add the clique information */
    2879 if( !consdata->cliqueadded && consdata->nbinvars >= 2 )
    2880 {
    2881 if( firstclique == INT_MAX )
    2882 firstclique = c;
    2883 lastclique = c;
    2884 }
    2885 }
    2886
    2887 /* add clique and implication information */
    2888 for( c = firstclique; c < lastclique && !SCIPisStopped(scip); ++c )
    2889 {
    2890 SCIP_CONS* cons;
    2891 SCIP_CONSDATA* consdata;
    2892
    2893 assert(*result != SCIP_CUTOFF);
    2894
    2895 cons = conss[c];
    2896 assert(cons != NULL);
    2897
    2898 /* ignore deleted constraints */
    2899 if( !SCIPconsIsActive(cons) )
    2900 continue;
    2901
    2902 consdata = SCIPconsGetData(cons);
    2903 assert(consdata != NULL);
    2904
    2905 if( !consdata->cliqueadded && consdata->nbinvars >= 3 )
    2906 {
    2907 /* add set partitioning condition as clique */
    2908 int ncliquebdchgs;
    2909
    2910 SCIP_CALL( SCIPaddClique(scip, consdata->binvars, NULL, consdata->nbinvars, TRUE, &infeasible, &ncliquebdchgs) );
    2911 *nchgbds += ncliquebdchgs;
    2912
    2913 if( infeasible )
    2914 {
    2915 *result = SCIP_CUTOFF;
    2916 return SCIP_OKAY;
    2917 }
    2918
    2919 consdata->cliqueadded = TRUE;
    2920 }
    2921 }
    2922
    2923#ifdef SCIP_DISABLED_CODE
    2924 /* The following should work, but does not seem to be tested well. */
    2925
    2926 /* transfer aggregated linking variables to the corresponding binary variables */
    2927 SCIP_CALL( aggregateVariables(scip, conshdlrdata->varmap, conss, nconss, naggrvars, &cutoff) );
    2928#endif
    2929
    2930 if( cutoff )
    2931 *result = SCIP_CUTOFF;
    2932 else if( oldndelconss < *ndelconss || oldnfixedvars < *nfixedvars || oldnchgbds < *nchgbds || oldnaggrvars < *naggrvars)
    2933 *result = SCIP_SUCCESS;
    2934
    2935 return SCIP_OKAY; /*lint !e438*/
    2936}
    2937
    2938
    2939/** propagation conflict resolving method of constraint handler */
    2940static
    2941SCIP_DECL_CONSRESPROP(consRespropLinking)
    2942{ /*lint --e{715}*/
    2943 SCIP_CONSDATA* consdata;
    2944 SCIP_VAR* linkvar;
    2945 int v;
    2946
    2947 SCIPdebugMsg(scip, "conflict resolving method of " CONSHDLR_NAME " constraint handler\n");
    2948
    2949 consdata = SCIPconsGetData(cons);
    2950 assert(consdata != NULL);
    2951
    2952 linkvar = consdata->linkvar;
    2953 assert(linkvar != NULL);
    2954
    2955 *result = SCIP_DIDNOTFIND;
    2956
    2957 if( inferinfo == -1 )
    2958 {
    2959 /* we have to resolve a fixing of a binary variable which was done due to fixed binary variables */
    2960 assert(SCIPvarIsBinary(infervar));
    2961 assert(SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)));
    2962 assert(SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)));
    2963
    2964 if( boundtype == SCIP_BOUNDTYPE_UPPER )
    2965 {
    2966 /* we fixed the binary variable to zero since one of the other binary variable was fixed to one (set
    2967 * partitioning condition)
    2968 */
    2969 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
    2970
    2971 for( v = 0; v < consdata->nbinvars; ++v )
    2972 {
    2973 if( SCIPgetVarLbAtIndex(scip, consdata->binvars[v], bdchgidx, FALSE) > 0.5 )
    2974 {
    2975 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[v]) );
    2976 break;
    2977 }
    2978 }
    2979 assert(v < consdata->nbinvars);
    2980 }
    2981 else
    2982 {
    2983 /* we fixed the binary variable to one since all other binary variable were fixed to zero */
    2984 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
    2985 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) > 0.5);
    2986
    2987 for( v = 0; v < consdata->nbinvars; ++v )
    2988 {
    2989 if( consdata->binvars[v] != infervar )
    2990 {
    2991 /* the reason variable must be assigned to zero */
    2992 assert(SCIPgetVarUbAtIndex(scip, consdata->binvars[v], bdchgidx, FALSE) < 0.5);
    2993 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[v]) );
    2994 }
    2995 }
    2996 }
    2997 }
    2998 else if( inferinfo == -2 )
    2999 {
    3000 /* we have to resolve a fixing of a binary variable which was done due to the linking variable lower bound */
    3001 assert(SCIPvarIsBinary(infervar));
    3002 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
    3003 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5); /*@repair: neu*/
    3004 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5); /*@repair: neu*/
    3005 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3006 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3007
    3008 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, bdchgidx) );
    3009 }
    3010 else if( inferinfo == -3 )
    3011 {
    3012 /* we have to resolve a fixing of a binary variable which was done due to the linking variable upper bound */
    3013 assert(SCIPvarIsBinary(infervar));
    3014 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
    3015 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
    3016 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5);
    3017 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3018 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3019
    3020 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, bdchgidx) );
    3021 }
    3022 else if( inferinfo == -4 )
    3023 {
    3024 SCIP_VAR** binvars;
    3025 SCIP_Real* vals;
    3026 SCIP_Real lb;
    3027 int nbinvars;
    3028 int b;
    3029
    3030 /* we tightened the lower bound of the linking variable due the fixing of the corresponding binary variable to zero */
    3031 assert(infervar == linkvar);
    3032 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
    3033
    3034 binvars = consdata->binvars;
    3035 nbinvars = consdata->nbinvars;
    3036 vals = consdata->vals;
    3037
    3038 /* get propagated lower bound */
    3039 lb = SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE);
    3040
    3041 for( b = 0; b < nbinvars; ++b )
    3042 {
    3043 if( vals[b] >= lb )
    3044 break;
    3045
    3046 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
    3047 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
    3048 }
    3049 }
    3050 else if( inferinfo == -5 )
    3051 {
    3052 SCIP_VAR** binvars;
    3053 SCIP_Real* vals;
    3054 SCIP_Real ub;
    3055 int nbinvars;
    3056 int b;
    3057
    3058 /* we tightened the upper bound of the linking variable due the fixing of the corresponding binary variable two zero */
    3059
    3060 assert(infervar == linkvar);
    3061 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
    3062
    3063 binvars = consdata->binvars;
    3064 nbinvars = consdata->nbinvars;
    3065 vals = consdata->vals;
    3066
    3067 /* get old and new upper bound */
    3068 ub = SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE);
    3069
    3070 /* resolve tightening of upper bound of the linking variable by binary variables */
    3071 for( b = nbinvars - 1; b >= 0; --b )
    3072 {
    3073 if( vals[b] <= ub )
    3074 break;
    3075
    3076 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
    3077 }
    3078 }
    3079 else if( inferinfo == -6 )
    3080 {
    3081 /* we fixed a binary variable to one since the linking variable was fixed */
    3082 assert(SCIPvarIsBinary(infervar));
    3083 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
    3084 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3085 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3086 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3087 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3088
    3089 assert( !SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, FALSE)) );
    3090
    3091 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, bdchgidx) );
    3092 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, bdchgidx) );
    3093 }
    3094 else
    3095 {
    3096 /* we fixed the linking variable to (vals[inferinfo]) since the corresponding binary variable was fixed to one */
    3097 assert(infervar == linkvar);
    3098 assert(inferinfo >= 0);
    3099 assert(inferinfo < consdata->nbinvars);
    3100 assert(SCIPisEQ(scip, consdata->vals[inferinfo], SCIPgetVarUbAtIndex(scip, consdata->linkvar, bdchgidx, TRUE))
    3101 || SCIPisEQ(scip, consdata->vals[inferinfo], SCIPgetVarLbAtIndex(scip, consdata->linkvar, bdchgidx, TRUE)));
    3102
    3103 assert(SCIPgetVarLbAtIndex(scip, consdata->binvars[inferinfo], bdchgidx, FALSE) > 0.5);
    3104 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[inferinfo]) );
    3105 }
    3106
    3107 *result = SCIP_SUCCESS;
    3108
    3109 return SCIP_OKAY;
    3110}
    3111
    3112/** variable rounding lock method of constraint handler */
    3113static
    3114SCIP_DECL_CONSLOCK(consLockLinking)
    3115{ /*lint --e{715}*/
    3116 SCIP_CONSDATA* consdata;
    3117 int b;
    3118
    3119 assert(locktype == SCIP_LOCKTYPE_MODEL);
    3120
    3121 consdata = SCIPconsGetData(cons);
    3122 assert(consdata != NULL);
    3123
    3124 /* lock linking variable in both directions */
    3125 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->linkvar, locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
    3126
    3127 /* look binary variables in both directions */
    3128 for( b = 0; b < consdata->nbinvars; ++b )
    3129 {
    3130 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->binvars[b], locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
    3131 }
    3132
    3133 return SCIP_OKAY;
    3134}
    3135
    3136/** constraint activation notification method of constraint handler */
    3137static
    3138SCIP_DECL_CONSACTIVE(consActiveLinking)
    3139{ /*lint --e{715}*/
    3140 assert(cons != NULL);
    3141 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    3142 assert(SCIPconsIsTransformed(cons));
    3143
    3145 {
    3146 SCIP_CALL( addNlrow(scip, cons) );
    3147 }
    3148
    3149 return SCIP_OKAY;
    3150}
    3151
    3152
    3153/** constraint deactivation notification method of constraint handler */
    3154static
    3155SCIP_DECL_CONSDEACTIVE(consDeactiveLinking)
    3156{ /*lint --e{715}*/
    3157 SCIP_CONSDATA* consdata;
    3158
    3159 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    3160 assert(SCIPconsIsTransformed(cons));
    3161
    3162 /* get constraint data */
    3163 consdata = SCIPconsGetData(cons);
    3164 assert(consdata != NULL);
    3165
    3166 /* remove row from NLP, if still in solving
    3167 * if we are in exitsolve, the whole NLP will be freed anyway
    3168 */
    3169 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && consdata->nlrow1 != NULL )
    3170 {
    3171 assert(consdata->nlrow2 != NULL);
    3172 SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow1) );
    3173 SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow2) );
    3174 }
    3175
    3176 return SCIP_OKAY;
    3177}
    3178
    3179/** constraint enabling notification method of constraint handler */
    3180static
    3181SCIP_DECL_CONSENABLE(consEnableLinking)
    3182{ /*lint --e{715}*/
    3183#ifdef SCIP_DISABLED_CODE
    3184 SCIP_CONSHDLRDATA* conshdlrdata;
    3185#endif
    3186 SCIP_CONSDATA* consdata;
    3187
    3188#ifdef SCIP_DISABLED_CODE
    3189 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3190 assert(conshdlrdata != NULL);
    3191#endif
    3192
    3193 consdata = SCIPconsGetData(cons);
    3194 assert(consdata != NULL);
    3195
    3196 if( consdata->nbinvars <= 1 && SCIPgetStage(scip) >= SCIP_STAGE_TRANSFORMED )
    3197 {
    3198 SCIP_CALL( SCIPdisableCons(scip, cons) );
    3199 assert(consdata->nbinvars == 0 || SCIPvarGetLbGlobal(consdata->binvars[0]) > 0.5);
    3200 }
    3201#ifdef SCIP_DISABLED_CODE
    3202 /** @todo The following might help, but it would need to be tested whether it speeds up the solution process. */
    3203 else if( conshdlrdata->linearize )
    3204 {
    3205 SCIP_CALL( consdataLinearize(scip, cons, consdata) );
    3206 SCIP_CALL( SCIPdelCons(scip, cons) );
    3207 }
    3208#endif
    3209 return SCIP_OKAY;
    3210}
    3211
    3212/** constraint display method of constraint handler */
    3213static
    3214SCIP_DECL_CONSPRINT(consPrintLinking)
    3215{ /*lint --e{715}*/
    3216 assert(scip != NULL);
    3217 assert(conshdlr != NULL);
    3218 assert(cons != NULL);
    3219
    3221
    3222 return SCIP_OKAY;
    3223}
    3224
    3225
    3226/** constraint copying method of constraint handler */
    3227static
    3228SCIP_DECL_CONSCOPY(consCopyLinking)
    3229{ /*lint --e{715}*/
    3230 SCIP_CONSDATA* sourceconsdata;
    3231 SCIP_VAR** binvars;
    3232 SCIP_VAR* linkvar;
    3233 SCIP_Real* vals;
    3234 const char* consname;
    3235 int nbinvars;
    3236 int v;
    3237
    3238 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(sourcecons)), CONSHDLR_NAME) != 0 )
    3239 {
    3240 SCIPerrorMessage("constraint is not a linking constraint\n");
    3241 SCIPABORT();
    3242 return SCIP_INVALIDDATA; /*lint !e527*/
    3243 }
    3244
    3245 (*valid) = TRUE;
    3246
    3247 sourceconsdata = SCIPconsGetData(sourcecons);
    3248 assert(sourceconsdata != NULL);
    3249
    3250 /* get number of binary variables, linking variables */
    3251 nbinvars = sourceconsdata->nbinvars;
    3252 linkvar = sourceconsdata->linkvar;
    3253
    3254 /* duplicate variable array */
    3255 if( nbinvars > 0 )
    3256 {
    3257 SCIP_CALL( SCIPduplicateBufferArray(scip, &binvars, sourceconsdata->binvars, nbinvars) );
    3258 SCIP_CALL( SCIPduplicateBufferArray(scip, &vals, sourceconsdata->vals, nbinvars) );
    3259 }
    3260 else
    3261 {
    3262 binvars = NULL;
    3263 vals = NULL;
    3264 }
    3265
    3266 /* get copy for the binary variables */
    3267 for( v = 0; v < nbinvars && *valid; ++v )
    3268 {
    3269 assert(binvars != NULL); /* for flexelint */
    3270 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, binvars[v], &binvars[v], varmap, consmap, global, valid) );
    3271 assert(!(*valid) || binvars[v] != NULL);
    3272 }
    3273
    3274 /* copy the linking variable */
    3275 if( *valid )
    3276 {
    3277 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, linkvar, &linkvar, varmap, consmap, global, valid) );
    3278 assert(!(*valid) || linkvar != NULL);
    3279 }
    3280
    3281 /* only create the target constraint, if all variables could be copied */
    3282 if( *valid )
    3283 {
    3284 if( name != NULL )
    3285 consname = name;
    3286 else
    3287 consname = SCIPconsGetName(sourcecons);
    3288
    3289 SCIP_CALL( SCIPcreateConsLinking(scip, cons, consname, linkvar, binvars, vals, nbinvars,
    3290 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    3291 }
    3292
    3293 /* free buffer array */
    3294 if( nbinvars > 0 )
    3295 {
    3297 SCIPfreeBufferArrayNull(scip, &binvars);
    3298 }
    3299
    3300 return SCIP_OKAY;
    3301}
    3302
    3303/** constraint parsing method of constraint handler */
    3304static
    3305SCIP_DECL_CONSPARSE(consParseLinking)
    3306{ /*lint --e{715}*/
    3307 SCIP_VAR** binvars;
    3308 SCIP_VAR* linkvar;
    3309 SCIP_Real* vals;
    3310 char* endptr;
    3311 int varssize;
    3312 int nbinvars;
    3313
    3314 assert(scip != NULL);
    3315 assert(success != NULL);
    3316 assert(str != NULL);
    3317 assert(name != NULL);
    3318 assert(cons != NULL);
    3319
    3320 *success = TRUE;
    3321
    3322 /* parse linking variable */
    3323 SCIP_CALL( SCIPparseVarName(scip, str, &linkvar, &endptr) );
    3324
    3325 if( linkvar == NULL )
    3326 {
    3327 SCIPerrorMessage("unknown variable name at '%s'\n", str);
    3328 *success = FALSE;
    3329 return SCIP_OKAY;
    3330 }
    3331
    3332 /* find "==" */
    3333 endptr = strchr(endptr, '=');
    3334
    3335 /* if the string end has been reached without finding the "==" */
    3336 if( endptr == NULL )
    3337 {
    3338 SCIPerrorMessage("Could not find initializing '='.\n");
    3339 *success = FALSE;
    3340 return SCIP_OKAY;
    3341 }
    3342
    3343 str = endptr;
    3344
    3345 /* skip "==" */
    3346 str += *(str+1) == '=' ? 2 : 1;
    3347
    3348 /* skip whitespace */
    3349 SCIP_CALL( SCIPskipSpace((char**)&str) );
    3350
    3351 nbinvars = 0;
    3352 varssize = 16;
    3353 SCIP_CALL( SCIPallocBufferArray(scip, &binvars, varssize) );
    3354 SCIP_CALL( SCIPallocBufferArray(scip, &vals, varssize) );
    3355
    3356 /* check for the string "no binary variables yet" */
    3357 if( strncmp(str, "no binary variables yet", 24) != 0 )
    3358 {
    3359 int requsize;
    3360 int v;
    3361
    3362 /* parse linear sum to get variables and coefficients */
    3363 SCIP_CALL( SCIPparseVarsLinearsum(scip, str, binvars, vals, &nbinvars, varssize, &requsize, &endptr, success) );
    3364
    3365 if( *success && requsize > varssize )
    3366 {
    3367 /* realloc buffers and try again */
    3368 varssize = requsize;
    3369 SCIP_CALL( SCIPreallocBufferArray(scip, &binvars, varssize) );
    3370 SCIP_CALL( SCIPreallocBufferArray(scip, &vals, varssize) );
    3371
    3372 SCIP_CALL( SCIPparseVarsLinearsum(scip, str, binvars, vals, &nbinvars, varssize, &requsize, &endptr, success) );
    3373 assert(!*success || requsize <= varssize); /* if successful, then should have had enough space now */
    3374 }
    3375
    3376 /* check coefficients */
    3377 if( *success )
    3378 {
    3379 /* convert SCIP_Real to integer */
    3380 for( v = 0; v < nbinvars; ++v )
    3381 {
    3382 if( SCIPisIntegral(scip, vals[v]) )
    3383 vals[v] = SCIPconvertRealToInt(scip, vals[v]);
    3384 }
    3385 }
    3386 }
    3387
    3388 if( *success )
    3389 {
    3390 SCIP_CALL( SCIPcreateConsLinking(scip, cons, name, linkvar, binvars, vals, nbinvars,
    3391 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    3392 }
    3393
    3394 SCIPfreeBufferArray(scip, &vals);
    3395 SCIPfreeBufferArray(scip, &binvars);
    3396
    3397 return SCIP_OKAY;
    3398}
    3399
    3400/** constraint method of constraint handler which returns the variables (if possible) */
    3401static
    3402SCIP_DECL_CONSGETVARS(consGetVarsLinking)
    3403{ /*lint --e{715}*/
    3404 SCIP_CONSDATA* consdata;
    3405
    3406 consdata = SCIPconsGetData(cons);
    3407 assert(consdata != NULL);
    3408
    3409 if( varssize < consdata->nbinvars + 1)
    3410 (*success) = FALSE;
    3411 else
    3412 {
    3413 assert(vars != NULL);
    3414
    3415 BMScopyMemoryArray(vars, consdata->binvars, consdata->nbinvars);
    3416 vars[consdata->nbinvars] = consdata->linkvar;
    3417 (*success) = TRUE;
    3418 }
    3419
    3420 return SCIP_OKAY;
    3421}
    3422
    3423/** constraint method of constraint handler which returns the number of variables (if possible) */
    3424static
    3425SCIP_DECL_CONSGETNVARS(consGetNVarsLinking)
    3426{ /*lint --e{715}*/
    3427 SCIP_CONSDATA* consdata;
    3428
    3429 consdata = SCIPconsGetData(cons);
    3430 assert(consdata != NULL);
    3431
    3432 (*nvars) = consdata->nbinvars + 1;
    3433 (*success) = TRUE;
    3434
    3435 return SCIP_OKAY;
    3436}
    3437
    3438/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
    3439static
    3440SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphLinking)
    3441{ /*lint --e{715}*/
    3442 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_PERM, cons, graph, success) );
    3443
    3444 return SCIP_OKAY;
    3445}
    3446
    3447/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
    3448static
    3449SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphLinking)
    3450{ /*lint --e{715}*/
    3451 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_SIGNPERM, cons, graph, success) );
    3452
    3453 return SCIP_OKAY;
    3454}
    3455
    3456/*
    3457 * Callback methods of event handler
    3458 */
    3459
    3460/** execution method of event handler */
    3461static
    3462SCIP_DECL_EVENTEXEC(eventExecBinvar)
    3463{ /*lint --e{715}*/
    3464 SCIP_CONSDATA* consdata;
    3465 SCIP_EVENTTYPE eventtype;
    3466
    3467 assert(eventhdlr != NULL);
    3468 assert(eventdata != NULL);
    3469 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    3470 assert(event != NULL);
    3471
    3472 consdata = (SCIP_CONSDATA*)eventdata;
    3473 assert(consdata != NULL);
    3474
    3475 eventtype = SCIPeventGetType(event);
    3476 switch( eventtype )
    3477 {
    3479 consdata->nfixedones++;
    3480 break;
    3482 consdata->nfixedones--;
    3483 consdata->firstnonfixed = 0;
    3484 consdata->lastnonfixed = consdata->nbinvars - 1;
    3485 break;
    3487 consdata->nfixedzeros++;
    3488 break;
    3490 consdata->firstnonfixed = 0;
    3491 consdata->lastnonfixed = consdata->nbinvars - 1;
    3492 consdata->nfixedzeros--;
    3493 break;
    3494 default:
    3495 SCIPerrorMessage("invalid event type\n");
    3496 return SCIP_INVALIDDATA;
    3497 }
    3498 assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nbinvars);
    3499 assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nbinvars);
    3500
    3501 /*debugMsg(scip, " -> constraint has %d zero-fixed and %d one-fixed of %d variables\n",
    3502 consdata->nfixedzeros, consdata->nfixedones, consdata->nvars);*/
    3503
    3504 return SCIP_OKAY;
    3505}
    3506
    3507/*
    3508 * constraint specific interface methods
    3509 */
    3510
    3511/** creates the handler for linking constraints and includes it in SCIP */
    3513 SCIP* scip /**< SCIP data structure */
    3514 )
    3515{
    3516 SCIP_CONSHDLRDATA* conshdlrdata;
    3517 SCIP_CONSHDLR* conshdlr;
    3518 SCIP_EVENTHDLR* eventhdlr;
    3519
    3520 /* create event handler for bound change events */
    3522 eventExecBinvar, NULL) );
    3523
    3524 /* create linking constraint handler data */
    3525 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
    3526
    3527 /* include constraint handler */
    3530 consEnfolpLinking, consEnfopsLinking, consCheckLinking, consLockLinking,
    3531 conshdlrdata) );
    3532
    3533 assert(conshdlr != NULL);
    3534
    3535 /* set non-fundamental callbacks via specific setter functions */
    3536 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinking, consCopyLinking) );
    3537 SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveLinking) );
    3538 SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveLinking) );
    3539 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinking) );
    3540 SCIP_CALL( SCIPsetConshdlrEnable(scip, conshdlr, consEnableLinking) );
    3541 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolLinking) );
    3542 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinking) );
    3543 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinking) );
    3544 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinking) );
    3545 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinking) );
    3546 SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreLinking) );
    3547 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinking) );
    3548 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinking) );
    3550 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinking) );
    3553 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinking) );
    3554 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinking, consSepasolLinking, CONSHDLR_SEPAFREQ,
    3556 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinking) );
    3557 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxLinking) );
    3558 SCIP_CALL( SCIPsetConshdlrGetPermsymGraph(scip, conshdlr, consGetPermsymGraphLinking) );
    3559 SCIP_CALL( SCIPsetConshdlrGetSignedPermsymGraph(scip, conshdlr, consGetSignedPermsymGraphLinking) );
    3560
    3561 /* include the linear constraint to linking constraint upgrade in the linear constraint handler */
    3562 /* SCIP_CALL( SCIPincludeLinconsUpgrade(scip, linconsUpgdLinking, LINCONSUPGD_PRIORITY, CONSHDLR_NAME) ); */
    3563
    3564 /* add linking constraint handler parameters */
    3566 "constraints/" CONSHDLR_NAME "/linearize", "this constraint will not propagate or separate, linear and setppc are used?",
    3567 &conshdlrdata->linearize, FALSE, DEFAULT_LINEARIZE, NULL, NULL) );
    3568
    3569 return SCIP_OKAY;
    3570}
    3571
    3572/** creates and captures a linking constraint
    3573 *
    3574 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    3575 */
    3577 SCIP* scip, /**< SCIP data structure */
    3578 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    3579 const char* name, /**< name of constraint */
    3580 SCIP_VAR* linkvar, /**< linking variable (continuous or integer) which should be linked */
    3581 SCIP_VAR** binvars, /**< binary variables */
    3582 SCIP_Real* vals, /**< coefficients of the binary variables */
    3583 int nbinvars, /**< number of binary starting variables */
    3584 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    3585 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    3586 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    3587 * Usually set to TRUE. */
    3588 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    3589 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    3590 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    3591 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    3592 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    3593 * Usually set to TRUE. */
    3594 SCIP_Bool local, /**< is constraint only valid locally?
    3595 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    3596 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    3597 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    3598 * adds coefficients to this constraint. */
    3599 SCIP_Bool dynamic, /**< is constraint subject to aging?
    3600 * Usually set to FALSE. Set to TRUE for own cuts which
    3601 * are separated as constraints. */
    3602 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    3603 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    3604 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    3605 * if it may be moved to a more global node?
    3606 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    3607 )
    3608{
    3609 SCIP_CONSHDLR* conshdlr;
    3610 SCIP_CONSDATA* consdata;
    3611 SCIP_CONSHDLRDATA* conshdlrdata;
    3612 int k;
    3613
    3614 assert(scip != NULL);
    3615 assert(linkvar != NULL);
    3616 assert(binvars != NULL || nbinvars == 0);
    3617 assert(vals != NULL || nbinvars == 0);
    3618
    3619 /* find the linking constraint handler */
    3620 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    3621 if( conshdlr == NULL )
    3622 {
    3623 SCIPerrorMessage("linking constraint handler not found\n");
    3624 return SCIP_PLUGINNOTFOUND;
    3625 }
    3626
    3627 SCIPdebugMsg(scip, "create linking constraint for variable <%s> with %d binary variables (SCIP stage %d)\n",
    3628 SCIPvarGetName(linkvar), nbinvars, SCIPgetStage(scip));
    3629
    3630 if( binvars == NULL && ( !SCIPvarIsIntegral(linkvar)
    3632 || SCIPisInfinity(scip, SCIPvarGetUbGlobal(linkvar)) ) )
    3633 {
    3634 SCIPerrorMessage("linking variable <%s> is %s\n",
    3635 SCIPvarGetName(linkvar), SCIPvarIsIntegral(linkvar) ? "unbounded" : "continuous");
    3636 return SCIP_INVALIDDATA;
    3637 }
    3638
    3639 for( k = 0; k < nbinvars; ++k )
    3640 {
    3641 SCIPdebugMsg(scip, "Var %d : <%s>\n", k, SCIPvarGetName(binvars[k]));
    3642 if( !SCIPisFinite(vals[k]) || SCIPisInfinity(scip, REALABS(vals[k])) )
    3643 {
    3644 SCIPerrorMessage("linking value %lf of <%s> is %s\n",
    3645 vals[k], SCIPvarGetName(binvars[k]), SCIPisFinite(vals[k]) ? "infinite" : "nan");
    3646 return SCIP_INVALIDDATA;
    3647 }
    3648 }
    3649
    3650 /* get constraint handler data */
    3651 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3652 assert(conshdlrdata != NULL);
    3653
    3654 if( conshdlrdata->varmap == NULL )
    3655 {
    3656 SCIP_CALL( SCIPhashmapCreate(&conshdlrdata->varmap, SCIPblkmem(scip), HASHSIZE_BINVARSCONS) );
    3657 }
    3658 assert(conshdlrdata->varmap != NULL);
    3659
    3660 /* check if the linking for the requests linking variable already exists */
    3661 assert(!SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(linkvar)));
    3662
    3663 /* create the constraint specific data */
    3664 SCIP_CALL( consdataCreate(scip, conshdlrdata->eventhdlr, &consdata, linkvar, binvars, vals, nbinvars) );
    3665
    3666 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata,
    3667 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    3668
    3669 /* create binary variables for the real domain */
    3670 if( consdata->binvars == NULL )
    3671 {
    3672 SCIP_CALL( consdataCreateBinvars(scip, *cons, consdata, conshdlrdata->eventhdlr, conshdlrdata->linearize) );
    3673 }
    3674
    3675 /* insert linking constraint into the hash map */
    3676 SCIP_CALL( SCIPhashmapInsert(conshdlrdata->varmap, getHashmapKey(linkvar), *cons) );
    3677 assert(SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(linkvar)));
    3678
    3679 return SCIP_OKAY;
    3680}
    3681
    3682/** creates and captures a linking constraint
    3683 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
    3684 * method SCIPcreateConsLinking(); all flags can be set via SCIPsetCons<Flagname>-methods in scip.h
    3685 *
    3686 * @see SCIPcreateConsLinking() for information about the basic constraint flag configuration
    3687 *
    3688 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    3689 */
    3691 SCIP* scip, /**< SCIP data structure */
    3692 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    3693 const char* name, /**< name of constraint */
    3694 SCIP_VAR* linkvar, /**< linking variable (continuous or integer) which should be linked */
    3695 SCIP_VAR** binvars, /**< binary variables, or NULL */
    3696 SCIP_Real* vals, /**< coefficients of the binary variables */
    3697 int nbinvars /**< number of binary variables */
    3698 )
    3699{
    3700 assert(scip != NULL);
    3701
    3702 SCIP_CALL( SCIPcreateConsLinking(scip, cons, name, linkvar, binvars, vals, nbinvars,
    3704
    3705 return SCIP_OKAY;
    3706}
    3707
    3708/** checks if for the given linking variable (continuous or integer) a linking constraint exists */
    3710 SCIP* scip, /**< SCIP data structure */
    3711 SCIP_VAR* linkvar /**< linking variable (continuous or integer) which should be linked */
    3712 )
    3713{
    3714 SCIP_CONSHDLR* conshdlr;
    3715 SCIP_CONSHDLRDATA* conshdlrdata;
    3716
    3717 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    3718 assert(conshdlr != NULL);
    3719
    3720 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3721 assert(conshdlrdata != NULL);
    3722
    3723 return (conshdlrdata->varmap != NULL) && SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(linkvar));
    3724}
    3725
    3726/** returns the linking constraint belonging the given linking variable (continuous or integer) or NULL if it does not exist yet */
    3728 SCIP* scip, /**< SCIP data structure */
    3729 SCIP_VAR* linkvar /**< linking variable (continuous or integer) which should be linked */
    3730 )
    3731{
    3732 SCIP_CONSHDLR* conshdlr;
    3733 SCIP_CONSHDLRDATA* conshdlrdata;
    3734
    3735 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    3736 assert(conshdlr != NULL);
    3737
    3738 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3739 assert(conshdlrdata != NULL);
    3740
    3741 if( conshdlrdata->varmap != NULL )
    3742 return (SCIP_CONS*) SCIPhashmapGetImage(conshdlrdata->varmap, getHashmapKey(linkvar));
    3743 else
    3744 return NULL;
    3745}
    3746
    3747/** returns the linking variable (continuous or integer) of the linking constraint */
    3749 SCIP* scip, /**< SCIP data structure */
    3750 SCIP_CONS* cons /**< linking constraint */
    3751 )
    3752{
    3753 SCIP_CONSDATA* consdata;
    3754
    3755 assert(scip != NULL);
    3756
    3757 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    3758 {
    3759 SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
    3760 SCIPABORT();
    3761 return NULL; /*lint !e527*/
    3762 }
    3763
    3764 consdata = SCIPconsGetData(cons);
    3765 assert(consdata != NULL);
    3766
    3767 return consdata->linkvar;
    3768}
    3769
    3770/** returns the binary variables of the linking constraint */
    3772 SCIP* scip, /**< SCIP data structure */
    3773 SCIP_CONS* cons, /**< linking constraint */
    3774 SCIP_VAR*** binvars, /**< pointer to store the binary variables array pointer */
    3775 int* nbinvars /**< pointer to store the number of returned binary variables */
    3776 )
    3777{
    3778 SCIP_CONSDATA* consdata;
    3779
    3780 assert(scip != NULL);
    3781
    3782 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    3783 {
    3784 SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
    3785 SCIPABORT();
    3786 return SCIP_INVALIDDATA; /*lint !e527*/
    3787 }
    3788
    3789 consdata = SCIPconsGetData(cons);
    3790 assert(consdata != NULL);
    3791 assert(consdata->binvars != NULL);
    3792
    3793 if( binvars != NULL )
    3794 (*binvars) = consdata->binvars;
    3795 if( nbinvars != NULL )
    3796 (*nbinvars) = consdata->nbinvars;
    3797
    3798 return SCIP_OKAY;
    3799}
    3800
    3801/** returns the number of binary variables of the linking constraint */
    3803 SCIP* scip, /**< SCIP data structure */
    3804 SCIP_CONS* cons /**< linking constraint */
    3805 )
    3806{
    3807 SCIP_CONSDATA* consdata;
    3808
    3809 assert(scip != NULL);
    3810
    3811 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    3812 {
    3813 SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
    3814 SCIPABORT();
    3815 return -1; /*lint !e527*/
    3816 }
    3817
    3818 consdata = SCIPconsGetData(cons);
    3819 assert(consdata != NULL);
    3820
    3821 return consdata->nbinvars;
    3822}
    3823
    3824/** returns the coefficients of the binary variables */
    3826 SCIP* scip, /**< SCIP data structure */
    3827 SCIP_CONS* cons /**< linking constraint */
    3828 )
    3829{
    3830 SCIP_CONSDATA* consdata;
    3831
    3832 assert(scip != NULL);
    3833
    3834 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    3835 {
    3836 SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
    3837 SCIPABORT();
    3838 return NULL; /*lint !e527*/
    3839 }
    3840
    3841 consdata = SCIPconsGetData(cons);
    3842 assert(consdata != NULL);
    3843 consdataSort(consdata);
    3844
    3845 return consdata->vals;
    3846}
    3847
    3848/** return all binary variable information of the linking constraint */
    3850 SCIP_CONS* cons, /**< linking constraint */
    3851 SCIP_VAR*** binvars, /**< pointer to store binary variables, or NULL */
    3852 SCIP_Real** vals, /**< pointer to store the binary coefficients, or NULL */
    3853 int* nbinvars /**< pointer to store the number of binary variables, or NULL */
    3854 )
    3855{
    3856 SCIP_CONSDATA* consdata;
    3857
    3858 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    3859 {
    3860 SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
    3861 SCIPABORT();
    3862 return SCIP_ERROR;
    3863 }
    3864
    3865 consdata = SCIPconsGetData(cons);
    3866 assert(consdata != NULL);
    3867
    3868 consdataSort(consdata);
    3869
    3870 if( binvars != NULL )
    3871 *binvars = consdata->binvars;
    3872 if( vals != NULL )
    3873 *vals = consdata->vals;
    3874 if( nbinvars != NULL )
    3875 *nbinvars = consdata->nbinvars;
    3876
    3877 return SCIP_OKAY;
    3878}
    SCIP_VAR ** b
    Definition: circlepacking.c:65
    static SCIP_RETCODE aggregateVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars)
    Constraint handler for linear constraints in their most general form, .
    static SCIP_DECL_CONSRESPROP(consRespropLinking)
    static SCIP_RETCODE consdataLinearize(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata)
    Definition: cons_linking.c:389
    static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
    Definition: cons_linking.c:232
    static SCIP_DECL_CONSENFORELAX(consEnforelaxLinking)
    #define CONSHDLR_NEEDSCONS
    Definition: cons_linking.c:99
    #define CONSHDLR_SEPAFREQ
    Definition: cons_linking.c:93
    static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *linkvar, SCIP_VAR *binvar, SCIP_Bool lblinkvar, SCIP_Bool ublinkvar)
    Definition: cons_linking.c:675
    static SCIP_RETCODE enforcePseudo(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, SCIP_Bool *infeasible, int *nchgbds, SCIP_Bool *solvelp)
    static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinking)
    #define CONSHDLR_CHECKPRIORITY
    Definition: cons_linking.c:92
    static SCIP_DECL_CONSDEACTIVE(consDeactiveLinking)
    static SCIP_RETCODE addCuts(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff)
    #define CONSHDLR_DESC
    Definition: cons_linking.c:85
    static SCIP_RETCODE catchAllEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr)
    Definition: cons_linking.c:336
    static SCIP_RETCODE consFixLinkvar(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff)
    Definition: cons_linking.c:723
    static SCIP_RETCODE dropEvent(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos)
    Definition: cons_linking.c:305
    static SCIP_RETCODE dropAllEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr)
    Definition: cons_linking.c:362
    static SCIP_RETCODE removeFixedBinvars(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_CONS *cons)
    #define CONSHDLR_PROP_TIMING
    Definition: cons_linking.c:101
    static SCIP_DECL_CONSINITSOL(consInitsolLinking)
    static SCIP_DECL_CONSTRANS(consTransLinking)
    static SCIP_DECL_CONSENFOPS(consEnfopsLinking)
    static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
    Definition: cons_linking.c:214
    static SCIP_RETCODE processBinvarFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool *addcut, SCIP_Bool *mustcheck)
    static void * getHashmapKey(SCIP_VAR *var)
    Definition: cons_linking.c:146
    #define CONSHDLR_MAXPREROUNDS
    Definition: cons_linking.c:96
    static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **binvars, int nbinvars)
    Definition: cons_linking.c:172
    static SCIP_Bool checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
    #define CONSHDLR_SEPAPRIORITY
    Definition: cons_linking.c:90
    static SCIP_DECL_CONSPRINT(consPrintLinking)
    static SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphLinking)
    static SCIP_DECL_CONSENABLE(consEnableLinking)
    #define DEFAULT_LINEARIZE
    Definition: cons_linking.c:106
    static SCIP_DECL_CONSACTIVE(consActiveLinking)
    static SCIP_RETCODE addSymmetryInformation(SCIP *scip, SYM_SYMTYPE symtype, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
    static SCIP_DECL_CONSEXITSOL(consExitsolLinking)
    static SCIP_RETCODE catchEvent(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos)
    Definition: cons_linking.c:273
    static SCIP_RETCODE processRealBoundChg(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool *mustcheck)
    Definition: cons_linking.c:780
    static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_CONSDATA **consdata, SCIP_VAR *linkvar, SCIP_VAR **binvars, SCIP_Real *vals, int nbinvars)
    Definition: cons_linking.c:530
    static SCIP_RETCODE consdataCreateBinvars(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool linearize)
    Definition: cons_linking.c:428
    static SCIP_DECL_EVENTEXEC(eventExecBinvar)
    static SCIP_DECL_CONSGETVARS(consGetVarsLinking)
    static SCIP_DECL_CONSSEPALP(consSepalpLinking)
    static SCIP_DECL_CONSCHECK(consCheckLinking)
    static SCIP_DECL_CONSPARSE(consParseLinking)
    static SCIP_DECL_CONSPRESOL(consPresolLinking)
    static SCIP_RETCODE tightenedLinkvar(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_Bool *cutoff, int *nchgbds)
    static SCIP_DECL_CONSPROP(consPropLinking)
    #define CONSHDLR_PROPFREQ
    Definition: cons_linking.c:94
    static SCIP_RETCODE createRows(SCIP *scip, SCIP_CONS *cons)
    static SCIP_DECL_CONSINITLP(consInitlpLinking)
    static SCIP_DECL_CONSCOPY(consCopyLinking)
    #define CONSHDLR_PRESOLTIMING
    Definition: cons_linking.c:102
    static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_CONS *cons, int pos)
    Definition: cons_linking.c:980
    static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result)
    static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
    Definition: cons_linking.c:615
    static void consdataSort(SCIP_CONSDATA *consdata)
    Definition: cons_linking.c:156
    static SCIP_RETCODE addNlrow(SCIP *scip, SCIP_CONS *cons)
    static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *cutoff, SCIP_Bool *separated, int *nchgbds)
    #define CONSHDLR_EAGERFREQ
    Definition: cons_linking.c:95
    #define EVENTHDLR_DESC
    Definition: cons_linking.c:88
    static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
    Definition: cons_linking.c:191
    #define CONSHDLR_ENFOPRIORITY
    Definition: cons_linking.c:91
    static SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphLinking)
    #define CONSHDLR_DELAYSEPA
    Definition: cons_linking.c:97
    static SCIP_DECL_CONSLOCK(consLockLinking)
    static SCIP_DECL_CONSENFOLP(consEnfolpLinking)
    #define HASHSIZE_BINVARSCONS
    Definition: cons_linking.c:105
    #define CONSHDLR_NAME
    Definition: cons_linking.c:84
    #define EVENTHDLR_NAME
    Definition: cons_linking.c:87
    static SCIP_DECL_CONSDELETE(consDeleteLinking)
    static SCIP_DECL_CONSINITPRE(consInitpreLinking)
    static SCIP_DECL_CONSFREE(consFreeLinking)
    static SCIP_DECL_CONSSEPASOL(consSepasolLinking)
    static SCIP_DECL_CONSGETNVARS(consGetNVarsLinking)
    #define CONSHDLR_DELAYPROP
    Definition: cons_linking.c:98
    constraint handler for linking binary variables to a linking (continuous or integer) variable
    Constraint handler for the set partitioning / packing / covering constraints .
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIPABORT()
    Definition: def.h:327
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    int SCIPgetNBinvarsLinking(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPgetBinvarsLinking(SCIP *scip, SCIP_CONS *cons, SCIP_VAR ***binvars, int *nbinvars)
    SCIP_Bool SCIPexistsConsLinking(SCIP *scip, SCIP_VAR *linkvar)
    SCIP_VAR * SCIPgetLinkvarLinking(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    SCIP_CONS * SCIPgetConsLinking(SCIP *scip, SCIP_VAR *linkvar)
    SCIP_RETCODE SCIPcreateConsLinking(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *linkvar, SCIP_VAR **binvars, SCIP_Real *vals, int nbinvars, 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 SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_RETCODE SCIPcreateConsSetpart(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_setppc.c:9402
    SCIP_RETCODE SCIPcreateConsBasicLinking(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *linkvar, SCIP_VAR **binvars, SCIP_Real *vals, int nbinvars)
    SCIP_Real * SCIPgetValsLinking(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPgetBinvarsDataLinking(SCIP_CONS *cons, SCIP_VAR ***binvars, SCIP_Real **vals, int *nbinvars)
    SCIP_RETCODE SCIPincludeConshdlrLinking(SCIP *scip)
    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:647
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:759
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    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
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3284
    SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
    Definition: misc.c:3143
    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 SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3482
    SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:4067
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
    Definition: misc.c:11162
    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
    SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
    SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
    SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
    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 SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
    Definition: scip_cons.c:808
    SCIP_RETCODE SCIPsetConshdlrEnable(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENABLE((*consenable)))
    Definition: scip_cons.c:716
    SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
    Definition: scip_cons.c:540
    SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
    Definition: scip_cons.c:831
    SCIP_RETCODE SCIPsetConshdlrInitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITPRE((*consinitpre)))
    Definition: scip_cons.c:492
    SCIP_RETCODE SCIPsetConshdlrSepa(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSSEPALP((*conssepalp)), SCIP_DECL_CONSSEPASOL((*conssepasol)), int sepafreq, int sepapriority, SCIP_Bool delaysepa)
    Definition: scip_cons.c:235
    SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
    Definition: scip_cons.c:281
    SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: scip_cons.c:181
    SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
    Definition: scip_cons.c:693
    SCIP_RETCODE SCIPsetConshdlrGetPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETPERMSYMGRAPH((*consgetpermsymgraph)))
    Definition: scip_cons.c:900
    SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
    Definition: scip_cons.c:578
    SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
    Definition: scip_cons.c:372
    SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
    Definition: scip_cons.c:323
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_RETCODE 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 SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
    Definition: scip_cons.c:624
    SCIP_RETCODE SCIPsetConshdlrInitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITSOL((*consinitsol)))
    Definition: scip_cons.c:444
    SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4336
    SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
    Definition: scip_cons.c:601
    SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
    Definition: scip_cons.c:647
    SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
    Definition: scip_cons.c:854
    SCIP_RETCODE SCIPsetConshdlrActive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSACTIVE((*consactive)))
    Definition: scip_cons.c:670
    SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
    Definition: scip_cons.c:785
    SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
    Definition: cons.c:8419
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8648
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_RETCODE SCIPenableCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1837
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8558
    SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
    Definition: scip_cons.c:2536
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8588
    SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
    Definition: cons.c:8698
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8578
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8450
    SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: scip_cons.c:997
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8608
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8628
    SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
    Definition: cons.c:8486
    SCIP_RETCODE SCIPdisableCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1871
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1812
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8638
    SCIP_Bool SCIPconsIsAdded(SCIP_CONS *cons)
    Definition: cons.c:8818
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8668
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8568
    SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1784
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8658
    SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
    Definition: scip_cut.c:225
    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_Bool SCIPhasCurrentNodeLP(SCIP *scip)
    Definition: scip_lp.c:87
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    #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 SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #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 SCIPaddLinearCoefToNlRow(SCIP *scip, SCIP_NLROW *nlrow, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_nlp.c:1161
    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_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
    Definition: scip_lp.c:1508
    SCIP_Real SCIPgetRowLPFeasibility(SCIP *scip, SCIP_ROW *row)
    Definition: scip_lp.c:1974
    SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
    Definition: lp.c:17917
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    void SCIPupdateSolLPConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
    Definition: scip_sol.c:469
    SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
    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_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeastol(SCIP *scip)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    int SCIPconvertRealToInt(SCIP *scip, SCIP_Real real)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPinRepropagation(SCIP *scip)
    Definition: scip_tree.c:146
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5210
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8882
    SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
    Definition: scip_var.c:2119
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
    Definition: var.c:23771
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
    Definition: var.c:23430
    SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
    Definition: scip_var.c:10550
    SCIP_RETCODE SCIPinferVarUbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:7069
    SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
    Definition: var.c:23748
    SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
    Definition: var.c:17550
    SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
    Definition: scip_var.c:728
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23652
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5296
    SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2872
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    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_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
    Definition: scip_var.c:120
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
    Definition: scip_var.c:10318
    SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6964
    SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2736
    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 SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
    Definition: scip_var.c:361
    SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
    Definition: scip_var.c:474
    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_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
    Definition: var.c:23736
    void SCIPsortRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
    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)
    memory allocation routines
    #define BMScopyMemoryArray(ptr, source, num)
    Definition: memory.h:134
    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
    public data structures and miscellaneous methods
    #define SCIPisFinite(x)
    Definition: pub_misc.h:82
    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 problem copies
    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 solutions
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1221
    structs for symmetry computations
    methods for dealing with symmetry detection graphs
    @ SCIP_CONFTYPE_PROPAGATION
    Definition: type_conflict.h:62
    struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
    Definition: type_cons.h:64
    struct SCIP_ConsData SCIP_CONSDATA
    Definition: type_cons.h:65
    #define SCIP_EVENTTYPE_BOUNDCHANGED
    Definition: type_event.h:127
    struct SCIP_EventData SCIP_EVENTDATA
    Definition: type_event.h:179
    #define SCIP_EVENTTYPE_UBTIGHTENED
    Definition: type_event.h:79
    #define SCIP_EVENTTYPE_LBRELAXED
    Definition: type_event.h:78
    uint64_t SCIP_EVENTTYPE
    Definition: type_event.h:156
    #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_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    @ 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_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_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_PRESOLVING
    Definition: type_set.h:49
    @ SCIP_STAGE_TRANSFORMED
    Definition: type_set.h:47
    @ 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
    @ 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_AGGREGATED
    Definition: type_var.h:55
    @ SCIP_VARSTATUS_LOOSE
    Definition: type_var.h:52
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141