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-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file cons_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
    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(cutoff != NULL);
    802 assert(nchgbds != NULL);
    803 assert(mustcheck != NULL);
    804
    806
    807 consdata = SCIPconsGetData(cons);
    808 assert(consdata != NULL);
    809
    810 /* ensure that the binary variables are sorted in non-decreasing order w.r.t. their coefficients */
    811 consdataSort(consdata);
    812
    813 nbinvars = consdata->nbinvars;
    814
    815 /* in case there is only at most one binary variables, the constraints should already be disabled */
    816 assert(nbinvars > 1);
    817
    818 /* if more than one binary variable is fixed to one or at least nbinvars minus one variable are fixed to zero */
    819 if( consdata->nfixedones > 0 || consdata->nfixedzeros >= nbinvars-1 )
    820 return SCIP_OKAY;
    821
    822 linkvar = consdata->linkvar;
    823 assert(linkvar != NULL);
    824
    825 binvars = consdata->binvars;
    826 vals = consdata->vals;
    827
    828 lb = SCIPvarGetLbLocal(linkvar);
    829 ub = SCIPvarGetUbLocal(linkvar);
    830
    831 assert(lb <= ub);
    832
    833#ifndef NDEBUG
    834 /* check that the first variable are locally fixed to zero */
    835 for( b = 0; b < consdata->firstnonfixed; ++b )
    836 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
    837
    838 /* check that the last variable are locally fixed to zero */
    839 for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
    840 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
    841#endif
    842
    843 for( b = consdata->firstnonfixed; b < nbinvars; ++b )
    844 {
    845 if( SCIPisLT(scip, vals[b], lb) )
    846 {
    847 SCIP_VAR* var;
    848
    849 var = binvars[b];
    850 assert(var != NULL);
    851
    852 SCIPdebugMsg(scip, "fix variable <%s> to zero due to the lower bound of the linking variable <%s> [%g,%g]\n",
    853 SCIPvarGetName(var), SCIPvarGetName(linkvar), lb, ub);
    854
    855 SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -2, &infeasible, &tightened) );
    856
    857 if( infeasible )
    858 {
    859 SCIP_CALL( analyzeConflict(scip, cons, linkvar, var, TRUE, FALSE) );
    860 *cutoff = TRUE;
    861 return SCIP_OKAY;
    862 }
    863
    864 if( tightened )
    865 (*nchgbds)++;
    866
    867 /* adjust constraint state */
    868 consdata->firstnonfixed++;
    869 }
    870 else
    871 break;
    872 }
    873
    874 /* fix binary variables to zero if not yet fixed, from local upper bound + 1*/
    875 for( b = consdata->lastnonfixed; b >= 0; --b )
    876 {
    877 if( SCIPisGT(scip, vals[b], ub) )
    878 {
    879 SCIP_VAR* var;
    880
    881 var = binvars[b];
    882 assert(var != NULL);
    883
    884 SCIPdebugMsg(scip, "fix variable <%s> to zero due to the upper bound of the linking variable <%s> [%g,%g]\n",
    885 SCIPvarGetName(var), SCIPvarGetName(linkvar), lb, ub);
    886
    887 SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -3, &infeasible, &tightened) );
    888
    889 if( infeasible )
    890 {
    891 SCIP_CALL( analyzeConflict(scip, cons, linkvar, var, FALSE, TRUE) );
    892 *cutoff = TRUE;
    893 return SCIP_OKAY;
    894 }
    895
    896 if( tightened )
    897 (*nchgbds)++;
    898
    899 /* adjust constraint state */
    900 consdata->lastnonfixed--;
    901 }
    902 else
    903 break;
    904 }
    905
    906 if( consdata->firstnonfixed > consdata->lastnonfixed )
    907 {
    908 *cutoff = TRUE;
    909 return SCIP_OKAY;
    910 }
    911
    912 *mustcheck = (*nchgbds) == 0;
    913
    914 /* if linking variable is fixed, create for the binary variables which have a coefficient equal to the fixed value a
    915 * set partitioning constraint
    916 */
    917 if( SCIPisEQ(scip, lb, ub) )
    918 {
    919 if( consdata->firstnonfixed == consdata->lastnonfixed )
    920 {
    921 SCIP_VAR* var;
    922
    923 var = binvars[consdata->firstnonfixed];
    924
    925 SCIPdebugMsg(scip, "fix variable <%s> to one due to the fixed linking variable <%s> [%g,%g]\n",
    926 SCIPvarGetName(var), SCIPvarGetName(linkvar), lb, ub);
    927
    928 /* TODO can the forbidden cases be covered more elegantly? */
    930 return SCIP_OKAY;
    931
    935 return SCIP_OKAY;
    936
    937 SCIP_CALL( SCIPinferBinvarCons(scip, var, TRUE, cons, -6, &infeasible, &tightened) );
    938
    939 if( infeasible )
    940 {
    941 SCIP_CALL( analyzeConflict(scip, cons, linkvar, var, TRUE, TRUE) );
    942 *cutoff = TRUE;
    943 return SCIP_OKAY;
    944 }
    945
    946 if( tightened )
    947 (*nchgbds)++;
    948
    949 SCIPdebugMsg(scip, " -> disabling linking constraint <%s>\n", SCIPconsGetName(cons));
    951
    952 *mustcheck = FALSE;
    953 }
    954 else if( SCIPgetDepth(scip) <= 0 )
    955 {
    956 SCIP_CONS* setppc;
    957 SCIP_VAR** vars;
    958 int nvars;
    959
    960 /* get sub array of variables which have the same coefficient */
    961 vars = &consdata->binvars[consdata->firstnonfixed];
    962 nvars = consdata->lastnonfixed - consdata->firstnonfixed + 1;
    963
    964 SCIP_CALL( SCIPcreateConsSetpart(scip, &setppc, SCIPconsGetName(cons), nvars, vars,
    968
    969 SCIP_CALL( SCIPaddCons(scip, setppc) );
    970 SCIP_CALL( SCIPreleaseCons(scip, &setppc) );
    971
    973 }
    974 }
    975
    976 return SCIP_OKAY;
    977}
    978
    979/** deletes coefficient at given position from the binary variable array */
    980static
    982 SCIP* scip, /**< SCIP data structure */
    983 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    984 SCIP_CONS* cons, /**< linking constraint */
    985 int pos /**< position of coefficient to delete */
    986 )
    987{
    988 SCIP_CONSDATA* consdata;
    989 SCIP_VAR* var;
    990
    991 assert(scip != NULL);
    992 assert(eventhdlr != NULL);
    993
    994 consdata = SCIPconsGetData(cons);
    995 assert(consdata != NULL);
    996 assert(0 <= pos && pos < consdata->nbinvars);
    997
    998 var = consdata->binvars[pos];
    999 assert(var != NULL);
    1000 assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
    1001
    1002 /* remove the rounding locks for the deleted variable */
    1003 SCIP_CALL( SCIPunlockVarCons(scip, var, cons, TRUE, TRUE) );
    1004
    1005 /* if we are in transformed problem, delete the event data of the variable */
    1006 if( SCIPconsIsTransformed(cons) )
    1007 {
    1008 SCIP_CONSHDLR* conshdlr;
    1009 SCIP_CONSHDLRDATA* conshdlrdata;
    1010
    1011 /* get event handler */
    1012 conshdlr = SCIPconsGetHdlr(cons);
    1013 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    1014 assert(conshdlrdata != NULL);
    1015 assert(conshdlrdata->eventhdlr != NULL);
    1016
    1017 /* drop bound change events of variable */
    1018 SCIP_CALL( dropEvent(scip, consdata, conshdlrdata->eventhdlr, pos) );
    1019 }
    1020
    1021 /* move the last variable to the free slot */
    1022 if( pos != consdata->nbinvars - 1 )
    1023 {
    1024 consdata->binvars[pos] = consdata->binvars[consdata->nbinvars-1];
    1025 consdata->vals[pos] = consdata->vals[consdata->nbinvars-1];
    1026 consdata->sorted = FALSE;
    1027 }
    1028
    1029 consdata->nbinvars--;
    1030
    1031 /* release variable */
    1032 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    1033
    1034 return SCIP_OKAY;
    1035}
    1036
    1037/** remove the trailing and leading binary variables that are fixed to zero */
    1038static
    1040 SCIP* scip, /**< SCIP data structure */
    1041 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    1042 SCIP_CONS* cons /**< linking constraint */
    1043 )
    1044{
    1045 SCIP_CONSDATA* consdata;
    1046 int nbinvars;
    1047 int b;
    1048
    1049 consdata = SCIPconsGetData(cons);
    1050 assert(consdata != NULL);
    1051 assert(consdata->sorted);
    1052
    1054 assert(!SCIPinProbing(scip));
    1055 assert(!SCIPinRepropagation(scip));
    1056
    1057 nbinvars = consdata->nbinvars;
    1058
    1059 for( b = nbinvars - 1; b > consdata->lastnonfixed; --b )
    1060 {
    1061 SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
    1062 }
    1063
    1064 for( b = consdata->firstnonfixed - 1; b >= 0; --b )
    1065 {
    1066 SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
    1067 }
    1068
    1069 for( b = consdata->nbinvars - 1; b >= 0; --b )
    1070 {
    1071 if( SCIPvarGetUbLocal(consdata->binvars[b]) < 0.5 )
    1072 {
    1073 SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
    1074 }
    1075 }
    1076
    1077 /* set the constraint state */
    1078 consdata->firstnonfixed = 0;
    1079 consdata->lastnonfixed = consdata->nbinvars - 1;
    1080
    1081 return SCIP_OKAY;
    1082}
    1083
    1084/** tightened the linking variable due to binary variables which are fixed to zero */
    1085static
    1087 SCIP* scip, /**< SCIP data structure */
    1088 SCIP_CONS* cons, /**< linking constraint to be processed */
    1089 SCIP_CONSDATA* consdata, /**< linking constraint to be processed */
    1090 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    1091 int* nchgbds /**< pointer to store the number of changed variable bounds */
    1092 )
    1093{
    1094 SCIP_VAR** binvars;
    1095 SCIP_VAR* linkvar;
    1096 SCIP_Real* vals;
    1097
    1098 SCIP_Bool infeasible;
    1099 SCIP_Bool tightened;
    1100 int nbinvars;
    1101 int b;
    1102
    1103 /* if more than one binary variable is fixed to one or at least nbinvars minus one variable are fixed to zero return */
    1104 if( consdata->nfixedones > 1 || consdata->nfixedzeros >= consdata->nbinvars-1 )
    1105 return SCIP_OKAY;
    1106
    1107 if( *cutoff )
    1108 return SCIP_OKAY;
    1109
    1110 assert(consdata->sorted);
    1111
    1112 linkvar = consdata->linkvar;
    1113 binvars = consdata->binvars;
    1114 vals = consdata->vals;
    1115 nbinvars = consdata->nbinvars;
    1116
    1117#ifndef NDEBUG
    1118 /* check that the first variable are locally fixed to zero */
    1119 for( b = 0; b < consdata->firstnonfixed; ++b )
    1120 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
    1121#endif
    1122
    1123 assert(consdata->firstnonfixed < nbinvars);
    1124 assert(consdata->lastnonfixed < nbinvars);
    1125
    1126 /* find first non fixed binary variable */
    1127 for( b = consdata->firstnonfixed; b < nbinvars; ++b )
    1128 {
    1129 if( SCIPvarGetUbLocal(binvars[b]) > 0.5 )
    1130 break;
    1131
    1132 consdata->firstnonfixed++;
    1133 }
    1134
    1135 SCIP_CALL( SCIPinferVarLbCons(scip, linkvar, vals[b], cons, -4, TRUE, &infeasible, &tightened) );
    1136
    1137 /* start conflict analysis if infeasible */
    1138 if( infeasible )
    1139 {
    1140 /* analyze the cutoff if if SOLVING stage and conflict analysis is turned on */
    1142 {
    1143 SCIPdebugMsg(scip, "conflict at <%s> due to bounds and fixed binvars: [lb,ub] = [%g,%g]; b= %d; coef = %g \n",
    1144 SCIPvarGetName(linkvar), SCIPvarGetLbLocal(linkvar), SCIPvarGetUbLocal(linkvar), b, vals[b]);
    1145
    1147
    1148 /* ??????????? use resolve method and only add binvars which are needed to exceed the upper bound */
    1149
    1150 /* add conflicting variables */
    1151 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, NULL) );
    1152
    1153 for( b = 0; b < consdata->firstnonfixed; ++b )
    1154 {
    1155 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
    1156 }
    1157
    1158 /* analyze the conflict */
    1160 }
    1161
    1162 *cutoff = TRUE;
    1163 return SCIP_OKAY;
    1164 }
    1165
    1166 if( tightened )
    1167 (*nchgbds)++;
    1168
    1169#ifndef NDEBUG
    1170 /* check that the last variable are locally fixed to zero */
    1171 for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
    1172 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
    1173#endif
    1174
    1175 /* find last non fixed variable */
    1176 for( b = consdata->lastnonfixed; b >= 0; --b )
    1177 {
    1178 if( SCIPvarGetUbLocal(binvars[b]) > 0.5 )
    1179 break;
    1180
    1181 consdata->lastnonfixed--;
    1182 }
    1183
    1185 SCIP_CALL( SCIPinferVarUbCons(scip, linkvar, (SCIP_Real)vals[b], cons, -5, TRUE, &infeasible, &tightened) );
    1186
    1187 if( infeasible )
    1188 {
    1189 /* conflict analysis can only be applied in solving stage and if conflict analysis is turned on */
    1191 {
    1192 SCIPdebugMsg(scip, "conflict at <%s> due to bounds and fixed binvars: [lb,ub] = [%g,%g]; b = %d; coef = %g,\n",
    1193 SCIPvarGetName(linkvar), SCIPvarGetLbLocal(linkvar), SCIPvarGetUbLocal(linkvar), b, vals[b]);
    1194
    1196
    1197 /* ??????????? use resolve method and only add binvars which are needed to fall below the lower bound */
    1198
    1199 /* add conflicting variables */
    1200 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, NULL) );
    1201
    1202 for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
    1203 {
    1204 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
    1205 }
    1206
    1207 /* analyze the conflict */
    1209 }
    1210
    1211 *cutoff = TRUE;
    1212 return SCIP_OKAY;
    1213 }
    1214
    1215 if( tightened )
    1216 (*nchgbds)++;
    1217
    1218 return SCIP_OKAY;
    1219}
    1220
    1221/** checks constraint for violation only looking at the fixed binary variables, applies further fixings if possible */
    1222static
    1224 SCIP* scip, /**< SCIP data structure */
    1225 SCIP_CONS* cons, /**< linking constraint to be processed */
    1226 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    1227 int* nchgbds, /**< pointer to store the number of changed variable bounds */
    1228 SCIP_Bool* addcut, /**< pointer to store whether this constraint must be added as a cut */
    1229 SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
    1230 )
    1231{
    1232 SCIP_CONSDATA* consdata;
    1233 SCIP_Bool infeasible;
    1234 SCIP_Bool tightened;
    1235
    1236 assert(cons != NULL);
    1237 assert(SCIPconsGetHdlr(cons) != NULL);
    1238 assert(cutoff != NULL);
    1239 assert(nchgbds != NULL);
    1240 assert(addcut != NULL);
    1241 assert(mustcheck != NULL);
    1242
    1244
    1245 consdata = SCIPconsGetData(cons);
    1246 assert(consdata != NULL);
    1247 assert(consdata->nbinvars == 0 || consdata->binvars != NULL);
    1248 assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nbinvars);
    1249 assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nbinvars);
    1250
    1251 /* ensure that the binary variables are sorted in non-decreasing order w.r.t. their coefficients */
    1252 consdataSort(consdata);
    1253
    1254 /* in case there is only at most one binary variables, the constraints should already be disabled */
    1255 assert(consdata->nbinvars > 1);
    1256
    1257 if( *cutoff )
    1258 return SCIP_OKAY;
    1259
    1260 if( consdata->nfixedones == 1 )
    1261 {
    1262 /* exactly one variable is fixed to 1:
    1263 * - all other binary variables in a set partitioning must be zero
    1264 * - linking variable is fixed to that binary variable
    1265 */
    1266 if( consdata->nfixedzeros < consdata->nbinvars - 1 ||
    1267 SCIPisLT(scip, SCIPvarGetLbLocal(consdata->linkvar), SCIPvarGetUbLocal(consdata->linkvar)) )
    1268 {
    1269 SCIP_VAR** vars;
    1270 SCIP_VAR* var;
    1271#ifndef NDEBUG
    1272 SCIP_Bool fixedonefound;
    1273#endif
    1274 int nvars;
    1275 int v;
    1276
    1277 SCIPdebugMsg(scip, " -> fixing all other variables to zero due to the set partitioning condition <%s>\n",
    1278 SCIPconsGetName(cons));
    1279
    1280 /* unfixed variables exist: fix them to zero;
    1281 * this could result in additional variables fixed to one due to aggregations; in this case, the
    1282 * constraint is infeasible in local bounds
    1283 */
    1284 vars = consdata->binvars;
    1285 nvars = consdata->nbinvars;
    1286#ifndef NDEBUG
    1287 fixedonefound = FALSE;
    1288#endif
    1289
    1290 for( v = 0; v < nvars && consdata->nfixedones == 1 && !(*cutoff); ++v ) /* cppcheck-suppress knownConditionTrueFalse */
    1291 {
    1292 var = vars[v];
    1293 assert(SCIPvarIsBinary(var));
    1294 /* TODO can this be handled more elegantly? */
    1296 continue;
    1297
    1301 continue;
    1302
    1303 if( SCIPvarGetLbLocal(var) < 0.5 )
    1304 {
    1305 SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -1, &infeasible, &tightened) );
    1306 assert(!infeasible);
    1307 SCIPdebugMsg(scip, " -> fixed <%s> to zero (tightened=%u)\n", SCIPvarGetName(var), tightened);
    1308 }
    1309 else
    1310 {
    1311#ifndef NDEBUG
    1312 fixedonefound = TRUE;
    1313#endif
    1314 /* fix linking variable */
    1315 /* TODO check if variable status allows fixing (probably in consFixLinkvar) */
    1316 SCIP_CALL( consFixLinkvar(scip, cons, v, cutoff) );
    1317 }
    1318 }
    1319 if( !(*cutoff) )
    1320 {
    1321 /* the fixed to one variable must have been found, and at least one variable must have been fixed */
    1322 assert(consdata->nfixedones >= 1 || fixedonefound);
    1323
    1325 (*nchgbds)++;
    1326 }
    1327 }
    1328
    1329 /* now all other variables are fixed to zero:
    1330 * the constraint is feasible, and if it's not modifiable, it is redundant
    1331 */
    1332 if( !SCIPconsIsModifiable(cons) && consdata->nfixedones == 1 ) /* cppcheck-suppress knownConditionTrueFalse */
    1333 {
    1334 SCIPdebugMsg(scip, " -> disabling set linking constraint <%s>\n", SCIPconsGetName(cons));
    1336 }
    1337 }
    1338 else if( consdata->nfixedones >= 2 )
    1339 {
    1340 /* at least two variables are fixed to 1:
    1341 * - the set partitioning condition is violated
    1342 */
    1343 SCIPdebugMsg(scip, " -> conflict on " CONSHDLR_NAME " constraint <%s> due to the set partitioning condition\n", SCIPconsGetName(cons));
    1344
    1346
    1347 /* conflict analysis can only be applied in solving stage and if it is applicable */
    1349 {
    1350 SCIP_VAR** vars;
    1351 int nvars;
    1352 int n;
    1353 int v;
    1354
    1355 vars = consdata->binvars;
    1356 nvars = consdata->nbinvars;
    1357
    1358 /* initialize conflict analysis, and add the two variables assigned to one to conflict candidate queue */
    1360
    1361 n = 0;
    1362
    1363 for( v = 0; v < nvars && n < 2; ++v )
    1364 {
    1365 if( SCIPvarGetLbLocal(vars[v]) > 0.5 )
    1366 {
    1368 n++;
    1369 }
    1370 }
    1371 assert(n == 2);
    1372
    1373 /* analyze the conflict */
    1375 }
    1376
    1377 *cutoff = TRUE;
    1378 }
    1379 else if( consdata->nfixedzeros == consdata->nbinvars )
    1380 {
    1381 /* all variables are fixed to zero:
    1382 * - the set partitioning condition is violated, and if it's unmodifiable, the node
    1383 * can be cut off -- otherwise, the constraint must be added as a cut and further pricing must
    1384 * be performed
    1385 */
    1386 assert(consdata->nfixedones == 0);
    1387
    1388 SCIPdebugMsg(scip, " -> " CONSHDLR_NAME " constraint <%s> is infeasible due to the set partitioning condition\n",
    1389 SCIPconsGetName(cons));
    1390
    1392 if( SCIPconsIsModifiable(cons) )
    1393 *addcut = TRUE;
    1394 else
    1395 {
    1396 /* conflict analysis can only be applied in solving stage and if it is applicable */
    1398 {
    1399 SCIP_VAR** vars;
    1400 int nvars;
    1401 int v;
    1402
    1403 vars = consdata->binvars;
    1404 nvars = consdata->nbinvars;
    1405
    1406 /* initialize conflict analysis, add all variables of infeasible constraint to conflict candidate queue */
    1408
    1409 for( v = 0; v < nvars; ++v )
    1410 {
    1411 assert(SCIPvarGetUbLocal(vars[v]) < 0.5);
    1413 }
    1414
    1415 /* analyze the conflict */
    1417 }
    1418 *cutoff = TRUE;
    1419 }
    1420 }
    1421 else if( consdata->nfixedzeros == consdata->nbinvars - 1 )
    1422 {
    1423 /* all variables except one are fixed to zero:
    1424 * - an unmodifiable set partitioning constraint is feasible and can be disabled after the
    1425 * remaining variable is fixed to one
    1426 * - a modifiable set partitioning constraint must be checked manually
    1427 */
    1428 assert(consdata->nfixedones == 0);
    1429
    1430 if( !SCIPconsIsModifiable(cons) )
    1431 {
    1432 SCIP_VAR** vars;
    1433 SCIP_VAR* var;
    1434 int nvars;
    1435 int v;
    1436
    1437 /* search the single variable that can be fixed */
    1438 vars = consdata->binvars;
    1439 nvars = consdata->nbinvars;
    1440 for( v = 0; v < nvars && !(*cutoff); ++v )
    1441 {
    1442 var = vars[v];
    1443 assert(SCIPisFeasZero(scip, SCIPvarGetLbLocal(var)));
    1445
    1446 if( SCIPvarGetUbLocal(var) > 0.5 )
    1447 {
    1448 assert(SCIPvarGetLbLocal(var) < 0.5);
    1449 SCIPdebugMsg(scip, " -> fixing remaining binary variable <%s> to one in " CONSHDLR_NAME " constraint <%s>\n",
    1450 SCIPvarGetName(var), SCIPconsGetName(cons));
    1451
    1453 {
    1454 SCIP_CALL( SCIPinferBinvarCons(scip, var, TRUE, cons, -1, &infeasible, &tightened) );
    1455 assert(!infeasible);
    1456 assert(tightened);
    1457 }
    1458
    1459 /* fix linking variable */
    1460 /* TODO check if variable status allows fixing (probably in consFixLinkvar)*/
    1461 SCIP_CALL( consFixLinkvar(scip, cons, v, cutoff) );
    1462 break;
    1463 }
    1464 }
    1465 assert(v < nvars);
    1466 assert(consdata->nfixedzeros == consdata->nbinvars - 1);
    1467 assert(consdata->nfixedones == 1);
    1468
    1470 (*nchgbds)++;
    1471 }
    1472 }
    1473 else
    1474 {
    1475 SCIP_CALL( tightenedLinkvar(scip, cons, consdata, cutoff, nchgbds) );
    1476 }
    1477
    1478 *mustcheck = (*nchgbds) == 0;
    1479
    1480 assert(consdata->nfixedzeros + consdata->nfixedones <= consdata->nbinvars);
    1481
    1482 return SCIP_OKAY;
    1483}
    1484
    1485/** returns whether the given solution is feasible for the given linking constraint */
    1486static
    1488 SCIP* scip, /**< SCIP data structure */
    1489 SCIP_CONS* cons, /**< linking constraint to be checked */
    1490 SCIP_SOL* sol /**< primal solution, or NULL for current LP/pseudo solution */
    1491 )
    1492{
    1493 SCIP_CONSDATA* consdata;
    1494 SCIP_VAR** binvars;
    1495 SCIP_Real* vals;
    1496 SCIP_Real solval;
    1497 SCIP_Real linksum;
    1498 SCIP_Real linkvarval;
    1499 SCIP_Real setpartsum;
    1500 SCIP_Real setpartsumbound;
    1501 SCIP_Real absviol;
    1502 SCIP_Real relviol;
    1503 int nbinvars;
    1504 int b;
    1505
    1506 assert(scip != NULL);
    1507 assert(cons != NULL);
    1508
    1509 SCIPdebugMsg(scip, "checking linking constraint <%s> for feasibility of solution %p\n", SCIPconsGetName(cons), (void*)sol);
    1510
    1511 consdata = SCIPconsGetData(cons);
    1512 assert(consdata != NULL);
    1513 assert(consdata->binvars != NULL || consdata->nbinvars == 0);
    1514
    1515 /* in case there is only at most one binary variables, the constraints should already be disabled */
    1516 assert(consdata->nbinvars > 1);
    1517
    1518 /* calculate the constraint's activity for the linking part and the set partitioning part */
    1519 binvars = consdata->binvars;
    1520 vals = consdata->vals;
    1521 nbinvars = consdata->nbinvars;
    1522
    1523 linksum = 0.0;
    1524 setpartsum = 0.0;
    1525 setpartsumbound = 1.0 + 2*SCIPfeastol(scip);
    1526
    1527 for( b = 0; b < nbinvars && setpartsum < setpartsumbound; ++b ) /* if sum >= sumbound, the feasibility is clearly decided */
    1528 {
    1529 assert(SCIPvarIsBinary(binvars[b]));
    1530
    1531 solval = SCIPgetSolVal(scip, sol, binvars[b]);
    1532 assert(SCIPisFeasGE(scip, solval, 0.0) && SCIPisFeasLE(scip, solval, 1.0));
    1533
    1534 linksum += vals[b] * solval;
    1535 setpartsum += solval;
    1536 }
    1537
    1538 /* calculate and update absolute and relative violation of the equality constraint */
    1539 linkvarval = SCIPgetSolVal(scip, sol, consdata->linkvar);
    1540 absviol = REALABS(linksum - linkvarval);
    1541 relviol = REALABS(SCIPrelDiff(linksum, linkvarval));
    1542 if( sol != NULL )
    1543 SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
    1544
    1545 /* calculate and update absolute and relative violation of the set partitioning constraint */
    1546 absviol = REALABS(setpartsum - 1.0);
    1547 relviol = REALABS(SCIPrelDiff(setpartsum, 1.0));
    1548 if( sol != NULL )
    1549 SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
    1550
    1551 /* check if the fixed binary variable match with the linking variable */
    1552 return SCIPisFeasEQ(scip, linksum, linkvarval) && SCIPisFeasEQ(scip, setpartsum, 1.0);
    1553}
    1554
    1555#ifdef SCIP_DISABLED_CODE
    1556/* The following should work, but does not seem to be tested well. */
    1557
    1558/** transfer aggregated integer variables to the corresponding binary variables */
    1559static
    1561 SCIP* scip, /**< SCIP data structure */
    1562 SCIP_HASHMAP* varmap, /**< hash map mapping a integer variables to its linking constraint */
    1563 SCIP_CONS** conss, /**< array of linking constraint */
    1564 int nconss, /**< number of linking constraints */
    1565 int* naggrvars, /**< pointer to store the number of aggregate variables */
    1566 SCIP_Bool* cutoff /**< pointer to store if a cutoff was detected */
    1567 )
    1568{
    1569 SCIP_CONS* aggrcons;
    1570 SCIP_CONSDATA* aggrconsdata;
    1571 SCIP_CONSDATA* consdata;
    1572 SCIP_VAR** binvars;
    1573 SCIP_VAR** aggrbinvars;
    1574 SCIP_VAR* linkvar;
    1575 SCIP_VAR* aggrvar;
    1576 SCIP_Real aggrconst;
    1577 SCIP_Real aggrscalar;
    1578 SCIP_Bool infeasible;
    1579 SCIP_Bool redundant;
    1580 SCIP_Bool aggregated;
    1581 int offset;
    1582 int aggroffset;
    1583 int nbinvars;
    1584 int shift;
    1585 int b;
    1586 int c;
    1587
    1588 assert(varmap != NULL);
    1589
    1590 for( c = 0; c < nconss; ++c )
    1591 {
    1592 consdata = SCIPconsGetData(conss[c]);
    1593 assert(consdata != NULL);
    1594
    1595 linkvar = consdata->linkvar;
    1596 assert(linkvar != NULL);
    1597
    1599 {
    1600 aggrvar = SCIPvarGetAggrVar(linkvar);
    1601 aggrcons = (SCIP_CONS*) SCIPhashmapGetImage(varmap, getHashmapKey(aggrvar));
    1602
    1603 /* check if the aggregate variable belongs to a linking constraint */
    1604 if( aggrcons != NULL )
    1605 {
    1606 aggrconsdata = SCIPconsGetData(aggrcons);
    1607 assert(aggrconsdata != NULL);
    1608
    1609 aggrconst = SCIPvarGetAggrConstant(linkvar);
    1610 aggrscalar = SCIPvarGetAggrScalar(linkvar);
    1611
    1612 /**@todo extend the aggregation for those cases were the aggrscalar is not equal to 1.0 */
    1613 if( SCIPisEQ(scip, aggrscalar, 1.0 ) )
    1614 {
    1615 /* since both variables are integer variable and the aggrscalar is 1.0 the aggrconst should
    1616 * integral
    1617 */
    1618 assert(SCIPisIntegral(scip, aggrconst));
    1619 shift = SCIPconvertRealToInt(scip, aggrconst);
    1620
    1621 offset = consdata->offset;
    1622 binvars = consdata->binvars;
    1623 aggroffset = aggrconsdata->offset;
    1624 aggrbinvars = aggrconsdata->binvars;
    1625
    1626 nbinvars = MIN(consdata->nbinvars + offset, aggrconsdata->nbinvars + shift + aggroffset);
    1627
    1628 for( b = MAX(offset, aggroffset-shift); b < nbinvars; ++b )
    1629 {
    1630 assert(b - offset >= 0);
    1631 assert(b + shift - aggroffset >= 0);
    1632 assert(b < consdata->nbinvars);
    1633 assert(b < aggrconsdata->nbinvars - shift);
    1634
    1635 /* add aggregation x - y = 0.0 */
    1636 SCIP_CALL( SCIPaggregateVars(scip, binvars[b-offset], aggrbinvars[b+shift-aggroffset], 1.0, -1.0, 0.0,
    1637 &infeasible, &redundant, &aggregated) );
    1638
    1639 if( infeasible )
    1640 {
    1641 (*cutoff) = TRUE;
    1642 return SCIP_OKAY;
    1643 }
    1644
    1645 if( aggregated )
    1646 (*naggrvars)++;
    1647 }
    1648 }
    1649 }
    1650 }
    1651 }
    1652 return SCIP_OKAY;
    1653}
    1654#endif
    1655
    1656/** create two rows for the linking constraint
    1657 *
    1658 * - row1: {sum_{b=1}^n-1 vals[b] * binvars[b]} - linkvar = 0
    1659 * - row2: {sum_{b=0}^n-1 binvars[b]} = 1.0
    1660 */
    1661static
    1663 SCIP* scip, /**< SCIP data structure */
    1664 SCIP_CONS* cons /**< linking constraint */
    1665 )
    1666{
    1667 SCIP_CONSDATA* consdata;
    1668 char rowname[SCIP_MAXSTRLEN];
    1669 int b;
    1670
    1671 assert( cons != NULL);
    1672
    1673 /* get constraint data */
    1674 consdata = SCIPconsGetData(cons);
    1675 assert(consdata != NULL);
    1676 assert(consdata->row1 == NULL);
    1677 assert(consdata->row2 == NULL);
    1678 assert(consdata->nbinvars > 1);
    1679
    1680 /* create the LP row which captures the linking between the real and binary variables */
    1681 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[link]", SCIPconsGetName(cons));
    1682
    1683 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row1, cons, rowname, 0.0, 0.0,
    1685
    1686 /* add linking variable to the row */
    1687 assert(consdata->linkvar != NULL);
    1688 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row1, consdata->linkvar, -1.0) );
    1689
    1690 /* adding binary variables to the row */
    1691 assert(consdata->binvars != NULL);
    1692 for( b = 0; b < consdata->nbinvars; ++b )
    1693 {
    1694 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row1, consdata->binvars[b], consdata->vals[b]) );
    1695 }
    1696
    1697 /* create the LP row which captures the set partitioning condition of the binary variables */
    1698 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[setppc]", SCIPconsGetName(cons));
    1699 assert( consdata->nbinvars > 0 );
    1700
    1701 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row2, cons, rowname, 1.0, 1.0,
    1703
    1704 SCIP_CALL( SCIPaddVarsToRowSameCoef(scip, consdata->row2, consdata->nbinvars, consdata->binvars, 1.0) );
    1705
    1706 return SCIP_OKAY;
    1707}
    1708
    1709
    1710/** adds linking constraint as cut to the LP */
    1711static
    1713 SCIP* scip, /**< SCIP data structure */
    1714 SCIP_CONS* cons, /**< linking constraint */
    1715 SCIP_Bool* cutoff /**< whether a cutoff has been detected */
    1716 )
    1717{
    1718 SCIP_CONSDATA* consdata;
    1719
    1720 assert( cutoff != NULL );
    1721 *cutoff = FALSE;
    1722
    1723 consdata = SCIPconsGetData(cons);
    1724 assert(consdata != NULL);
    1725
    1726 /* in case there is only at most one binary variables, the constraints should already be disabled */
    1727 assert(consdata->nbinvars > 1);
    1728
    1729 if( consdata->row1 == NULL )
    1730 {
    1731 assert(consdata->row2 == NULL);
    1732
    1733 /* convert linking data into LP rows */
    1734 SCIP_CALL( createRows(scip, cons) );
    1735 }
    1736 assert(consdata->row1 != NULL);
    1737 assert(consdata->row2 != NULL);
    1738
    1739 /* insert LP linking row as cut */
    1740 if( !SCIProwIsInLP(consdata->row1) )
    1741 {
    1742 SCIPdebugMsg(scip, "adding linking row of constraint <%s> as cut to the LP\n", SCIPconsGetName(cons));
    1743 SCIP_CALL( SCIPaddRow(scip, consdata->row1, TRUE/*FALSE*/, cutoff) );
    1744 }
    1745
    1746 /* insert LP set partitioning row as cut */
    1747 if( !SCIProwIsInLP(consdata->row2) )
    1748 {
    1749 SCIPdebugMsg(scip, "adding set partitioning row of constraint <%s> as cut to the LP\n", SCIPconsGetName(cons));
    1750 SCIP_CALL( SCIPaddRow(scip, consdata->row2, TRUE/*FALSE*/, cutoff) );
    1751 }
    1752
    1753 return SCIP_OKAY;
    1754}
    1755
    1756/** adds linking constraint as rows to the NLP, if not added yet */
    1757static
    1759 SCIP* scip, /**< SCIP data structure */
    1760 SCIP_CONS* cons /**< linking constraint */
    1761 )
    1762{
    1763 SCIP_CONSDATA* consdata;
    1764
    1765 assert(SCIPisNLPConstructed(scip));
    1766
    1767 /* skip deactivated, redundant, or local constraints (the NLP does not allow for local rows at the moment) */
    1768 if( !SCIPconsIsActive(cons) || !SCIPconsIsChecked(cons) || SCIPconsIsLocal(cons) )
    1769 return SCIP_OKAY;
    1770
    1771 consdata = SCIPconsGetData(cons);
    1772 assert(consdata != NULL);
    1773
    1774 if( consdata->nlrow1 == NULL )
    1775 {
    1776 char rowname[SCIP_MAXSTRLEN];
    1777 SCIP_Real* coefs;
    1778 int i;
    1779
    1780 assert(consdata->nlrow2 == NULL);
    1781
    1782 /* create the NLP row which captures the linking between the real and binary variables */
    1783 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[link]", SCIPconsGetName(cons));
    1784
    1785 /* create nlrow1 with binary variables */
    1786 SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow1, rowname,
    1787 0.0, consdata->nbinvars, consdata->binvars, consdata->vals, NULL, 0.0, 0.0, SCIP_EXPRCURV_LINEAR) );
    1788 /* add linking variable to the row */
    1789 SCIP_CALL( SCIPaddLinearCoefToNlRow(scip, consdata->nlrow1, consdata->linkvar, -1.0) );
    1790
    1791 /* create the NLP row which captures the set partitioning condition of the binary variables */
    1792 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[setppc]", SCIPconsGetName(cons));
    1793
    1794 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, consdata->nbinvars) );
    1795 for( i = 0; i < consdata->nbinvars; ++i )
    1796 coefs[i] = 1.0;
    1797
    1798 SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow2, rowname,
    1799 0.0, consdata->nbinvars, consdata->binvars, coefs, NULL, 1.0, 1.0, SCIP_EXPRCURV_LINEAR) );
    1800
    1801 SCIPfreeBufferArray(scip, &coefs);
    1802 }
    1803
    1804 assert(SCIPnlrowIsInNLP(consdata->nlrow1) == SCIPnlrowIsInNLP(consdata->nlrow2));
    1805 if( !SCIPnlrowIsInNLP(consdata->nlrow1) )
    1806 {
    1807 SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow1) );
    1808 SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow2) );
    1809 }
    1810
    1811 return SCIP_OKAY;
    1812}
    1813
    1814/** checks constraint for violation, and adds it as a cuts if possible */
    1815static
    1817 SCIP* scip, /**< SCIP data structure */
    1818 SCIP_CONS* cons, /**< linking constraint to be separated */
    1819 SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
    1820 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    1821 SCIP_Bool* separated, /**< pointer to store TRUE, if a cut was found */
    1822 int* nchgbds /**< pointer to store the number of changed variables bounds */
    1823 )
    1824{
    1825 SCIP_CONSDATA* consdata;
    1826 SCIP_Bool addcut;
    1827 SCIP_Bool mustcheck;
    1828
    1829 assert(cons != NULL);
    1830 assert(SCIPconsGetHdlr(cons) != NULL);
    1831 assert(cutoff != NULL);
    1832 assert(separated != NULL);
    1833 assert(nchgbds != NULL);
    1834
    1836
    1837 consdata = SCIPconsGetData(cons);
    1838 assert(consdata != NULL);
    1839
    1840 /* in case there is only at most one binary variables, the constraints should already be disabled */
    1841 assert(consdata->nbinvars > 1);
    1842
    1843 SCIPdebugMsg(scip, "separating constraint <%s>\n", SCIPconsGetName(cons));
    1844
    1845 *cutoff = FALSE;
    1846 addcut = FALSE;
    1847 mustcheck = TRUE;
    1848
    1849 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
    1850 if( sol == NULL )
    1851 {
    1852 SCIP_CALL( processRealBoundChg(scip, cons, cutoff, nchgbds, &mustcheck) );
    1853 }
    1854
    1855 if( mustcheck && !(*cutoff) )
    1856 {
    1857 /* variable's fixings didn't give us any information -> we have to check the constraint */
    1858 if( sol == NULL && consdata->row1 != NULL )
    1859 {
    1860 SCIP_Real feasibility;
    1861 SCIP_Real tmp;
    1862
    1863 assert(consdata->row2 != NULL);
    1864
    1865 /* skip constraints already in the LP */
    1866 if( SCIProwIsInLP(consdata->row1) && SCIProwIsInLP(consdata->row2))
    1867 return SCIP_OKAY;
    1868
    1869 feasibility = 1.0;
    1870
    1871 /* check first row (linking) for feasibility */
    1872 if( !SCIProwIsInLP(consdata->row1) )
    1873 {
    1874 tmp = SCIPgetRowLPFeasibility(scip, consdata->row1);
    1875 feasibility = MIN(feasibility, tmp);
    1876 }
    1877
    1878 /* check second row (setppc) for feasibility */
    1879 if( !SCIProwIsInLP(consdata->row2) )
    1880 {
    1881 tmp = SCIPgetRowLPFeasibility(scip, consdata->row2);
    1882 feasibility = MIN(feasibility, tmp);
    1883 }
    1884 addcut = SCIPisFeasNegative(scip, feasibility);
    1885 }
    1886 else
    1887 addcut = !checkCons(scip, cons, sol);
    1888
    1889 if( !addcut )
    1890 {
    1891 /* constraint was feasible -> increase age */
    1892 SCIP_CALL( SCIPincConsAge(scip, cons) );
    1893 }
    1894 }
    1895
    1896 if( addcut )
    1897 {
    1898 /* insert LP row as cut */
    1899 assert(!(*cutoff));
    1900 SCIP_CALL( addCuts(scip, cons, cutoff) );
    1902 *separated = TRUE;
    1903 }
    1904
    1905 return SCIP_OKAY;
    1906}
    1907
    1908/** enforces the pseudo solution on the given constraint */
    1909static
    1911 SCIP* scip, /**< SCIP data structure */
    1912 SCIP_CONS* cons, /**< linking constraint to be separated */
    1913 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    1914 SCIP_Bool* infeasible, /**< pointer to store TRUE, if the constraint was infeasible */
    1915 int* nchgbds, /**< pointer to store the number of changed variable bounds */
    1916 SCIP_Bool* solvelp /**< pointer to store TRUE, if the LP has to be solved */
    1917 )
    1918{
    1919 SCIP_Bool addcut;
    1920 SCIP_Bool mustcheck;
    1921
    1922 assert(!SCIPhasCurrentNodeLP(scip));
    1923 assert(cons != NULL);
    1924 assert(SCIPconsGetHdlr(cons) != NULL);
    1925 assert(cutoff != NULL);
    1926 assert(infeasible != NULL);
    1927 assert(nchgbds != NULL);
    1928 assert(solvelp != NULL);
    1929
    1931
    1932 addcut = FALSE;
    1933 mustcheck = TRUE;
    1934
    1935 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
    1936 SCIP_CALL( processRealBoundChg(scip, cons, cutoff, nchgbds, &mustcheck) );
    1937 SCIP_CALL( processBinvarFixings(scip, cons, cutoff, nchgbds, &addcut, &mustcheck) );
    1938
    1939 if( mustcheck )
    1940 {
    1941 assert(!addcut);
    1942
    1943 if( checkCons(scip, cons, NULL) )
    1944 {
    1945 /* constraint was feasible -> increase age */
    1946 SCIP_CALL( SCIPincConsAge(scip, cons) );
    1947 }
    1948 else
    1949 {
    1950 /* constraint was infeasible -> reset age */
    1952 *infeasible = TRUE;
    1953 }
    1954 }
    1955
    1956 if( addcut )
    1957 {
    1958 assert(!(*cutoff));
    1959 /* a cut must be added to the LP -> we have to solve the LP immediately */
    1961 *solvelp = TRUE;
    1962 }
    1963
    1964 return SCIP_OKAY;
    1965}
    1966
    1967/** helper function to enforce constraints */
    1968static
    1970 SCIP* scip, /**< SCIP data structure */
    1971 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    1972 SCIP_CONS** conss, /**< constraints to process */
    1973 int nconss, /**< number of constraints */
    1974 int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
    1975 SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
    1976 SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
    1977 )
    1978{
    1979 SCIP_Bool cutoff;
    1980 SCIP_Bool separated;
    1981 int nchgbds;
    1982 int c;
    1983
    1984 assert(conshdlr != NULL);
    1985 assert(nconss == 0 || conss != NULL);
    1986 assert(result != NULL);
    1987
    1989
    1990 SCIPdebugMsg(scip, "Enforcing %d linking constraints for %s solution\n", nconss, sol == NULL ? "LP" : "relaxation");
    1991
    1992 cutoff = FALSE;
    1993 separated = FALSE;
    1994 nchgbds = 0;
    1995
    1996 /* check all useful linking constraints for feasibility */
    1997 for( c = 0; c < nusefulconss && !cutoff && nchgbds == 0; ++c )
    1998 {
    1999 SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
    2000 }
    2001
    2002 /* check all obsolete linking constraints for feasibility */
    2003 for( c = nusefulconss; c < nconss && !cutoff && !separated && nchgbds == 0; ++c )
    2004 {
    2005 SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
    2006 }
    2007
    2008 /* return the correct result */
    2009 if( cutoff )
    2010 *result = SCIP_CUTOFF;
    2011 else if( nchgbds > 0 )
    2012 *result = SCIP_REDUCEDDOM;
    2013 else if( separated )
    2014 *result = SCIP_SEPARATED;
    2015 else
    2016 *result = SCIP_FEASIBLE;
    2017
    2018 return SCIP_OKAY;
    2019}
    2020
    2021/** adds symmetry information of constraint to a symmetry detection graph */
    2022static
    2024 SCIP* scip, /**< SCIP pointer */
    2025 SYM_SYMTYPE symtype, /**< type of symmetries that need to be added */
    2026 SCIP_CONS* cons, /**< constraint */
    2027 SYM_GRAPH* graph, /**< symmetry detection graph */
    2028 SCIP_Bool* success /**< pointer to store whether symmetry information could be added */
    2029 )
    2030{
    2031 SCIP_CONSDATA* consdata;
    2032 SCIP_VAR** vars;
    2033 SCIP_Real* vals;
    2034 SCIP_Real constant = 0.0;
    2035 int nlocvars;
    2036 int nvars;
    2037 int i;
    2038
    2039 assert(scip != NULL);
    2040 assert(cons != NULL);
    2041 assert(graph != NULL);
    2042 assert(success != NULL);
    2043
    2044 consdata = SCIPconsGetData(cons);
    2045 assert(consdata != NULL);
    2046
    2047 /* get active variables of the constraint */
    2048 nvars = SCIPgetNVars(scip);
    2049 nlocvars = consdata->nbinvars + 1;
    2050
    2051 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
    2052 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
    2053
    2054 /* get binary variables */
    2055 for( i = 0; i < consdata->nbinvars; ++i )
    2056 {
    2057 vars[i] = consdata->binvars[i];
    2058 vals[i] = consdata->vals[i];
    2059 }
    2060
    2061 /* get linking variable */
    2062 vars[consdata->nbinvars] = consdata->linkvar;
    2063 vals[consdata->nbinvars] = -1.0;
    2064
    2065 SCIP_CALL( SCIPgetSymActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant, SCIPisTransformed(scip)) );
    2066
    2067 SCIP_CALL( SCIPextendPermsymDetectionGraphLinear(scip, graph, vars, vals, nlocvars,
    2068 cons, -constant, -constant, success) );
    2069
    2070 SCIPfreeBufferArray(scip, &vals);
    2071 SCIPfreeBufferArray(scip, &vars);
    2072
    2073 return SCIP_OKAY;
    2074}
    2075
    2076/*
    2077 * Callback methods of constraint handler
    2078 */
    2079
    2080/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    2081static
    2082SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinking)
    2083{ /*lint --e{715}*/
    2084 assert(scip != NULL);
    2085 assert(conshdlr != NULL);
    2086
    2088
    2089 /* call inclusion method of constraint handler */
    2091
    2092 *valid = TRUE;
    2093
    2094 return SCIP_OKAY;
    2095}
    2096
    2097/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
    2098static
    2099SCIP_DECL_CONSFREE(consFreeLinking)
    2100{
    2101 SCIP_CONSHDLRDATA* conshdlrdata;
    2102
    2103 assert(conshdlr != NULL);
    2104 assert(scip != NULL);
    2105
    2107
    2108 /* free constraint handler data */
    2109 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2110 assert(conshdlrdata != NULL);
    2111
    2112 conshdlrdataFree(scip, &conshdlrdata);
    2113
    2114 return SCIP_OKAY;
    2115}
    2116
    2117
    2118/** presolving initialization method of constraint handler (called when presolving is about to begin) */
    2119static
    2120SCIP_DECL_CONSINITPRE(consInitpreLinking)
    2121{ /*lint --e{715}*/
    2122 SCIP_CONSHDLRDATA* conshdlrdata;
    2123 SCIP_CONSDATA* consdata;
    2124 int c;
    2125
    2126 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2127 assert(conshdlrdata != NULL);
    2128
    2129 /* disable all linking constraints which contain at most one binary variable */
    2130 for( c = 0; c < nconss; ++c )
    2131 {
    2132 consdata = SCIPconsGetData(conss[c]);
    2133 assert(consdata != NULL);
    2134
    2135 /* skip constraints which are not added */
    2136 if( !SCIPconsIsAdded(conss[c]) )
    2137 continue;
    2138
    2139 if( consdata->nbinvars <= 1 )
    2140 {
    2141 SCIP_CALL( SCIPdisableCons(scip, conss[c]) );
    2142 assert(consdata->nbinvars == 0 || SCIPvarGetLbGlobal(consdata->binvars[0]) > 0.5);
    2143 }
    2144 else if( conshdlrdata->linearize )
    2145 {
    2146 SCIP_CALL( consdataLinearize(scip, conss[c], consdata) );
    2147 SCIP_CALL( SCIPdelCons(scip, conss[c]) );
    2148 }
    2149 }
    2150
    2151 return SCIP_OKAY;
    2152}
    2153
    2154/** solving process initialization method of constraint handler */
    2155static
    2156SCIP_DECL_CONSINITSOL(consInitsolLinking)
    2157{ /*lint --e{715}*/
    2158 /* add nlrow representations to NLP, if NLP had been constructed */
    2160 {
    2161 int c;
    2162 for( c = 0; c < nconss; ++c )
    2163 {
    2164 SCIP_CALL( addNlrow(scip, conss[c]) );
    2165 }
    2166 }
    2167
    2168 return SCIP_OKAY;
    2169}
    2170
    2171/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
    2172static
    2173SCIP_DECL_CONSEXITSOL(consExitsolLinking)
    2174{ /*lint --e{715}*/
    2175 SCIP_CONSDATA* consdata;
    2176 int c;
    2177
    2178 for( c = 0; c < nconss; ++c )
    2179 {
    2180 consdata = SCIPconsGetData(conss[c]);
    2181 assert(consdata != NULL);
    2182
    2183 /* release the rows and nlrows of all constraints */
    2184 if( consdata->row1 != NULL )
    2185 {
    2186 assert(consdata->row2 != NULL);
    2187
    2188 SCIP_CALL( SCIPreleaseRow(scip, &consdata->row1) );
    2189 SCIP_CALL( SCIPreleaseRow(scip, &consdata->row2) );
    2190 }
    2191
    2192 if( consdata->nlrow1 != NULL )
    2193 {
    2194 assert(consdata->nlrow2 != NULL);
    2195
    2196 SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow1) );
    2197 SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow2) );
    2198 }
    2199 }
    2200
    2201 return SCIP_OKAY;
    2202}
    2203
    2204
    2205/** frees specific constraint data */
    2206static
    2207SCIP_DECL_CONSDELETE(consDeleteLinking)
    2208{ /*lint --e{715}*/
    2209 SCIP_CONSHDLRDATA* conshdlrdata;
    2210
    2211 assert(conshdlr != NULL);
    2212 assert(consdata != NULL);
    2213 assert(*consdata != NULL);
    2214
    2216
    2217 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2218 assert(conshdlrdata != NULL);
    2219 assert(conshdlrdata->eventhdlr != NULL);
    2220
    2221 /* remove linking constraint form variable hash map */
    2222 assert(conshdlrdata->varmap != NULL);
    2223 assert(SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey((*consdata)->linkvar)));
    2224 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->varmap, getHashmapKey((*consdata)->linkvar)) );
    2225
    2226 if( (*consdata)->nbinvars > 0 && SCIPisTransformed(scip) )
    2227 {
    2228 SCIP_CALL( dropAllEvents(scip, *consdata, conshdlrdata->eventhdlr) );
    2229 }
    2230
    2231 /* free consdata */
    2232 SCIP_CALL( consdataFree(scip, consdata) );
    2233
    2234 return SCIP_OKAY;
    2235}
    2236
    2237
    2238/** transforms constraint data into data belonging to the transformed problem */
    2239static
    2240SCIP_DECL_CONSTRANS(consTransLinking)
    2241{ /*lint --e{715}*/
    2242 SCIP_CONSDATA* sourcedata;
    2243 SCIP_CONSDATA* targetdata;
    2244 SCIP_CONSHDLRDATA* conshdlrdata;
    2245
    2246 assert(conshdlr != NULL);
    2248 assert(sourcecons != NULL);
    2249 assert(targetcons != NULL);
    2250
    2252
    2253 /* free constraint handler data */
    2254 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2255 assert(conshdlrdata != NULL);
    2256 assert(conshdlrdata->eventhdlr != NULL);
    2257
    2258 sourcedata = SCIPconsGetData(sourcecons);
    2259 assert(sourcedata != NULL);
    2260 assert(sourcedata->row1 == NULL); /* in original problem, there cannot be LP rows */
    2261 assert(sourcedata->row2 == NULL); /* in original problem, there cannot be LP rows */
    2262
    2263 SCIPdebugMsg(scip, "transform linking constraint for variable <%s>\n", SCIPvarGetName(sourcedata->linkvar));
    2264
    2265 /* create constraint data for target constraint */
    2266 SCIP_CALL( consdataCreate(scip, conshdlrdata->eventhdlr, &targetdata,
    2267 sourcedata->linkvar, sourcedata->binvars, sourcedata->vals, sourcedata->nbinvars) );
    2268
    2269 /* create target constraint */
    2270 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
    2271 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    2272 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
    2273 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
    2274 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
    2275
    2276 /* insert (transformed) linking constraint into the hash map */
    2277 assert(conshdlrdata->varmap != NULL);
    2278 SCIP_CALL( SCIPhashmapInsert(conshdlrdata->varmap, getHashmapKey(targetdata->linkvar), *targetcons) );
    2279
    2280 return SCIP_OKAY;
    2281}
    2282
    2283/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
    2284static
    2285SCIP_DECL_CONSINITLP(consInitlpLinking)
    2286{ /*lint --e{715}*/
    2287 SCIP_CONSDATA* consdata;
    2288 int c;
    2289
    2290 *infeasible = FALSE;
    2291
    2292 for( c = 0; c < nconss && !(*infeasible); ++c )
    2293 {
    2294 assert(SCIPconsIsInitial(conss[c]));
    2295
    2296 consdata = SCIPconsGetData(conss[c]);
    2297 assert(consdata != NULL);
    2298
    2299 if( consdata->nbinvars <= 1 )
    2300 continue;
    2301
    2302 SCIP_CALL( addCuts(scip, conss[c], infeasible) );
    2303 }
    2304
    2305 return SCIP_OKAY;
    2306}
    2307
    2308
    2309/** separation method of constraint handler for LP solutions */
    2310static
    2311SCIP_DECL_CONSSEPALP(consSepalpLinking)
    2312{ /*lint --e{715}*/
    2313 SCIP_Bool cutoff;
    2314 SCIP_Bool separated;
    2315 int nchgbds;
    2316 int c;
    2317
    2318 assert(conshdlr != NULL);
    2319 assert(nconss == 0 || conss != NULL);
    2320 assert(result != NULL);
    2321
    2323
    2324 SCIPdebugMsg(scip, "separating %d/%d linking constraints\n", nusefulconss, nconss);
    2325
    2326 cutoff = FALSE;
    2327 separated = FALSE;
    2328 nchgbds = 0;
    2329
    2330 /* check all useful linking constraints for feasibility */
    2331 for( c = 0; c < nusefulconss && !cutoff; ++c )
    2332 {
    2333 SCIP_CALL( separateCons(scip, conss[c], NULL, &cutoff, &separated, &nchgbds) );
    2334 }
    2335
    2336 /* return the correct result */
    2337 if( cutoff )
    2338 *result = SCIP_CUTOFF;
    2339 else if( nchgbds > 0 )
    2340 *result = SCIP_REDUCEDDOM;
    2341 else if( separated )
    2342 *result = SCIP_SEPARATED;
    2343 else
    2344 *result = SCIP_DIDNOTFIND;
    2345
    2346 return SCIP_OKAY;
    2347}
    2348
    2349
    2350/** separation method of constraint handler for arbitrary primal solutions */
    2351static
    2352SCIP_DECL_CONSSEPASOL(consSepasolLinking)
    2353{ /*lint --e{715}*/
    2354 SCIP_Bool cutoff;
    2355 SCIP_Bool separated;
    2356 int nchgbds;
    2357 int c;
    2358
    2359 assert(conshdlr != NULL);
    2360 assert(nconss == 0 || conss != NULL);
    2361 assert(result != NULL);
    2362
    2364
    2365 SCIPdebugMsg(scip, "separating %d/%d " CONSHDLR_NAME " constraints\n", nusefulconss, nconss);
    2366
    2367 cutoff = FALSE;
    2368 separated = FALSE;
    2369 nchgbds = 0;
    2370
    2371 /* check all useful set partitioning / packing / covering constraints for feasibility */
    2372 for( c = 0; c < nusefulconss && !cutoff; ++c )
    2373 {
    2374 SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
    2375 }
    2376
    2377 /* return the correct result */
    2378 if( cutoff )
    2379 *result = SCIP_CUTOFF;
    2380 else if( nchgbds > 0 )
    2381 *result = SCIP_REDUCEDDOM;
    2382 else if( separated )
    2383 *result = SCIP_SEPARATED;
    2384 else
    2385 *result = SCIP_DIDNOTFIND;
    2386
    2387 return SCIP_OKAY;
    2388}
    2389
    2390
    2391/** constraint enforcing method of constraint handler for LP solutions */
    2392static
    2393SCIP_DECL_CONSENFOLP(consEnfolpLinking)
    2394{ /*lint --e{715}*/
    2395 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
    2396
    2397 return SCIP_OKAY;
    2398}
    2399
    2400
    2401/** constraint enforcing method of constraint handler for relaxation solutions */
    2402static
    2403SCIP_DECL_CONSENFORELAX(consEnforelaxLinking)
    2404{ /*lint --e{715}*/
    2405 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
    2406
    2407 return SCIP_OKAY;
    2408}
    2409
    2410
    2411/** constraint enforcing method of constraint handler for pseudo solutions */
    2412static
    2413SCIP_DECL_CONSENFOPS(consEnfopsLinking)
    2414{ /*lint --e{715}*/
    2415 SCIP_Bool cutoff;
    2416 SCIP_Bool infeasible;
    2417 int nchgbds;
    2418 SCIP_Bool solvelp;
    2419 int c;
    2420
    2421 assert(conshdlr != NULL);
    2422 assert(nconss == 0 || conss != NULL);
    2423 assert(result != NULL);
    2424
    2426
    2427 SCIPdebugMsg(scip, "pseudo enforcing %d " CONSHDLR_NAME " constraints\n", nconss);
    2428
    2429 if( objinfeasible )
    2430 {
    2431 *result = SCIP_DIDNOTRUN;
    2432 return SCIP_OKAY;
    2433 }
    2434
    2435 cutoff = FALSE;
    2436 infeasible = FALSE;
    2437 nchgbds = 0;
    2438 solvelp = FALSE;
    2439
    2440 /* check all linking constraint for domain reductions and feasibility */
    2441 for( c = 0; c < nconss && !cutoff && !solvelp; ++c )
    2442 {
    2443 SCIP_CALL( enforcePseudo(scip, conss[c], &cutoff, &infeasible, &nchgbds, &solvelp) );
    2444 }
    2445
    2446 if( cutoff )
    2447 *result = SCIP_CUTOFF;
    2448 else if( nchgbds > 0 )
    2449 *result = SCIP_REDUCEDDOM;
    2450 else if( solvelp )
    2451 *result = SCIP_SOLVELP;
    2452 else if( infeasible )
    2453 *result = SCIP_INFEASIBLE;
    2454 else
    2455 *result = SCIP_FEASIBLE;
    2456
    2457 return SCIP_OKAY;
    2458}
    2459
    2460
    2461/** feasibility check method of constraint handler for integral solutions */
    2462static
    2463SCIP_DECL_CONSCHECK(consCheckLinking)
    2464{ /*lint --e{715}*/
    2465 SCIP_CONS* cons;
    2466 SCIP_CONSDATA* consdata;
    2467 int c;
    2468
    2469 assert(conshdlr != NULL);
    2470 assert(nconss == 0 || conss != NULL);
    2471 assert(result != NULL);
    2472
    2474
    2475 *result = SCIP_FEASIBLE;
    2476
    2477 /* check all linking constraints for feasibility */
    2478 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
    2479 {
    2480 cons = conss[c];
    2481 consdata = SCIPconsGetData(cons);
    2482 assert(consdata != NULL);
    2483
    2484 if( consdata->nbinvars > 1 && (checklprows || consdata->row1 == NULL || !SCIProwIsInLP(consdata->row1)) )
    2485 {
    2486 if( !checkCons(scip, cons, sol) )
    2487 {
    2488 /* constraint is violated */
    2489 *result = SCIP_INFEASIBLE;
    2490
    2491 if( printreason )
    2492 {
    2493 int pos;
    2494 int b;
    2495
    2496 pos = -1;
    2497
    2498#ifndef NDEBUG
    2499 for( b = 0; b < consdata->nbinvars; ++b )
    2500 {
    2501 assert(consdata->binvars[b] != NULL);
    2502 assert(SCIPvarIsBinary(consdata->binvars[b]));
    2503 }
    2504#endif
    2505
    2506 SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
    2507 SCIPinfoMessage(scip, NULL, ";\n");
    2508
    2509 /* check that at most one binary variable is fixed */
    2510 for( b = 0; b < consdata->nbinvars; ++b )
    2511 {
    2512 assert( SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, sol, consdata->binvars[b])) );
    2513
    2514 /* check if binary variable is fixed */
    2515 if( SCIPgetSolVal(scip, sol, consdata->binvars[b]) > 0.5 )
    2516 {
    2517 if( pos != -1 )
    2518 {
    2519 SCIPinfoMessage(scip, NULL, "violation: more than one binary variable is set to one");
    2520 break;
    2521 }
    2522 pos = b ;
    2523 }
    2524 }
    2525
    2526 /* check that at least one binary variable is fixed */
    2527 if( pos == -1 )
    2528 {
    2529 SCIPinfoMessage(scip, NULL, "violation: none of the binary variables is set to one\n");
    2530 }
    2531 else if( !SCIPisFeasEQ(scip, consdata->vals[pos], SCIPgetSolVal(scip, sol, consdata->linkvar)) )
    2532 {
    2533 /* check if the fixed binary variable match with the linking variable */
    2534 SCIPinfoMessage(scip, NULL, "violation: <%s> = <%g> and <%s> is one\n",
    2535 SCIPvarGetName(consdata->linkvar), SCIPgetSolVal(scip, sol, consdata->linkvar),
    2536 SCIPvarGetName(consdata->binvars[pos]) );
    2537 }
    2538 }
    2539 }
    2540 }
    2541 }
    2542
    2543 return SCIP_OKAY;
    2544}
    2545
    2546/** domain propagation method of constraint handler */
    2547static
    2548SCIP_DECL_CONSPROP(consPropLinking)
    2549{ /*lint --e{715}*/
    2550 SCIP_Bool cutoff = FALSE;
    2551 int nchgbds = 0;
    2552 int c;
    2553
    2554 assert(conshdlr != NULL);
    2555 assert(nconss == 0 || conss != NULL);
    2556 assert(result != NULL);
    2557
    2559
    2560 SCIPdebugMsg(scip, "propagating %d/%d " CONSHDLR_NAME " constraints\n", nusefulconss, nconss);
    2561
    2562 /* propagate all useful set partitioning / packing / covering constraints */
    2563 for( c = 0; c < nusefulconss && !cutoff; ++c )
    2564 {
    2565 SCIP_Bool addcut;
    2566 SCIP_Bool mustcheck;
    2567
    2568 SCIP_CALL( processRealBoundChg(scip, conss[c], &cutoff, &nchgbds, &mustcheck) );
    2569 SCIP_CALL( processBinvarFixings(scip, conss[c], &cutoff, &nchgbds, &addcut, &mustcheck) );
    2570 } /*lint !e438*/
    2571
    2572 /* return the correct result */
    2573 if( cutoff )
    2574 *result = SCIP_CUTOFF;
    2575 else if( nchgbds > 0 )
    2576 *result = SCIP_REDUCEDDOM;
    2577 else
    2578 *result = SCIP_DIDNOTFIND;
    2579
    2580 return SCIP_OKAY;
    2581}
    2582
    2583
    2584/** presolving method of constraint handler */
    2585static
    2586SCIP_DECL_CONSPRESOL(consPresolLinking)
    2587{ /*lint --e{715}*/
    2588 SCIP_CONSHDLRDATA* conshdlrdata;
    2589 int oldnfixedvars;
    2590 int oldnchgbds;
    2591 int oldnaggrvars;
    2592 int oldndelconss;
    2593 int firstchange;
    2594 int firstclique;
    2595 int lastclique;
    2596 int c;
    2597 SCIP_Bool fixed;
    2598 SCIP_Bool cutoff;
    2599 SCIP_Bool infeasible;
    2600 SCIP_Bool mustcheck;
    2601
    2602 assert(conshdlr != NULL);
    2603 assert(scip != NULL);
    2604 assert(result != NULL);
    2605
    2607
    2608 SCIPdebugMsg(scip, "presolve %d linking constraints\n", nconss);
    2609
    2610 (*result) = SCIP_DIDNOTFIND;
    2611
    2612 oldnchgbds = *nchgbds;
    2613 oldnaggrvars = *naggrvars;
    2614 oldnfixedvars = *nfixedvars;
    2615 oldndelconss = *ndelconss;
    2616 cutoff = FALSE;
    2617
    2618 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2619 assert(conshdlrdata != NULL);
    2620
    2621 /* process constraints */
    2622 firstchange = INT_MAX;
    2623 firstclique = INT_MAX;
    2624 lastclique = -1;
    2625
    2626 /* check for each linking constraint the set partitioning condition */
    2627 for( c = 0; c < nconss && !SCIPisStopped(scip); ++c )
    2628 {
    2629 SCIP_CONS* cons;
    2630 SCIP_CONSDATA* consdata;
    2631
    2632 assert(*result != SCIP_CUTOFF);
    2633
    2634 cons = conss[c];
    2635 assert(cons != NULL);
    2636 assert(!SCIPconsIsModifiable(cons));
    2637
    2638 SCIPdebugMsg(scip, "presolve linking constraints <%s>\n", SCIPconsGetName(cons));
    2639
    2640 consdata = SCIPconsGetData(cons);
    2641 assert(consdata != NULL);
    2642
    2643 if( !SCIPconsIsEnabled(cons) /* || consdata->nbinvars <= 1 */ )
    2644 continue;
    2645
    2646 /* in case there is only at most one binary variables, the constraints should already be disabled */
    2647 assert(consdata->nbinvars > 1);
    2648
    2649 /*SCIPdebugMsg(scip, "presolving set partitioning / packing / covering constraint <%s>\n", SCIPconsGetName(cons));*/
    2650 if( consdata->nfixedones >= 2 )
    2651 {
    2652 /* at least two variables are fixed to 1:
    2653 * - a linking constraint is infeasible due to the set partitioning condition
    2654 */
    2655 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> is infeasible\n", SCIPconsGetName(cons));
    2656 *result = SCIP_CUTOFF;
    2657 return SCIP_OKAY;
    2658 }
    2659
    2660 if( consdata->nfixedones == 1 )
    2661 {
    2662 /* exactly one variable is fixed to 1:
    2663 * - all other binary variables must be zero due to the set partitioning condition
    2664 * - linking variable has to be fixed to corresponding binary variable which is fixed to one
    2665 * - if constraint is not modifiable it can be removed
    2666 */
    2667 SCIP_VAR* var;
    2668 int v;
    2669
    2670 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> has a binary variable fixed to 1.0\n", SCIPconsGetName(cons));
    2671
    2672 for( v = 0; v < consdata->nbinvars; ++v )
    2673 {
    2674 var = consdata->binvars[v];
    2675 assert(var != NULL);
    2676
    2677 if( SCIPvarGetLbGlobal(var) < 0.5 && SCIPvarGetUbGlobal(var) > 0.5 )
    2678 {
    2679 SCIP_CALL( SCIPfixVar(scip, var, 0.0, &infeasible, &fixed) );
    2680
    2681 if( infeasible )
    2682 {
    2683 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == 0\n",
    2684 SCIPconsGetName(cons), SCIPvarGetName(var));
    2685
    2686 *result = SCIP_CUTOFF;
    2687 return SCIP_OKAY;
    2688 }
    2689 assert(fixed);
    2690 (*nfixedvars)++;
    2691 }
    2692 else if( SCIPvarGetLbGlobal(var) > 0.5 )
    2693 {
    2694 /* fix linking variable */
    2695 assert(SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_LOOSE
    2696 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_AGGREGATED
    2697 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_COLUMN
    2698 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_FIXED
    2699 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_NEGATED);
    2700 SCIP_CALL( SCIPfixVar(scip, consdata->linkvar, consdata->vals[v], &infeasible, &fixed) );
    2701
    2702 if( infeasible )
    2703 {
    2704 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == %g\n",
    2705 SCIPconsGetName(cons), SCIPvarGetName(consdata->linkvar), consdata->vals[v]);
    2706
    2707 *result = SCIP_CUTOFF;
    2708 return SCIP_OKAY;
    2709 }
    2710
    2711 if( fixed )
    2712 (*nfixedvars)++;
    2713 }
    2714 }
    2715
    2716 /* now all other variables are fixed to zero:
    2717 * the constraint is feasible, and if it's not modifiable, it is redundant
    2718 */
    2719 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> is redundant\n", SCIPconsGetName(cons));
    2720 SCIP_CALL( SCIPdelCons(scip, cons) );
    2721 (*ndelconss)++;
    2722 continue;
    2723 }
    2724
    2725 if( consdata->nfixedzeros == consdata->nbinvars )
    2726 {
    2727 /* all variables are fixed to zero:
    2728 * - a linking constraint is infeasible due the set partitioning condition
    2729 */
    2730 assert(consdata->nfixedones == 0);
    2731
    2732 SCIPdebugMsg(scip, "linking constraint <%s> is infeasible due to set partitioning condition\n", SCIPconsGetName(cons));
    2733 *result = SCIP_CUTOFF;
    2734 return SCIP_OKAY;
    2735 }
    2736
    2737 if( consdata->nfixedzeros == consdata->nbinvars - 1 )
    2738 {
    2739 /* all variables except one are fixed to zero:
    2740 * - a linking constraint is feasible due the set partitioning condition
    2741 * - the remaining binary variable can be fixed to one
    2742 * - linking variable has to be fixed to corresponding binary variable which is fixed to one
    2743 * - constraint can be deleted since it is not modifiable
    2744 */
    2745 SCIP_VAR* var;
    2746 int v;
    2747
    2748 assert(consdata->nfixedones == 0);
    2749
    2750 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> has only one binary variable not fixed to zero\n",
    2751 SCIPconsGetName(cons));
    2752
    2753 /* search unfixed variable */
    2754 /* intentional empty for loop to increment counter to proper position */
    2755 /* TODO speed up loop by considering only variables between firstnonfixed and lastnonfixed */
    2756 for( v = 0; v < consdata->nbinvars && SCIPvarGetUbGlobal(consdata->binvars[v]) < 0.5; ++v ); /*lint !e722*/
    2757 assert(v < consdata->nbinvars);
    2758 var = consdata->binvars[v];
    2759
    2760 /* fix remaining binary variable */
    2761 SCIP_CALL( SCIPfixVar(scip, var, 1.0, &infeasible, &fixed) );
    2762 if( infeasible )
    2763 {
    2764 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == 1\n",
    2765 SCIPconsGetName(cons), SCIPvarGetName(var));
    2766 *result = SCIP_CUTOFF;
    2767 return SCIP_OKAY;
    2768 }
    2769 assert(fixed);
    2770 (*nfixedvars)++;
    2771
    2772 /* fix linking variable */
    2773 assert(SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_LOOSE
    2774 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_AGGREGATED
    2775 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_COLUMN
    2776 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_FIXED
    2777 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_NEGATED);
    2778 SCIP_CALL( SCIPfixVar(scip, consdata->linkvar, consdata->vals[v], &infeasible, &fixed) );
    2779
    2780 if( infeasible )
    2781 {
    2782 SCIPdebugMsg(scip, CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == %g\n",
    2783 SCIPconsGetName(cons), SCIPvarGetName(consdata->linkvar), consdata->vals[v]);
    2784
    2785 *result = SCIP_CUTOFF;
    2786 return SCIP_OKAY;
    2787 }
    2788 assert(!SCIPvarIsActive(consdata->linkvar) || fixed);
    2789 if( fixed )
    2790 (*nfixedvars)++;
    2791
    2792 /* delete constraint from problem */
    2793 SCIP_CALL( SCIPdelCons(scip, cons) );
    2794 (*ndelconss)++;
    2795 continue;
    2796 }
    2797
    2798 if( consdata->nfixedzeros == consdata->nbinvars - 2 ) /*lint !e641*/
    2799 {
    2800 SCIP_VAR* var;
    2801 SCIP_VAR* var1;
    2802 SCIP_VAR* var2;
    2803 SCIP_Bool redundant;
    2804 SCIP_Bool aggregated;
    2805 int v;
    2806
    2807 /* aggregate variable, if set partitioning condition consists only of two
    2808 * non-fixed variables
    2809 */
    2810
    2811 /* search unfixed variable */
    2812 var1 = NULL;
    2813 var2 = NULL;
    2814 for( v = 0; v < consdata->nbinvars && var2 == NULL; ++v )
    2815 {
    2816 var = consdata->binvars[v];
    2817 if( SCIPvarGetUbGlobal(var) > 0.5 )
    2818 {
    2819 if( var1 == NULL )
    2820 var1 = var;
    2821 else
    2822 var2 = var;
    2823 }
    2824 }
    2825 assert(var1 != NULL && var2 != NULL);
    2826
    2827 /* aggregate binary equality var1 + var2 == 1 */
    2828 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: aggregate <%s> + <%s> == 1\n",
    2829 SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
    2830 SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
    2831
    2832 /* evaluate aggregation result */
    2833 if( infeasible )
    2834 {
    2835 SCIPdebugMsg(scip, "linking constraint <%s>: infeasible aggregation <%s> + <%s> == 1\n",
    2836 SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
    2837 *result = SCIP_CUTOFF;
    2838 return SCIP_OKAY;
    2839 }
    2840 if( aggregated )
    2841 (*naggrvars)++;
    2842 }
    2843
    2844 /* apply real bound to binary variables */
    2845 SCIP_CALL( processRealBoundChg(scip, cons, &cutoff, nchgbds, &mustcheck) );
    2846
    2847 /* tightened linking variable */
    2848 SCIP_CALL( tightenedLinkvar(scip, cons, consdata, &cutoff, nchgbds) );
    2849
    2850 /* remove the trailing and leeading binary variable which are fixed to zero */
    2851 SCIP_CALL( removeFixedBinvars(scip, conshdlrdata->eventhdlr, cons) );
    2852
    2853 /* fix the linking variable to the only remaining value and the corresponding binary variable to 1.0 */
    2854 if( ! cutoff && consdata->nbinvars == 1 )
    2855 {
    2856 SCIP_VAR* linkvar;
    2857 SCIP_VAR* binvar;
    2858 SCIP_Real val;
    2859
    2860 linkvar = consdata->linkvar;
    2861 binvar = consdata->binvars[0];
    2862 val = consdata->vals[0];
    2863
    2864 SCIPdebugMsg(scip, "linking constraint <%s>: fix <%s> to %16.9g as only one binary variable remains",
    2865 SCIPconsGetName(cons), SCIPvarGetName(linkvar), val);
    2866
    2867 SCIP_CALL( SCIPfixVar(scip, binvar, 1.0, &infeasible, &fixed) );
    2868 assert(fixed);
    2869 ++(*nfixedvars);
    2870
    2871 if( ! infeasible )
    2872 {
    2873 SCIP_CALL( SCIPfixVar(scip, linkvar, val, &infeasible, &fixed) );
    2874 assert(fixed);
    2875 ++(*nfixedvars);
    2876 }
    2877 cutoff = infeasible;
    2878
    2879 SCIP_CALL( SCIPdelCons(scip, cons) );
    2880 ++(*ndelconss);
    2881 }
    2882
    2883 if( cutoff )
    2884 {
    2885 *result = SCIP_CUTOFF;
    2886 return SCIP_OKAY;
    2887 }
    2888
    2889 /* remember the first changed constraint to begin the next redundancy round with */
    2890 if( firstchange == INT_MAX )
    2891 firstchange = c;
    2892
    2893 /* remember the first and last constraints for which we have to add the clique information */
    2894 if( !consdata->cliqueadded && consdata->nbinvars >= 2 )
    2895 {
    2896 if( firstclique == INT_MAX )
    2897 firstclique = c;
    2898 lastclique = c;
    2899 }
    2900 }
    2901
    2902 /* add clique and implication information */
    2903 for( c = firstclique; c < lastclique && !SCIPisStopped(scip); ++c )
    2904 {
    2905 SCIP_CONS* cons;
    2906 SCIP_CONSDATA* consdata;
    2907
    2908 assert(*result != SCIP_CUTOFF);
    2909
    2910 cons = conss[c];
    2911 assert(cons != NULL);
    2912
    2913 /* ignore deleted constraints */
    2914 if( !SCIPconsIsActive(cons) )
    2915 continue;
    2916
    2917 consdata = SCIPconsGetData(cons);
    2918 assert(consdata != NULL);
    2919
    2920 if( !consdata->cliqueadded && consdata->nbinvars >= 3 )
    2921 {
    2922 /* add set partitioning condition as clique */
    2923 int ncliquebdchgs;
    2924
    2925 SCIP_CALL( SCIPaddClique(scip, consdata->binvars, NULL, consdata->nbinvars, TRUE, &infeasible, &ncliquebdchgs) );
    2926 *nchgbds += ncliquebdchgs;
    2927
    2928 if( infeasible )
    2929 {
    2930 *result = SCIP_CUTOFF;
    2931 return SCIP_OKAY;
    2932 }
    2933
    2934 consdata->cliqueadded = TRUE;
    2935 }
    2936 }
    2937
    2938#ifdef SCIP_DISABLED_CODE
    2939 /* The following should work, but does not seem to be tested well. */
    2940
    2941 /* transfer aggregated linking variables to the corresponding binary variables */
    2942 SCIP_CALL( aggregateVariables(scip, conshdlrdata->varmap, conss, nconss, naggrvars, &cutoff) );
    2943#endif
    2944
    2945 if( cutoff )
    2946 *result = SCIP_CUTOFF;
    2947 else if( oldndelconss < *ndelconss || oldnfixedvars < *nfixedvars || oldnchgbds < *nchgbds || oldnaggrvars < *naggrvars)
    2948 *result = SCIP_SUCCESS;
    2949
    2950 return SCIP_OKAY; /*lint !e438*/
    2951}
    2952
    2953
    2954/** propagation conflict resolving method of constraint handler */
    2955static
    2956SCIP_DECL_CONSRESPROP(consRespropLinking)
    2957{ /*lint --e{715}*/
    2958 SCIP_CONSDATA* consdata;
    2959 SCIP_VAR* linkvar;
    2960 int v;
    2961
    2962 SCIPdebugMsg(scip, "conflict resolving method of " CONSHDLR_NAME " constraint handler\n");
    2963
    2964 consdata = SCIPconsGetData(cons);
    2965 assert(consdata != NULL);
    2966
    2967 linkvar = consdata->linkvar;
    2968 assert(linkvar != NULL);
    2969
    2970 *result = SCIP_DIDNOTFIND;
    2971
    2972 if( inferinfo == -1 )
    2973 {
    2974 /* we have to resolve a fixing of a binary variable which was done due to fixed binary variables */
    2975 assert(SCIPvarIsBinary(infervar));
    2976 assert(SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)));
    2977 assert(SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)));
    2978
    2979 if( boundtype == SCIP_BOUNDTYPE_UPPER )
    2980 {
    2981 /* we fixed the binary variable to zero since one of the other binary variable was fixed to one (set
    2982 * partitioning condition)
    2983 */
    2984 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
    2985
    2986 for( v = 0; v < consdata->nbinvars; ++v )
    2987 {
    2988 if( SCIPgetVarLbAtIndex(scip, consdata->binvars[v], bdchgidx, FALSE) > 0.5 )
    2989 {
    2990 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[v]) );
    2991 break;
    2992 }
    2993 }
    2994 assert(v < consdata->nbinvars);
    2995 }
    2996 else
    2997 {
    2998 /* we fixed the binary variable to one since all other binary variable were fixed to zero */
    2999 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
    3000 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) > 0.5);
    3001
    3002 for( v = 0; v < consdata->nbinvars; ++v )
    3003 {
    3004 if( consdata->binvars[v] != infervar )
    3005 {
    3006 /* the reason variable must be assigned to zero */
    3007 assert(SCIPgetVarUbAtIndex(scip, consdata->binvars[v], bdchgidx, FALSE) < 0.5);
    3008 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[v]) );
    3009 }
    3010 }
    3011 }
    3012 }
    3013 else if( inferinfo == -2 )
    3014 {
    3015 /* we have to resolve a fixing of a binary variable which was done due to the linking variable lower bound */
    3016 assert(SCIPvarIsBinary(infervar));
    3017 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
    3018 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5); /*@repair: neu*/
    3019 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5); /*@repair: neu*/
    3020 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3021 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3022
    3023 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, bdchgidx) );
    3024 }
    3025 else if( inferinfo == -3 )
    3026 {
    3027 /* we have to resolve a fixing of a binary variable which was done due to the linking variable upper bound */
    3028 assert(SCIPvarIsBinary(infervar));
    3029 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
    3030 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
    3031 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5);
    3032 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3033 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3034
    3035 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, bdchgidx) );
    3036 }
    3037 else if( inferinfo == -4 )
    3038 {
    3039 SCIP_VAR** binvars;
    3040 SCIP_Real* vals;
    3041 SCIP_Real lb;
    3042 int nbinvars;
    3043 int b;
    3044
    3045 /* we tightened the lower bound of the linking variable due the fixing of the corresponding binary variable to zero */
    3046 assert(infervar == linkvar);
    3047 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
    3048
    3049 binvars = consdata->binvars;
    3050 nbinvars = consdata->nbinvars;
    3051 vals = consdata->vals;
    3052
    3053 /* get propagated lower bound */
    3054 lb = SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE);
    3055
    3056 for( b = 0; b < nbinvars; ++b )
    3057 {
    3058 if( vals[b] >= lb )
    3059 break;
    3060
    3061 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
    3062 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
    3063 }
    3064 }
    3065 else if( inferinfo == -5 )
    3066 {
    3067 SCIP_VAR** binvars;
    3068 SCIP_Real* vals;
    3069 SCIP_Real ub;
    3070 int nbinvars;
    3071 int b;
    3072
    3073 /* we tightened the upper bound of the linking variable due the fixing of the corresponding binary variable two zero */
    3074
    3075 assert(infervar == linkvar);
    3076 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
    3077
    3078 binvars = consdata->binvars;
    3079 nbinvars = consdata->nbinvars;
    3080 vals = consdata->vals;
    3081
    3082 /* get old and new upper bound */
    3083 ub = SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE);
    3084
    3085 /* resolve tightening of upper bound of the linking variable by binary variables */
    3086 for( b = nbinvars - 1; b >= 0; --b )
    3087 {
    3088 if( vals[b] <= ub )
    3089 break;
    3090
    3091 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
    3092 }
    3093 }
    3094 else if( inferinfo == -6 )
    3095 {
    3096 /* we fixed a binary variable to one since the linking variable was fixed */
    3097 assert(SCIPvarIsBinary(infervar));
    3098 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
    3099 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3100 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3101 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3102 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
    3103
    3104 assert( !SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, FALSE)) );
    3105
    3106 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, bdchgidx) );
    3107 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, bdchgidx) );
    3108 }
    3109 else
    3110 {
    3111 /* we fixed the linking variable to (vals[inferinfo]) since the corresponding binary variable was fixed to one */
    3112 assert(infervar == linkvar);
    3113 assert(inferinfo >= 0);
    3114 assert(inferinfo < consdata->nbinvars);
    3115 assert(SCIPisEQ(scip, consdata->vals[inferinfo], SCIPgetVarUbAtIndex(scip, consdata->linkvar, bdchgidx, TRUE))
    3116 || SCIPisEQ(scip, consdata->vals[inferinfo], SCIPgetVarLbAtIndex(scip, consdata->linkvar, bdchgidx, TRUE)));
    3117
    3118 assert(SCIPgetVarLbAtIndex(scip, consdata->binvars[inferinfo], bdchgidx, FALSE) > 0.5);
    3119 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[inferinfo]) );
    3120 }
    3121
    3122 *result = SCIP_SUCCESS;
    3123
    3124 return SCIP_OKAY;
    3125}
    3126
    3127/** variable rounding lock method of constraint handler */
    3128static
    3129SCIP_DECL_CONSLOCK(consLockLinking)
    3130{ /*lint --e{715}*/
    3131 SCIP_CONSDATA* consdata;
    3132 int b;
    3133
    3134 assert(locktype == SCIP_LOCKTYPE_MODEL);
    3135
    3136 consdata = SCIPconsGetData(cons);
    3137 assert(consdata != NULL);
    3138
    3139 /* lock linking variable in both directions */
    3140 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->linkvar, locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
    3141
    3142 /* look binary variables in both directions */
    3143 for( b = 0; b < consdata->nbinvars; ++b )
    3144 {
    3145 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->binvars[b], locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
    3146 }
    3147
    3148 return SCIP_OKAY;
    3149}
    3150
    3151/** constraint activation notification method of constraint handler */
    3152static
    3153SCIP_DECL_CONSACTIVE(consActiveLinking)
    3154{ /*lint --e{715}*/
    3155 assert(cons != NULL);
    3156 assert(SCIPconsIsTransformed(cons));
    3157
    3159
    3161 {
    3162 SCIP_CALL( addNlrow(scip, cons) );
    3163 }
    3164
    3165 return SCIP_OKAY;
    3166}
    3167
    3168
    3169/** constraint deactivation notification method of constraint handler */
    3170static
    3171SCIP_DECL_CONSDEACTIVE(consDeactiveLinking)
    3172{ /*lint --e{715}*/
    3173 SCIP_CONSDATA* consdata;
    3174
    3175 assert(SCIPconsIsTransformed(cons));
    3176
    3178
    3179 /* get constraint data */
    3180 consdata = SCIPconsGetData(cons);
    3181 assert(consdata != NULL);
    3182
    3183 /* remove row from NLP, if still in solving
    3184 * if we are in exitsolve, the whole NLP will be freed anyway
    3185 */
    3186 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && consdata->nlrow1 != NULL )
    3187 {
    3188 assert(consdata->nlrow2 != NULL);
    3189 SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow1) );
    3190 SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow2) );
    3191 }
    3192
    3193 return SCIP_OKAY;
    3194}
    3195
    3196/** constraint enabling notification method of constraint handler */
    3197static
    3198SCIP_DECL_CONSENABLE(consEnableLinking)
    3199{ /*lint --e{715}*/
    3200#ifdef SCIP_DISABLED_CODE
    3201 SCIP_CONSHDLRDATA* conshdlrdata;
    3202#endif
    3203 SCIP_CONSDATA* consdata;
    3204
    3205#ifdef SCIP_DISABLED_CODE
    3206 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3207 assert(conshdlrdata != NULL);
    3208#endif
    3209
    3210 consdata = SCIPconsGetData(cons);
    3211 assert(consdata != NULL);
    3212
    3213 if( consdata->nbinvars <= 1 && SCIPgetStage(scip) >= SCIP_STAGE_TRANSFORMED )
    3214 {
    3215 SCIP_CALL( SCIPdisableCons(scip, cons) );
    3216 assert(consdata->nbinvars == 0 || SCIPvarGetLbGlobal(consdata->binvars[0]) > 0.5);
    3217 }
    3218#ifdef SCIP_DISABLED_CODE
    3219 /** @todo The following might help, but it would need to be tested whether it speeds up the solution process. */
    3220 else if( conshdlrdata->linearize )
    3221 {
    3222 SCIP_CALL( consdataLinearize(scip, cons, consdata) );
    3223 SCIP_CALL( SCIPdelCons(scip, cons) );
    3224 }
    3225#endif
    3226 return SCIP_OKAY;
    3227}
    3228
    3229/** constraint display method of constraint handler */
    3230static
    3231SCIP_DECL_CONSPRINT(consPrintLinking)
    3232{ /*lint --e{715}*/
    3233 assert(scip != NULL);
    3234 assert(conshdlr != NULL);
    3235 assert(cons != NULL);
    3236
    3238
    3239 return SCIP_OKAY;
    3240}
    3241
    3242
    3243/** constraint copying method of constraint handler */
    3244static
    3245SCIP_DECL_CONSCOPY(consCopyLinking)
    3246{ /*lint --e{715}*/
    3247 SCIP_CONSDATA* sourceconsdata;
    3248 SCIP_VAR** binvars;
    3249 SCIP_VAR* linkvar;
    3250 SCIP_Real* vals;
    3251 const char* consname;
    3252 int nbinvars;
    3253 int v;
    3254
    3256
    3257 (*valid) = TRUE;
    3258
    3259 sourceconsdata = SCIPconsGetData(sourcecons);
    3260 assert(sourceconsdata != NULL);
    3261
    3262 /* get number of binary variables, linking variables */
    3263 nbinvars = sourceconsdata->nbinvars;
    3264 linkvar = sourceconsdata->linkvar;
    3265
    3266 /* duplicate variable array */
    3267 if( nbinvars > 0 )
    3268 {
    3269 SCIP_CALL( SCIPduplicateBufferArray(scip, &binvars, sourceconsdata->binvars, nbinvars) );
    3270 SCIP_CALL( SCIPduplicateBufferArray(scip, &vals, sourceconsdata->vals, nbinvars) );
    3271 }
    3272 else
    3273 {
    3274 binvars = NULL;
    3275 vals = NULL;
    3276 }
    3277
    3278 /* get copy for the binary variables */
    3279 for( v = 0; v < nbinvars && *valid; ++v )
    3280 {
    3281 assert(binvars != NULL); /* for flexelint */
    3282 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, binvars[v], &binvars[v], varmap, consmap, global, valid) );
    3283 assert(!(*valid) || binvars[v] != NULL);
    3284 }
    3285
    3286 /* copy the linking variable */
    3287 if( *valid )
    3288 {
    3289 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, linkvar, &linkvar, varmap, consmap, global, valid) );
    3290 assert(!(*valid) || linkvar != NULL);
    3291 }
    3292
    3293 /* only create the target constraint, if all variables could be copied */
    3294 if( *valid )
    3295 {
    3296 if( name != NULL )
    3297 consname = name;
    3298 else
    3299 consname = SCIPconsGetName(sourcecons);
    3300
    3301 SCIP_CALL( SCIPcreateConsLinking(scip, cons, consname, linkvar, binvars, vals, nbinvars,
    3302 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    3303 }
    3304
    3305 /* free buffer array */
    3306 if( nbinvars > 0 )
    3307 {
    3309 SCIPfreeBufferArrayNull(scip, &binvars);
    3310 }
    3311
    3312 return SCIP_OKAY;
    3313}
    3314
    3315/** constraint parsing method of constraint handler */
    3316static
    3317SCIP_DECL_CONSPARSE(consParseLinking)
    3318{ /*lint --e{715}*/
    3319 SCIP_VAR** binvars;
    3320 SCIP_VAR* linkvar;
    3321 SCIP_Real* vals;
    3322 char* endptr;
    3323 int varssize;
    3324 int nbinvars;
    3325
    3326 assert(scip != NULL);
    3327 assert(success != NULL);
    3328 assert(str != NULL);
    3329 assert(name != NULL);
    3330 assert(cons != NULL);
    3331
    3332 *success = TRUE;
    3333
    3334 /* parse linking variable */
    3335 SCIP_CALL( SCIPparseVarName(scip, str, &linkvar, &endptr) );
    3336
    3337 if( linkvar == NULL )
    3338 {
    3339 SCIPerrorMessage("unknown variable name at '%s'\n", str);
    3340 *success = FALSE;
    3341 return SCIP_OKAY;
    3342 }
    3343
    3344 /* find "==" */
    3345 endptr = strchr(endptr, '=');
    3346
    3347 /* if the string end has been reached without finding the "==" */
    3348 if( endptr == NULL )
    3349 {
    3350 SCIPerrorMessage("Could not find initializing '='.\n");
    3351 *success = FALSE;
    3352 return SCIP_OKAY;
    3353 }
    3354
    3355 str = endptr;
    3356
    3357 /* skip "==" */
    3358 str += *(str+1) == '=' ? 2 : 1;
    3359
    3360 /* skip whitespace */
    3361 SCIP_CALL( SCIPskipSpace((char**)&str) );
    3362
    3363 nbinvars = 0;
    3364 varssize = 16;
    3365 SCIP_CALL( SCIPallocBufferArray(scip, &binvars, varssize) );
    3366 SCIP_CALL( SCIPallocBufferArray(scip, &vals, varssize) );
    3367
    3368 /* check for the string "no binary variables yet" */
    3369 if( strncmp(str, "no binary variables yet", 24) != 0 )
    3370 {
    3371 int requsize;
    3372 int v;
    3373
    3374 /* parse linear sum to get variables and coefficients */
    3375 SCIP_CALL( SCIPparseVarsLinearsum(scip, str, binvars, vals, &nbinvars, varssize, &requsize, &endptr, success) );
    3376
    3377 if( *success && requsize > varssize )
    3378 {
    3379 /* realloc buffers and try again */
    3380 varssize = requsize;
    3381 SCIP_CALL( SCIPreallocBufferArray(scip, &binvars, varssize) );
    3382 SCIP_CALL( SCIPreallocBufferArray(scip, &vals, varssize) );
    3383
    3384 SCIP_CALL( SCIPparseVarsLinearsum(scip, str, binvars, vals, &nbinvars, varssize, &requsize, &endptr, success) );
    3385 assert(!*success || requsize <= varssize); /* if successful, then should have had enough space now */
    3386 }
    3387
    3388 /* check coefficients */
    3389 if( *success )
    3390 {
    3391 /* convert SCIP_Real to integer */
    3392 for( v = 0; v < nbinvars; ++v )
    3393 {
    3394 if( SCIPisIntegral(scip, vals[v]) )
    3395 vals[v] = SCIPconvertRealToInt(scip, vals[v]);
    3396 }
    3397 }
    3398 }
    3399
    3400 if( *success )
    3401 {
    3402 SCIP_CALL( SCIPcreateConsLinking(scip, cons, name, linkvar, binvars, vals, nbinvars,
    3403 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    3404 }
    3405
    3406 SCIPfreeBufferArray(scip, &vals);
    3407 SCIPfreeBufferArray(scip, &binvars);
    3408
    3409 return SCIP_OKAY;
    3410}
    3411
    3412/** constraint method of constraint handler which returns the variables (if possible) */
    3413static
    3414SCIP_DECL_CONSGETVARS(consGetVarsLinking)
    3415{ /*lint --e{715}*/
    3416 SCIP_CONSDATA* consdata;
    3417
    3418 consdata = SCIPconsGetData(cons);
    3419 assert(consdata != NULL);
    3420
    3421 if( varssize < consdata->nbinvars + 1)
    3422 (*success) = FALSE;
    3423 else
    3424 {
    3425 assert(vars != NULL);
    3426
    3427 BMScopyMemoryArray(vars, consdata->binvars, consdata->nbinvars);
    3428 vars[consdata->nbinvars] = consdata->linkvar;
    3429 (*success) = TRUE;
    3430 }
    3431
    3432 return SCIP_OKAY;
    3433}
    3434
    3435/** constraint method of constraint handler which returns the number of variables (if possible) */
    3436static
    3437SCIP_DECL_CONSGETNVARS(consGetNVarsLinking)
    3438{ /*lint --e{715}*/
    3439 SCIP_CONSDATA* consdata;
    3440
    3441 consdata = SCIPconsGetData(cons);
    3442 assert(consdata != NULL);
    3443
    3444 (*nvars) = consdata->nbinvars + 1;
    3445 (*success) = TRUE;
    3446
    3447 return SCIP_OKAY;
    3448}
    3449
    3450/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
    3451static
    3452SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphLinking)
    3453{ /*lint --e{715}*/
    3454 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_PERM, cons, graph, success) );
    3455
    3456 return SCIP_OKAY;
    3457}
    3458
    3459/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
    3460static
    3461SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphLinking)
    3462{ /*lint --e{715}*/
    3463 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_SIGNPERM, cons, graph, success) );
    3464
    3465 return SCIP_OKAY;
    3466}
    3467
    3468/*
    3469 * Callback methods of event handler
    3470 */
    3471
    3472/** execution method of event handler */
    3473static
    3474SCIP_DECL_EVENTEXEC(eventExecBinvar)
    3475{ /*lint --e{715}*/
    3476 SCIP_CONSDATA* consdata;
    3477 SCIP_EVENTTYPE eventtype;
    3478
    3479 assert(eventhdlr != NULL);
    3480 assert(eventdata != NULL);
    3481 assert(event != NULL);
    3482
    3484
    3485 consdata = (SCIP_CONSDATA*)eventdata;
    3486 assert(consdata != NULL);
    3487
    3488 eventtype = SCIPeventGetType(event);
    3489 switch( eventtype )
    3490 {
    3492 consdata->nfixedones++;
    3493 break;
    3495 consdata->nfixedones--;
    3496 consdata->firstnonfixed = 0;
    3497 consdata->lastnonfixed = consdata->nbinvars - 1;
    3498 break;
    3500 consdata->nfixedzeros++;
    3501 break;
    3503 consdata->firstnonfixed = 0;
    3504 consdata->lastnonfixed = consdata->nbinvars - 1;
    3505 consdata->nfixedzeros--;
    3506 break;
    3507 default:
    3508 SCIPerrorMessage("invalid event type\n");
    3509 return SCIP_INVALIDDATA;
    3510 }
    3511 assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nbinvars);
    3512 assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nbinvars);
    3513
    3514 /*debugMsg(scip, " -> constraint has %d zero-fixed and %d one-fixed of %d variables\n",
    3515 consdata->nfixedzeros, consdata->nfixedones, consdata->nvars);*/
    3516
    3517 return SCIP_OKAY;
    3518}
    3519
    3520/*
    3521 * constraint specific interface methods
    3522 */
    3523
    3524/** creates the handler for linking constraints and includes it in SCIP */
    3526 SCIP* scip /**< SCIP data structure */
    3527 )
    3528{
    3529 SCIP_CONSHDLRDATA* conshdlrdata;
    3530 SCIP_CONSHDLR* conshdlr;
    3531 SCIP_EVENTHDLR* eventhdlr;
    3532
    3533 /* create event handler for bound change events */
    3535 eventExecBinvar, NULL) );
    3536
    3537 /* create linking constraint handler data */
    3538 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
    3539
    3540 /* include constraint handler */
    3543 consEnfolpLinking, consEnfopsLinking, consCheckLinking, consLockLinking,
    3544 conshdlrdata) );
    3545
    3546 assert(conshdlr != NULL);
    3547
    3548 /* set non-fundamental callbacks via specific setter functions */
    3549 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinking, consCopyLinking) );
    3550 SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveLinking) );
    3551 SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveLinking) );
    3552 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinking) );
    3553 SCIP_CALL( SCIPsetConshdlrEnable(scip, conshdlr, consEnableLinking) );
    3554 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolLinking) );
    3555 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinking) );
    3556 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinking) );
    3557 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinking) );
    3558 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinking) );
    3559 SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreLinking) );
    3560 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinking) );
    3561 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinking) );
    3563 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinking) );
    3566 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinking) );
    3567 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinking, consSepasolLinking, CONSHDLR_SEPAFREQ,
    3569 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinking) );
    3570 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxLinking) );
    3571 SCIP_CALL( SCIPsetConshdlrGetPermsymGraph(scip, conshdlr, consGetPermsymGraphLinking) );
    3572 SCIP_CALL( SCIPsetConshdlrGetSignedPermsymGraph(scip, conshdlr, consGetSignedPermsymGraphLinking) );
    3573
    3574 /* include the linear constraint to linking constraint upgrade in the linear constraint handler */
    3575 /* SCIP_CALL( SCIPincludeLinconsUpgrade(scip, linconsUpgdLinking, LINCONSUPGD_PRIORITY, CONSHDLR_NAME) ); */
    3576
    3577 /* add linking constraint handler parameters */
    3579 "constraints/" CONSHDLR_NAME "/linearize", "this constraint will not propagate or separate, linear and setppc are used?",
    3580 &conshdlrdata->linearize, FALSE, DEFAULT_LINEARIZE, NULL, NULL) );
    3581
    3582 return SCIP_OKAY;
    3583}
    3584
    3585/** creates and captures a linking constraint
    3586 *
    3587 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    3588 */
    3590 SCIP* scip, /**< SCIP data structure */
    3591 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    3592 const char* name, /**< name of constraint */
    3593 SCIP_VAR* linkvar, /**< linking variable (continuous or integer) which should be linked */
    3594 SCIP_VAR** binvars, /**< binary variables */
    3595 SCIP_Real* vals, /**< coefficients of the binary variables */
    3596 int nbinvars, /**< number of binary starting variables */
    3597 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    3598 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    3599 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    3600 * Usually set to TRUE. */
    3601 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    3602 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    3603 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    3604 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    3605 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    3606 * Usually set to TRUE. */
    3607 SCIP_Bool local, /**< is constraint only valid locally?
    3608 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    3609 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    3610 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    3611 * adds coefficients to this constraint. */
    3612 SCIP_Bool dynamic, /**< is constraint subject to aging?
    3613 * Usually set to FALSE. Set to TRUE for own cuts which
    3614 * are separated as constraints. */
    3615 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    3616 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    3617 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    3618 * if it may be moved to a more global node?
    3619 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    3620 )
    3621{
    3622 SCIP_CONSHDLR* conshdlr;
    3623 SCIP_CONSDATA* consdata;
    3624 SCIP_CONSHDLRDATA* conshdlrdata;
    3625 int k;
    3626
    3627 assert(scip != NULL);
    3628 assert(linkvar != NULL);
    3629 assert(binvars != NULL || nbinvars == 0);
    3630 assert(vals != NULL || nbinvars == 0);
    3631
    3632 /* find the linking constraint handler */
    3633 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    3634 if( conshdlr == NULL )
    3635 {
    3636 SCIPerrorMessage("linking constraint handler not found\n");
    3637 return SCIP_PLUGINNOTFOUND;
    3638 }
    3639
    3640 SCIPdebugMsg(scip, "create linking constraint for variable <%s> with %d binary variables (SCIP stage %d)\n",
    3641 SCIPvarGetName(linkvar), nbinvars, SCIPgetStage(scip));
    3642
    3643 if( binvars == NULL && ( !SCIPvarIsIntegral(linkvar)
    3645 || SCIPisInfinity(scip, SCIPvarGetUbGlobal(linkvar)) ) )
    3646 {
    3647 SCIPerrorMessage("linking variable <%s> is %s\n",
    3648 SCIPvarGetName(linkvar), SCIPvarIsIntegral(linkvar) ? "unbounded" : "continuous");
    3649 return SCIP_INVALIDDATA;
    3650 }
    3651
    3652 for( k = 0; k < nbinvars; ++k )
    3653 {
    3654 SCIPdebugMsg(scip, "Var %d : <%s>\n", k, SCIPvarGetName(binvars[k]));
    3655 if( !SCIPisFinite(vals[k]) || SCIPisInfinity(scip, REALABS(vals[k])) )
    3656 {
    3657 SCIPerrorMessage("linking value %lf of <%s> is %s\n",
    3658 vals[k], SCIPvarGetName(binvars[k]), SCIPisFinite(vals[k]) ? "infinite" : "nan");
    3659 return SCIP_INVALIDDATA;
    3660 }
    3661 }
    3662
    3663 /* get constraint handler data */
    3664 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3665 assert(conshdlrdata != NULL);
    3666
    3667 if( conshdlrdata->varmap == NULL )
    3668 {
    3669 SCIP_CALL( SCIPhashmapCreate(&conshdlrdata->varmap, SCIPblkmem(scip), HASHSIZE_BINVARSCONS) );
    3670 }
    3671 assert(conshdlrdata->varmap != NULL);
    3672
    3673 /* check if the linking for the requests linking variable already exists */
    3674 assert(!SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(linkvar)));
    3675
    3676 /* create the constraint specific data */
    3677 SCIP_CALL( consdataCreate(scip, conshdlrdata->eventhdlr, &consdata, linkvar, binvars, vals, nbinvars) );
    3678
    3679 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata,
    3680 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    3681
    3682 /* create binary variables for the real domain */
    3683 if( consdata->binvars == NULL )
    3684 {
    3685 SCIP_CALL( consdataCreateBinvars(scip, *cons, consdata, conshdlrdata->eventhdlr, conshdlrdata->linearize) );
    3686 }
    3687
    3688 /* insert linking constraint into the hash map */
    3689 SCIP_CALL( SCIPhashmapInsert(conshdlrdata->varmap, getHashmapKey(linkvar), *cons) );
    3690 assert(SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(linkvar)));
    3691
    3692 return SCIP_OKAY;
    3693}
    3694
    3695/** creates and captures a linking constraint
    3696 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
    3697 * method SCIPcreateConsLinking(); all flags can be set via SCIPsetCons<Flagname>-methods in scip.h
    3698 *
    3699 * @see SCIPcreateConsLinking() for information about the basic constraint flag configuration
    3700 *
    3701 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    3702 */
    3704 SCIP* scip, /**< SCIP data structure */
    3705 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    3706 const char* name, /**< name of constraint */
    3707 SCIP_VAR* linkvar, /**< linking variable (continuous or integer) which should be linked */
    3708 SCIP_VAR** binvars, /**< binary variables, or NULL */
    3709 SCIP_Real* vals, /**< coefficients of the binary variables */
    3710 int nbinvars /**< number of binary variables */
    3711 )
    3712{
    3713 assert(scip != NULL);
    3714
    3715 SCIP_CALL( SCIPcreateConsLinking(scip, cons, name, linkvar, binvars, vals, nbinvars,
    3717
    3718 return SCIP_OKAY;
    3719}
    3720
    3721/** checks if for the given linking variable (continuous or integer) a linking constraint exists */
    3723 SCIP* scip, /**< SCIP data structure */
    3724 SCIP_VAR* linkvar /**< linking variable (continuous or integer) which should be linked */
    3725 )
    3726{
    3727 SCIP_CONSHDLR* conshdlr;
    3728 SCIP_CONSHDLRDATA* conshdlrdata;
    3729
    3730 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    3731 assert(conshdlr != NULL);
    3732
    3733 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3734 assert(conshdlrdata != NULL);
    3735
    3736 return (conshdlrdata->varmap != NULL) && SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(linkvar));
    3737}
    3738
    3739/** returns the linking constraint belonging the given linking variable (continuous or integer) or NULL if it does not exist yet */
    3741 SCIP* scip, /**< SCIP data structure */
    3742 SCIP_VAR* linkvar /**< linking variable (continuous or integer) which should be linked */
    3743 )
    3744{
    3745 SCIP_CONSHDLR* conshdlr;
    3746 SCIP_CONSHDLRDATA* conshdlrdata;
    3747
    3748 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    3749 assert(conshdlr != NULL);
    3750
    3751 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3752 assert(conshdlrdata != NULL);
    3753
    3754 if( conshdlrdata->varmap != NULL )
    3755 return (SCIP_CONS*) SCIPhashmapGetImage(conshdlrdata->varmap, getHashmapKey(linkvar));
    3756 else
    3757 return NULL;
    3758}
    3759
    3760/** returns the linking variable (continuous or integer) of the linking constraint */
    3762 SCIP* scip, /**< SCIP data structure */
    3763 SCIP_CONS* cons /**< linking constraint */
    3764 )
    3765{
    3766 SCIP_CONSDATA* consdata;
    3767
    3768 assert(scip != NULL);
    3769
    3771
    3772 consdata = SCIPconsGetData(cons);
    3773 assert(consdata != NULL);
    3774
    3775 return consdata->linkvar;
    3776}
    3777
    3778/** returns the binary variables of the linking constraint */
    3780 SCIP* scip, /**< SCIP data structure */
    3781 SCIP_CONS* cons, /**< linking constraint */
    3782 SCIP_VAR*** binvars, /**< pointer to store the binary variables array pointer */
    3783 int* nbinvars /**< pointer to store the number of returned binary variables */
    3784 )
    3785{
    3786 SCIP_CONSDATA* consdata;
    3787
    3788 assert(scip != NULL);
    3789
    3791
    3792 consdata = SCIPconsGetData(cons);
    3793 assert(consdata != NULL);
    3794 assert(consdata->binvars != NULL);
    3795
    3796 if( binvars != NULL )
    3797 (*binvars) = consdata->binvars;
    3798 if( nbinvars != NULL )
    3799 (*nbinvars) = consdata->nbinvars;
    3800
    3801 return SCIP_OKAY;
    3802}
    3803
    3804/** returns the number of binary variables of the linking constraint */
    3806 SCIP* scip, /**< SCIP data structure */
    3807 SCIP_CONS* cons /**< linking constraint */
    3808 )
    3809{
    3810 SCIP_CONSDATA* consdata;
    3811
    3812 assert(scip != NULL);
    3813
    3815
    3816 consdata = SCIPconsGetData(cons);
    3817 assert(consdata != NULL);
    3818
    3819 return consdata->nbinvars;
    3820}
    3821
    3822/** returns the coefficients of the binary variables */
    3824 SCIP* scip, /**< SCIP data structure */
    3825 SCIP_CONS* cons /**< linking constraint */
    3826 )
    3827{
    3828 SCIP_CONSDATA* consdata;
    3829
    3830 assert(scip != NULL);
    3831
    3833
    3834 consdata = SCIPconsGetData(cons);
    3835 assert(consdata != NULL);
    3836 consdataSort(consdata);
    3837
    3838 return consdata->vals;
    3839}
    3840
    3841/** return all binary variable information of the linking constraint */
    3843 SCIP_CONS* cons, /**< linking constraint */
    3844 SCIP_VAR*** binvars, /**< pointer to store binary variables, or NULL */
    3845 SCIP_Real** vals, /**< pointer to store the binary coefficients, or NULL */
    3846 int* nbinvars /**< pointer to store the number of binary variables, or NULL */
    3847 )
    3848{
    3849 SCIP_CONSDATA* consdata;
    3850
    3852
    3853 consdata = SCIPconsGetData(cons);
    3854 assert(consdata != NULL);
    3855
    3856 consdataSort(consdata);
    3857
    3858 if( binvars != NULL )
    3859 *binvars = consdata->binvars;
    3860 if( vals != NULL )
    3861 *vals = consdata->vals;
    3862 if( nbinvars != NULL )
    3863 *nbinvars = consdata->nbinvars;
    3864
    3865 return SCIP_OKAY;
    3866}
    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:981
    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:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define REALABS(x)
    Definition: def.h:191
    #define SCIP_CALL(x)
    Definition: def.h:364
    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:9493
    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:655
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:767
    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:4320
    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:4340
    SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
    Definition: scip_cons.c:601
    SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
    Definition: scip_cons.c:647
    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:8423
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8652
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8413
    SCIP_RETCODE SCIPenableCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1837
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8562
    SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
    Definition: scip_cons.c:2536
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8592
    SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
    Definition: cons.c:8702
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8582
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8454
    SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: scip_cons.c:997
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8612
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8632
    SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
    Definition: cons.c:8490
    SCIP_RETCODE SCIPdisableCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1871
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8393
    SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1812
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8642
    SCIP_Bool SCIPconsIsAdded(SCIP_CONS *cons)
    Definition: cons.c:8822
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8672
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8572
    SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1784
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8662
    SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
    Definition: scip_cut.c:225
    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:1763
    void SCIPupdateSolLPConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
    Definition: scip_sol.c:467
    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:23674
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23510
    SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8882
    SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
    Definition: scip_var.c:2119
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
    Definition: var.c:23803
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
    Definition: var.c:23462
    SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
    Definition: scip_var.c:10550
    SCIP_RETCODE 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:23780
    SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
    Definition: var.c:17595
    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:24174
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23684
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5296
    SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2872
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_RETCODE 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:23522
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    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:24152
    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:23768
    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:1219
    structs for symmetry computations
    methods for dealing with symmetry detection graphs
    @ SCIP_CONFTYPE_PROPAGATION
    Definition: type_conflict.h:62
    struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
    Definition: type_cons.h:64
    struct SCIP_ConsData SCIP_CONSDATA
    Definition: type_cons.h:65
    #define SCIP_EVENTTYPE_BOUNDCHANGED
    Definition: type_event.h:127
    struct SCIP_EventData SCIP_EVENTDATA
    Definition: type_event.h:179
    #define SCIP_EVENTTYPE_UBTIGHTENED
    Definition: type_event.h:79
    #define SCIP_EVENTTYPE_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_INVALIDCALL
    Definition: type_retcode.h:51
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_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