SCIP

    Solving Constraint Integer Programs

    cons_bounddisjunction.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_bounddisjunction.c
    26 * @ingroup DEFPLUGINS_CONS
    27 * @brief constraint handler for bound disjunction constraints \f$(x_1 \{\leq,\geq\} b_1) \vee \ldots \vee (x_n \{\leq,\geq\} b_n)\f$
    28 * @author Tobias Achterberg
    29 * @author Marc Pfetsch
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    36#include "scip/cons_linear.h"
    37#include "scip/cons_logicor.h"
    38#include "scip/cons_setppc.h"
    39#include "scip/expr_pow.h"
    40#include "scip/expr_var.h"
    41#include "scip/pub_conflict.h"
    42#include "scip/pub_cons.h"
    43#include "scip/pub_event.h"
    44#include "scip/pub_lp.h"
    45#include "scip/pub_message.h"
    46#include "scip/pub_misc.h"
    47#include "scip/pub_var.h"
    48#include "scip/scip_branch.h"
    49#include "scip/scip_conflict.h"
    50#include "scip/scip_cons.h"
    51#include "scip/scip_copy.h"
    52#include "scip/scip_event.h"
    53#include "scip/scip_expr.h"
    54#include "scip/scip_general.h"
    55#include "scip/scip_mem.h"
    56#include "scip/scip_message.h"
    57#include "scip/scip_nlp.h"
    58#include "scip/scip_numerics.h"
    59#include "scip/scip_param.h"
    60#include "scip/scip_prob.h"
    61#include "scip/scip_probing.h"
    62#include "scip/scip_sol.h"
    64#include "scip/scip_tree.h"
    65#include "scip/scip_var.h"
    66#include "scip/symmetry_graph.h"
    68
    69
    70/**@name Constraint handler properties
    71 *
    72 * @{
    73 */
    74#define CONSHDLR_NAME "bounddisjunction"
    75#define CONSHDLR_DESC "bound disjunction constraints"
    76#define CONSHDLR_ENFOPRIORITY -3000000 /**< priority of the constraint handler for constraint enforcing */
    77#define CONSHDLR_CHECKPRIORITY -3000000 /**< priority of the constraint handler for checking feasibility */
    78#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
    79#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
    80 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
    81#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
    82#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    83#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
    84
    85#define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_FAST
    86#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
    87
    88/**@} */
    89
    90/**@name Event handler properties
    91 *
    92 * @{
    93 */
    94
    95#define EVENTHDLR_NAME "bounddisjunction"
    96#define EVENTHDLR_DESC "event handler for bound disjunction constraints"
    97
    98/**@} */
    99
    100/**@name Conflict handler properties
    101 *
    102 * @{
    103 */
    104
    105#define CONFLICTHDLR_NAME "bounddisjunction"
    106#define CONFLICTHDLR_DESC "conflict handler creating bound disjunction constraints"
    107#define CONFLICTHDLR_PRIORITY -3000000
    108
    109/**@} */
    110
    111/**@name Default parameter values
    112 *
    113 * @{
    114 */
    115
    116#define DEFAULT_CONTINUOUSFRAC 0.4 /**< maximal percantage of continuous variables within a conflict */
    117
    118/**@} */
    119
    120/**@name Age increase defines
    121 *
    122 * @{
    123 */
    124
    125/* @todo make this a parameter setting */
    126#if 1 /* @todo test which AGEINCREASE formula is better! */
    127#define AGEINCREASE(n) (1.0 + 0.2*n)
    128#else
    129#define AGEINCREASE(n) (0.1*n)
    130#endif
    131
    132/**@} */
    133
    134
    135/**@name Comparison for two values
    136 *
    137 * @{
    138 */
    139
    140#ifdef SCIP_DISABLED_CODE /* These only work if one also passes integral values in case of integral variables. This is not always the case and not even asserted. */
    141/** use defines for numeric compare methods to be slightly faster for integral values */
    142#define isFeasLT(scip, var, val1, val2) (SCIPvarIsIntegral(var) ? (val2) - (val1) > 0.5 : SCIPisFeasLT(scip, val1, val2))
    143#define isFeasLE(scip, var, val1, val2) (SCIPvarIsIntegral(var) ? (val2) - (val1) > -0.5 : SCIPisFeasLE(scip, val1, val2))
    144#define isFeasGT(scip, var, val1, val2) (SCIPvarIsIntegral(var) ? (val1) - (val2) > 0.5 : SCIPisFeasGT(scip, val1, val2))
    145#define isFeasGE(scip, var, val1, val2) (SCIPvarIsIntegral(var) ? (val1) - (val2) > -0.5 : SCIPisFeasGE(scip, val1, val2))
    146#else
    147#define isFeasLT(scip, var, val1, val2) SCIPisFeasLT(scip, val1, val2)
    148#define isFeasLE(scip, var, val1, val2) SCIPisFeasLE(scip, val1, val2)
    149#define isFeasGT(scip, var, val1, val2) SCIPisFeasGT(scip, val1, val2)
    150#define isFeasGE(scip, var, val1, val2) SCIPisFeasGE(scip, val1, val2)
    151#endif
    152/**@} */
    153
    154
    155/** constraint handler data */
    156struct SCIP_ConshdlrData
    157{
    158 SCIP_EVENTHDLR* eventhdlr; /**< event handler for events on watched variables */
    159};
    160
    161/** bound disjunction constraint data */
    162struct SCIP_ConsData
    163{
    164 SCIP_VAR** vars; /**< variables of the literals in the constraint */
    165 SCIP_BOUNDTYPE* boundtypes; /**< types of bounds of the literals (lower or upper bounds) */
    166 SCIP_Real* bounds; /**< bounds of the literals */
    167 int varssize; /**< size of vars, boundtypes, and bounds arrays */
    168 int nvars; /**< number of variables in the constraint */
    169 int watchedvar1; /**< position of the first watched variable */
    170 int watchedvar2; /**< position of the second watched variable */
    171 int filterpos1; /**< event filter position of first watched variable */
    172 int filterpos2; /**< event filter position of second watched variable */
    173};
    174
    175/**@name Local methods
    176 *
    177 * @{
    178 */
    179
    180/** adds rounding locks for the given variable in the given bound disjunction constraint */
    181static
    183 SCIP* scip, /**< SCIP data structure */
    184 SCIP_CONS* cons, /**< bound disjunction constraint */
    185 SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
    186 int pos /**< position of the variable in the constraint */
    187 )
    188{
    189 assert(consdata != NULL);
    190 assert(0 <= pos && pos < consdata->nvars);
    191
    192 if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
    193 {
    194 SCIP_CALL( SCIPlockVarCons(scip, consdata->vars[pos], cons, TRUE, FALSE) );
    195 }
    196 else
    197 {
    198 SCIP_CALL( SCIPlockVarCons(scip, consdata->vars[pos], cons, FALSE, TRUE) );
    199 }
    200
    201 return SCIP_OKAY;
    202}
    203
    204/** removes rounding locks for the given variable in the given bound disjunction constraint */
    205static
    207 SCIP* scip, /**< SCIP data structure */
    208 SCIP_CONS* cons, /**< bound disjunction constraint */
    209 SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
    210 int pos /**< position of the variable in the constraint */
    211 )
    212{
    213 assert(consdata != NULL);
    214 assert(0 <= pos && pos < consdata->nvars);
    215
    216 if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
    217 {
    218 SCIP_CALL( SCIPunlockVarCons(scip, consdata->vars[pos], cons, TRUE, FALSE) );
    219 }
    220 else
    221 {
    222 SCIP_CALL( SCIPunlockVarCons(scip, consdata->vars[pos], cons, FALSE, TRUE) );
    223 }
    224
    225 return SCIP_OKAY;
    226}
    227
    228/** catches the events on a single variable of the bound disjunction constraint */
    229static
    231 SCIP* scip, /**< SCIP data structure */
    232 SCIP_CONS* cons, /**< bound disjunction constraint */
    233 SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
    234 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    235 int pos, /**< position of the variable in the constraint */
    236 int* filterpos /**< pointer to store position of event filter entry, or NULL */
    237 )
    238{
    239 assert(consdata != NULL);
    240 assert(0 <= pos && pos < consdata->nvars);
    241
    242 if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
    243 {
    245 eventhdlr, (SCIP_EVENTDATA*)cons, filterpos) );
    246 }
    247 else
    248 {
    250 eventhdlr, (SCIP_EVENTDATA*)cons, filterpos) );
    251 }
    252
    253 return SCIP_OKAY;
    254}
    255
    256/** drops the events on a single variable of the bound disjunction constraint */
    257static
    259 SCIP* scip, /**< SCIP data structure */
    260 SCIP_CONS* cons, /**< bound disjunction constraint */
    261 SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
    262 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    263 int pos, /**< position of the variable in the constraint */
    264 int filterpos /**< position of event filter entry returned by SCIPcatchVarEvent(), or -1 */
    265 )
    266{
    267 assert(consdata != NULL);
    268 assert(0 <= pos && pos < consdata->nvars);
    269
    270 if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
    271 {
    273 eventhdlr, (SCIP_EVENTDATA*)cons, filterpos) );
    274 }
    275 else
    276 {
    278 eventhdlr, (SCIP_EVENTDATA*)cons, filterpos) );
    279 }
    280
    281 return SCIP_OKAY;
    282}
    283
    284/** creates constraint handler data for bound disjunction constraint handler */
    285static
    287 SCIP* scip, /**< SCIP data structure */
    288 SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
    289 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    290 )
    291{
    292 assert(scip != NULL);
    293 assert(conshdlrdata != NULL);
    294 assert(eventhdlr != NULL);
    295
    296 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
    297
    298 /* set event handler for catching events on watched variables */
    299 (*conshdlrdata)->eventhdlr = eventhdlr;
    300
    301 return SCIP_OKAY;
    302}
    303
    304/** frees constraint handler data for bound disjunction constraint handler */
    305static
    307 SCIP* scip, /**< SCIP data structure */
    308 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
    309 )
    310{
    311 assert(conshdlrdata != NULL);
    312 assert(*conshdlrdata != NULL);
    313
    314 SCIPfreeBlockMemory(scip, conshdlrdata);
    315}
    316
    317/** creates a bound disjunction constraint data object */
    318static
    320 SCIP* scip, /**< SCIP data structure */
    321 SCIP_CONSDATA** consdata, /**< pointer to store the bound disjunction constraint data */
    322 int nvars, /**< number of variables in the constraint */
    323 SCIP_VAR** vars, /**< variables of the literals in the constraint */
    324 SCIP_BOUNDTYPE* boundtypes, /**< types of bounds of the literals (lower or upper bounds) */
    325 SCIP_Real* bounds /**< bounds of the literals */
    326 )
    327{
    328 assert(consdata != NULL);
    329 assert(nvars == 0 || vars != NULL);
    330 assert(nvars == 0 || boundtypes != NULL);
    331 assert(nvars == 0 || bounds != NULL);
    332
    333 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
    334
    335 if( nvars > 0 )
    336 {
    338 {
    339 int k;
    340 int v;
    341#ifndef NDEBUG
    342 int nviolations = 0;
    343#endif
    344 SCIP_Bool redundant;
    345 SCIP_VAR** varsbuffer;
    346 SCIP_BOUNDTYPE* boundtypesbuffer;
    347 SCIP_Real* boundsbuffer;
    348
    349 SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
    350 SCIP_CALL( SCIPallocBufferArray(scip, &boundtypesbuffer, nvars) );
    351 SCIP_CALL( SCIPallocBufferArray(scip, &boundsbuffer, nvars) );
    352
    353 k = 0;
    354 redundant = FALSE;
    355 /* loop over variables, compare fixed ones against its bound disjunction */
    356 for( v = 0; v < nvars && !redundant; ++v )
    357 {
    358 SCIP_VAR* var = vars[v];
    359 SCIP_BOUNDTYPE boundtype = boundtypes[v];
    360 SCIP_Real bound = bounds[v];
    361
    362 /* is the variable fixed? */
    364 {
    365 if( (boundtype == SCIP_BOUNDTYPE_LOWER && isFeasGE(scip, var, SCIPvarGetLbLocal(var), bound))
    366 || (boundtype == SCIP_BOUNDTYPE_UPPER && isFeasLE(scip, var, SCIPvarGetUbLocal(var), bound)) )
    367 {
    368 /* save this feasible assignment at the first position */
    369 varsbuffer[0] = var;
    370 boundtypesbuffer[0] = boundtype;
    371 boundsbuffer[0] = bound;
    372 k = 1;
    373 redundant = TRUE;
    374 }
    375#ifndef NDEBUG
    376 else
    377 ++nviolations;
    378#endif
    379 }
    380 else
    381 {
    382 /* append unfixed variable to buffer */
    383 varsbuffer[k] = var;
    384 boundtypesbuffer[k] = boundtype;
    385 boundsbuffer[k] = bound;
    386 ++k;
    387 }
    388 }
    389
    390 /* duplicate a single, infeasible assignment, wlog the first one */
    391 if( k == 0 )
    392 {
    393 assert(nviolations == nvars);
    394 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, vars, 1) );
    395 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->boundtypes, boundtypes, 1) );
    396 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->bounds, bounds, 1) );
    397 (*consdata)->varssize = 1;
    398 (*consdata)->nvars = 1;
    399 }
    400 else
    401 {
    402 /* if the bound disjunction is already trivially satisfied, we keep only a single feasible assignment */
    403 assert(!redundant || k == 1);
    404
    405 /* we only copy the buffered variables required to represent the constraint */
    406 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
    407 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->boundtypes, boundtypesbuffer, k) );
    408 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->bounds, boundsbuffer, k) );
    409 (*consdata)->varssize = k;
    410 (*consdata)->nvars = k;
    411 }
    412
    413 /* free buffer storage */
    414 SCIPfreeBufferArray(scip, &boundsbuffer);
    415 SCIPfreeBufferArray(scip, &boundtypesbuffer);
    416 SCIPfreeBufferArray(scip, &varsbuffer);
    417 }
    418 else
    419 {
    420 /* without problem compression, the entire vars array is copied */
    421 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, vars, nvars) );
    422 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->boundtypes, boundtypes, nvars) );
    423 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->bounds, bounds, nvars) );
    424 (*consdata)->varssize = nvars;
    425 (*consdata)->nvars = nvars;
    426 }
    427 }
    428 else
    429 {
    430 (*consdata)->vars = NULL;
    431 (*consdata)->boundtypes = NULL;
    432 (*consdata)->bounds = NULL;
    433 (*consdata)->varssize = 0;
    434 (*consdata)->nvars = 0;
    435 }
    436 (*consdata)->watchedvar1 = -1;
    437 (*consdata)->watchedvar2 = -1;
    438 (*consdata)->filterpos1 = -1;
    439 (*consdata)->filterpos2 = -1;
    440
    441 /* get transformed variables, if we are in the transformed problem */
    443 {
    444 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
    445 }
    446
    447 return SCIP_OKAY;
    448}
    449
    450/** creates a bound disjunction constraint data object with possibly redundant literals */
    451static
    453 SCIP* scip, /**< SCIP data structure */
    454 SCIP_CONSDATA** consdata, /**< pointer to store the bound disjunction constraint data */
    455 int nvars, /**< number of variables in the constraint */
    456 SCIP_VAR** vars, /**< variables of the literals in the constraint */
    457 SCIP_BOUNDTYPE* boundtypes, /**< types of bounds of the literals (lower or upper bounds) */
    458 SCIP_Real* bounds /**< bounds of the literals */
    459 )
    460{
    461 assert(consdata != NULL);
    462 assert(nvars == 0 || vars != NULL);
    463 assert(nvars == 0 || boundtypes != NULL);
    464 assert(nvars == 0 || bounds != NULL);
    465
    466 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
    467
    468 if( nvars > 0 )
    469 {
    470 SCIP_BOUNDTYPE* boundtypesbuffer;
    471 SCIP_Real* boundsbuffer;
    472 SCIP_VAR** varsbuffer;
    473 SCIP_VAR* var;
    474 int nvarsbuffer = 0;
    475 int nviolated = 0;
    476 int v = 0;
    477
    478 SCIP_CALL( SCIPduplicateBufferArray(scip, &varsbuffer, vars, nvars) );
    479 SCIP_CALL( SCIPduplicateBufferArray(scip, &boundtypesbuffer, boundtypes, nvars) );
    480 SCIP_CALL( SCIPduplicateBufferArray(scip, &boundsbuffer, bounds, nvars) );
    481
    482 /* sort variables according to index; this allows us to check for redundancy easily below because duplicate
    483 * variables must now appear consecutively */
    484 SCIPsortPtrRealInt((void**)varsbuffer, boundsbuffer, (int*) boundtypesbuffer, SCIPvarComp, nvars);
    485
    486 /* filter out redundant literals */
    487 while( v < nvars )
    488 {
    489 int lowerindex;
    490 int upperindex;
    491
    492 var = varsbuffer[v];
    493
    494 /* compress fixed variables */
    496 {
    497 /* if the literal is feasible for the fixed variable, then the whole constraint is feasible, so we reduce
    498 * it to only this literal
    499 */
    500 if( ( boundtypesbuffer[v] == SCIP_BOUNDTYPE_LOWER && isFeasGE(scip, var, SCIPvarGetLbLocal(var), boundsbuffer[v]) )
    501 || ( boundtypesbuffer[v] == SCIP_BOUNDTYPE_UPPER && isFeasLE(scip, var, SCIPvarGetUbLocal(var), boundsbuffer[v]) ) )
    502 {
    503 /* save this feasible assignment at the first position */
    504 varsbuffer[0] = var;
    505 boundtypesbuffer[0] = boundtypesbuffer[v];
    506 boundsbuffer[0] = boundsbuffer[v];
    507 nvarsbuffer = 1;
    508 break;
    509 }
    510 else
    511 {
    512 /* otherwise the literal is violated - we skip the literal */
    513 ++nviolated;
    514 ++v;
    515 continue;
    516 }
    517 }
    518
    519 /* initialize bound indices */
    520 if( boundtypesbuffer[v] == SCIP_BOUNDTYPE_LOWER )
    521 {
    522 lowerindex = v;
    523 upperindex = -1;
    524 }
    525 else
    526 {
    527 assert(boundtypesbuffer[v] == SCIP_BOUNDTYPE_UPPER);
    528
    529 lowerindex = -1;
    530 upperindex = v;
    531 }
    532
    533 ++v;
    534
    535 /* check subsequent variables with the same variable for redundancy */
    536 while( v < nvars && varsbuffer[v] == var )
    537 {
    538 if( boundtypesbuffer[v] == SCIP_BOUNDTYPE_LOWER )
    539 {
    540 /* keep the weaker lower bound */
    541 if( lowerindex == -1 || boundsbuffer[lowerindex] > boundsbuffer[v] )
    542 lowerindex = v;
    543 }
    544 else
    545 {
    546 assert(boundtypesbuffer[v] == SCIP_BOUNDTYPE_UPPER);
    547
    548 /* keep the weaker upper bound */
    549 if( upperindex == -1 || boundsbuffer[upperindex] < boundsbuffer[v] )
    550 upperindex = v;
    551 }
    552
    553 ++v;
    554 }
    555
    556 /* keep bound sequence */
    557 if( upperindex != -1 && lowerindex > upperindex )
    558 SCIPswapInts(&lowerindex, &upperindex);
    559
    560 /* keep first bound */
    561 if( lowerindex != -1 )
    562 {
    563 assert(nvarsbuffer != upperindex);
    564
    565 varsbuffer[nvarsbuffer] = varsbuffer[lowerindex];
    566 boundtypesbuffer[nvarsbuffer] = boundtypesbuffer[lowerindex];
    567 boundsbuffer[nvarsbuffer] = boundsbuffer[lowerindex];
    568 ++nvarsbuffer;
    569 }
    570
    571 /* keep second bound */
    572 if( upperindex != -1 )
    573 {
    574 varsbuffer[nvarsbuffer] = varsbuffer[upperindex];
    575 boundtypesbuffer[nvarsbuffer] = boundtypesbuffer[upperindex];
    576 boundsbuffer[nvarsbuffer] = boundsbuffer[upperindex];
    577 ++nvarsbuffer;
    578 }
    579 }
    580 assert(nvarsbuffer > 0 || SCIPisConsCompressionEnabled(scip)); /* no variables can only happen if compression is enabled */
    581
    582#ifndef NDEBUG
    583 /* if there are no variables left, this is because all literals are infeasible */
    584 if( nvarsbuffer == 0 )
    585 {
    586 for( v = 0; v < nvars; v++ )
    587 {
    588 var = vars[v];
    589 assert( SCIPisEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) );
    590 assert( (boundtypes[v] == SCIP_BOUNDTYPE_LOWER && isFeasLT(scip, var, SCIPvarGetLbLocal(var), bounds[v]))
    591 || (boundtypes[v] == SCIP_BOUNDTYPE_UPPER && isFeasGT(scip, var, SCIPvarGetUbLocal(var), bounds[v])) );
    592 }
    593 }
    594 else
    595 {
    596 /* check that the literals are not redundant */
    597 for( v = 0; v < nvarsbuffer; v++ )
    598 {
    599 int v2;
    600 assert(varsbuffer[v] != NULL);
    601 for( v2 = v+1; v2 < nvarsbuffer; v2++ )
    602 assert(varsbuffer[v] != varsbuffer[v2] || boundtypesbuffer[v] != boundtypesbuffer[v2]);
    603 }
    604 }
    605#endif
    606
    607 /* if all literals are infeasible, we keep the first */
    608 if( SCIPisConsCompressionEnabled(scip) && nviolated > 0 && nvarsbuffer == 0 )
    609 nvarsbuffer = 1;
    610
    611 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, nvarsbuffer) );
    612 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->boundtypes, boundtypesbuffer, nvarsbuffer) );
    613 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->bounds, boundsbuffer, nvarsbuffer) );
    614 (*consdata)->varssize = nvarsbuffer;
    615 (*consdata)->nvars = nvarsbuffer;
    616
    617 /* free buffer storage */
    618 SCIPfreeBufferArray(scip, &boundsbuffer);
    619 SCIPfreeBufferArray(scip, &boundtypesbuffer);
    620 SCIPfreeBufferArray(scip, &varsbuffer);
    621 }
    622 else
    623 {
    624 (*consdata)->vars = NULL;
    625 (*consdata)->boundtypes = NULL;
    626 (*consdata)->bounds = NULL;
    627 (*consdata)->varssize = 0;
    628 (*consdata)->nvars = 0;
    629 }
    630 (*consdata)->watchedvar1 = -1;
    631 (*consdata)->watchedvar2 = -1;
    632 (*consdata)->filterpos1 = -1;
    633 (*consdata)->filterpos2 = -1;
    634
    635 /* get transformed variables, if we are in the transformed problem */
    637 {
    638 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
    639 }
    640
    641 return SCIP_OKAY;
    642}
    643
    644/** frees a bound disjunction constraint data */
    645static
    647 SCIP* scip, /**< SCIP data structure */
    648 SCIP_CONSDATA** consdata /**< pointer to the bound disjunction constraint */
    649 )
    650{
    651 assert(consdata != NULL);
    652 assert(*consdata != NULL);
    653
    654 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
    655 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->boundtypes, (*consdata)->varssize);
    656 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->bounds, (*consdata)->varssize);
    657 SCIPfreeBlockMemory(scip, consdata);
    658}
    659
    660/** prints bound disjunction constraint to file stream */
    661static
    663 SCIP* scip, /**< SCIP data structure */
    664 SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
    665 FILE* file, /**< output file (or NULL for standard output) */
    666 SCIP_Bool endline /**< should an endline be set? */
    667 )
    668{
    669 int v;
    670
    671 assert(consdata != NULL);
    672
    673 /* print coefficients */
    674 SCIPinfoMessage(scip, file, "bounddisjunction(");
    675 for( v = 0; v < consdata->nvars; ++v )
    676 {
    677 assert(consdata->vars[v] != NULL);
    678 if( v > 0 )
    679 SCIPinfoMessage(scip, file, ", ");
    680 SCIPinfoMessage(scip, file, "<%s> %s %.15g", SCIPvarGetName(consdata->vars[v]),
    681 consdata->boundtypes[v] == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", consdata->bounds[v]);
    682 }
    683 SCIPinfoMessage(scip, file, ")");
    684
    685 if( endline )
    686 SCIPinfoMessage(scip, file, "\n");
    687}
    688
    689/** stores the given variable numbers as watched variables, and updates the event processing */
    690static
    692 SCIP* scip, /**< SCIP data structure */
    693 SCIP_CONS* cons, /**< bound disjunction constraint */
    694 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    695 int watchedvar1, /**< new first watched variable */
    696 int watchedvar2 /**< new second watched variable */
    697 )
    698{
    699 SCIP_CONSDATA* consdata;
    700
    701 consdata = SCIPconsGetData(cons);
    702 assert(consdata != NULL);
    703 assert(watchedvar1 == -1 || watchedvar1 != watchedvar2);
    704 assert(watchedvar1 != -1 || watchedvar2 == -1);
    705 assert(watchedvar1 == -1 || (0 <= watchedvar1 && watchedvar1 < consdata->nvars));
    706 assert(watchedvar2 == -1 || (0 <= watchedvar2 && watchedvar2 < consdata->nvars));
    707
    708 /* don't watch variables for non active constraints */
    709 if( !SCIPconsIsActive(cons) )
    710 return SCIP_OKAY;
    711
    712 /* if one watched variable is equal to the old other watched variable, just switch positions */
    713 if( watchedvar1 == consdata->watchedvar2 || watchedvar2 == consdata->watchedvar1 )
    714 {
    715 int tmp;
    716
    717 tmp = consdata->watchedvar1;
    718 consdata->watchedvar1 = consdata->watchedvar2;
    719 consdata->watchedvar2 = tmp;
    720 tmp = consdata->filterpos1;
    721 consdata->filterpos1 = consdata->filterpos2;
    722 consdata->filterpos2 = tmp;
    723 }
    724 assert(watchedvar1 == -1 || watchedvar1 != consdata->watchedvar2);
    725 assert(watchedvar2 == -1 || watchedvar2 != consdata->watchedvar1);
    726
    727 /* drop events on old watched variables */
    728 if( consdata->watchedvar1 != -1 && consdata->watchedvar1 != watchedvar1 )
    729 {
    730 assert(consdata->filterpos1 != -1);
    731 SCIP_CALL( dropEvents(scip, cons, consdata, eventhdlr, consdata->watchedvar1, consdata->filterpos1) );
    732 consdata->watchedvar1 = -1;
    733 }
    734 if( consdata->watchedvar2 != -1 && consdata->watchedvar2 != watchedvar2 )
    735 {
    736 assert(consdata->filterpos2 != -1);
    737 SCIP_CALL( dropEvents(scip, cons, consdata, eventhdlr, consdata->watchedvar2, consdata->filterpos2) );
    738 consdata->watchedvar2 = -1;
    739 }
    740
    741 /* catch events on new watched variables */
    742 if( watchedvar1 != -1 && watchedvar1 != consdata->watchedvar1 )
    743 {
    744 SCIP_CALL( catchEvents(scip, cons, consdata, eventhdlr, watchedvar1, &consdata->filterpos1) );
    745 }
    746 if( watchedvar2 != -1 && watchedvar2 != consdata->watchedvar2 )
    747 {
    748 SCIP_CALL( catchEvents(scip, cons, consdata, eventhdlr, watchedvar2, &consdata->filterpos2) );
    749 }
    750
    751 /* set the new watched variables */
    752 consdata->watchedvar1 = watchedvar1;
    753 consdata->watchedvar2 = watchedvar2;
    754
    755 return SCIP_OKAY;
    756}
    757
    758/** check whether two intervals overlap */
    759static
    761 SCIP* scip,
    762 SCIP_VAR* var,
    763 SCIP_BOUNDTYPE boundtype1,
    764 SCIP_Real bound1,
    765 SCIP_BOUNDTYPE boundtype2,
    766 SCIP_Real bound2
    767 )
    768{
    769 SCIP_Bool overlapping = FALSE;
    770
    771 if( boundtype1 == SCIP_BOUNDTYPE_LOWER )
    772 {
    773 assert(boundtype2 == SCIP_BOUNDTYPE_UPPER);
    774
    775 if( SCIPisLE(scip, bound1 - bound2, (SCIP_Real)SCIPvarIsIntegral(var)) )
    776 overlapping = TRUE;
    777 }
    778 else
    779 {
    780 assert(boundtype2 == SCIP_BOUNDTYPE_LOWER);
    781
    782 if( SCIPisLE(scip, bound2 - bound1, (SCIP_Real)SCIPvarIsIntegral(var)) )
    783 overlapping = TRUE;
    784 }
    785
    786 return overlapping;
    787}
    788
    789/** deletes coefficient at given position from bound disjunction constraint data */
    790static
    792 SCIP* scip, /**< SCIP data structure */
    793 SCIP_CONS* cons, /**< bound disjunction constraint */
    794 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    795 int pos /**< position of coefficient to delete */
    796 )
    797{
    798 SCIP_CONSDATA* consdata;
    799
    800 assert(eventhdlr != NULL);
    801
    802 consdata = SCIPconsGetData(cons);
    803 assert(consdata != NULL);
    804 assert(0 <= pos && pos < consdata->nvars);
    805 assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(consdata->vars[pos]));
    806
    807 /* remove the rounding locks of variable */
    808 SCIP_CALL( unlockRounding(scip, cons, consdata, pos) );
    809
    810 if( SCIPconsIsTransformed(cons) )
    811 {
    812 /* if the position is watched, stop watching the position */
    813 if( consdata->watchedvar1 == pos )
    814 {
    815 SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, consdata->watchedvar2, -1) );
    816 }
    817 if( consdata->watchedvar2 == pos )
    818 {
    819 SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, consdata->watchedvar1, -1) );
    820 }
    821 }
    822 assert(pos != consdata->watchedvar1);
    823 assert(pos != consdata->watchedvar2);
    824
    825 /* move the last variable to the free slot */
    826 consdata->vars[pos] = consdata->vars[consdata->nvars-1];
    827 consdata->boundtypes[pos] = consdata->boundtypes[consdata->nvars-1];
    828 consdata->bounds[pos] = consdata->bounds[consdata->nvars-1];
    829 consdata->nvars--;
    830
    831 /* if the last variable (that moved) was watched, update the watched position */
    832 if( consdata->watchedvar1 == consdata->nvars )
    833 consdata->watchedvar1 = pos;
    834 if( consdata->watchedvar2 == consdata->nvars )
    835 consdata->watchedvar2 = pos;
    836
    838
    839 return SCIP_OKAY;
    840}
    841
    842/** adds literal to bound disjunction constraint data */
    843static
    845 SCIP* scip, /**< SCIP data structure */
    846 SCIP_CONS* cons, /**< bound disjunction constraint */
    847 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    848 SCIP_VAR* var, /**< variable in literal */
    849 SCIP_BOUNDTYPE boundtype, /**< boundtype of literal */
    850 SCIP_Real bound, /**< bound of literal */
    851 SCIP_Bool* redundant /**< flag to indicate whether constraint has been bound redundant */
    852 )
    853{
    854 SCIP_CONSDATA* consdata;
    855 int samebndidx;
    856 int v;
    857
    858 assert(eventhdlr != NULL);
    859
    860 consdata = SCIPconsGetData(cons);
    861 assert(consdata != NULL);
    862 assert(var != NULL);
    863 assert(!SCIPisInfinity(scip, REALABS(bound)));
    864 assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
    865
    866 /* ensure enough memory in consdata arrays */
    867 if( consdata->varssize == consdata->nvars )
    868 {
    869 int newsize;
    870
    871 newsize = SCIPcalcMemGrowSize(scip, consdata->nvars + 1);
    872 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
    873 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->boundtypes, consdata->varssize, newsize) );
    874 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->bounds, consdata->varssize, newsize) );
    875 consdata->varssize = newsize;
    876 }
    877 assert(consdata->varssize > consdata->nvars);
    878
    879 /* remember the position of the literal in the constraint that has the same bound type on the same variable
    880 *
    881 * example: (x >= 5) or (x <= 2) and literal (x >= 2) should be added.
    882 * if we see (x >= 5) first, we cannot stop immediately because only in combination with the second literal
    883 * we see that the constraint is redundant.
    884 */
    885 samebndidx = -1;
    886
    887 for( v = 0; v < consdata->nvars; v++ )
    888 {
    889 /* check if the variable is already part of the constraint */
    890 if( consdata->vars[v] == var )
    891 {
    892 if( consdata->boundtypes[v] == boundtype )
    893 samebndidx = v;
    894 else if( isOverlapping(scip, var, consdata->boundtypes[v], consdata->bounds[v], boundtype, bound) )
    895 {
    896 *redundant = TRUE;
    897 return SCIP_OKAY;
    898 }
    899 }
    900 }
    901
    902 /* the combination of variable and boundtype is already part of the constraint; check whether the clause
    903 * can be relaxed
    904 */
    905 if( samebndidx > -1 )
    906 {
    907 if( (boundtype == SCIP_BOUNDTYPE_LOWER && SCIPisLT(scip, bound, consdata->bounds[samebndidx]))
    908 || (boundtype == SCIP_BOUNDTYPE_UPPER && SCIPisGT(scip, bound, consdata->bounds[samebndidx])) )
    909 {
    910 SCIPdebugMsg(scip, "relax clause of <%s>: (<%s> %s %.15g) -> (<%s> %s %.15g)\n", SCIPconsGetName(cons),
    911 SCIPvarGetName(var), boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", consdata->bounds[samebndidx],
    912 SCIPvarGetName(var), boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", bound);
    913 consdata->bounds[samebndidx] = bound;
    914 }
    915 }
    916 else
    917 {
    918 /* add the variable to the end of the array */
    919 consdata->vars[consdata->nvars] = var;
    920 consdata->boundtypes[consdata->nvars] = boundtype;
    921 consdata->bounds[consdata->nvars] = bound;
    922 consdata->nvars++;
    923
    924 if( SCIPconsIsTransformed(cons) )
    925 {
    926 /* add rounding lock of variable */
    927 SCIP_CALL( lockRounding(scip, cons, consdata, consdata->nvars-1) );
    928
    929 /* if less than 2 variables are watched, add the new one to the watched variables */
    930 if( consdata->watchedvar1 == -1 )
    931 {
    932 assert(consdata->watchedvar2 == -1);
    933 SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, consdata->nvars-1, -1) );
    934 }
    935 else if( consdata->watchedvar2 == -1 )
    936 {
    937 SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, consdata->watchedvar1, consdata->nvars-1) );
    938 }
    939 }
    940 }
    941
    943
    944 return SCIP_OKAY;
    945}
    946
    947/** deletes all variables with global bounds violating the literal, checks for global bounds satisfying the literal */
    948static
    950 SCIP* scip, /**< SCIP data structure */
    951 SCIP_CONS* cons, /**< bound disjunction constraint */
    952 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    953 SCIP_Bool* redundant /**< returns whether a variable fixed to one exists in the constraint */
    954 )
    955{
    956 SCIP_CONSDATA* consdata;
    957 int v;
    958 SCIP_Real bnd;
    959
    960 assert(eventhdlr != NULL);
    961 assert(redundant != NULL);
    962
    963 consdata = SCIPconsGetData(cons);
    964 assert(consdata != NULL);
    965 assert(consdata->nvars == 0 || consdata->vars != NULL);
    966
    967 *redundant = FALSE;
    968 v = 0;
    969 while( v < consdata->nvars )
    970 {
    971 SCIP_VAR* var;
    972
    973 var = consdata->vars[v];
    974
    975 if( consdata->boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
    976 {
    977 bnd = SCIPcomputeVarLbGlobal(scip, var);
    978 if( isFeasGE(scip, var, bnd, consdata->bounds[v]) )
    979 {
    980 *redundant = TRUE;
    981 return SCIP_OKAY;
    982 }
    983 else
    984 {
    985 bnd = SCIPcomputeVarUbGlobal(scip, var);
    986 if( isFeasLT(scip, var, bnd, consdata->bounds[v]) )
    987 {
    988 SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
    989 }
    990 else
    991 ++v;
    992 }
    993 }
    994 else
    995 {
    996 assert(consdata->boundtypes[v] == SCIP_BOUNDTYPE_UPPER);
    997 bnd = SCIPcomputeVarUbGlobal(scip, var);
    998 if( isFeasLE(scip, var, bnd, consdata->bounds[v]) )
    999 {
    1000 *redundant = TRUE;
    1001 return SCIP_OKAY;
    1002 }
    1003 else
    1004 {
    1005 bnd = SCIPcomputeVarLbGlobal(scip, var);
    1006 if( isFeasGT(scip, var, bnd, consdata->bounds[v]) )
    1007 {
    1008 SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
    1009 }
    1010 else
    1011 ++v;
    1012 }
    1013 }
    1014 }
    1015
    1016 SCIPdebugMsg(scip, "after global bounds: ");
    1017 SCIPdebug(consdataPrint(scip, consdata, NULL, TRUE));
    1018
    1019 return SCIP_OKAY;
    1020}
    1021
    1022/** returns whether literal at the given position is satisfied in the local bounds */
    1023static
    1025 SCIP* scip, /**< SCIP data structure */
    1026 SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
    1027 int pos /**< position of the literal */
    1028 )
    1029{
    1030 SCIP_Real bnd;
    1031
    1032 assert(consdata != NULL);
    1033 assert(0 <= pos && pos < consdata->nvars);
    1034
    1035 if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
    1036 {
    1037 bnd = SCIPcomputeVarLbLocal(scip, consdata->vars[pos]);
    1038 return isFeasGE(scip, consdata->vars[pos], bnd, consdata->bounds[pos]);
    1039 }
    1040 else
    1041 {
    1042 bnd = SCIPcomputeVarUbLocal(scip, consdata->vars[pos]);
    1043 return isFeasLE(scip, consdata->vars[pos], bnd, consdata->bounds[pos]);
    1044 }
    1045}
    1046
    1047/** returns whether literal at the given position is violated in the local bounds */
    1048static
    1050 SCIP* scip, /**< SCIP data structure */
    1051 SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
    1052 int pos /**< position of the literal */
    1053 )
    1054{
    1055 SCIP_Real bnd;
    1056
    1057 assert(consdata != NULL);
    1058 assert(0 <= pos && pos < consdata->nvars);
    1059
    1060 if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
    1061 {
    1062 bnd = SCIPcomputeVarUbLocal(scip, consdata->vars[pos]);
    1063 return isFeasLT(scip, consdata->vars[pos], bnd, consdata->bounds[pos]);
    1064 }
    1065 else
    1066 {
    1067 bnd = SCIPcomputeVarLbLocal(scip, consdata->vars[pos]);
    1068 return isFeasGT(scip, consdata->vars[pos], bnd, consdata->bounds[pos]);
    1069 }
    1070}
    1071
    1072/** replace variables by their representative active (or multi-aggregated) variables */
    1073static
    1075 SCIP* scip, /**< SCIP data structure */
    1076 SCIP_CONS* cons, /**< bound disjunction constraint */
    1077 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    1078 SCIP_Bool* redundant /**< flag to indicate whether constraint has been bound redundant */
    1079 )
    1080{
    1081 SCIP_CONSDATA* consdata;
    1082 SCIP_VAR* var;
    1083 SCIP_BOUNDTYPE boundtype;
    1085 int v;
    1086
    1087 assert(scip != NULL);
    1088 assert(cons != NULL);
    1089 assert(eventhdlr != NULL);
    1090
    1091 consdata = SCIPconsGetData(cons);
    1092 assert(consdata != NULL);
    1093
    1094 v = 0;
    1095 while( v < consdata->nvars )
    1096 {
    1097#ifndef NDEBUG
    1098 SCIP_VAR* oldvar;
    1099#endif
    1100 var = consdata->vars[v];
    1101 assert(var != NULL);
    1102
    1103#ifndef NDEBUG
    1104 oldvar = var;
    1105#endif
    1106
    1108 {
    1109 /* check whether the literal is satisfied and the constraint is thus redundant */
    1110 if( isLiteralSatisfied(scip, consdata, v) )
    1111 {
    1112 *redundant = TRUE;
    1113 break;
    1114 }
    1115 if( isLiteralViolated(scip, consdata, v) )
    1116 {
    1117 SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
    1118 continue;
    1119 }
    1120
    1121 ++v;
    1122
    1123 continue;
    1124 }
    1125
    1126 /* get active/fixed/multiaggr equivalent of v'th literal */
    1127 bound = consdata->bounds[v];
    1128 boundtype = consdata->boundtypes[v];
    1129 SCIP_CALL( SCIPvarGetProbvarBound(&var, &bound, &boundtype) );
    1130 assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED || oldvar != var);
    1131
    1132 SCIPdebugMsg(scip, "in <%s>, replace <%s>[%g,%g] %c= %g by <%s>[%g,%g] %c= %g\n", SCIPconsGetName(cons),
    1133 SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbGlobal(consdata->vars[v]), SCIPvarGetUbGlobal(consdata->vars[v]), (consdata->boundtypes[v] == SCIP_BOUNDTYPE_LOWER ? '>' : '<'), consdata->bounds[v],
    1134 SCIPvarGetName(var), SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), (boundtype == SCIP_BOUNDTYPE_LOWER ? '>' : '<'), bound);
    1135
    1136 /* if literal is satisfied, then constraint is redundant and we can stop */
    1137 if( (boundtype == SCIP_BOUNDTYPE_LOWER && isFeasLE(scip, var, bound, SCIPvarGetLbGlobal(var))) || /*lint !e666*/
    1138 (boundtype == SCIP_BOUNDTYPE_UPPER && isFeasGE(scip, var, bound, SCIPvarGetUbGlobal(var))) ) /*lint !e666*/
    1139 {
    1140 *redundant = TRUE;
    1141 break;
    1142 }
    1143
    1144 /* if literal is not fixed, replace it */
    1146 {
    1147 /* add new literal */
    1148 SCIP_CALL( addCoef(scip, cons, eventhdlr, var, boundtype, bound, redundant) );
    1149 }
    1150
    1151 /* remove old literal */
    1152 SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
    1153 }
    1154
    1155 return SCIP_OKAY;
    1156}
    1157
    1158/** try to upgrade the bounddisjunction constraint
    1159 *
    1160 * if only binary variables are left, we can upgrade a bounddisjunction to a logicor constraint(, if only two variables
    1161 * are left, this logicor constraint can be formulated as set-packing constraint as well)
    1162 *
    1163 * e.g.: bounddisjunction( x1 >= 1, x2 <= 0; x3 >= 1; x4 <= 0 ) => x1 + ~x2 + x3 + ~x4 >= 1
    1164 */
    1165static
    1167 SCIP* scip, /**< SCIP data structure */
    1168 SCIP_CONS* cons, /**< bound disjunction constraint that detected the conflict */
    1169 int* ndelconss, /**< pointer to store the number of delete constraint */
    1170 int* naddconss /**< pointer to store the number of added constraint */
    1171 )
    1172{
    1173 SCIP_CONSDATA* consdata;
    1174 SCIP_VAR** newvars;
    1175 SCIP_Bool allbinary;
    1176 int nvars;
    1177 int v;
    1178
    1179 assert(scip != NULL);
    1180 assert(cons != NULL);
    1181 assert(ndelconss != NULL);
    1182 assert(naddconss != NULL);
    1183 assert(naddconss != NULL);
    1184 assert(!SCIPconsIsModifiable(cons));
    1185
    1186 consdata = SCIPconsGetData(cons);
    1187 assert(consdata != NULL);
    1188
    1189 nvars = consdata->nvars;
    1190 assert(nvars >= 2);
    1191 assert(consdata->vars != NULL);
    1192
    1193 allbinary = TRUE;
    1194
    1195 SCIP_CALL( SCIPallocBufferArray(scip, &newvars, nvars) );
    1196
    1197 for( v = nvars - 1; v >= 0; --v )
    1198 {
    1199 if( !SCIPvarIsBinary(consdata->vars[v]) )
    1200 {
    1201 allbinary = FALSE;
    1202 break;
    1203 }
    1204 else
    1205 {
    1206 if( consdata->boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
    1207 {
    1208 assert(SCIPisFeasGT(scip, consdata->bounds[v], 0.0));
    1209
    1210 if( nvars == 2 )
    1211 {
    1212 SCIP_CALL( SCIPgetNegatedVar(scip, consdata->vars[v], &(newvars[v])) );
    1213 }
    1214 else
    1215 newvars[v] = consdata->vars[v];
    1216 }
    1217 else
    1218 {
    1219 assert(consdata->boundtypes[v] == SCIP_BOUNDTYPE_UPPER);
    1220 assert(SCIPisFeasLT(scip, consdata->bounds[v], 1.0));
    1221
    1222 if( nvars > 2 )
    1223 {
    1224 SCIP_CALL( SCIPgetNegatedVar(scip, consdata->vars[v], &(newvars[v])) );
    1225 }
    1226 else
    1227 newvars[v] = consdata->vars[v];
    1228 }
    1229 }
    1230 }
    1231
    1232 if( allbinary )
    1233 {
    1234 SCIP_CONS* newcons;
    1235
    1236 if( nvars == 2 )
    1237 {
    1238 SCIP_CALL( SCIPcreateConsSetpack(scip, &newcons, SCIPconsGetName(cons), nvars, newvars,
    1243 }
    1244 else
    1245 {
    1246 SCIP_CALL( SCIPcreateConsLogicor(scip, &newcons, SCIPconsGetName(cons), nvars, newvars,
    1251 }
    1252
    1253 /* add the upgraded constraint to the problem */
    1254 SCIPdebugMsg(scip, "upgrading constraint <%s> to the following %s constraint\n", SCIPconsGetName(cons), (nvars == 2 ? "setppc" : "logicor"));
    1255 SCIPdebugPrintCons(scip, newcons, NULL);
    1256 SCIP_CALL( SCIPaddConsUpgrade(scip, cons, &newcons) );
    1257 ++(*naddconss);
    1258
    1259 /* remove the underlying constraint from the problem */
    1260 SCIP_CALL( SCIPdelCons(scip, cons) );
    1261 ++(*ndelconss);
    1262 }
    1263
    1264 SCIPfreeBufferArray(scip, &newvars);
    1265
    1266 return SCIP_OKAY;
    1267}
    1268
    1269/** analyzes conflicting assignment on given constraint, and adds conflict constraint to problem */
    1270static
    1272 SCIP* scip, /**< SCIP data structure */
    1273 SCIP_CONS* cons /**< bound disjunction constraint that detected the conflict */
    1274 )
    1275{
    1276 SCIP_CONSDATA* consdata;
    1277 int v;
    1278
    1279 /* conflict analysis can only be applied in solving stage and if it is turned on */
    1281 return SCIP_OKAY;
    1282
    1283 consdata = SCIPconsGetData(cons);
    1284 assert(consdata != NULL);
    1285
    1286 /* initialize conflict analysis, and add all bounds of infeasible constraint to conflict candidate queue */
    1288
    1289 for( v = 0; v < consdata->nvars; ++v )
    1290 {
    1291 /* the opposite bound is in conflict with this literal */
    1292 SCIP_CALL( SCIPaddConflictBd(scip, consdata->vars[v], SCIPboundtypeOpposite(consdata->boundtypes[v]), NULL) );
    1293 }
    1294
    1295 /* analyze the conflict */
    1297
    1298 return SCIP_OKAY;
    1299}
    1300
    1301/** disables or deletes the given constraint, depending on the current depth */
    1302static
    1304 SCIP* scip, /**< SCIP data structure */
    1305 SCIP_CONS* cons /**< bound disjunction constraint to be disabled */
    1306 )
    1307{
    1308 assert(SCIPconsGetValidDepth(cons) <= SCIPgetDepth(scip));
    1309
    1311 {
    1312 SCIP_CALL( SCIPdelCons(scip, cons) );
    1313 }
    1314 else
    1315 {
    1316 SCIP_CALL( SCIPdisableCons(scip, cons) );
    1317 }
    1318
    1319 return SCIP_OKAY;
    1320}
    1321
    1322/** checks constraint for violation only looking at the watched variables, applies bound changes if possible */
    1323static
    1325 SCIP* scip, /**< SCIP data structure */
    1326 SCIP_CONS* cons, /**< bound disjunction constraint to be processed */
    1327 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    1328 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    1329 SCIP_Bool* infeasible, /**< pointer to store TRUE, if the constraint is infeasible in current bounds */
    1330 SCIP_Bool* reduceddom, /**< pointer to store TRUE, if a domain reduction was found */
    1331 SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
    1332 )
    1333{
    1334 SCIP_CONSDATA* consdata;
    1335 SCIP_VAR** vars;
    1336 SCIP_BOUNDTYPE* boundtypes;
    1337 SCIP_Real* bounds;
    1338 SCIP_Longint nbranchings1;
    1339 SCIP_Longint nbranchings2;
    1340 int nvars;
    1341 int watchedvar1;
    1342 int watchedvar2;
    1343
    1344 assert(cons != NULL);
    1345 assert(SCIPconsGetHdlr(cons) != NULL);
    1346 assert(cutoff != NULL);
    1347 assert(reduceddom != NULL);
    1348 assert(mustcheck != NULL);
    1349
    1351
    1352 consdata = SCIPconsGetData(cons);
    1353 assert(consdata != NULL);
    1354 assert(consdata->watchedvar1 == -1 || consdata->watchedvar1 != consdata->watchedvar2);
    1355
    1356 /* init bools */
    1357 *cutoff = FALSE;
    1358 *infeasible = FALSE;
    1359 *reduceddom = FALSE;
    1360 *mustcheck = FALSE;
    1361
    1362 SCIPdebugMsg(scip, "processing watched variables of constraint <%s>\n", SCIPconsGetName(cons));
    1363
    1364 nvars = consdata->nvars;
    1365 vars = consdata->vars;
    1366 boundtypes = consdata->boundtypes;
    1367 bounds = consdata->bounds;
    1368 assert(nvars == 0 || vars != NULL);
    1369 assert(nvars == 0 || boundtypes != NULL);
    1370 assert(nvars == 0 || bounds != NULL);
    1371
    1372 /* check watched variables if they are satisfying the literal */
    1373 if( consdata->watchedvar1 >= 0 && isLiteralSatisfied(scip, consdata, consdata->watchedvar1) )
    1374 {
    1375 /* the literal is satisfied, making the constraint redundant */
    1376 SCIPdebugMsg(scip, " -> disabling constraint <%s> (watchedvar1 satisfied)\n", SCIPconsGetName(cons));
    1377 SCIP_CALL( disableCons(scip, cons) );
    1378 return SCIP_OKAY;
    1379 }
    1380 if( consdata->watchedvar2 >= 0 && isLiteralSatisfied(scip, consdata, consdata->watchedvar2) )
    1381 {
    1382 /* the literal is satisfied, making the constraint redundant */
    1383 SCIPdebugMsg(scip, " -> disabling constraint <%s> (watchedvar2 satisfied)\n", SCIPconsGetName(cons));
    1384 SCIP_CALL( disableCons(scip, cons) );
    1385 return SCIP_OKAY;
    1386 }
    1387
    1388 /* check if watched variables are still undecided */
    1389 watchedvar1 = -1;
    1390 watchedvar2 = -1;
    1391 nbranchings1 = SCIP_LONGINT_MAX;
    1392 nbranchings2 = SCIP_LONGINT_MAX;
    1393 if( consdata->watchedvar1 >= 0 && !isLiteralViolated(scip, consdata, consdata->watchedvar1) )
    1394 {
    1395 watchedvar1 = consdata->watchedvar1;
    1396 nbranchings1 = -1; /* prefer keeping the watched variable */
    1397 }
    1398 if( consdata->watchedvar2 >= 0 && !isLiteralViolated(scip, consdata, consdata->watchedvar2) )
    1399 {
    1400 if( watchedvar1 == -1 )
    1401 {
    1402 watchedvar1 = consdata->watchedvar2;
    1403 nbranchings1 = -1; /* prefer keeping the watched variable */
    1404 }
    1405 else
    1406 {
    1407 watchedvar2 = consdata->watchedvar2;
    1408 nbranchings2 = -1; /* prefer keeping the watched variable */
    1409 }
    1410 }
    1411 assert(watchedvar1 >= 0 || watchedvar2 == -1);
    1412 assert(nbranchings1 <= nbranchings2);
    1413 assert(watchedvar1 != -1 || nbranchings1 == SCIP_LONGINT_MAX);
    1414 assert(watchedvar2 != -1 || nbranchings2 == SCIP_LONGINT_MAX);
    1415
    1416 /* search for new watched variables */
    1417 if( watchedvar2 == -1 )
    1418 {
    1419 int v;
    1420
    1421 for( v = 0; v < nvars; ++v )
    1422 {
    1423 SCIP_Longint nbranchings;
    1424
    1425 /* don't process the watched variables again */
    1426 if( v == consdata->watchedvar1 || v == consdata->watchedvar2 )
    1427 continue;
    1428
    1429 /* check, if the literal is violated */
    1430 if( isLiteralViolated(scip, consdata, v) )
    1431 continue;
    1432
    1433 /* check, if the literal is satisfied */
    1434 if( isLiteralSatisfied(scip, consdata, v) )
    1435 {
    1436 assert(v != consdata->watchedvar1);
    1437 assert(v != consdata->watchedvar2);
    1438
    1439 /* the literal is satisfied, making the constraint redundant;
    1440 * make sure, the feasible variable is watched and disable the constraint
    1441 */
    1442 SCIPdebugMsg(scip, " -> disabling constraint <%s> (variable <%s> fixed to 1.0)\n",
    1443 SCIPconsGetName(cons), SCIPvarGetName(vars[v]));
    1444 if( consdata->watchedvar1 != -1 )
    1445 {
    1446 SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, consdata->watchedvar1, v) );
    1447 }
    1448 else
    1449 {
    1450 SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, v, consdata->watchedvar2) );
    1451 }
    1452 SCIP_CALL( disableCons(scip, cons) );
    1453 return SCIP_OKAY;
    1454 }
    1455
    1456 /* the literal is still undecided and can be used as watched variable */
    1457 nbranchings = SCIPvarGetNBranchingsCurrentRun(vars[v],
    1459 if( nbranchings < nbranchings2 )
    1460 {
    1461 if( nbranchings < nbranchings1 )
    1462 {
    1463 watchedvar2 = watchedvar1;
    1464 nbranchings2 = nbranchings1;
    1465 watchedvar1 = v;
    1466 nbranchings1 = nbranchings;
    1467 }
    1468 else
    1469 {
    1470 watchedvar2 = v;
    1471 nbranchings2 = nbranchings;
    1472 }
    1473 }
    1474 }
    1475 }
    1476 assert(nbranchings1 <= nbranchings2);
    1477 assert(watchedvar1 >= 0 || watchedvar2 == -1);
    1478
    1479 if( watchedvar1 == -1 )
    1480 {
    1481 /* there is no undecided literal left -> the constraint is infeasible
    1482 * - a modifiable constraint is infeasible
    1483 * - an unmodifiable constraint is infeasible and the node can be cut off
    1484 */
    1485 assert(watchedvar2 == -1);
    1486
    1487 SCIPdebugMsg(scip, " -> constraint <%s> is infeasible\n", SCIPconsGetName(cons));
    1488 *infeasible = TRUE;
    1489
    1491 if( !SCIPconsIsModifiable(cons) )
    1492 {
    1493 /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
    1494 SCIP_CALL( analyzeConflict(scip, cons) );
    1495
    1496 /* mark the node to be cut off */
    1497 *cutoff = TRUE;
    1498 }
    1499 }
    1500 else if( watchedvar2 == -1 )
    1501 {
    1502 /* there is only one undecided literal:
    1503 * - a modifiable constraint must be checked manually
    1504 * - we cannot change bounds of multi-aggregated variables and have to check manually
    1505 * - an unmodifiable constraint is feasible and can be disabled after the remaining literal is satisfied
    1506 */
    1507 assert(0 <= watchedvar1 && watchedvar1 < nvars);
    1508 assert(!isLiteralViolated(scip, consdata, watchedvar1));
    1509 assert(!isLiteralSatisfied(scip, consdata, watchedvar1));
    1510 if( SCIPconsIsModifiable(cons)
    1512 *mustcheck = TRUE;
    1513 else
    1514 {
    1515 SCIP_Bool infbdchg;
    1516
    1517#ifndef NDEBUG
    1518 int v;
    1519
    1520 /* check whether all other literals are violated */
    1521 for (v = 0; v < nvars; ++v)
    1522 {
    1523 if ( v != watchedvar1 )
    1524 {
    1525 assert( isLiteralViolated(scip, consdata, v) );
    1526 }
    1527 }
    1528#endif
    1529
    1530 /* satisfy remaining literal and disable constraint; make sure, the fixed-to-one variable is watched */
    1531 SCIPdebugMsg(scip, " -> single-literal constraint <%s> (change bound <%s> %s %g) at depth %d\n",
    1532 SCIPconsGetName(cons), SCIPvarGetName(vars[watchedvar1]),
    1533 boundtypes[watchedvar1] == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", bounds[watchedvar1], SCIPgetDepth(scip));
    1534
    1535 if( boundtypes[watchedvar1] == SCIP_BOUNDTYPE_LOWER )
    1536 {
    1537 SCIP_CALL( SCIPinferVarLbCons(scip, vars[watchedvar1], bounds[watchedvar1], cons, watchedvar1, TRUE,
    1538 &infbdchg, NULL) );
    1539 }
    1540 else
    1541 {
    1542 SCIP_CALL( SCIPinferVarUbCons(scip, vars[watchedvar1], bounds[watchedvar1], cons, watchedvar1, TRUE,
    1543 &infbdchg, NULL) );
    1544 }
    1545 assert(!infbdchg);
    1547 if( watchedvar1 != consdata->watchedvar1 ) /* keep one of the watched variables */
    1548 {
    1549 SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, watchedvar1, consdata->watchedvar1) );
    1550 }
    1551 SCIP_CALL( disableCons(scip, cons) );
    1552 *reduceddom = TRUE;
    1553 }
    1554 }
    1555 else
    1556 {
    1557 SCIPdebugMsg(scip, " -> new watched variables <%s> and <%s> of constraint <%s> are still undecided\n",
    1558 SCIPvarGetName(vars[watchedvar1]), SCIPvarGetName(vars[watchedvar2]), SCIPconsGetName(cons));
    1559
    1560 /* switch to the new watched variables */
    1561 SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, watchedvar1, watchedvar2) );
    1562
    1563 /* there are at least two undecided variables -> the constraint must be checked manually */
    1564 *mustcheck = TRUE;
    1565
    1566 /* disable propagation of constraint until the corresponding bound of a watched variable changed */
    1568
    1569 /* increase aging counter */
    1570 SCIP_CALL( SCIPaddConsAge(scip, cons, AGEINCREASE(consdata->nvars)) );
    1571 }
    1572
    1573 return SCIP_OKAY;
    1574}
    1575
    1576/** checks constraint for violation, returns TRUE iff constraint is violated */
    1577static
    1579 SCIP* scip, /**< SCIP data structure */
    1580 SCIP_CONS* cons, /**< bound disjunction constraint to be checked */
    1581 SCIP_SOL* sol /**< primal CIP solution */
    1582 )
    1583{
    1584 SCIP_CONSDATA* consdata;
    1585 SCIP_VAR** vars;
    1586 SCIP_BOUNDTYPE* boundtypes;
    1587 SCIP_Real* bounds;
    1588 SCIP_Real solval;
    1589 SCIP_Real viol;
    1590 SCIP_Real absviol;
    1591 int violpos;
    1592 int nvars;
    1593 int v;
    1594
    1595 consdata = SCIPconsGetData(cons);
    1596 assert(consdata != NULL);
    1597
    1598 nvars = consdata->nvars;
    1599 vars = consdata->vars;
    1600 boundtypes = consdata->boundtypes;
    1601 bounds = consdata->bounds;
    1602 assert(nvars == 0 || vars != NULL);
    1603 assert(nvars == 0 || boundtypes != NULL);
    1604 assert(nvars == 0 || bounds != NULL);
    1605
    1606 /* check the given solution */
    1607 absviol = SCIP_REAL_MAX;
    1608 violpos = -1;
    1609 for( v = 0; v < nvars; ++v )
    1610 {
    1611 solval = SCIPgetSolVal(scip, sol, vars[v]);
    1612
    1613 /* update absolute violation if needed */
    1614 viol = (boundtypes[v] == SCIP_BOUNDTYPE_LOWER) ? bounds[v] - solval : solval - bounds[v];
    1615 if( viol < absviol )
    1616 {
    1617 absviol = viol;
    1618 violpos = v;
    1619 }
    1620
    1621 if( (boundtypes[v] == SCIP_BOUNDTYPE_LOWER && isFeasGE(scip, vars[v], solval, bounds[v]))
    1622 || (boundtypes[v] == SCIP_BOUNDTYPE_UPPER && isFeasLE(scip, vars[v], solval, bounds[v])) )
    1623 {
    1624 return FALSE;
    1625 }
    1626 }
    1627 /* update constraint violation in solution */
    1628 if( sol != NULL )
    1629 {
    1630 SCIP_Real relviol;
    1631
    1632 assert(0 == nvars || -1 != violpos);
    1633
    1634 if( 0 == nvars )
    1635 relviol = SCIP_REAL_MAX;
    1636 else
    1637 relviol = SCIPrelDiff(SCIPgetSolVal(scip, sol, vars[violpos]), bounds[violpos]);
    1638
    1639 SCIPupdateSolConsViolation(scip, sol, absviol, relviol);
    1640 }
    1641 return TRUE;
    1642}
    1643
    1644/* registers variables of a constraint as branching candidates
    1645 * indicates whether an n-ary branch is necessary to enforce this constraint,
    1646 * because all active literals are w.r.t. continuous variables which bound (in the literal) is at the variable's bound
    1647 */
    1648static
    1650 SCIP* scip, /**< SCIP data structure */
    1651 SCIP_CONS* cons, /**< bound disjunction constraint which variables should be registered for branching */
    1652 SCIP_SOL* sol, /**< solution (NULL for LP solution) */
    1653 SCIP_Bool* cutoff, /**< pointer to store whether the constraint cannot be made feasible by branching */
    1654 SCIP_Bool* neednarybranch /**< pointer to store TRUE, if n-ary branching is necessary to enforce this constraint */
    1655 )
    1656{
    1657 SCIP_CONSDATA* consdata;
    1658 SCIP_VAR** vars;
    1659 SCIP_BOUNDTYPE* boundtypes;
    1660 SCIP_Real* bounds;
    1661 SCIP_Real violation;
    1662 SCIP_Real varlb;
    1663 SCIP_Real varub;
    1664 int nvars;
    1665 int v;
    1666
    1667 assert(cons != NULL);
    1668 assert(SCIPconsGetHdlr(cons) != NULL);
    1669 assert(cutoff != NULL);
    1670 assert(neednarybranch != NULL);
    1671
    1673
    1674 consdata = SCIPconsGetData(cons);
    1675 assert(consdata != NULL);
    1676 nvars = consdata->nvars;
    1677 vars = consdata->vars;
    1678 boundtypes = consdata->boundtypes;
    1679 bounds = consdata->bounds;
    1680 assert(nvars == 0 || vars != NULL);
    1681 assert(nvars == 0 || boundtypes != NULL);
    1682 assert(nvars == 0 || bounds != NULL);
    1683
    1684 *cutoff = TRUE;
    1685 *neednarybranch = TRUE;
    1686
    1687 for( v = 0; v < nvars; ++v )
    1688 {
    1689 SCIP_VAR* var;
    1690
    1691 var = vars[v];
    1692 assert(var != NULL);
    1693
    1694 /* constraint should be violated, so all bounds in the constraint have to be violated */
    1695 assert( !(boundtypes[v] == SCIP_BOUNDTYPE_LOWER && SCIPisFeasGE(scip, SCIPgetSolVal(scip, sol, var), bounds[v])) &&
    1696 !(boundtypes[v] == SCIP_BOUNDTYPE_UPPER && SCIPisFeasLE(scip, SCIPgetSolVal(scip, sol, var), bounds[v])) );
    1697
    1698 varlb = SCIPcomputeVarLbLocal(scip, var);
    1699 varub = SCIPcomputeVarUbLocal(scip, var);
    1700
    1701 /* if literal is x >= varlb, but upper bound on x is < varlb, then this literal can never be satisfied,
    1702 * thus there is no use for branching
    1703 */
    1704 if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER && isFeasLT(scip, var, varub, bounds[v]) )
    1705 continue;
    1706
    1707 /* if literal is x <= varub, but lower bound on x is > varub, then this literal can never be satisfied,
    1708 * thus there is no use for branching
    1709 */
    1710 if( boundtypes[v] == SCIP_BOUNDTYPE_UPPER && isFeasGT(scip, var, varlb, bounds[v]) )
    1711 continue;
    1712
    1713 /* if literal is always satisfied, then no need to branch on it may happen if propagation is disabled for some
    1714 * reason and due to numerics current solution does not satisfy literal, but variable bounds do
    1715 */
    1716 if( isLiteralSatisfied(scip, consdata, v) )
    1717 continue;
    1718
    1719 violation = SCIPgetSolVal(scip, sol, var) - bounds[v];
    1720
    1721 /* if variable is continuous, then we cannot branch on one of the variable bounds */
    1722 if( SCIPvarIsIntegral(vars[v]) ||
    1723 ((SCIPisInfinity(scip, -varlb) || !SCIPisFeasEQ(scip, bounds[v], varlb)) &&
    1724 (SCIPisInfinity(scip, varub) || !SCIPisFeasEQ(scip, bounds[v], varub))) )
    1725 {
    1726 SCIP_CALL( SCIPaddExternBranchCand(scip, var, REALABS(violation), bounds[v]) );
    1727 *neednarybranch = FALSE;
    1728 }
    1729 *cutoff = FALSE;
    1730 }
    1731
    1732 return SCIP_OKAY;
    1733}
    1734
    1735/** enforces the pseudo or LP solution on the given constraint */
    1736static
    1738 SCIP* scip, /**< SCIP data structure */
    1739 SCIP_CONS* cons, /**< bound disjunction constraint to be separated */
    1740 SCIP_SOL* sol, /**< solution which should be enforced (NULL for LP solution) */
    1741 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    1742 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    1743 SCIP_Bool* infeasible, /**< pointer to store TRUE, if the constraint was infeasible */
    1744 SCIP_Bool* reduceddom, /**< pointer to store TRUE, if a domain reduction was found */
    1745 SCIP_Bool* registeredbrcand /**< pointer to store TRUE, if branching variable candidates were registered or was already true */
    1746 )
    1747{
    1748 SCIP_Bool mustcheck;
    1749 SCIP_Bool neednarybranch;
    1750
    1751 assert(cons != NULL);
    1752 assert(SCIPconsGetHdlr(cons) != NULL);
    1753 assert(cutoff != NULL);
    1754 assert(infeasible != NULL);
    1755 assert(reduceddom != NULL);
    1756 assert(registeredbrcand != NULL);
    1757
    1759
    1760 SCIPdebugMsg(scip, "enforce bound disjunction constraint <%s>\n", SCIPconsGetName(cons));
    1761
    1762 /* update and check the watched variables, if they were changed since last processing */
    1764 {
    1765 SCIP_CALL( processWatchedVars(scip, cons, eventhdlr, cutoff, infeasible, reduceddom, &mustcheck) );
    1766 }
    1767 else
    1768 mustcheck = TRUE;
    1769
    1770 if( mustcheck )
    1771 {
    1772 if( isConsViolated(scip, cons, sol) )
    1773 {
    1774 /* constraint was infeasible -> reset age */
    1776 *infeasible = TRUE;
    1777
    1778 /* register branching candidates */
    1779 SCIP_CALL( registerBranchingCandidates(scip, cons, sol, cutoff, &neednarybranch) );
    1780
    1781 if( !neednarybranch )
    1782 *registeredbrcand = TRUE;
    1783 }
    1784 }
    1785
    1786 return SCIP_OKAY;
    1787}
    1788
    1789/** enforces a constraint by creating an n-ary branch consisting of a set of child nodes, each enforcing one literal
    1790 */
    1791static
    1793 SCIP* scip, /**< SCIP data structure */
    1794 SCIP_CONS* cons, /**< bound disjunction constraint to branch on */
    1795 SCIP_SOL* sol /**< solution which should be enforced (NULL for LP solution) */
    1796 )
    1797{
    1798 SCIP_CONSDATA* consdata;
    1799 SCIP_VAR** vars;
    1800 SCIP_BOUNDTYPE* boundtypes;
    1801 SCIP_Real* bounds;
    1802 SCIP_Real varlb;
    1803 SCIP_Real varub;
    1804 int nvars;
    1805 int v;
    1806
    1807 SCIP_Real priority;
    1808 SCIP_Real estimate;
    1809 SCIP_NODE* node;
    1810
    1811 assert(cons != NULL);
    1812 assert(SCIPconsGetHdlr(cons) != NULL);
    1813
    1815
    1816 consdata = SCIPconsGetData(cons);
    1817 assert(consdata != NULL);
    1818 nvars = consdata->nvars;
    1819 vars = consdata->vars;
    1820 boundtypes = consdata->boundtypes;
    1821 bounds = consdata->bounds;
    1822 assert(nvars == 0 || vars != NULL);
    1823 assert(nvars == 0 || boundtypes != NULL);
    1824 assert(nvars == 0 || bounds != NULL);
    1825
    1826 for( v = 0; v < nvars; ++v )
    1827 {
    1828 SCIP_VAR* var;
    1829
    1830 var = vars[v];
    1831 assert(var != NULL);
    1832
    1833 /* constraint should be violated, so all bounds in the constraint have to be violated */
    1834 assert( !(boundtypes[v] == SCIP_BOUNDTYPE_LOWER && isFeasGE(scip, var, SCIPgetSolVal(scip, sol, var), bounds[v])) && /*lint !e666*/
    1835 !(boundtypes[v] == SCIP_BOUNDTYPE_UPPER && isFeasLE(scip, var, SCIPgetSolVal(scip, sol, var), bounds[v])) ); /*lint !e666*/
    1836
    1837 varlb = SCIPcomputeVarLbLocal(scip, var);
    1838 varub = SCIPcomputeVarUbLocal(scip, var);
    1839
    1840 /* if literal is x >= varlb, but upper bound on x is < varlb, then this literal can never be satisfied,
    1841 * thus there is no use in creating an extra child for it
    1842 */
    1843 if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER && isFeasLT(scip, var, varub, bounds[v]) )
    1844 continue;
    1845 /* if literal is x <= varub, but lower bound on x is > varub, then this literal can never be satisfied,
    1846 * thus there is no use in creating an extra child for it
    1847 */
    1848 if( boundtypes[v] == SCIP_BOUNDTYPE_UPPER && isFeasGT(scip, var, varlb, bounds[v]) )
    1849 continue;
    1850 /* if literal is always satisfied, then no need to branch on it */
    1851 if( isLiteralSatisfied(scip, consdata, v) )
    1852 continue;
    1853
    1854 /* create a child that enforces the current literal */
    1855 priority = SCIPcalcNodeselPriority(scip, var, boundtypes[v] == SCIP_BOUNDTYPE_LOWER ?
    1857 estimate = SCIPcalcChildEstimate (scip, var, bounds[v]);
    1858
    1859 SCIPdebugMsg(scip, " -> creating child to enforce: <%s> %c= %g (priority: %g, estimate: %g)\n",
    1860 SCIPvarGetName(vars[v]), boundtypes[v] == SCIP_BOUNDTYPE_LOWER ? '>' : '<', bounds[v], priority, estimate);
    1861
    1862 SCIP_CALL( SCIPcreateChild(scip, &node, priority, estimate) );
    1863
    1864 /* enforce current literal */
    1866 {
    1867 SCIP_CONS* brcons;
    1868 SCIP_Real one;
    1869
    1870 one = 1.0;
    1871
    1872 if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
    1873 {
    1874 SCIP_CALL( SCIPcreateConsLinear(scip, &brcons, "bounddisjbranch", 1, &var, &one, bounds[v], SCIPinfinity(scip),
    1878 SCIPconsIsStickingAtNode(cons)) );
    1879 }
    1880 else
    1881 {
    1882 SCIP_CALL( SCIPcreateConsLinear(scip, &brcons, "bounddisjbranch", 1, &var, &one, -SCIPinfinity(scip), bounds[v],
    1886 SCIPconsIsStickingAtNode(cons)) );
    1887 }
    1888 SCIP_CALL( SCIPaddConsNode(scip, node, brcons, NULL) );
    1889 SCIP_CALL( SCIPreleaseCons(scip, &brcons) );
    1890 }
    1891 else
    1892 {
    1893 assert(SCIPvarIsActive(var));
    1894 if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
    1895 {
    1896 SCIP_CALL( SCIPchgVarLbNode(scip, node, var, bounds[v]) );
    1897 }
    1898 else
    1899 {
    1900 SCIP_CALL( SCIPchgVarUbNode(scip, node, var, bounds[v]) );
    1901 }
    1902 }
    1903
    1904 /* delete bound disjunction constraint from child node */
    1905 SCIP_CALL( SCIPdelConsNode(scip, node, cons) );
    1906 }
    1907
    1908 return SCIP_OKAY;
    1909}
    1910
    1911/** helper function to enforce constraints */
    1912static
    1914 SCIP* scip, /**< SCIP data structure */
    1915 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    1916 SCIP_CONS** conss, /**< constraints to process */
    1917 int nconss, /**< number of constraints */
    1918 SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
    1919 SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
    1920 )
    1921{
    1922 SCIP_CONSHDLRDATA* conshdlrdata;
    1923 SCIP_Bool cutoff;
    1924 SCIP_Bool infeasible;
    1925 SCIP_Bool reduceddom;
    1926 SCIP_Bool registeredbrcand;
    1927 SCIP_Bool infeasiblecons;
    1928 int c;
    1929 int nnarybranchconsvars;
    1930 SCIP_CONS* narybranchcons; /* constraint that is a candidate for an n-ary branch */
    1931
    1932 assert(conshdlr != NULL);
    1933 assert(nconss == 0 || conss != NULL);
    1934 assert(result != NULL);
    1935
    1937
    1938 SCIPdebugMsg(scip, "Enforcing %d bound disjunction constraints for %s solution\n", nconss, sol == NULL ? "LP" : "relaxation");
    1939
    1940 *result = SCIP_FEASIBLE;
    1941
    1942 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    1943 assert(conshdlrdata != NULL);
    1944
    1945 cutoff = FALSE;
    1946 infeasible = FALSE;
    1947 reduceddom = FALSE;
    1948 registeredbrcand = FALSE;
    1949 narybranchcons = NULL;
    1950 nnarybranchconsvars = INT_MAX;
    1951
    1952 /* check all bound disjunction constraints for feasibility */
    1953 for( c = 0; c < nconss && !cutoff && !reduceddom; ++c )
    1954 {
    1955 infeasiblecons = FALSE;
    1956 SCIP_CALL( enforceCurrentSol(scip, conss[c], sol, conshdlrdata->eventhdlr, &cutoff, &infeasiblecons, &reduceddom,
    1957 &registeredbrcand) );
    1958 infeasible |= infeasiblecons;
    1959 if( infeasiblecons && !registeredbrcand )
    1960 {
    1961 /* if cons. c has less literals than the previous candidate for an n-ary branch, then keep cons. c as candidate for n-ary branch */
    1962 if( narybranchcons == NULL || SCIPconsGetData(conss[c])->nvars < nnarybranchconsvars )
    1963 {
    1964 narybranchcons = conss[c];
    1965 nnarybranchconsvars = SCIPconsGetData(narybranchcons)->nvars;
    1966 assert(nnarybranchconsvars > 0);
    1967 }
    1968 }
    1969 }
    1970
    1971 if( cutoff )
    1972 *result = SCIP_CUTOFF;
    1973 else if( reduceddom )
    1974 *result = SCIP_REDUCEDDOM;
    1975 else if( infeasible )
    1976 {
    1977 if( registeredbrcand )
    1978 {
    1979 *result = SCIP_INFEASIBLE;
    1980 }
    1981 else
    1982 {
    1983 SCIP_CALL( createNAryBranch(scip, narybranchcons, sol) );
    1984 *result = SCIP_BRANCHED;
    1985 }
    1986 }
    1987
    1988 return SCIP_OKAY;
    1989}
    1990
    1991/** adds symmetry information of constraint to a symmetry detection graph */
    1992static
    1994 SCIP* scip, /**< SCIP pointer */
    1995 SYM_SYMTYPE symtype, /**< type of symmetries that need to be added */
    1996 SCIP_CONS* cons, /**< constraint */
    1997 SYM_GRAPH* graph, /**< symmetry detection graph */
    1998 SCIP_Bool* success /**< pointer to store whether symmetry information could be added */
    1999 )
    2000{
    2001 SCIP_CONSDATA* consdata;
    2002 SCIP_VAR** vars;
    2003 SCIP_Real* vals;
    2004 SCIP_Real constant;
    2006 int consnodeidx;
    2007 int opnodeidx;
    2008 int nodeidx;
    2009 int nconsvars;
    2010 int nlocvars;
    2011 int nvars;
    2012 int i;
    2013
    2014 assert(scip != NULL);
    2015 assert(cons != NULL);
    2016 assert(graph != NULL);
    2017 assert(success != NULL);
    2018
    2019 *success = TRUE;
    2020
    2021 consdata = SCIPconsGetData(cons);
    2022 assert(consdata != NULL);
    2023
    2024 /* add node initializing constraint (with artificial rhs) */
    2025 SCIP_CALL( SCIPaddSymgraphConsnode(scip, graph, cons, 0.0, 0.0, &consnodeidx) );
    2026
    2027 /* create nodes and edges for each literal in the bounddisjunction */
    2028 nvars = SCIPgetNVars(scip);
    2029 nconsvars = consdata->nvars;
    2030
    2031 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
    2032 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
    2033
    2034 for( i = 0; i < nconsvars; ++i )
    2035 {
    2036 /* add node and edge for bound expression of literal */
    2037 SCIP_CALL( SCIPaddSymgraphOpnode(scip, graph, (int) SYM_CONSOPTYPE_BDDISJ, &opnodeidx) ); /*lint !e641*/
    2038 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, consnodeidx, opnodeidx, FALSE, 0.0) );
    2039
    2040 /* get active variables */
    2041 vars[0] = consdata->vars[i];
    2042 vals[0] = consdata->boundtypes[i] == SCIP_BOUNDTYPE_UPPER ? 1.0 : -1.0;
    2043 nlocvars = 1;
    2044 constant = 0.0;
    2045
    2046 SCIP_CALL( SCIPgetSymActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant,
    2048
    2049 /* add node and edge for bound on literal (bound adapted by constant) */
    2050 bound = consdata->boundtypes[i] == SCIP_BOUNDTYPE_UPPER ? consdata->bounds[i] : -consdata->bounds[i];
    2051 bound -= constant;
    2052
    2053 SCIP_CALL( SCIPaddSymgraphValnode(scip, graph, bound, &nodeidx) );
    2054 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, opnodeidx, nodeidx, FALSE, 0.0) );
    2055
    2056 /* check whether variable is (multi-)aggregated */
    2057 nodeidx = opnodeidx;
    2058 if( nlocvars > 1 )
    2059 {
    2060 /* encode aggregation by a sum-expression and connect it to bdexpr node */
    2061 SCIP_CALL( SCIPaddSymgraphOpnode(scip, graph, (int) SYM_CONSOPTYPE_SUM, &nodeidx) ); /*lint !e641*/
    2062 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, opnodeidx, nodeidx, FALSE, 0.0) );
    2063 }
    2064
    2065 /* add nodes and edges for variables in aggregation (ignore constant, has been treated above) */
    2066 SCIP_CALL( SCIPaddSymgraphVarAggregation(scip, graph, nodeidx, vars, vals, nlocvars, 0.0) );
    2067 }
    2068
    2069 SCIPfreeBufferArray(scip, &vals);
    2070 SCIPfreeBufferArray(scip, &vars);
    2071
    2072 return SCIP_OKAY;
    2073}
    2074
    2075/**@} */
    2076
    2077/**@name Callback methods of constraint handler
    2078 *
    2079 * @{
    2080 */
    2081
    2082/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    2083static
    2084SCIP_DECL_CONSHDLRCOPY(conshdlrCopyBounddisjunction)
    2085{ /*lint --e{715}*/
    2086 assert(scip != NULL);
    2087 assert(conshdlr != NULL);
    2088
    2090
    2091 /* call inclusion method of constraint handler */
    2093
    2094 *valid = TRUE;
    2095
    2096 return SCIP_OKAY;
    2097}
    2098
    2099/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
    2100static
    2101SCIP_DECL_CONSFREE(consFreeBounddisjunction)
    2102{ /*lint --e{715}*/
    2103 SCIP_CONSHDLRDATA* conshdlrdata;
    2104
    2105 assert(conshdlr != NULL);
    2106 assert(scip != NULL);
    2107
    2109
    2110 /* free constraint handler data */
    2111 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2112 assert(conshdlrdata != NULL);
    2113
    2114 conshdlrdataFree(scip, &conshdlrdata);
    2115
    2116 SCIPconshdlrSetData(conshdlr, NULL);
    2117
    2118 return SCIP_OKAY;
    2119}
    2120
    2121
    2122/** presolving deinitialization method of constraint handler (called after presolving has been finished) */
    2123static
    2124SCIP_DECL_CONSEXITPRE(consExitpreBounddisjunction)
    2125{ /*lint --e{715}*/
    2126 SCIP_CONSHDLRDATA* conshdlrdata;
    2127 SCIP_CONS* cons;
    2128 SCIP_Bool redundant;
    2129 int c;
    2130
    2131 assert(conshdlr != NULL);
    2132 assert(scip != NULL);
    2133
    2135
    2136 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2137 assert(conshdlrdata != NULL);
    2138
    2139 /* fast processing of constraints, apply global bounds and remove fixed variables */
    2140 for( c = 0; c < nconss; ++c )
    2141 {
    2142 cons = conss[c];
    2143 assert(cons != NULL);
    2144
    2145 SCIPdebugMsg(scip, "exit-presolving bound disjunction constraint <%s>\n", SCIPconsGetName(cons));
    2146
    2147 if( SCIPconsIsDeleted(cons) )
    2148 continue;
    2149
    2150 /* remove all literals that are violated in global bounds, check redundancy due to global bounds */
    2151 SCIP_CALL( applyGlobalBounds(scip, cons, conshdlrdata->eventhdlr, &redundant) );
    2152
    2153 if( !redundant )
    2154 {
    2155 /* replace variables by their representative active (or multi-aggregated) variables */
    2156 SCIP_CALL( removeFixedVariables(scip, cons, conshdlrdata->eventhdlr, &redundant) );
    2157 }
    2158
    2159 if( redundant && SCIPconsIsAdded(cons) )
    2160 {
    2161 SCIPdebugMsg(scip, "bound disjunction constraint <%s> is redundant\n", SCIPconsGetName(cons));
    2162 SCIP_CALL( SCIPdelCons(scip, cons) );
    2163 }
    2164 }
    2165
    2166 return SCIP_OKAY;
    2167}
    2168
    2169/** solving process initialization method of constraint handler */
    2170static
    2171SCIP_DECL_CONSINITSOL(consInitsolBounddisjunction)
    2172{ /*lint --e{715}*/
    2173 /* add nlrow representation to NLP, if NLP had been constructed and disjunction is simple enough */
    2175 {
    2176 SCIP_CONSDATA* consdata;
    2177 SCIP_NLROW* nlrow;
    2178 SCIP_EXPR* expr;
    2179 SCIP_EXPR* exprvar;
    2180 SCIP_Real lincoef;
    2181 SCIP_Real a, b;
    2182 int c;
    2183
    2184 for( c = 0; c < nconss; ++c )
    2185 {
    2186 /* skip deactivated or redundant constraints */
    2187 if( !SCIPconsIsActive(conss[c]) || !SCIPconsIsChecked(conss[c]) )
    2188 return SCIP_OKAY;
    2189
    2190 assert(!SCIPconsIsLocal(conss[c])); /* we are at the root node (or short before) */
    2191
    2192 consdata = SCIPconsGetData(conss[c]);
    2193 assert(consdata != NULL);
    2194
    2195 /* look for a bounddisjunction of the form
    2196 * x <= a or x >= b with a < b
    2197 * only one of the inequalities can be strictly satisfied, so we can reformulate as
    2198 * (x-a)*(b-x) <= 0
    2199 * this should be sufficient to get bounddisjunction constraints that represent semi-continuous variables into the NLP
    2200 */
    2201
    2202 if( consdata->nvars != 2 )
    2203 continue;
    2204
    2205 if( consdata->vars[0] != consdata->vars[1] )
    2206 continue;
    2207
    2208 if( consdata->boundtypes[0] == SCIP_BOUNDTYPE_UPPER && consdata->boundtypes[1] == SCIP_BOUNDTYPE_LOWER )
    2209 {
    2210 a = consdata->bounds[0];
    2211 b = consdata->bounds[1];
    2212 }
    2213 else if( consdata->boundtypes[0] == SCIP_BOUNDTYPE_LOWER && consdata->boundtypes[1] == SCIP_BOUNDTYPE_UPPER )
    2214 {
    2215 a = consdata->bounds[1];
    2216 b = consdata->bounds[0];
    2217 }
    2218 else
    2219 {
    2220 continue;
    2221 }
    2222
    2223 if( a >= b )
    2224 continue;
    2225
    2226 SCIP_CALL( SCIPcreateExprVar(scip, &exprvar, consdata->vars[0], NULL, NULL) );
    2227 SCIP_CALL( SCIPcreateExprPow(scip, &expr, exprvar, 2.0, NULL, NULL) );
    2228
    2229 /* add xb-xx-ab+ax <= 0 as -ab <= -(a+b)x + x^2 */
    2230 lincoef = -a - b;
    2231 SCIP_CALL( SCIPcreateNlRow(scip, &nlrow, SCIPconsGetName(conss[c]),
    2232 0.0, 1, consdata->vars, &lincoef, expr, -a*b, SCIPinfinity(scip), SCIP_EXPRCURV_CONVEX) );
    2233
    2234 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
    2235 SCIP_CALL( SCIPreleaseExpr(scip, &exprvar) );
    2236
    2237 SCIP_CALL( SCIPaddNlRow(scip, nlrow) );
    2238 SCIP_CALL( SCIPreleaseNlRow(scip, &nlrow) );
    2239 }
    2240 }
    2241
    2242 return SCIP_OKAY;
    2243}
    2244
    2245/** frees specific constraint data */
    2246static
    2247SCIP_DECL_CONSDELETE(consDeleteBounddisjunction)
    2248{ /*lint --e{715}*/
    2249 assert(conshdlr != NULL);
    2250 assert(consdata != NULL);
    2251 assert(*consdata != NULL);
    2252
    2254
    2255 /* free LP row and bound disjunction constraint */
    2256 consdataFree(scip, consdata);
    2257
    2258 return SCIP_OKAY;
    2259}
    2260
    2261
    2262/** transforms constraint data into data belonging to the transformed problem */
    2263static
    2264SCIP_DECL_CONSTRANS(consTransBounddisjunction)
    2265{ /*lint --e{715}*/
    2266 SCIP_CONSDATA* sourcedata;
    2267 SCIP_CONSDATA* targetdata;
    2268
    2269 /*debugMsg(scip, "Trans method of bound disjunction constraints\n");*/
    2270
    2271 assert(conshdlr != NULL);
    2273 assert(sourcecons != NULL);
    2274 assert(targetcons != NULL);
    2275
    2277
    2278 sourcedata = SCIPconsGetData(sourcecons);
    2279 assert(sourcedata != NULL);
    2280
    2281 /* create constraint data for target constraint */
    2282 SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars,
    2283 sourcedata->boundtypes, sourcedata->bounds) );
    2284
    2285 /* create target constraint */
    2286 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
    2287 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    2288 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
    2289 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
    2290 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
    2291
    2292 return SCIP_OKAY;
    2293}
    2294
    2295
    2296/** constraint enforcing method of constraint handler for LP solutions */
    2297static
    2298SCIP_DECL_CONSENFOLP(consEnfolpBounddisjunction)
    2299{ /*lint --e{715}*/
    2300 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, NULL, result) );
    2301
    2302 return SCIP_OKAY;
    2303}
    2304
    2305
    2306/** constraint enforcing method of constraint handler for relaxation solutions */
    2307static
    2308SCIP_DECL_CONSENFORELAX(consEnforelaxBounddisjunction)
    2309{ /*lint --e{715}*/
    2310 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, sol, result) );
    2311
    2312 return SCIP_OKAY;
    2313}
    2314
    2315
    2316/** constraint enforcing method of constraint handler for pseudo solutions */
    2317static
    2318SCIP_DECL_CONSENFOPS(consEnfopsBounddisjunction)
    2319{ /*lint --e{715}*/
    2320 SCIP_CONSHDLRDATA* conshdlrdata;
    2321 SCIP_Bool cutoff;
    2322 SCIP_Bool infeasible;
    2323 SCIP_Bool reduceddom;
    2324 SCIP_Bool registeredbrcand;
    2325 int c;
    2326 SCIP_CONS* narybranchcons; /* constraint that is a candidate for an n-ary branch */
    2327
    2328 assert(conshdlr != NULL);
    2329 assert(nconss == 0 || conss != NULL);
    2330 assert(result != NULL);
    2331
    2333
    2334 SCIPdebugMsg(scip, "pseudo enforcing %d bound disjunction constraints\n", nconss);
    2335
    2336 *result = SCIP_FEASIBLE;
    2337
    2338 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2339 assert(conshdlrdata != NULL);
    2340
    2341 cutoff = FALSE;
    2342 infeasible = FALSE;
    2343 reduceddom = FALSE;
    2344 registeredbrcand = FALSE;
    2345 narybranchcons = NULL;
    2346
    2347 /* check all bound disjunction constraints for feasibility */
    2348 for( c = 0; c < nconss && !cutoff && !reduceddom; ++c )
    2349 {
    2350 SCIP_CALL( enforceCurrentSol(scip, conss[c], NULL, conshdlrdata->eventhdlr, &cutoff, &infeasible, &reduceddom,
    2351 &registeredbrcand) );
    2352 if( infeasible && !registeredbrcand )
    2353 {
    2354 /* if cons. c has less literals than the previous candidate for an n-ary branch, then keep cons. c as candidate for n-ary branch */
    2355 if( !narybranchcons || SCIPconsGetData(conss[c])->nvars < SCIPconsGetData(narybranchcons)->nvars )
    2356 narybranchcons = conss[c];
    2357 }
    2358 }
    2359
    2360 if( cutoff )
    2361 *result = SCIP_CUTOFF;
    2362 else if( reduceddom )
    2363 *result = SCIP_REDUCEDDOM;
    2364 else if( infeasible )
    2365 {
    2366 if( registeredbrcand )
    2367 {
    2368 *result = SCIP_INFEASIBLE;
    2369 }
    2370 else
    2371 {
    2372 SCIP_CALL( createNAryBranch(scip, narybranchcons, NULL) );
    2373 *result = SCIP_BRANCHED;
    2374 }
    2375 }
    2376
    2377 return SCIP_OKAY;
    2378}
    2379
    2380
    2381/** feasibility check method of constraint handler for integral solutions */
    2382static
    2383SCIP_DECL_CONSCHECK(consCheckBounddisjunction)
    2384{ /*lint --e{715}*/
    2385 SCIP_CONS* cons;
    2386 SCIP_CONSDATA* consdata;
    2387 int c;
    2388
    2389 assert(conshdlr != NULL);
    2390 assert(nconss == 0 || conss != NULL);
    2391 assert(result != NULL);
    2392
    2394
    2395 *result = SCIP_FEASIBLE;
    2396
    2397 /* check all bound disjunction constraints for feasibility */
    2398 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
    2399 {
    2400 cons = conss[c];
    2401 consdata = SCIPconsGetData(cons);
    2402 assert(consdata != NULL);
    2403
    2404 if( isConsViolated(scip, cons, sol) )
    2405 {
    2406 if( printreason )
    2407 {
    2408 int v;
    2409
    2410 SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
    2411 SCIPinfoMessage(scip, NULL, ";\nviolation: ");
    2412 for( v = 0; v < consdata->nvars; ++v )
    2413 {
    2414 assert(consdata->vars[v] != NULL);
    2415 if( v > 0 )
    2416 SCIPinfoMessage(scip, NULL, ", ");
    2417 SCIPinfoMessage(scip, NULL, "<%s> = %.15g",
    2418 SCIPvarGetName(consdata->vars[v]), SCIPgetSolVal(scip, sol, consdata->vars[v]));
    2419 }
    2420 SCIPinfoMessage(scip, NULL, ")\n");
    2421 }
    2422
    2423 /* constraint is violated */
    2424 *result = SCIP_INFEASIBLE;
    2425 }
    2426 }
    2427
    2428 return SCIP_OKAY;
    2429}
    2430
    2431
    2432/** domain propagation method of constraint handler */
    2433static
    2434SCIP_DECL_CONSPROP(consPropBounddisjunction)
    2435{ /*lint --e{715}*/
    2436 SCIP_CONSHDLRDATA* conshdlrdata;
    2437 SCIP_Bool cutoff;
    2438 SCIP_Bool infeasible;
    2439 SCIP_Bool reduceddom;
    2440 SCIP_Bool mustcheck;
    2441 SCIP_Bool consreduceddom;
    2442 int c;
    2443
    2444 assert(conshdlr != NULL);
    2445 assert(nconss == 0 || conss != NULL);
    2446 assert(result != NULL);
    2447
    2449
    2450 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2451 assert(conshdlrdata != NULL);
    2452
    2453 cutoff = FALSE;
    2454 infeasible = FALSE;
    2455 reduceddom = FALSE;
    2456
    2457 /* propagate all useful bound disjunction constraints */
    2458 for( c = 0; c < nusefulconss && !cutoff; ++c )
    2459 {
    2460 SCIP_CALL( processWatchedVars(scip, conss[c], conshdlrdata->eventhdlr,
    2461 &cutoff, &infeasible, &consreduceddom, &mustcheck) );
    2462 reduceddom = reduceddom || consreduceddom;
    2463 }
    2464
    2465 /* return the correct result */
    2466 if( cutoff )
    2467 *result = SCIP_CUTOFF;
    2468 else if( reduceddom )
    2469 *result = SCIP_REDUCEDDOM;
    2470 else
    2471 *result = SCIP_DIDNOTFIND;
    2472
    2473 return SCIP_OKAY; /*lint !e438*/
    2474}
    2475
    2476
    2477/** presolving method of constraint handler */
    2478static
    2479SCIP_DECL_CONSPRESOL(consPresolBounddisjunction)
    2480{ /*lint --e{715}*/
    2481 SCIP_CONSHDLRDATA* conshdlrdata;
    2482 SCIP_CONS* cons;
    2483 SCIP_CONSDATA* consdata;
    2484 SCIP_Bool infeasible;
    2485 SCIP_Bool redundant;
    2486 SCIP_Bool tightened;
    2487 int c;
    2488
    2489 assert(conshdlr != NULL);
    2490 assert(scip != NULL);
    2491 assert(result != NULL);
    2492
    2494
    2495 *result = SCIP_DIDNOTFIND;
    2496
    2497 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2498 assert(conshdlrdata != NULL);
    2499
    2500 /* process constraints */
    2501 for( c = 0; c < nconss && *result != SCIP_CUTOFF && !SCIPisStopped(scip); ++c )
    2502 {
    2503 cons = conss[c];
    2504 assert(cons != NULL);
    2505 consdata = SCIPconsGetData(cons);
    2506 assert(consdata != NULL);
    2507
    2508 SCIPdebugMsg(scip, "presolving bound disjunction constraint <%s>\n", SCIPconsGetName(cons));
    2509
    2510 /* force presolving the constraint in the initial round */
    2511 if( nrounds == 0 )
    2512 {
    2514 }
    2515
    2516 /* remove all literals that are violated in global bounds, check redundancy due to global bounds */
    2517 SCIP_CALL( applyGlobalBounds(scip, cons, conshdlrdata->eventhdlr, &redundant) );
    2518
    2519 if( !redundant )
    2520 {
    2521 /* replace variables by their representative active (or multi-aggregated) variables */
    2522 SCIP_CALL( removeFixedVariables(scip, cons, conshdlrdata->eventhdlr, &redundant) );
    2523 }
    2524
    2525 /**@todo find pairs of negated variables in constraint: constraint is redundant */
    2526 /**@todo find sets of equal variables in constraint: multiple entries of variable can be replaced by single entry */
    2527
    2528 if( redundant )
    2529 {
    2530 SCIPdebugMsg(scip, "bound disjunction constraint <%s> is redundant\n", SCIPconsGetName(cons));
    2531 SCIP_CALL( SCIPdelCons(scip, cons) );
    2532 (*ndelconss)++;
    2533 *result = SCIP_SUCCESS;
    2534 continue;
    2535 }
    2536 else if( !SCIPconsIsModifiable(cons) )
    2537 {
    2538 /* if unmodifiable constraint has no variables, it is infeasible,
    2539 * if unmodifiable constraint has only one variable, the literal can be satisfied and the constraint deleted
    2540 */
    2541 if( consdata->nvars == 0 )
    2542 {
    2543 SCIPdebugMsg(scip, "bound disjunction constraint <%s> is infeasible\n", SCIPconsGetName(cons));
    2544 *result = SCIP_CUTOFF;
    2545 return SCIP_OKAY;
    2546 }
    2547
    2548 if( SCIPconsGetNUpgradeLocks(cons) >= 1 )
    2549 continue;
    2550
    2551 if( consdata->nvars == 1 )
    2552 {
    2553 SCIPdebugMsg(scip, "bound disjunction constraint <%s> has only one undecided literal\n",
    2554 SCIPconsGetName(cons));
    2555
    2556 assert(consdata->vars != NULL);
    2557 assert(!isLiteralSatisfied(scip, consdata, 0));
    2558 assert(!isLiteralViolated(scip, consdata, 0));
    2559
    2560 if( SCIPvarIsActive(consdata->vars[0]) )
    2561 {
    2562 if( consdata->boundtypes[0] == SCIP_BOUNDTYPE_LOWER )
    2563 {
    2564 SCIP_CALL( SCIPtightenVarLb(scip, consdata->vars[0], consdata->bounds[0], TRUE, &infeasible, &tightened) );
    2565 }
    2566 else
    2567 {
    2568 SCIP_CALL( SCIPtightenVarUb(scip, consdata->vars[0], consdata->bounds[0], TRUE, &infeasible, &tightened) );
    2569 }
    2570 if( infeasible )
    2571 {
    2572 SCIPdebugMsg(scip, " -> infeasible fixing\n");
    2573 *result = SCIP_CUTOFF;
    2574 return SCIP_OKAY;
    2575 }
    2576 assert(tightened);
    2577 (*nchgbds)++;
    2578 }
    2579 else
    2580 {
    2581 /* upgrade to a linear constraint, if vars[0] is multi-aggregated */
    2582 SCIP_CONS* lincons;
    2583 SCIP_Real one;
    2584
    2585 assert(SCIPvarGetStatus(consdata->vars[0]) == SCIP_VARSTATUS_MULTAGGR);
    2586
    2587 one = 1.0;
    2588 if( consdata->boundtypes[0] == SCIP_BOUNDTYPE_LOWER )
    2589 {
    2591 1, &consdata->vars[0], &one, consdata->bounds[0], SCIPinfinity(scip),
    2595 SCIPconsIsStickingAtNode(cons)) );
    2596 }
    2597 else
    2598 {
    2600 1, &consdata->vars[0], &one, -SCIPinfinity(scip), consdata->bounds[0],
    2604 SCIPconsIsStickingAtNode(cons)) );
    2605 }
    2606
    2607 /* add the upgraded constraint to the problem */
    2608 SCIP_CALL( SCIPaddConsUpgrade(scip, cons, &lincons) );
    2609 ++(*nupgdconss);
    2610 }
    2611
    2612 SCIP_CALL( SCIPdelCons(scip, cons) );
    2613 (*ndelconss)++;
    2614 *result = SCIP_SUCCESS;
    2615 continue;
    2616 }
    2617 else
    2618 {
    2619 /* try to upgrade the bounddisjunction constraint */
    2620 SCIP_CALL( upgradeCons(scip, cons, ndelconss, naddconss) );
    2621 }
    2622 }
    2623 }
    2624
    2625 /**@todo preprocess pairs of bound disjunction constraints */
    2626
    2627 return SCIP_OKAY;
    2628}
    2629
    2630
    2631/** propagation conflict resolving method of constraint handler */
    2632static
    2633SCIP_DECL_CONSRESPROP(consRespropBounddisjunction)
    2634{ /*lint --e{715}*/
    2635 SCIP_CONSDATA* consdata;
    2636 SCIP_VAR** vars;
    2637 SCIP_BOUNDTYPE* boundtypes;
    2638#ifndef NDEBUG
    2639 SCIP_Real* bounds;
    2640#endif
    2641 int v;
    2642
    2643 assert(conshdlr != NULL);
    2644 assert(cons != NULL);
    2645 assert(infervar != NULL);
    2646 assert(result != NULL);
    2647
    2649
    2650 consdata = SCIPconsGetData(cons);
    2651 assert(consdata != NULL);
    2652 assert(consdata->vars != NULL);
    2653 assert(consdata->nvars > 0);
    2654 assert(0 <= inferinfo && inferinfo < consdata->nvars);
    2655 assert(consdata->vars[inferinfo] == infervar);
    2656
    2657 vars = consdata->vars;
    2658 boundtypes = consdata->boundtypes;
    2659#ifndef NDEBUG
    2660 bounds = consdata->bounds;
    2661 assert(bounds != NULL);
    2662#endif
    2663 assert(boundtypes != NULL);
    2664
    2665 SCIPdebugMsg(scip, "conflict resolving method of bound disjunction constraint handler\n");
    2666
    2667 /* the only deductions are bounds tightened to a literal's bound on bound disjunction constraints where all other
    2668 * literals are violated
    2669 */
    2670 assert((boundtypes[inferinfo] == SCIP_BOUNDTYPE_LOWER
    2671 && SCIPisFeasGE(scip, SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE), bounds[inferinfo]))
    2672 || (boundtypes[inferinfo] == SCIP_BOUNDTYPE_UPPER
    2673 && SCIPisFeasLE(scip, SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE), bounds[inferinfo])));
    2674
    2675 for( v = 0; v < consdata->nvars; ++v )
    2676 {
    2677 if( v != inferinfo )
    2678 {
    2679 assert(consdata->vars[v] != infervar || consdata->boundtypes[v] != consdata->boundtypes[inferinfo]);
    2680
    2681 /* the reason literal must have been violated
    2682 * we do not check for multi-aggregated variables, since SCIPgetVarXbAtIndex is not implemented for them */
    2683 /* Use a weaker comparison to SCIPgetVarXbAtIndex here (i.e., SCIPisXT instead of SCIPisFeasXT),
    2684 * because SCIPgetVarXbAtIndex might differ from the local bound at time bdchgidx by epsilon. */
    2685 assert(SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_MULTAGGR
    2686 || (boundtypes[v] == SCIP_BOUNDTYPE_LOWER
    2687 && SCIPisLT(scip, SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, TRUE), bounds[v]))
    2688 || (boundtypes[v] == SCIP_BOUNDTYPE_UPPER
    2689 && SCIPisGT(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, TRUE), bounds[v])));
    2690 SCIP_CALL( SCIPaddConflictBd(scip, vars[v], SCIPboundtypeOpposite(boundtypes[v]), bdchgidx) );
    2691 }
    2692 }
    2693
    2694 *result = SCIP_SUCCESS;
    2695
    2696 return SCIP_OKAY;
    2697}
    2698
    2699
    2700/** variable rounding lock method of constraint handler */
    2701static
    2702SCIP_DECL_CONSLOCK(consLockBounddisjunction)
    2703{ /*lint --e{715}*/
    2704 SCIP_CONSDATA* consdata;
    2705 int i;
    2706
    2707 consdata = SCIPconsGetData(cons);
    2708 assert(consdata != NULL);
    2709
    2710 /* lock every single coefficient */
    2711 for( i = 0; i < consdata->nvars; ++i )
    2712 {
    2713 if( consdata->boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
    2714 {
    2715 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
    2716 }
    2717 else
    2718 {
    2719 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
    2720 }
    2721 }
    2722
    2723 return SCIP_OKAY;
    2724}
    2725
    2726
    2727/** constraint activation notification method of constraint handler */
    2728static
    2729SCIP_DECL_CONSACTIVE(consActiveBounddisjunction)
    2730{ /*lint --e{715}*/
    2731 SCIP_CONSHDLRDATA* conshdlrdata;
    2732 SCIP_CONSDATA* consdata;
    2733
    2734 assert(conshdlr != NULL);
    2735 assert(cons != NULL);
    2736 assert(SCIPconsIsTransformed(cons));
    2737
    2739
    2740 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2741 assert(conshdlrdata != NULL);
    2742 consdata = SCIPconsGetData(cons);
    2743 assert(consdata != NULL);
    2744 assert(consdata->watchedvar1 == -1 || consdata->watchedvar1 != consdata->watchedvar2);
    2745
    2746 SCIPdebugMsg(scip, "activating information for bound disjunction constraint <%s>\n", SCIPconsGetName(cons));
    2747 SCIPdebug(consdataPrint(scip, consdata, NULL, TRUE));
    2748
    2749 /* catch events on watched variables */
    2750 if( consdata->watchedvar1 != -1 )
    2751 {
    2752 SCIP_CALL( catchEvents(scip, cons, consdata, conshdlrdata->eventhdlr, consdata->watchedvar1,
    2753 &consdata->filterpos1) );
    2754 }
    2755 if( consdata->watchedvar2 != -1 )
    2756 {
    2757 SCIP_CALL( catchEvents(scip, cons, consdata, conshdlrdata->eventhdlr, consdata->watchedvar2,
    2758 &consdata->filterpos2) );
    2759 }
    2760
    2761 return SCIP_OKAY;
    2762}
    2763
    2764
    2765/** constraint deactivation notification method of constraint handler */
    2766static
    2767SCIP_DECL_CONSDEACTIVE(consDeactiveBounddisjunction)
    2768{ /*lint --e{715}*/
    2769 SCIP_CONSHDLRDATA* conshdlrdata;
    2770 SCIP_CONSDATA* consdata;
    2771
    2772 assert(conshdlr != NULL);
    2773 assert(cons != NULL);
    2774 assert(SCIPconsIsTransformed(cons));
    2775
    2777
    2778 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2779 assert(conshdlrdata != NULL);
    2780 consdata = SCIPconsGetData(cons);
    2781 assert(consdata != NULL);
    2782 assert(consdata->watchedvar1 == -1 || consdata->watchedvar1 != consdata->watchedvar2);
    2783
    2784 SCIPdebugMsg(scip, "deactivating information for bound disjunction constraint <%s>\n", SCIPconsGetName(cons));
    2785 SCIPdebug(consdataPrint(scip, consdata, NULL, TRUE));
    2786
    2787 /* drop events on watched variables */
    2788 if( consdata->watchedvar1 != -1 )
    2789 {
    2790 assert(consdata->filterpos1 != -1);
    2791 SCIP_CALL( dropEvents(scip, cons, consdata, conshdlrdata->eventhdlr, consdata->watchedvar1, consdata->filterpos1) );
    2792 consdata->watchedvar1 = -1;
    2793 }
    2794 if( consdata->watchedvar2 != -1 )
    2795 {
    2796 assert(consdata->filterpos2 != -1);
    2797 SCIP_CALL( dropEvents(scip, cons, consdata, conshdlrdata->eventhdlr, consdata->watchedvar2, consdata->filterpos2) );
    2798 consdata->watchedvar2 = -1;
    2799 }
    2800
    2801 return SCIP_OKAY;
    2802}
    2803
    2804
    2805/** constraint display method of constraint handler */
    2806static
    2807SCIP_DECL_CONSPRINT(consPrintBounddisjunction)
    2808{ /*lint --e{715}*/
    2809 assert( scip != NULL );
    2810 assert( conshdlr != NULL );
    2811 assert( cons != NULL );
    2812
    2813 consdataPrint(scip, SCIPconsGetData(cons), file, FALSE);
    2814
    2815 return SCIP_OKAY;
    2816}
    2817
    2818/** constraint copying method of constraint handler */
    2819static
    2820SCIP_DECL_CONSCOPY(consCopyBounddisjunction)
    2821{ /*lint --e{715}*/
    2822 SCIP_VAR** sourcevars;
    2823 SCIP_VAR** targetvars;
    2824 SCIP_BOUNDTYPE* boundtypes;
    2825 SCIP_Real* bounds;
    2826 int nvars;
    2827 int v;
    2828
    2829 assert(valid != NULL);
    2830
    2831 *valid = TRUE;
    2832
    2833 /* get source data */
    2834 sourcevars = SCIPgetVarsBounddisjunction(sourcescip, sourcecons);
    2835 nvars = SCIPgetNVarsBounddisjunction(sourcescip, sourcecons);
    2836 boundtypes = SCIPgetBoundtypesBounddisjunction(sourcescip, sourcecons);
    2837 bounds = SCIPgetBoundsBounddisjunction(sourcescip, sourcecons);
    2838
    2839 SCIP_CALL( SCIPallocBufferArray(scip, &targetvars, nvars) );
    2840
    2841 /* map source variables to active variables of the target SCIP */
    2842 for( v = 0; v < nvars && *valid; ++v )
    2843 {
    2844 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcevars[v], &targetvars[v], varmap, consmap, global, valid) );
    2845 assert(!(*valid) || targetvars[v] != NULL);
    2846 }
    2847
    2848 /* only create the target constraint, if all variables could be copied */
    2849 if( *valid )
    2850 {
    2851 SCIP_CALL( SCIPcreateConsBounddisjunction(scip, cons, name ? name : SCIPconsGetName(sourcecons), nvars, targetvars, boundtypes,
    2852 bounds, initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    2853 }
    2854
    2855 SCIPfreeBufferArray(scip, &targetvars);
    2856
    2857 return SCIP_OKAY;
    2858}
    2859
    2860/** constraint parsing method of constraint handler */
    2861static
    2862SCIP_DECL_CONSPARSE(consParseBounddisjunction)
    2863{ /*lint --e{715}*/
    2864 SCIP_BOUNDTYPE* boundtypes;
    2865 SCIP_Real* bounds;
    2866 SCIP_VAR** vars;
    2867 char* endptr;
    2868 int varssize;
    2869 int nvars;
    2870
    2871 assert( success != NULL );
    2872 *success = TRUE;
    2873
    2874 SCIPdebugMsg(scip, "parse <%s> as bounddisjunction constraint\n", str);
    2875
    2876 /* skip white space */
    2877 SCIP_CALL( SCIPskipSpace((char**)&str) );
    2878
    2879 /* check for string "bounddisjunction" */
    2880 if( strncmp(str, "bounddisjunction(", 16) != 0 )
    2881 {
    2882 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "error during parsing: expected \"bounddisjunction(\" in <%s>.\n", str);
    2883 *success = FALSE;
    2884 return SCIP_OKAY;
    2885 }
    2886
    2887 /* skip "bounddisjunction(" */
    2888 str += 17;
    2889
    2890 varssize = 100;
    2891 nvars = 0;
    2892
    2893 /* allocate buffer array for variables */
    2894 SCIP_CALL( SCIPallocBufferArray(scip, &vars, varssize) );
    2895 SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, varssize) );
    2896 SCIP_CALL( SCIPallocBufferArray(scip, &bounds, varssize) );
    2897
    2898 /* parse string until ")" */
    2899 while( *str != ')' )
    2900 {
    2901 SCIP_VAR* var;
    2902
    2903 /* parse variable name */
    2904 SCIP_CALL( SCIPparseVarName(scip, str, &var, &endptr) );
    2905
    2906 if( var == NULL )
    2907 {
    2908 endptr = strchr(endptr, ')');
    2909
    2910 if( endptr == NULL )
    2911 {
    2912 *success = FALSE;
    2913 goto TERMINATE;
    2914 }
    2915
    2916 break;
    2917 }
    2918
    2919 str = endptr;
    2920
    2921 /* skip white space */
    2922 SCIP_CALL( SCIPskipSpace((char**)&str) );
    2923
    2924 /* parse bound type */
    2925 switch( *str )
    2926 {
    2927 case '<':
    2928 boundtypes[nvars] = SCIP_BOUNDTYPE_UPPER;
    2929 break;
    2930 case '>':
    2931 boundtypes[nvars] = SCIP_BOUNDTYPE_LOWER;
    2932 break;
    2933 default:
    2934 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "variable with name <%s> does not exist\n", SCIPvarGetName(var));
    2935 *success = FALSE;
    2936 goto TERMINATE;
    2937 }
    2938
    2939 ++str;
    2940 if( *str != '=' )
    2941 {
    2942 SCIPdebugMsg(scip, "expected '=': %s\n", str);
    2943 *success = FALSE;
    2944 goto TERMINATE;
    2945 }
    2946
    2947 /* skip '=' */
    2948 ++str;
    2949
    2950 /* parse bound value */
    2951 if( !SCIPparseReal(scip, str, &bounds[nvars], &endptr) )
    2952 {
    2953 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error during parsing of the weight: %s\n", str);
    2954 *success = FALSE;
    2955 goto TERMINATE;
    2956 }
    2957
    2958 str = endptr;
    2959
    2960 /* set variable */
    2961 vars[nvars++] = var;
    2962
    2963 /* check if the size of the variable array was big enough */
    2964 if( nvars > varssize )
    2965 {
    2966 /* reallocate memory */
    2967 varssize *= 2;
    2968 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, varssize) );
    2969 SCIP_CALL( SCIPreallocBufferArray(scip, &boundtypes, varssize) );
    2970 SCIP_CALL( SCIPreallocBufferArray(scip, &bounds, varssize) );
    2971 }
    2972
    2973 /* skip white space */
    2974 SCIP_CALL( SCIPskipSpace((char**)&str) );
    2975
    2976 /* skip ',' */
    2977 if( *str == ',' )
    2978 ++str;
    2979 }
    2980
    2981 /* add bounddisjunction */
    2982 if( *success && nvars > 0 )
    2983 {
    2984 SCIP_CALL( SCIPcreateConsBounddisjunction(scip, cons, name, nvars, vars, boundtypes, bounds,
    2985 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    2986 }
    2987
    2988 TERMINATE:
    2989 /* free variable buffer */
    2990 SCIPfreeBufferArray(scip, &bounds);
    2991 SCIPfreeBufferArray(scip, &boundtypes);
    2992 SCIPfreeBufferArray(scip, &vars);
    2993
    2994 return SCIP_OKAY;
    2995}
    2996
    2997/** constraint method of constraint handler which returns the variables (if possible) */
    2998static
    2999SCIP_DECL_CONSGETVARS(consGetVarsBounddisjunction)
    3000{ /*lint --e{715}*/
    3001 SCIP_CONSDATA* consdata;
    3002
    3003 assert(cons != NULL);
    3004
    3005 consdata = SCIPconsGetData(cons);
    3006 assert(consdata != NULL);
    3007
    3008 if( varssize < consdata->nvars )
    3009 (*success) = FALSE;
    3010 else
    3011 {
    3012 assert(vars != NULL);
    3013
    3014 BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
    3015 (*success) = TRUE;
    3016 }
    3017
    3018 return SCIP_OKAY;
    3019}
    3020
    3021/** constraint method of constraint handler which returns the number of variables (if possible) */
    3022static
    3023SCIP_DECL_CONSGETNVARS(consGetNVarsBounddisjunction)
    3024{ /*lint --e{715}*/
    3025 SCIP_CONSDATA* consdata;
    3026
    3027 assert(cons != NULL);
    3028
    3029 consdata = SCIPconsGetData(cons);
    3030 assert(consdata != NULL);
    3031
    3032 (*nvars) = consdata->nvars;
    3033 (*success) = TRUE;
    3034
    3035 return SCIP_OKAY;
    3036}
    3037
    3038/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
    3039static
    3040SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphBounddisjunction)
    3041{ /*lint --e{715}*/
    3042 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_PERM, cons, graph, success) );
    3043
    3044 return SCIP_OKAY;
    3045}
    3046
    3047/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
    3048static
    3049SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphBounddisjunction)
    3050{ /*lint --e{715}*/
    3051 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_SIGNPERM, cons, graph, success) );
    3052
    3053 return SCIP_OKAY;
    3054}
    3055
    3056/**@} */
    3057
    3058/**@name Callback methods of event handler
    3059 *
    3060 * @{
    3061 */
    3062
    3063static
    3064SCIP_DECL_EVENTEXEC(eventExecBounddisjunction)
    3065{ /*lint --e{715}*/
    3066 assert(eventhdlr != NULL);
    3067 assert(eventdata != NULL);
    3068 assert(event != NULL);
    3069
    3071
    3072 /*SCIPdebugMsg(scip, "exec method of event handler for bound disjunction constraints\n");*/
    3073
    3074 assert(SCIPconsGetData((SCIP_CONS*)eventdata) != NULL);
    3075 assert(SCIPconsIsActive((SCIP_CONS*)eventdata) || SCIPconsIsUpdatedeactivate((SCIP_CONS*)eventdata));
    3076
    3077 if( (SCIPeventGetType(event) & SCIP_EVENTTYPE_BOUNDRELAXED) != 0 )
    3078 {
    3079 SCIP_CALL( SCIPenableCons(scip, (SCIP_CONS*)eventdata) );
    3080 }
    3081 else
    3082 assert((SCIPeventGetType(event) & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0);
    3083
    3085
    3086 return SCIP_OKAY;
    3087}
    3088
    3089/**@} */
    3090
    3091/**@name Callback methods of conflict handler
    3092 *
    3093 * @{
    3094 */
    3095
    3096/** conflict handler data struct */
    3097struct SCIP_ConflicthdlrData
    3098{
    3099 SCIP_Real continuousfrac; /**< maximal percantage of continuous variables within a conflict */
    3100};
    3101
    3102/** conflict processing method of conflict handler (called when conflict was found) */
    3103static
    3104SCIP_DECL_CONFLICTEXEC(conflictExecBounddisjunction)
    3105{ /*lint --e{715}*/
    3106 SCIP_VAR** vars;
    3107 SCIP_CONFLICTHDLRDATA* conflicthdlrdata;
    3108 SCIP_BOUNDTYPE* boundtypes;
    3109 SCIP_Real* bounds;
    3110 SCIP_CONS* cons;
    3111 char consname[SCIP_MAXSTRLEN];
    3112 int nliterals;
    3113 int ncontinuous;
    3114 int i;
    3115
    3116 assert(conflicthdlr != NULL);
    3117 assert(bdchginfos != NULL || nbdchginfos == 0);
    3118 assert(result != NULL);
    3119
    3121
    3122 /* don't process already resolved conflicts */
    3123 if( resolved )
    3124 {
    3125 *result = SCIP_DIDNOTRUN;
    3126 return SCIP_OKAY;
    3127 }
    3128
    3129 conflicthdlrdata = SCIPconflicthdlrGetData(conflicthdlr);
    3130 assert(conflicthdlrdata != NULL);
    3131
    3132 *result = SCIP_DIDNOTFIND;
    3133 ncontinuous = 0;
    3134
    3135 /* create array of variables, boundtypes, and bound values in conflict constraint */
    3136 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
    3137 SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nbdchginfos) );
    3138 SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nbdchginfos) );
    3139
    3140 nliterals = 0;
    3141
    3142 for( i = 0; i < nbdchginfos; ++i )
    3143 {
    3144 SCIP_VAR* var;
    3146 SCIP_BOUNDTYPE boundtype;
    3147 int j;
    3148
    3149 assert(bdchginfos != NULL);
    3150
    3151 var = SCIPbdchginfoGetVar(bdchginfos[i]);
    3152 assert(var != NULL);
    3153
    3154 boundtype = SCIPboundtypeOpposite(SCIPbdchginfoGetBoundtype(bdchginfos[i]));
    3155 bound = relaxedbds[i];
    3156
    3157 /* for continuous variables, we can only use the relaxed version of the bounds negation: !(x <= u) -> x >= u */
    3158 if( SCIPvarIsIntegral(var) )
    3159 bound += (boundtype == SCIP_BOUNDTYPE_LOWER ? +1.0 : -1.0);
    3160
    3161 /* check whether we have seen the variable before */
    3162 for( j = nliterals-1; j >= 0; --j )
    3163 {
    3164 if( vars[j] != var )
    3165 continue;
    3166
    3167 /* check whether both literals contribute with the same bound type */
    3168 if( boundtypes[j] == boundtype )
    3169 {
    3170 /* check whether the lower bound can be relaxed */
    3171 if( boundtype == SCIP_BOUNDTYPE_LOWER && SCIPisLT(scip, bound, bounds[j]) )
    3172 {
    3173 SCIPdebugMsg(scip, "relax lower bound of variable <%s> from %g to %g in bounddisjunction conflict\n",
    3174 SCIPvarGetName(var), bounds[j], bound);
    3175 bounds[j] = bound;
    3176 }
    3177 /* check whether the upper bound can be relaxed */
    3178 else if( boundtype == SCIP_BOUNDTYPE_UPPER && SCIPisGT(scip, bound, bounds[j]) )
    3179 {
    3180 SCIPdebugMsg(scip, "relax upper bound of variable <%s> from %g to %g in bounddisjunction conflict\n",
    3181 SCIPvarGetName(var), bounds[j], bound);
    3182 bounds[j] = bound;
    3183 }
    3184
    3185 continue;
    3186 }
    3187 /* check whether the bounds are overlapping */
    3188 else if( isOverlapping(scip, var, boundtype, bound, boundtypes[j], bounds[j]) )
    3189 {
    3190 /* the conflict is redundant -> discard the conflict constraint */
    3191 SCIPdebugMsg(scip, "redundant bounddisjunction conflict due to overlapping\n");
    3192 goto DISCARDCONFLICT;
    3193 }
    3194 }
    3195
    3196 vars[nliterals] = var;
    3197 boundtypes[nliterals] = boundtype;
    3198 bounds[nliterals] = bound;
    3199
    3200 /* check if the relaxed bound is really a relaxed bound */
    3201 assert(SCIPbdchginfoGetBoundtype(bdchginfos[i]) == SCIP_BOUNDTYPE_LOWER || SCIPisGE(scip, relaxedbds[i], SCIPbdchginfoGetNewbound(bdchginfos[i])));
    3202 assert(SCIPbdchginfoGetBoundtype(bdchginfos[i]) == SCIP_BOUNDTYPE_UPPER || SCIPisLE(scip, relaxedbds[i], SCIPbdchginfoGetNewbound(bdchginfos[i])));
    3203
    3204 /* for continuous variables, we can only use the relaxed version of the bounds negation: !(x <= u) -> x >= u */
    3205 if( !SCIPvarIsIntegral(vars[nliterals]) )
    3206 {
    3207 if( (boundtypes[i] == SCIP_BOUNDTYPE_LOWER && SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), bounds[nliterals]))
    3208 || (boundtypes[i] == SCIP_BOUNDTYPE_UPPER && SCIPisFeasEQ(scip, SCIPvarGetUbGlobal(var), bounds[nliterals])) )
    3209 {
    3210 /* the literal is satisfied in global bounds (may happen due to weak "negation" of continuous variables)
    3211 * -> discard the conflict constraint
    3212 */
    3213 SCIPdebugMsg(scip, "redundant bounddisjunction conflict due to globally fulfilled literal\n");
    3214 goto DISCARDCONFLICT;
    3215 }
    3216 else
    3217 ncontinuous++;
    3218 }
    3219
    3220 nliterals++;
    3221 }
    3222
    3223 /* create a constraint out of the conflict set */
    3224 if( i == nbdchginfos && ncontinuous < conflicthdlrdata->continuousfrac * nbdchginfos + 0.5 )
    3225 {
    3227 SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &cons, consname, nliterals, vars, boundtypes, bounds,
    3228 FALSE, FALSE, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
    3229
    3230 /* add conflict to SCIP */
    3231 SCIP_CALL( SCIPaddConflict(scip, node, &cons, validnode, conftype, cutoffinvolved) );
    3232 SCIPdebugMsg(scip, "added conflict\n");
    3233 *result = SCIP_CONSADDED;
    3234 }
    3235
    3236 DISCARDCONFLICT:
    3237 /* free temporary memory */
    3238 SCIPfreeBufferArray(scip, &bounds);
    3239 SCIPfreeBufferArray(scip, &boundtypes);
    3240 SCIPfreeBufferArray(scip, &vars);
    3241
    3242 return SCIP_OKAY;
    3243}
    3244
    3245/** free method of conflict handler */
    3246static
    3247SCIP_DECL_CONFLICTFREE(conflictFreeBounddisjunction)
    3248{
    3249 SCIP_CONFLICTHDLRDATA* conflicthdlrdata;
    3250
    3251 assert(conflicthdlr != NULL);
    3252
    3253 /* get conflict handler data */
    3254 conflicthdlrdata = SCIPconflicthdlrGetData(conflicthdlr);
    3255 assert(conflicthdlrdata != NULL);
    3256
    3257 /* free conflict handler structure */
    3258 SCIPfreeBlockMemory(scip, &conflicthdlrdata);
    3259
    3260 return SCIP_OKAY;
    3261}
    3262
    3263/**@} */
    3264
    3265/** creates the handler for bound disjunction constraints and includes it in SCIP */
    3267 SCIP* scip /**< SCIP data structure */
    3268 )
    3269{
    3270 SCIP_CONSHDLRDATA* conshdlrdata;
    3271 SCIP_CONFLICTHDLRDATA* conflicthdlrdata;
    3272 SCIP_CONFLICTHDLR* conflicthdlr;
    3273 SCIP_CONSHDLR* conshdlr;
    3274 SCIP_EVENTHDLR* eventhdlr;
    3275
    3276 /* create event handler for events on watched variables */
    3278 eventExecBounddisjunction, NULL) );
    3279
    3280 /* allocate memory for conflict handler data */
    3281 SCIP_CALL( SCIPallocBlockMemory(scip, &conflicthdlrdata) );
    3282
    3283 /* create conflict handler parameter */
    3285 "conflict/" CONSHDLR_NAME "/continuousfrac", "maximal percantage of continuous variables within a conflict",
    3286 &conflicthdlrdata->continuousfrac, FALSE, DEFAULT_CONTINUOUSFRAC, 0.0, 1.0, NULL, NULL) );
    3287
    3288 /* create conflict handler for bound disjunction constraints */
    3290 conflictExecBounddisjunction, conflicthdlrdata) );
    3291
    3292 SCIP_CALL( SCIPsetConflicthdlrFree(scip, conflicthdlr, conflictFreeBounddisjunction) );
    3293
    3294 /* create constraint handler data */
    3295 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
    3296
    3297 /* include constraint handler */
    3300 consEnfolpBounddisjunction, consEnfopsBounddisjunction, consCheckBounddisjunction, consLockBounddisjunction,
    3301 conshdlrdata) );
    3302
    3303 assert(conshdlr != NULL);
    3304
    3305 /* set non-fundamental callbacks via specific setter functions */
    3306 SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveBounddisjunction) );
    3307 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyBounddisjunction, consCopyBounddisjunction) );
    3308 SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveBounddisjunction) );
    3309 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteBounddisjunction) );
    3310 SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreBounddisjunction) );
    3311 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolBounddisjunction) );
    3312 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeBounddisjunction) );
    3313 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsBounddisjunction) );
    3314 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsBounddisjunction) );
    3315 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseBounddisjunction) );
    3316 SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolBounddisjunction, CONSHDLR_MAXPREROUNDS,
    3318 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintBounddisjunction) );
    3319 SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropBounddisjunction, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
    3321 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropBounddisjunction) );
    3322 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransBounddisjunction) );
    3323 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxBounddisjunction) );
    3324 SCIP_CALL( SCIPsetConshdlrGetPermsymGraph(scip, conshdlr, consGetPermsymGraphBounddisjunction) );
    3325 SCIP_CALL( SCIPsetConshdlrGetSignedPermsymGraph(scip, conshdlr, consGetSignedPermsymGraphBounddisjunction) );
    3326
    3327 return SCIP_OKAY;
    3328}
    3329
    3330
    3331/** creates and captures a bound disjunction constraint
    3332 *
    3333 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    3334 */
    3336 SCIP* scip, /**< SCIP data structure */
    3337 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    3338 const char* name, /**< name of constraint */
    3339 int nvars, /**< number of variables in the constraint */
    3340 SCIP_VAR** vars, /**< variables of the literals in the constraint */
    3341 SCIP_BOUNDTYPE* boundtypes, /**< types of bounds of the literals (lower or upper bounds) */
    3342 SCIP_Real* bounds, /**< bounds of the literals */
    3343 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    3344 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    3345 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    3346 * Usually set to TRUE. */
    3347 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    3348 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    3349 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    3350 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    3351 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    3352 * Usually set to TRUE. */
    3353 SCIP_Bool local, /**< is constraint only valid locally?
    3354 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    3355 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    3356 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    3357 * adds coefficients to this constraint. */
    3358 SCIP_Bool dynamic, /**< is constraint subject to aging?
    3359 * Usually set to FALSE. Set to TRUE for own cuts which
    3360 * are separated as constraints. */
    3361 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    3362 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    3363 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    3364 * if it may be moved to a more global node?
    3365 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    3366 )
    3367{
    3368 SCIP_CONSHDLR* conshdlr;
    3369 SCIP_CONSDATA* consdata;
    3370
    3371 assert(scip != NULL);
    3372
    3373 /* find the bounddisjunction constraint handler */
    3374 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    3375 if( conshdlr == NULL )
    3376 {
    3377 SCIPerrorMessage("bound disjunction constraint handler not found\n");
    3378 return SCIP_PLUGINNOTFOUND;
    3379 }
    3380
    3381#ifndef NDEBUG
    3382 {
    3383 int v1;
    3384 /* ensure that the given data neither contains overlapping nor redundant literals */
    3385 for( v1 = 0; v1 < nvars; v1++ )
    3386 {
    3387 int v2;
    3388
    3389 /* check that the bounds are sensible, i.e., not nan or inf */
    3390 assert( SCIPisFinite(bounds[v1]) );
    3391
    3392 for( v2 = v1+1; v2 < nvars; v2++ )
    3393 {
    3394 assert(vars[v1] != vars[v2] || (SCIPboundtypeOpposite(boundtypes[v1]) == boundtypes[v2]
    3395 && !isOverlapping(scip, vars[v1], boundtypes[v1], bounds[v1], boundtypes[v2], bounds[v2])));
    3396 }
    3397 }
    3398 }
    3399#endif
    3400
    3401 /* create the constraint specific data */
    3402 SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, boundtypes, bounds) );
    3403
    3404 /* create constraint */
    3405 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
    3406 local, modifiable, dynamic, removable, stickingatnode) );
    3407
    3408 return SCIP_OKAY;
    3409}
    3410
    3411/** creates and captures a bound disjunction constraint
    3412 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
    3413 * method SCIPcreateConsBounddisjunction(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
    3414 *
    3415 * @see SCIPcreateConsBounddisjunction() for information about the basic constraint flag configuration
    3416 *
    3417 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    3418 */
    3420 SCIP* scip, /**< SCIP data structure */
    3421 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    3422 const char* name, /**< name of constraint */
    3423 int nvars, /**< number of variables in the constraint */
    3424 SCIP_VAR** vars, /**< variables of the literals in the constraint */
    3425 SCIP_BOUNDTYPE* boundtypes, /**< types of bounds of the literals (lower or upper bounds) */
    3426 SCIP_Real* bounds /**< bounds of the literals */
    3427 )
    3428{
    3429 assert(scip != NULL);
    3430
    3431 SCIP_CALL( SCIPcreateConsBounddisjunction(scip, cons, name, nvars, vars, boundtypes, bounds,
    3433
    3434 return SCIP_OKAY;
    3435}
    3436
    3437/** creates and captures a bound disjunction constraint with possibly redundant literals
    3438 *
    3439 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    3440 */
    3442 SCIP* scip, /**< SCIP data structure */
    3443 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    3444 const char* name, /**< name of constraint */
    3445 int nvars, /**< number of variables in the constraint */
    3446 SCIP_VAR** vars, /**< variables of the literals in the constraint */
    3447 SCIP_BOUNDTYPE* boundtypes, /**< types of bounds of the literals (lower or upper bounds) */
    3448 SCIP_Real* bounds, /**< bounds of the literals */
    3449 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    3450 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    3451 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    3452 * Usually set to TRUE. */
    3453 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    3454 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    3455 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    3456 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    3457 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    3458 * Usually set to TRUE. */
    3459 SCIP_Bool local, /**< is constraint only valid locally?
    3460 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    3461 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    3462 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    3463 * adds coefficients to this constraint. */
    3464 SCIP_Bool dynamic, /**< is constraint subject to aging?
    3465 * Usually set to FALSE. Set to TRUE for own cuts which
    3466 * are separated as constraints. */
    3467 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    3468 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    3469 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    3470 * if it may be moved to a more global node?
    3471 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    3472 )
    3473{
    3474 SCIP_CONSHDLR* conshdlr;
    3475 SCIP_CONSDATA* consdata;
    3476
    3477 assert(scip != NULL);
    3478
    3479 /* find the bounddisjunction constraint handler */
    3480 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    3481 if( conshdlr == NULL )
    3482 {
    3483 SCIPerrorMessage("bound disjunction constraint handler not found\n");
    3484 return SCIP_PLUGINNOTFOUND;
    3485 }
    3486
    3487 /* create the constraint specific data */
    3488 SCIP_CALL( consdataCreateRedundant(scip, &consdata, nvars, vars, boundtypes, bounds) );
    3489
    3490 /* create constraint */
    3491 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
    3492 local, modifiable, dynamic, removable, stickingatnode) );
    3493
    3494 return SCIP_OKAY;
    3495}
    3496
    3497/** creates and captures a bound disjunction constraint with possibly redundant literals
    3498 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
    3499 * method SCIPcreateConsBounddisjunction(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
    3500 *
    3501 * @see SCIPcreateConsBounddisjunction() for information about the basic constraint flag configuration
    3502 *
    3503 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    3504 */
    3506 SCIP* scip, /**< SCIP data structure */
    3507 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    3508 const char* name, /**< name of constraint */
    3509 int nvars, /**< number of variables in the constraint */
    3510 SCIP_VAR** vars, /**< variables of the literals in the constraint */
    3511 SCIP_BOUNDTYPE* boundtypes, /**< types of bounds of the literals (lower or upper bounds) */
    3512 SCIP_Real* bounds /**< bounds of the literals */
    3513 )
    3514{
    3515 assert(scip != NULL);
    3516
    3517 SCIP_CALL( SCIPcreateConsBounddisjunctionRedundant(scip, cons, name, nvars, vars, boundtypes, bounds,
    3519
    3520 return SCIP_OKAY;
    3521}
    3522
    3523/** gets number of variables in bound disjunction constraint */ /*lint -e{715}*/
    3525 SCIP* scip, /**< SCIP data structure */
    3526 SCIP_CONS* cons /**< constraint data */
    3527 )
    3528{
    3529 SCIP_CONSDATA* consdata;
    3530
    3532
    3533 consdata = SCIPconsGetData(cons);
    3534 assert(consdata != NULL);
    3535
    3536 return consdata->nvars;
    3537}
    3538
    3539/** gets array of variables in bound disjunction constraint */ /*lint -e{715}*/
    3541 SCIP* scip, /**< SCIP data structure */
    3542 SCIP_CONS* cons /**< constraint data */
    3543 )
    3544{
    3545 SCIP_CONSDATA* consdata;
    3546
    3548
    3549 consdata = SCIPconsGetData(cons);
    3550 assert(consdata != NULL);
    3551
    3552 return consdata->vars;
    3553}
    3554
    3555/** gets array of bound types in bound disjunction constraint */ /*lint -e{715}*/
    3557 SCIP* scip, /**< SCIP data structure */
    3558 SCIP_CONS* cons /**< constraint data */
    3559 )
    3560{
    3561 SCIP_CONSDATA* consdata;
    3562
    3564
    3565 consdata = SCIPconsGetData(cons);
    3566 assert(consdata != NULL);
    3567
    3568 return consdata->boundtypes;
    3569}
    3570
    3571/** gets array of bounds in bound disjunction constraint */ /*lint -e{715}*/
    3573 SCIP* scip, /**< SCIP data structure */
    3574 SCIP_CONS* cons /**< constraint data */
    3575 )
    3576{
    3577 SCIP_CONSDATA* consdata;
    3578
    3580
    3581 consdata = SCIPconsGetData(cons);
    3582 assert(consdata != NULL);
    3583
    3584 return consdata->bounds;
    3585}
    static long bound
    SCIP_VAR * a
    Definition: circlepacking.c:66
    SCIP_VAR ** b
    Definition: circlepacking.c:65
    #define isFeasGE(scip, var, val1, val2)
    static SCIP_RETCODE applyGlobalBounds(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *redundant)
    static SCIP_Bool isConsViolated(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
    static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds)
    static SCIP_DECL_CONSCOPY(consCopyBounddisjunction)
    #define AGEINCREASE(n)
    #define CONSHDLR_NEEDSCONS
    static SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphBounddisjunction)
    #define CONFLICTHDLR_PRIORITY
    #define isFeasLT(scip, var, val1, val2)
    #define CONFLICTHDLR_NAME
    static SCIP_RETCODE removeFixedVariables(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *redundant)
    static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
    #define CONSHDLR_CHECKPRIORITY
    static SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphBounddisjunction)
    #define CONSHDLR_DESC
    static SCIP_DECL_CONSDEACTIVE(consDeactiveBounddisjunction)
    static SCIP_DECL_CONSLOCK(consLockBounddisjunction)
    static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons)
    static SCIP_RETCODE upgradeCons(SCIP *scip, SCIP_CONS *cons, int *ndelconss, int *naddconss)
    static SCIP_DECL_CONSGETVARS(consGetVarsBounddisjunction)
    #define CONSHDLR_PROP_TIMING
    static SCIP_DECL_EVENTEXEC(eventExecBounddisjunction)
    #define CONFLICTHDLR_DESC
    static SCIP_DECL_CONSENFOPS(consEnfopsBounddisjunction)
    static SCIP_DECL_CONSRESPROP(consRespropBounddisjunction)
    static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
    static SCIP_DECL_CONFLICTEXEC(conflictExecBounddisjunction)
    static SCIP_RETCODE enforceCurrentSol(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *cutoff, SCIP_Bool *infeasible, SCIP_Bool *reduceddom, SCIP_Bool *registeredbrcand)
    #define CONSHDLR_MAXPREROUNDS
    #define isFeasLE(scip, var, val1, val2)
    static SCIP_DECL_CONSPROP(consPropBounddisjunction)
    static SCIP_DECL_CONSEXITPRE(consExitpreBounddisjunction)
    static SCIP_DECL_CONSCHECK(consCheckBounddisjunction)
    static SCIP_DECL_CONSPARSE(consParseBounddisjunction)
    static void consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file, SCIP_Bool endline)
    #define DEFAULT_CONTINUOUSFRAC
    static SCIP_RETCODE addSymmetryInformation(SCIP *scip, SYM_SYMTYPE symtype, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
    static SCIP_Bool isLiteralViolated(SCIP *scip, SCIP_CONSDATA *consdata, int pos)
    static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, int pos)
    static SCIP_DECL_CONSENFOLP(consEnfolpBounddisjunction)
    static SCIP_RETCODE switchWatchedvars(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int watchedvar1, int watchedvar2)
    static SCIP_RETCODE dropEvents(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos, int filterpos)
    #define isFeasGT(scip, var, val1, val2)
    static SCIP_Bool isLiteralSatisfied(SCIP *scip, SCIP_CONSDATA *consdata, int pos)
    static void consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
    static SCIP_DECL_CONSINITSOL(consInitsolBounddisjunction)
    static SCIP_RETCODE consdataCreateRedundant(SCIP *scip, SCIP_CONSDATA **consdata, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds)
    #define CONSHDLR_PROPFREQ
    static SCIP_DECL_CONSTRANS(consTransBounddisjunction)
    static SCIP_DECL_CONSFREE(consFreeBounddisjunction)
    static SCIP_RETCODE createNAryBranch(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
    static SCIP_DECL_CONSPRESOL(consPresolBounddisjunction)
    #define CONSHDLR_PRESOLTIMING
    static SCIP_DECL_CONSDELETE(consDeleteBounddisjunction)
    static SCIP_RETCODE catchEvents(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos, int *filterpos)
    #define CONSHDLR_EAGERFREQ
    static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, int pos)
    static SCIP_DECL_CONSPRINT(consPrintBounddisjunction)
    #define EVENTHDLR_DESC
    static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
    static SCIP_RETCODE registerBranchingCandidates(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *cutoff, SCIP_Bool *neednarybranch)
    #define CONSHDLR_ENFOPRIORITY
    static SCIP_DECL_CONSENFORELAX(consEnforelaxBounddisjunction)
    static SCIP_RETCODE processWatchedVars(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *cutoff, SCIP_Bool *infeasible, SCIP_Bool *reduceddom, SCIP_Bool *mustcheck)
    static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, SCIP_SOL *sol, SCIP_RESULT *result)
    #define CONSHDLR_NAME
    static SCIP_DECL_CONFLICTFREE(conflictFreeBounddisjunction)
    #define EVENTHDLR_NAME
    static SCIP_RETCODE disableCons(SCIP *scip, SCIP_CONS *cons)
    static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_Real bound, SCIP_Bool *redundant)
    static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyBounddisjunction)
    static SCIP_DECL_CONSGETNVARS(consGetNVarsBounddisjunction)
    #define CONSHDLR_DELAYPROP
    static SCIP_DECL_CONSACTIVE(consActiveBounddisjunction)
    static SCIP_Bool isOverlapping(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype1, SCIP_Real bound1, SCIP_BOUNDTYPE boundtype2, SCIP_Real bound2)
    constraint handler for bound disjunction constraints
    Constraint handler for linear constraints in their most general form, .
    Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
    Constraint handler for the set partitioning / packing / covering constraints .
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_REAL_MAX
    Definition: def.h:167
    #define SCIP_Bool
    Definition: def.h:100
    #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 SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #define REALABS(x)
    Definition: def.h:191
    #define SCIP_LONGINT_MAX
    Definition: def.h:151
    #define SCIP_CALL(x)
    Definition: def.h:364
    power and signed power expression handlers
    variable expression handler
    SCIP_Real * SCIPgetBoundsBounddisjunction(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsBasicBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds)
    SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, 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)
    int SCIPgetNVarsBounddisjunction(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsBounddisjunctionRedundant(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, 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_BOUNDTYPE * SCIPgetBoundtypesBounddisjunction(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsSetpack(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_setppc.c:9551
    SCIP_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 SCIPcreateConsLogicor(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)
    SCIP_RETCODE SCIPcreateConsBasicBounddisjunctionRedundant(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds)
    SCIP_VAR ** SCIPgetVarsBounddisjunction(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPincludeConshdlrBounddisjunction(SCIP *scip)
    SCIP_Bool SCIPisConsCompressionEnabled(SCIP *scip)
    Definition: scip_copy.c:662
    SCIP_RETCODE SCIPgetVarCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR *sourcevar, SCIP_VAR **targetvar, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *success)
    Definition: scip_copy.c:713
    SCIP_RETCODE SCIPcreateExprVar(SCIP *scip, SCIP_EXPR **expr, SCIP_VAR *var, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr_var.c:397
    SCIP_RETCODE SCIPcreateExprPow(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_Real exponent, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr_pow.c:3186
    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 SCIPaddConsUpgrade(SCIP *scip, SCIP_CONS *oldcons, SCIP_CONS **newcons)
    Definition: scip_prob.c:3368
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3420
    SCIP_RETCODE SCIPdelConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons)
    Definition: scip_prob.c:4017
    SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
    Definition: scip_prob.c:3901
    SCIP_RETCODE SCIPaddConflict(SCIP *scip, SCIP_NODE *node, SCIP_CONS **cons, SCIP_NODE *validnode, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
    Definition: scip_prob.c:3806
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
    Definition: misc.c:11162
    SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:139
    void SCIPswapInts(int *value1, int *value2)
    Definition: misc.c:10485
    SCIP_Real SCIPcalcNodeselPriority(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdir, SCIP_Real targetvalue)
    Definition: scip_branch.c:928
    SCIP_RETCODE SCIPaddExternBranchCand(SCIP *scip, SCIP_VAR *var, SCIP_Real score, SCIP_Real solval)
    Definition: scip_branch.c:673
    SCIP_Real SCIPcalcChildEstimate(SCIP *scip, SCIP_VAR *var, SCIP_Real targetvalue)
    Definition: scip_branch.c:955
    SCIP_RETCODE SCIPcreateChild(SCIP *scip, SCIP_NODE **node, SCIP_Real nodeselprio, SCIP_Real estimate)
    Definition: scip_branch.c:1025
    SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
    Definition: lp.c:17597
    SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
    SCIP_CONFLICTHDLRDATA * SCIPconflicthdlrGetData(SCIP_CONFLICTHDLR *conflicthdlr)
    const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
    SCIP_RETCODE SCIPaddConflictBd(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx)
    SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
    SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
    SCIP_RETCODE SCIPincludeConflicthdlrBasic(SCIP *scip, SCIP_CONFLICTHDLR **conflicthdlrptr, const char *name, const char *desc, int priority, SCIP_DECL_CONFLICTEXEC((*conflictexec)), SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
    SCIP_RETCODE SCIPsetConflicthdlrFree(SCIP *scip, SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTFREE((*conflictfree)))
    SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
    Definition: scip_cons.c:808
    void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: cons.c:4350
    SCIP_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 SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
    Definition: scip_cons.c:281
    SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: scip_cons.c:181
    SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
    Definition: scip_cons.c:693
    SCIP_RETCODE SCIPsetConshdlrGetPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETPERMSYMGRAPH((*consgetpermsymgraph)))
    Definition: scip_cons.c:900
    SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
    Definition: scip_cons.c:578
    SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
    Definition: scip_cons.c:372
    SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
    Definition: scip_cons.c:323
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4320
    SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
    Definition: scip_cons.c:516
    SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
    Definition: scip_cons.c:347
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_RETCODE SCIPsetConshdlrGetSignedPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH((*consgetsignedpermsymgraph)))
    Definition: scip_cons.c:924
    SCIP_RETCODE 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 SCIPconsIsPropagationEnabled(SCIP_CONS *cons)
    Definition: cons.c:8511
    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
    int SCIPconsGetNUpgradeLocks(SCIP_CONS *cons)
    Definition: cons.c:8845
    SCIP_RETCODE SCIPenableConsPropagation(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1951
    int SCIPconsGetValidDepth(SCIP_CONS *cons)
    Definition: cons.c:8476
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8592
    SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
    Definition: cons.c:8522
    SCIP_Bool SCIPconsIsUpdatedeactivate(SCIP_CONS *cons)
    Definition: cons.c:8464
    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_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 SCIPdisableConsPropagation(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1981
    SCIP_RETCODE SCIPaddConsAge(SCIP *scip, SCIP_CONS *cons, SCIP_Real deltaage)
    Definition: scip_cons.c:1755
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8572
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8662
    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_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
    Definition: scip_expr.c:1443
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    SCIP_RETCODE SCIPaddNlRow(SCIP *scip, SCIP_NLROW *nlrow)
    Definition: scip_nlp.c:396
    SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
    Definition: scip_nlp.c:110
    SCIP_RETCODE SCIPreleaseNlRow(SCIP *scip, SCIP_NLROW **nlrow)
    Definition: scip_nlp.c:1058
    SCIP_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
    void SCIPupdateSolConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
    Definition: scip_sol.c:451
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    int SCIPgetNRuns(SCIP *scip)
    SCIP_Longint SCIPgetNConflictConssApplied(SCIP *scip)
    SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPparseReal(SCIP *scip, const char *str, SCIP_Real *value, char **endptr)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6401
    SCIP_RETCODE SCIPvarGetProbvarBound(SCIP_VAR **var, SCIP_Real *bound, SCIP_BOUNDTYPE *boundtype)
    Definition: var.c:17846
    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 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 SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
    Definition: var.c:23462
    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_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6088
    SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
    Definition: var.c:17595
    SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6651
    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
    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_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24961
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23522
    SCIP_Real SCIPcomputeVarLbGlobal(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:8375
    SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
    Definition: scip_var.c:2166
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    SCIP_Real SCIPcomputeVarLbLocal(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:8417
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    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 SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6044
    SCIP_Longint SCIPvarGetNBranchingsCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
    Definition: var.c:21825
    SCIP_Real SCIPcomputeVarUbGlobal(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:8396
    SCIP_BOUNDTYPE SCIPbdchginfoGetBoundtype(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24981
    SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:8462
    SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24951
    void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), 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 SCIPaddSymgraphEdge(SCIP *scip, SYM_GRAPH *graph, int first, int second, SCIP_Bool hasval, SCIP_Real val)
    SCIP_RETCODE SCIPaddSymgraphOpnode(SCIP *scip, SYM_GRAPH *graph, int op, int *nodeidx)
    SCIP_RETCODE SCIPgetSymActiveVariables(SCIP *scip, SYM_SYMTYPE symtype, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
    SCIP_RETCODE SCIPaddSymgraphValnode(SCIP *scip, SYM_GRAPH *graph, SCIP_Real val, int *nodeidx)
    SCIP_RETCODE SCIPaddSymgraphConsnode(SCIP *scip, SYM_GRAPH *graph, SCIP_CONS *cons, SCIP_Real lhs, SCIP_Real rhs, int *nodeidx)
    SCIP_RETCODE SCIPaddSymgraphVarAggregation(SCIP *scip, SYM_GRAPH *graph, int rootidx, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real constant)
    memory allocation routines
    #define BMScopyMemoryArray(ptr, source, num)
    Definition: memory.h:134
    public methods for conflict analysis handlers
    public methods for managing constraints
    public methods for managing events
    public methods for LP management
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugPrintCons(x, y, z)
    Definition: pub_message.h:102
    public data structures and miscellaneous methods
    #define SCIPisFinite(x)
    Definition: pub_misc.h:82
    public methods for problem variables
    public methods for branching rule plugins and branching
    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 event handler plugins and event handlers
    public functions to work with algebraic expressions
    general public methods
    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 querying solving statistics
    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_ConflicthdlrData SCIP_CONFLICTHDLRDATA
    Definition: type_conflict.h:50
    struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
    Definition: type_cons.h:64
    struct SCIP_ConsData SCIP_CONSDATA
    Definition: type_cons.h:65
    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
    #define SCIP_EVENTTYPE_BOUNDRELAXED
    Definition: type_event.h:126
    #define SCIP_EVENTTYPE_BOUNDTIGHTENED
    Definition: type_event.h:125
    #define SCIP_EVENTTYPE_LBTIGHTENED
    Definition: type_event.h:77
    #define SCIP_EVENTTYPE_UBRELAXED
    Definition: type_event.h:80
    @ SCIP_EXPRCURV_CONVEX
    Definition: type_expr.h:63
    @ SCIP_BRANCHDIR_DOWNWARDS
    Definition: type_history.h:43
    @ SCIP_BRANCHDIR_UPWARDS
    Definition: type_history.h:44
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_VERBLEVEL_MINIMAL
    Definition: type_message.h:59
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_FEASIBLE
    Definition: type_result.h:45
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_INFEASIBLE
    Definition: type_result.h:46
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ 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_CONSOPTYPE_BDDISJ
    Definition: type_symmetry.h:80
    @ SYM_CONSOPTYPE_SUM
    Definition: type_symmetry.h:83
    @ SYM_SYMTYPE_SIGNPERM
    Definition: type_symmetry.h:62
    @ SYM_SYMTYPE_PERM
    Definition: type_symmetry.h:61
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56