Scippy

    SCIP

    Solving Constraint Integer Programs

    cons_varbound.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file cons_varbound.c
    26 * @ingroup DEFPLUGINS_CONS
    27 * @brief Constraint handler for variable bound constraints \f$lhs \le x + c y \le rhs\f$.
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Michael Winkler
    31 * @author Gerald Gamrath
    32 * @author Stefan Heinz
    33 *
    34 * This constraint handler handles a special type of linear constraints, namely variable bound constraints.
    35 * A variable bound constraint has the form
    36 * \f[
    37 * lhs \leq x + c y \leq rhs
    38 * \f]
    39 * with coefficient \f$c \in Q\f$, \f$lhs\in Q \cup \{-\infty\}\f$, \f$rhs\in Q \cup \{\infty\}\f$,
    40 * and decision variables \f$x\f$ (non-binary) and \f$y\f$ (binary or integer).
    41 *
    42 * @note Although x must be non-binary when the constraint is created, it can happen that x is upgraded to a binary
    43 * variable, e.g. due to aggregations or bound changes in presolving.
    44 */
    45/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    46
    47#include <ctype.h>
    49#include "scip/cons_linear.h"
    50#include "scip/cons_setppc.h"
    51#include "scip/cons_varbound.h"
    52#include "scip/pub_cons.h"
    53#include "scip/pub_event.h"
    54#include "scip/pub_lp.h"
    55#include "scip/pub_message.h"
    56#include "scip/pub_misc.h"
    57#include "scip/pub_misc_sort.h"
    58#include "scip/pub_var.h"
    59#include "scip/scip_conflict.h"
    60#include "scip/scip_cons.h"
    61#include "scip/scip_cut.h"
    62#include "scip/scip_event.h"
    63#include "scip/scip_general.h"
    64#include "scip/scip_lp.h"
    65#include "scip/scip_mem.h"
    66#include "scip/scip_message.h"
    67#include "scip/scip_nlp.h"
    68#include "scip/scip_numerics.h"
    69#include "scip/scip_param.h"
    70#include "scip/scip_prob.h"
    71#include "scip/scip_probing.h"
    72#include "scip/scip_sol.h"
    73#include "scip/scip_tree.h"
    74#include "scip/scip_var.h"
    75#include "scip/dbldblarith.h"
    76#include "scip/symmetry_graph.h"
    78#include <ctype.h>
    79#include <string.h>
    80
    81
    82/**@name Constraint handler properties
    83 *
    84 * @{
    85 */
    86
    87/* constraint handler properties */
    88#define CONSHDLR_NAME "varbound"
    89#define CONSHDLR_DESC "variable bounds lhs <= x + c*y <= rhs, x non-binary, y non-continuous"
    90#define CONSHDLR_SEPAPRIORITY +900000 /**< priority of the constraint handler for separation */
    91#define CONSHDLR_ENFOPRIORITY -500000 /**< priority of the constraint handler for constraint enforcing */
    92#define CONSHDLR_CHECKPRIORITY -500000 /**< priority of the constraint handler for checking feasibility */
    93#define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
    94#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
    95#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
    96 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
    97#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
    98#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
    99#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    100#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
    101
    102#define CONSHDLR_PRESOLTIMING (SCIP_PRESOLTIMING_FAST | SCIP_PRESOLTIMING_MEDIUM)
    103#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
    104
    105#define EVENTHDLR_NAME "varbound"
    106#define EVENTHDLR_DESC "bound change event handler for variable bound constraints"
    107
    108#define LINCONSUPGD_PRIORITY +50000 /**< priority of the constraint handler for upgrading of linear constraints */
    109
    110/**@} */
    111
    112/**@name Default parameter values
    113 *
    114 * @{
    115 */
    116
    117#define DEFAULT_PRESOLPAIRWISE TRUE /**< should pairwise constraint comparison be performed in presolving? */
    118#define DEFAULT_MAXLPCOEF 1e+09 /**< maximum coefficient in varbound constraint to be added as a row into LP */
    119#define DEFAULT_USEBDWIDENING TRUE /**< should bound widening be used to initialize conflict analysis? */
    120
    121
    122#define MAXSCALEDCOEF 1000LL /**< maximal coefficient value after scaling */
    123
    124/**@} */
    125
    126/** variable bound constraint data */
    127struct SCIP_ConsData
    128{
    129 SCIP_Real vbdcoef; /**< coefficient c of bounding variable y */
    130 SCIP_Real lhs; /**< left hand side of variable bound inequality */
    131 SCIP_Real rhs; /**< right hand side of variable bound inequality */
    132 SCIP_VAR* var; /**< variable x that has variable bound */
    133 SCIP_VAR* vbdvar; /**< binary, integer or implicit integer bounding variable y */
    134 SCIP_ROW* row; /**< LP row, if constraint is already stored in LP row format */
    135 SCIP_NLROW* nlrow; /**< NLP row, if constraint has been added to NLP relaxation */
    136 unsigned int presolved:1; /**< is the variable bound constraint already presolved? */
    137 unsigned int varboundsadded:1; /**< are the globally valid variable bounds added? */
    138 unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
    139 unsigned int tightened:1; /**< were the vbdcoef and all sides already tightened? */
    140};
    141
    142/** constraint handler data */
    143struct SCIP_ConshdlrData
    144{
    145 SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
    146 SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
    147 SCIP_Real maxlpcoef; /**< maximum coefficient in varbound constraint to be added as a row into LP */
    148 SCIP_Bool usebdwidening; /**< should bound widening be used to in conflict analysis? */
    149};
    150
    151/** Propagation rules */
    153{
    154 PROPRULE_1, /**< left hand side and bounds on y -> lower bound on x */
    155 PROPRULE_2, /**< left hand side and upper bound on x -> bound on y */
    156 PROPRULE_3, /**< right hand side and bounds on y -> upper bound on x */
    157 PROPRULE_4 /**< right hand side and lower bound on x -> bound on y */
    159typedef enum Proprule PROPRULE;
    160
    161
    162/**@name Local methods
    163 *
    164 * @{
    165 */
    166
    167/** compares two varbound constraints cons1: \f$ lhs1 \le x1 + c1 y1 \le rhs1 \f$ and cons2: \f$ lhs2 \le x2 + c2 y2 \le rhs2 \f$
    168 * w.r.t. the indices of the contained variables
    169 *
    170 * returns -1 if:
    171 * - the index of x1 is smaller than the index of x2 or
    172 * - x1 = x2 and the index of y1 is smaller than the index of y2 or
    173 * - x1 = x2 and y1 = y2 and cons2 was recently changed, but cons1 not
    174 *
    175 * returns 0 if x1 = x2, y1 = y2, and the changed status of both constraints is the same
    176 *
    177 * and returns +1 otherwise
    178 */
    179static
    180SCIP_DECL_SORTPTRCOMP(consVarboundComp)
    181{
    182 SCIP_CONSDATA* consdata1;
    183 SCIP_CONSDATA* consdata2;
    184
    185 assert(elem1 != NULL);
    186 assert(elem2 != NULL);
    187
    188 consdata1 = SCIPconsGetData((SCIP_CONS*) elem1);
    189 consdata2 = SCIPconsGetData((SCIP_CONS*) elem2);
    190
    191 assert(consdata1 != NULL);
    192 assert(consdata2 != NULL);
    193
    194 /* comparison is done over 3 ordered criteria:
    195 * (i) variable index of variable 1
    196 * (ii) variable index of variable 2.
    197 * (iii) changed status
    198 */
    199 if( SCIPvarGetIndex(consdata1->var) < SCIPvarGetIndex(consdata2->var)
    200 || (SCIPvarGetIndex(consdata1->var) == SCIPvarGetIndex(consdata2->var)
    201 && SCIPvarGetIndex(consdata1->vbdvar) < SCIPvarGetIndex(consdata2->vbdvar))
    202 || (SCIPvarGetIndex(consdata1->var) == SCIPvarGetIndex(consdata2->var)
    203 && SCIPvarGetIndex(consdata1->vbdvar) == SCIPvarGetIndex(consdata2->vbdvar)
    204 && !consdata1->changed && consdata2->changed) )
    205 return -1;
    206 else if( SCIPvarGetIndex(consdata1->var) == SCIPvarGetIndex(consdata2->var)
    207 && SCIPvarGetIndex(consdata1->vbdvar) == SCIPvarGetIndex(consdata2->vbdvar)
    208 && (consdata1->changed == consdata2->changed) )
    209 return 0;
    210 else
    211 return +1;
    212}
    213
    214/** creates constraint handler data for varbound constraint handler */
    215static
    217 SCIP* scip, /**< SCIP data structure */
    218 SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
    219 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    220 )
    221{
    222 assert(scip != NULL);
    223 assert(conshdlrdata != NULL);
    224
    225 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
    226
    227 /* set event handler for bound change events */
    228 (*conshdlrdata)->eventhdlr = eventhdlr;
    229
    230 return SCIP_OKAY;
    231}
    232
    233/** frees constraint handler data for varbound constraint handler */
    234static
    236 SCIP* scip, /**< SCIP data structure */
    237 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
    238 )
    239{
    240 assert(scip != NULL);
    241 assert(conshdlrdata != NULL);
    242 assert(*conshdlrdata != NULL);
    243
    244 SCIPfreeBlockMemory(scip, conshdlrdata);
    245}
    246
    247/** catches events for variables
    248 *
    249 * @todo if lhs or rhs is infinite, catch only changes of the bound that could lead to propagation
    250 */
    251static
    253 SCIP* scip, /**< SCIP data structure */
    254 SCIP_CONS* cons, /**< variable bound constraint */
    255 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    256 )
    257{
    258 SCIP_CONSDATA* consdata;
    259 assert(cons != NULL);
    260 assert(eventhdlr != NULL);
    261 consdata = SCIPconsGetData(cons);
    262 assert(consdata != NULL);
    263
    266
    267 return SCIP_OKAY;
    268}
    269
    270/** drops events for variables */
    271static
    273 SCIP* scip, /**< SCIP data structure */
    274 SCIP_CONS* cons, /**< variable bound constraint */
    275 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    276 )
    277{
    278 SCIP_CONSDATA* consdata;
    279 assert(cons != NULL);
    280 assert(eventhdlr != NULL);
    281 consdata = SCIPconsGetData(cons);
    282 assert(consdata != NULL);
    283
    286
    287 return SCIP_OKAY;
    288}
    289
    290/** creates a variable bound constraint data object */
    291static
    293 SCIP* scip, /**< SCIP data structure */
    294 SCIP_CONSDATA** consdata, /**< pointer to store the variable bound constraint data */
    295 SCIP_VAR* var, /**< variable x that has variable bound */
    296 SCIP_VAR* vbdvar, /**< binary, integer or implicit integer bounding variable y */
    297 SCIP_Real vbdcoef, /**< coefficient c of bounding variable y */
    298 SCIP_Real lhs, /**< left hand side of variable bound inequality */
    299 SCIP_Real rhs /**< right hand side of variable bound inequality */
    300 )
    301{
    302 assert(consdata != NULL);
    303 assert(SCIPvarIsIntegral(vbdvar));
    304
    305 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
    306
    307 if( SCIPisInfinity(scip, rhs) )
    308 rhs = SCIPinfinity(scip);
    309 else if( SCIPisInfinity(scip, -rhs) )
    310 rhs = -SCIPinfinity(scip);
    311
    312 if( SCIPisInfinity(scip, -lhs) )
    313 lhs = -SCIPinfinity(scip);
    314 else if( SCIPisInfinity(scip, lhs) )
    315 lhs = SCIPinfinity(scip);
    316
    317 if( SCIPisGT(scip, lhs, rhs) )
    318 {
    319 SCIPerrorMessage("left hand side of varbound constraint greater than right hand side\n");
    320 SCIPerrorMessage(" -> lhs=%g, rhs=%g\n", lhs, rhs);
    321 return SCIP_INVALIDDATA;
    322 }
    323
    324 if( SCIPisZero(scip, vbdcoef) )
    325 {
    326 SCIPerrorMessage("varbound coefficient must be different to zero.\n");
    327 return SCIP_INVALIDDATA;
    328 }
    329
    330 if( SCIPisInfinity(scip, vbdcoef) )
    331 vbdcoef = SCIPinfinity(scip);
    332 else if( SCIPisInfinity(scip, -vbdcoef) )
    333 vbdcoef = -SCIPinfinity(scip);
    334
    335 (*consdata)->var = var;
    336 (*consdata)->vbdvar = vbdvar;
    337 (*consdata)->vbdcoef = vbdcoef;
    338 (*consdata)->lhs = lhs;
    339 (*consdata)->rhs = rhs;
    340 (*consdata)->row = NULL;
    341 (*consdata)->nlrow = NULL;
    342 (*consdata)->presolved = FALSE;
    343 (*consdata)->varboundsadded = FALSE;
    344 (*consdata)->changed = TRUE;
    345 (*consdata)->tightened = FALSE;
    346
    347 /* if we are in the transformed problem, get transformed variables, add variable bound information, and catch events */
    349 {
    350 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->var, &(*consdata)->var) );
    351 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->vbdvar, &(*consdata)->vbdvar) );
    352
    353#ifndef NDEBUG
    354 assert(SCIPvarGetStatus(SCIPvarGetProbvar((*consdata)->var)) != SCIP_VARSTATUS_MULTAGGR);
    355 assert(SCIPvarGetStatus(SCIPvarGetProbvar((*consdata)->vbdvar)) != SCIP_VARSTATUS_MULTAGGR);
    356#endif
    357 }
    358
    359 /* capture variables */
    360 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->var) );
    361 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vbdvar) );
    362
    363 return SCIP_OKAY;
    364}
    365
    366/** frees a variable bound constraint data */
    367static
    369 SCIP* scip, /**< SCIP data structure */
    370 SCIP_CONSDATA** consdata /**< pointer to the variable bound constraint */
    371 )
    372{
    373 assert(consdata != NULL);
    374 assert(*consdata != NULL);
    375
    376 /* release the row */
    377 if( (*consdata)->row != NULL )
    378 {
    379 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row) );
    380 }
    381
    382 /* release the nlrow */
    383 if( (*consdata)->nlrow != NULL )
    384 {
    385 SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow) );
    386 }
    387
    388 /* release variables */
    389 SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->var) );
    390 SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->vbdvar) );
    391
    392 SCIPfreeBlockMemory(scip, consdata);
    393
    394 return SCIP_OKAY;
    395}
    396
    397/** creates LP row corresponding to variable bound constraint */
    398static
    400 SCIP* scip, /**< SCIP data structure */
    401 SCIP_CONS* cons /**< variable bound constraint */
    402 )
    403{
    404 SCIP_CONSDATA* consdata;
    405
    406 consdata = SCIPconsGetData(cons);
    407 assert(consdata != NULL);
    408 assert(consdata->row == NULL);
    409
    410 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, cons, SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
    412 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, consdata->var, 1.0) );
    413 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, consdata->vbdvar, consdata->vbdcoef) );
    414
    415 return SCIP_OKAY;
    416}
    417
    418/** adds linear relaxation of variable bound constraint to the LP */
    419static
    421 SCIP* scip, /**< SCIP data structure */
    422 SCIP_CONS* cons, /**< variable bound constraint */
    423 SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
    424 )
    425{
    426 SCIP_CONSHDLR* conshdlr;
    427 SCIP_CONSHDLRDATA* conshdlrdata;
    428 SCIP_CONSDATA* consdata;
    429
    430 consdata = SCIPconsGetData(cons);
    431 assert(consdata != NULL);
    432
    433 /* find the variable bound constraint handler */
    435 if( conshdlr == NULL )
    436 {
    437 SCIPerrorMessage("variable bound constraint handler not found\n");
    438 return SCIP_PLUGINNOTFOUND;
    439 }
    440
    441 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    442 assert(conshdlrdata != NULL);
    443
    444 assert(SCIPvarIsIntegral(consdata->vbdvar));
    445
    446 /* check whether the coefficient is too large to put the row into the LP */
    447 if( SCIPisGT(scip, REALABS(consdata->vbdcoef), conshdlrdata->maxlpcoef) )
    448 return SCIP_OKAY;
    449
    450 if( consdata->row == NULL )
    451 {
    453 }
    454 assert(consdata->row != NULL);
    455
    456 if( !SCIProwIsInLP(consdata->row) )
    457 {
    458 SCIPdebugMsg(scip, "adding relaxation of variable bound constraint <%s>: ", SCIPconsGetName(cons));
    459 SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->row, NULL)) );
    460 SCIP_CALL( SCIPaddRow(scip, consdata->row, FALSE, infeasible) );
    461 }
    462
    463 return SCIP_OKAY;
    464}
    465
    466/** adds varbound constraint as row to the NLP, if not added yet */
    467static
    469 SCIP* scip, /**< SCIP data structure */
    470 SCIP_CONS* cons /**< varbound constraint */
    471 )
    472{
    473 SCIP_CONSDATA* consdata;
    474
    475 assert(SCIPisNLPConstructed(scip));
    476
    477 /* skip deactivated, redundant, or local constraints (the NLP does not allow for local rows at the moment) */
    478 if( !SCIPconsIsActive(cons) || !SCIPconsIsChecked(cons) || SCIPconsIsLocal(cons) )
    479 return SCIP_OKAY;
    480
    481 consdata = SCIPconsGetData(cons);
    482 assert(consdata != NULL);
    483
    484 if( consdata->nlrow == NULL )
    485 {
    486 SCIP_VAR* vars[2];
    487 SCIP_Real coefs[2];
    488
    489 assert(consdata->lhs <= consdata->rhs);
    490
    491 vars[0] = consdata->var;
    492 vars[1] = consdata->vbdvar;
    493
    494 coefs[0] = 1.0;
    495 coefs[1] = consdata->vbdcoef;
    496
    497 SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow, SCIPconsGetName(cons),
    498 0.0, 2, vars, coefs, NULL, consdata->lhs, consdata->rhs, SCIP_EXPRCURV_LINEAR) );
    499
    500 assert(consdata->nlrow != NULL);
    501 }
    502
    503 if( !SCIPnlrowIsInNLP(consdata->nlrow) )
    504 {
    505 SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow) );
    506 }
    507
    508 return SCIP_OKAY;
    509}
    510
    511/** returns whether the given solution is feasible for the given variable bound constraint */
    512static
    514 SCIP* scip, /**< SCIP data structure */
    515 SCIP_CONS* cons, /**< variable bound constraint */
    516 SCIP_SOL* sol, /**< solution to check, NULL for current solution */
    517 SCIP_Bool checklprows /**< Do constraints represented by rows in the current LP have to be checked? */
    518 )
    519{
    520 SCIP_CONSDATA* consdata;
    521 SCIP_Real absviol;
    522 SCIP_Real relviol;
    523
    524 consdata = SCIPconsGetData(cons);
    525 assert(consdata != NULL);
    526
    527 SCIPdebugMsg(scip, "checking variable bound constraint <%s> for feasibility of solution %p (lprows=%u)\n",
    528 SCIPconsGetName(cons), (void*)sol, checklprows);
    529
    530 if( checklprows || consdata->row == NULL || !SCIProwIsInLP(consdata->row) )
    531 {
    532 SCIP_Real sum;
    533 SCIP_Real lhsrelviol;
    534 SCIP_Real rhsrelviol;
    535
    536 sum = SCIPgetSolVal(scip, sol, consdata->var) + consdata->vbdcoef * SCIPgetSolVal(scip, sol, consdata->vbdvar);
    537
    538 /* calculate constraint violation and update it in solution */
    539 absviol = MAX(consdata->lhs - sum, sum - consdata->rhs);
    540 lhsrelviol = SCIPrelDiff(consdata->lhs, sum);
    541 rhsrelviol = SCIPrelDiff(sum, consdata->rhs);
    542 relviol = MAX(lhsrelviol, rhsrelviol);
    543 if( sol != NULL )
    544 SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
    545
    546 return (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasGE(scip, sum, consdata->lhs))
    547 && (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasLE(scip, sum, consdata->rhs));
    548 }
    549 else
    550 return TRUE;
    551}
    552
    553
    554/** resolves a propagation on the given variable by supplying the variables needed for applying the corresponding
    555 * propagation rule (see propagateCons()):
    556 * (1) left hand side and bounds on y -> lower bound on x
    557 * (2) left hand side and upper bound on x -> bound on y
    558 * (3) right hand side and bounds on y -> upper bound on x
    559 * (4) right hand side and lower bound on x -> bound on y
    560 */
    561static
    563 SCIP* scip, /**< SCIP data structure */
    564 SCIP_CONS* cons, /**< constraint that inferred the bound change */
    565 SCIP_VAR* infervar, /**< variable that was deduced */
    566 PROPRULE proprule, /**< propagation rule that deduced the bound change */
    567 SCIP_BOUNDTYPE boundtype, /**< the type of the changed bound (lower or upper bound) */
    568 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
    569 SCIP_Real inferbd, /**< inference bound which needs to be explained */
    570 SCIP_Bool usebdwidening /**< should bound widening be used to in conflict analysis? */
    571 )
    572{
    573 SCIP_CONSDATA* consdata;
    574 SCIP_VAR* vbdvar;
    575 SCIP_VAR* var;
    576 SCIP_Real vbdcoef;
    577
    578 consdata = SCIPconsGetData(cons);
    579 assert(consdata != NULL);
    580 assert(!SCIPisZero(scip, consdata->vbdcoef));
    581
    582 var = consdata->var;
    583 assert(var != NULL);
    584
    585 vbdvar = consdata->vbdvar;
    586 assert(vbdvar != NULL);
    587
    588 vbdcoef = consdata->vbdcoef;
    589 assert(!SCIPisZero(scip, vbdcoef));
    590
    591 switch( proprule )
    592 {
    593 case PROPRULE_1:
    594 /* lhs <= x + c*y: left hand side and bounds on y -> lower bound on x */
    595 assert(infervar == var);
    596 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
    597 assert(!SCIPisInfinity(scip, -consdata->lhs));
    598
    599 if( usebdwidening )
    600 {
    601 SCIP_Real QUAD(relaxedbd);
    602
    603 /* For integer variables, we can reduce the inferbound by 1 - z * eps, because this will be adjusted
    604 * to the bound we need; however, we need to choose z large enough to prevent numerical troubles due to
    605 * too small and too large vbdcoef values.
    606 * If inferbound has a large value, adding z*eps might be lost due to fixed precision floating point
    607 * arithmetics, so we explicitly check this here.
    608 */
    609 if( SCIPvarIsIntegral(var) && inferbd < SCIPgetHugeValue(scip) * SCIPfeastol(scip)
    610 && REALABS(consdata->lhs) < SCIPgetHugeValue(scip) * SCIPfeastol(scip) )
    611 {
    612 SCIP_Real QUAD(tmp);
    613
    614 QUAD_ASSIGN(tmp, 2.0);
    616
    617 SCIPquadprecSumDD(relaxedbd, inferbd, -1.0);
    618
    619 SCIPquadprecSumQQ(relaxedbd, relaxedbd, tmp);
    620 SCIPquadprecSumQD(relaxedbd, -relaxedbd, consdata->lhs);
    621
    622 SCIPquadprecDivQD(relaxedbd, relaxedbd, vbdcoef);
    623 }
    624 else
    625 {
    626 SCIPquadprecSumDD(relaxedbd, consdata->lhs, -inferbd);
    627 SCIPquadprecDivQD(relaxedbd, relaxedbd, vbdcoef);
    628 }
    629
    630#ifndef NDEBUG
    631 {
    632 /* check the computed relaxed lower/upper bound is a proper reason for the inference bound which has to be explained */
    633 SCIP_Real QUAD(tmp);
    634
    635 SCIPquadprecProdQD(tmp, relaxedbd, vbdcoef);
    636 SCIPquadprecSumQD(tmp, -tmp, consdata->lhs);
    637
    638 assert(SCIPisEQ(scip, inferbd, SCIPadjustedVarLb(scip, var, QUAD_TO_DBL(tmp))));
    639 }
    640#endif
    641 if( vbdcoef > 0.0 )
    642 {
    643 /* decrease the computed relaxed upper bound by an epsilon; this ensures that we get the actual
    644 * inference bound due to the integrality condition of the variable bound variable
    645 */
    646 SCIPquadprecSumQD(relaxedbd, relaxedbd, -SCIPfeastol(scip));
    647 SCIP_CALL( SCIPaddConflictRelaxedUb(scip, vbdvar, bdchgidx, QUAD_TO_DBL(relaxedbd)) );
    648 }
    649 else
    650 {
    651 /* increase the computed relaxed lower bound by an epsilon; this ensures that we get the actual inference
    652 * bound due to the integrality condition of the variable bound variable
    653 */
    654 SCIPquadprecSumQD(relaxedbd, relaxedbd, SCIPfeastol(scip));
    655 SCIP_CALL( SCIPaddConflictRelaxedLb(scip, vbdvar, bdchgidx, QUAD_TO_DBL(relaxedbd)) );
    656 }
    657 }
    658 else
    659 {
    660 if( vbdcoef > 0.0 )
    661 {
    662 SCIP_CALL( SCIPaddConflictUb(scip, vbdvar, bdchgidx) );
    663 }
    664 else
    665 {
    666 SCIP_CALL( SCIPaddConflictLb(scip, vbdvar, bdchgidx) );
    667 }
    668 }
    669
    670 break;
    671
    672 case PROPRULE_2:
    673 /* lhs <= x + c*y: left hand side and upper bound on x -> bound on y */
    674 assert(infervar == vbdvar);
    675 assert(SCIPvarIsIntegral(vbdvar));
    676 assert(!SCIPisInfinity(scip, -consdata->lhs));
    677
    678 if( usebdwidening )
    679 {
    680 SCIP_Real QUAD(relaxedub);
    681
    682 /* compute the relaxed upper bound of the variable which would be sufficient to reach one less (greater) than the
    683 * inference bound
    684 */
    685 if( vbdcoef > 0.0 )
    686 {
    687 /* For integer variables, we can reduce the inferbound by 1-z*eps, because this will be adjusted
    688 * to the bound we need; however, we need to choose z large enough to prevent numerical troubles due to
    689 * too small and too large vbdcoef values.
    690 * If inferbound has a large value, adding z*eps might be lost due to fixed precision floating point
    691 * arithmetics, so we explicitly check this here.
    692 */
    693 if( SCIPvarIsIntegral(var) && inferbd < SCIPgetHugeValue(scip) * SCIPfeastol(scip)
    694 && REALABS(consdata->rhs) < SCIPgetHugeValue(scip) * SCIPfeastol(scip) )
    695 {
    696 SCIP_Real QUAD(tmp);
    697
    698 QUAD_ASSIGN(tmp, 2.0);
    700
    701 SCIPquadprecSumDD(relaxedub, inferbd, -1.0);
    702
    703 SCIPquadprecSumQQ(relaxedub, relaxedub, tmp);
    704 SCIPquadprecProdQD(relaxedub, relaxedub, vbdcoef);
    705
    706 SCIPquadprecSumQD(relaxedub, -relaxedub, consdata->lhs);
    707 }
    708 else
    709 {
    710 SCIPquadprecProdDD(relaxedub, inferbd, vbdcoef);
    711 SCIPquadprecSumQD(relaxedub, -relaxedub, consdata->lhs);
    712 }
    713
    714#ifndef NDEBUG
    715 {
    716 /* check the computed relaxed upper bound is a proper reason for the inference bound which has to be explained */
    717 SCIP_Real QUAD(tmp);
    718
    719 SCIPquadprecSumQD(tmp, -relaxedub, consdata->lhs);
    720 SCIPquadprecDivQD(tmp, tmp, vbdcoef);
    721
    722 assert(SCIPisEQ(scip, inferbd, SCIPadjustedVarLb(scip, vbdvar, QUAD_TO_DBL(tmp))));
    723 }
    724#endif
    725 }
    726 else
    727 {
    728 /* For integer variables, we can reduce the inferbound by 1-z*eps, because this will be adjusted
    729 * to the bound we need; however, we need to choose z large enough to prevent numerical troubles due to
    730 * too small and too large vbdcoef values.
    731 * If inferbound has a large value, adding z*eps might be lost due to fixed precision floating point
    732 * arithmetics, so we explicitly check this here.
    733 */
    734 if( SCIPvarIsIntegral(var) && inferbd < SCIPgetHugeValue(scip) * SCIPfeastol(scip)
    735 && REALABS(consdata->lhs) < SCIPgetHugeValue(scip) * SCIPfeastol(scip) )
    736 {
    737 SCIP_Real QUAD(tmp);
    738
    739 QUAD_ASSIGN(tmp, 2.0);
    741
    742 SCIPquadprecSumDD(relaxedub, inferbd, 1.0);
    743
    744 SCIPquadprecSumQQ(relaxedub, relaxedub, -tmp);
    745 SCIPquadprecProdQD(relaxedub, relaxedub, vbdcoef);
    746
    747 SCIPquadprecSumQD(relaxedub, -relaxedub, consdata->lhs);
    748 }
    749 else
    750 {
    751 SCIPquadprecProdDD(relaxedub, inferbd, vbdcoef);
    752 SCIPquadprecSumQD(relaxedub, -relaxedub, consdata->lhs);
    753 }
    754
    755#ifndef NDEBUG
    756 {
    757 /* check the computed relaxed upper bound is a proper reason for the inference bound which has to be explained */
    758 SCIP_Real QUAD(tmp);
    759
    760 SCIPquadprecSumQD(tmp, -relaxedub, consdata->lhs);
    761 SCIPquadprecDivQD(tmp, tmp, vbdcoef);
    762
    763 assert(SCIPisEQ(scip, inferbd, SCIPadjustedVarUb(scip, vbdvar, QUAD_TO_DBL(tmp))));
    764 }
    765#endif
    766 }
    767
    768 /* decrease the computed relaxed upper bound by an epsilon; this ensures that we get the actual inference bound due
    769 * to the integrality condition of the variable bound variable
    770 */
    771 SCIPquadprecSumQD(relaxedub, relaxedub, -SCIPfeastol(scip));
    772 SCIP_CALL( SCIPaddConflictRelaxedUb(scip, var, bdchgidx, QUAD_TO_DBL(relaxedub)) );
    773 }
    774 else
    775 {
    776 SCIP_CALL( SCIPaddConflictUb(scip, var, bdchgidx) );
    777 }
    778
    779 break;
    780
    781 case PROPRULE_3:
    782 /* x + c*y <= rhs: right hand side and bounds on y -> upper bound on x */
    783 assert(infervar == var);
    784 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
    785 assert(!SCIPisInfinity(scip, consdata->rhs));
    786
    787 if( usebdwidening )
    788 {
    789 SCIP_Real QUAD(relaxedbd);
    790
    791 /* For integer variables, we can reduce the inferbound by 1-z*eps, because this will be adjusted
    792 * to the bound we need; however, we need to choose z large enough to prevent numerical troubles due to
    793 * too small and too large vbdcoef values.
    794 * If inferbound has a large value, adding z*eps might be lost due to fixed precision floating point
    795 * arithmetics, so we explicitly check this here.
    796 */
    797 if( SCIPvarIsIntegral(var) && inferbd < SCIPgetHugeValue(scip) * SCIPfeastol(scip)
    798 && REALABS(consdata->rhs) < SCIPgetHugeValue(scip) * SCIPfeastol(scip) )
    799 {
    800 SCIP_Real QUAD(tmp);
    801
    802 QUAD_ASSIGN(tmp, 2.0);
    803
    805 SCIPquadprecSumDD(relaxedbd, inferbd, 1.0);
    806
    807 SCIPquadprecSumQQ(relaxedbd, relaxedbd, -tmp);
    808 SCIPquadprecSumQD(relaxedbd, relaxedbd, -consdata->rhs);
    809
    810 SCIPquadprecDivQD(relaxedbd, relaxedbd, -vbdcoef);
    811 }
    812 else
    813 {
    814 SCIPquadprecSumDD(relaxedbd, consdata->rhs, -inferbd);
    815 SCIPquadprecDivQD(relaxedbd, relaxedbd, vbdcoef);
    816 }
    817#ifndef NDEBUG
    818 {
    819 /* check the computed relaxed lower/upper bound is a proper reason for the inference bound which has to be explained */
    820 SCIP_Real QUAD(tmp);
    821
    822 SCIPquadprecProdQD(tmp, relaxedbd, -vbdcoef);
    823 SCIPquadprecSumQD(tmp, tmp, consdata->rhs);
    824
    825 assert(SCIPisEQ(scip, inferbd, SCIPadjustedVarUb(scip, var, QUAD_TO_DBL(tmp))));
    826 }
    827#endif
    828 if( vbdcoef > 0.0 )
    829 {
    830 /* increase the computed relaxed lower bound by an epsilon; this ensures that we get the actual inference bound due
    831 * to the integrality condition of the variable bound variable
    832 */
    833 SCIPquadprecSumQD(relaxedbd, relaxedbd, SCIPfeastol(scip));
    834 SCIP_CALL( SCIPaddConflictRelaxedLb(scip, vbdvar, bdchgidx, QUAD_TO_DBL(relaxedbd)) );
    835 }
    836 else
    837 {
    838 /* decrease the computed relaxed upper bound by an epsilon; this ensures that we get the actual inference bound due
    839 * to the integrality condition of the variable bound variable
    840 */
    841 SCIPquadprecSumQD(relaxedbd, relaxedbd, -SCIPfeastol(scip));
    842 SCIP_CALL( SCIPaddConflictRelaxedUb(scip, vbdvar, bdchgidx, QUAD_TO_DBL(relaxedbd)) );
    843 }
    844 }
    845 else
    846 {
    847 if( vbdcoef > 0.0 )
    848 {
    849 SCIP_CALL( SCIPaddConflictLb(scip, vbdvar, bdchgidx) );
    850 }
    851 else
    852 {
    853 SCIP_CALL( SCIPaddConflictUb(scip, vbdvar, bdchgidx) );
    854 }
    855 }
    856
    857 break;
    858
    859 case PROPRULE_4:
    860 /* x + c*y <= rhs: right hand side and lower bound on x -> bound on y */
    861 assert(infervar == vbdvar);
    862 assert(SCIPvarIsIntegral(vbdvar));
    863 assert(!SCIPisInfinity(scip, consdata->rhs));
    864
    865 if( usebdwidening )
    866 {
    867 SCIP_Real QUAD(relaxedlb);
    868
    869 /* compute the relaxed lower bound of the variable which would be sufficient to reach one greater (less) than the
    870 * inference bound
    871 */
    872 if( vbdcoef > 0.0 )
    873 {
    874 /* For integer variables, we can reduce the inferbound by 1-z*eps, because this will be adjusted
    875 * to the bound we need; however, we need to choose z large enough to prevent numerical troubles due to
    876 * too small and too large vbdcoef values.
    877 * If inferbound has a large value, adding z*eps might be lost due to fixed precision floating point
    878 * arithmetics, so we explicitly check this here.
    879 */
    880 if( SCIPvarIsIntegral(var) && inferbd < SCIPgetHugeValue(scip) * SCIPfeastol(scip)
    881 && REALABS(consdata->rhs) < SCIPgetHugeValue(scip) * SCIPfeastol(scip) )
    882 {
    883 SCIP_Real QUAD(tmp);
    884
    885 QUAD_ASSIGN(tmp, 2.0);
    887
    888 SCIPquadprecSumDD(relaxedlb, inferbd, 1.0);
    889 SCIPquadprecSumQQ(relaxedlb, relaxedlb, -tmp);
    890
    891 SCIPquadprecProdQD(relaxedlb, relaxedlb, vbdcoef);
    892
    893 SCIPquadprecSumQD(relaxedlb, -relaxedlb, consdata->rhs);
    894 }
    895 else
    896 {
    897 SCIPquadprecProdDD(relaxedlb, inferbd, vbdcoef);
    898 SCIPquadprecSumQD(relaxedlb, -relaxedlb, consdata->rhs);
    899 }
    900#ifndef NDEBUG
    901 {
    902 /* check the computed relaxed lower bound is a proper reason for the inference bound which has to be explained */
    903
    904 SCIP_Real QUAD(tmp);
    905
    906 QUAD_ASSIGN(tmp, consdata->rhs);
    907 SCIPquadprecSumQQ(tmp, tmp, -relaxedlb);
    908 SCIPquadprecDivQD(tmp, tmp, vbdcoef);
    909
    910 assert(SCIPisEQ(scip, inferbd, SCIPadjustedVarUb(scip, vbdvar, QUAD_TO_DBL(tmp))));
    911 }
    912#endif
    913 }
    914 else
    915 {
    916 /* For integer variables, we can reduce the inferbound by 1-z*eps, because this will be adjusted
    917 * to the bound we need; however, we need to choose z large enough to prevent numerical troubles due to
    918 * too small and too large vbdcoef values.
    919 * If inferbound has a large value, adding z*eps might be lost due to fixed precision floating point
    920 * arithmetics, so we explicitly check this here.
    921 */
    922 if( SCIPvarIsIntegral(var) && inferbd < SCIPgetHugeValue(scip) * SCIPfeastol(scip)
    923 && REALABS(consdata->lhs) < SCIPgetHugeValue(scip) * SCIPfeastol(scip) )
    924 {
    925 SCIP_Real QUAD(tmp);
    926
    927 QUAD_ASSIGN(tmp, 2.0);
    929
    930 SCIPquadprecSumDD(relaxedlb, inferbd, -1.0);
    931 SCIPquadprecSumQQ(relaxedlb, relaxedlb, tmp);
    932
    933 SCIPquadprecProdQD(relaxedlb, relaxedlb, vbdcoef);
    934
    935 SCIPquadprecSumQD(relaxedlb, -relaxedlb, consdata->rhs);
    936 }
    937 else
    938 {
    939 SCIPquadprecProdDD(relaxedlb, inferbd, vbdcoef);
    940 SCIPquadprecSumQD(relaxedlb, -relaxedlb, consdata->rhs);
    941 }
    942
    943#ifndef NDEBUG
    944 {
    945 /* check the computed relaxed lower bound is a proper reason for the inference bound which has to be explained */
    946
    947 SCIP_Real QUAD(tmp);
    948
    949 QUAD_ASSIGN(tmp, consdata->rhs);
    950 SCIPquadprecSumQQ(tmp, tmp, -relaxedlb);
    951 SCIPquadprecDivQD(tmp, tmp, vbdcoef);
    952
    953 assert(SCIPisEQ(scip, inferbd, SCIPadjustedVarLb(scip, vbdvar, QUAD_TO_DBL(tmp))));
    954 }
    955#endif
    956 }
    957
    958 /* increase the computed relaxed lower bound by an epsilon; this ensures that we get the actual inference bound due
    959 * to the integrality condition of the variable bound variable
    960 */
    961 SCIPquadprecSumQD(relaxedlb, relaxedlb, SCIPfeastol(scip));
    962 SCIP_CALL( SCIPaddConflictRelaxedLb(scip, var, bdchgidx, QUAD_TO_DBL(relaxedlb)) );
    963 }
    964 else
    965 {
    966 SCIP_CALL( SCIPaddConflictLb(scip, var, bdchgidx) );
    967 }
    968
    969 break;
    970
    971 default:
    972 SCIPerrorMessage("invalid inference information %d in variable bound constraint <%s>\n", proprule, SCIPconsGetName(cons));
    973 return SCIP_INVALIDDATA;
    974 }
    975
    976 return SCIP_OKAY;
    977}
    978
    979/** analyze infeasibility */
    980static
    982 SCIP* scip, /**< SCIP data structure */
    983 SCIP_CONS* cons, /**< variable bound constraint */
    984 SCIP_VAR* infervar, /**< variable that was deduced */
    985 SCIP_Real inferbd, /**< bound which led to infeasibility */
    986 PROPRULE proprule, /**< propagation rule that deduced the bound change */
    987 SCIP_BOUNDTYPE boundtype, /**< the type of the changed bound (lower or upper bound) */
    988 SCIP_Bool usebdwidening /**< should bound widening be used to in conflict analysis? */
    989 )
    990{
    991 /* conflict analysis can only be applied in solving stage and if it is applicable */
    993 return SCIP_OKAY;
    994
    995 /* initialize conflict analysis, and add all variables of infeasible constraint to conflict candidate queue */
    997
    998 /* add the bound which got violated */
    999 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    1000 {
    1001 if( usebdwidening )
    1002 {
    1003 SCIP_Real relaxedub;
    1004
    1005 /* adjust lower bound */
    1006 inferbd = SCIPadjustedVarLb(scip, infervar, inferbd);
    1007
    1008 /* compute a relaxed upper bound which would be sufficient to be still infeasible */
    1009 if( SCIPvarIsIntegral(infervar) )
    1010 relaxedub = inferbd - 1.0;
    1011 else
    1012 {
    1013 SCIP_CONSDATA* consdata;
    1014 SCIP_Real abscoef;
    1015
    1016 consdata = SCIPconsGetData(cons);
    1017 assert(consdata != NULL);
    1018
    1019 /* vbdvar can never be of non-integral type */
    1020 assert(infervar == consdata->var);
    1021
    1022 abscoef = REALABS(consdata->vbdcoef);
    1023
    1024 /* due to resolving a the propagation and dividing by the vbdcoef we need to make sure the the relaxed bound
    1025 * is big enough, therefore we multiply here with the vbdcoef
    1026 *
    1027 * @note it does not matter if we deceed the current local upper bound, because SCIPaddConflictRelaxedUb()
    1028 * is correcting the bound afterwards
    1029 */
    1030 /* coverity[copy_paste_error] */
    1031 relaxedub = inferbd - 2*SCIPfeastol(scip) * MAX(1, abscoef);
    1032 }
    1033
    1034 /* try to relax inference variable upper bound such that the infeasibility is still given */
    1035 SCIP_CALL( SCIPaddConflictRelaxedUb(scip, infervar, NULL, relaxedub) );
    1036
    1037 /* collect the upper bound which is reported to the conflict analysis */
    1038 inferbd = SCIPgetConflictVarUb(scip, infervar);
    1039
    1040 /* adjust inference bound with respect to the upper bound reported to the conflict analysis */
    1041 if( SCIPvarIsIntegral(infervar) )
    1042 inferbd = inferbd + 1.0;
    1043 else
    1044 {
    1045 SCIP_CONSDATA* consdata;
    1046 SCIP_Real abscoef;
    1047
    1048 consdata = SCIPconsGetData(cons);
    1049 assert(consdata != NULL);
    1050
    1051 /* vbdvar can never be of non-integral type */
    1052 assert(infervar == consdata->var);
    1053
    1054 abscoef = REALABS(consdata->vbdcoef);
    1055
    1056 /* due to resolving a the propagation and dividing by the vbdcoef we need to make sure the the relaxed bound
    1057 * is big enough, therefore we multiply here with the vbdcoef
    1058 */
    1059 inferbd = inferbd + 2*SCIPfeastol(scip) * MAX(1, abscoef);
    1060 }
    1061 }
    1062 else
    1063 {
    1064 SCIP_CALL( SCIPaddConflictUb(scip, infervar, NULL) );
    1065 }
    1066 }
    1067 else
    1068 {
    1069 if( usebdwidening )
    1070 {
    1071 SCIP_Real relaxedlb;
    1072
    1073 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
    1074
    1075 /* adjust upper bound */
    1076 inferbd = SCIPadjustedVarUb(scip, infervar, inferbd);
    1077
    1078 /* compute a relaxed lower bound which would be sufficient to be still infeasible */
    1079 if( SCIPvarIsIntegral(infervar) )
    1080 relaxedlb = inferbd + 1.0;
    1081 else
    1082 {
    1083 SCIP_CONSDATA* consdata;
    1084 SCIP_Real abscoef;
    1085
    1086 consdata = SCIPconsGetData(cons);
    1087 assert(consdata != NULL);
    1088
    1089 /* vbdvar can never be of non-integral type */
    1090 assert(infervar == consdata->var);
    1091
    1092 abscoef = REALABS(consdata->vbdcoef);
    1093
    1094 /* due to resolving a the propagation and dividing by the vbdcoef we need to make sure the the relaxed bound
    1095 * is big enough, therefore we multiply here with the vbdcoef
    1096 *
    1097 * @note it does not matter if we exceed the current local lower bound, because SCIPaddConflictRelaxedLb()
    1098 * is correcting the bound afterwards
    1099 */
    1100 /* coverity[copy_paste_error] */
    1101 relaxedlb = inferbd + 2*SCIPfeastol(scip) * MAX(1, abscoef);
    1102 }
    1103
    1104 /* try to relax inference variable upper bound such that the infeasibility is still given */
    1105 SCIP_CALL( SCIPaddConflictRelaxedLb(scip, infervar, NULL, relaxedlb) );
    1106
    1107 /* collect the lower bound which is reported to the conflict analysis */
    1108 inferbd = SCIPgetConflictVarLb(scip, infervar);
    1109
    1110 /* adjust inference bound with respect to the lower bound reported to the conflict analysis */
    1111 if( SCIPvarIsIntegral(infervar) )
    1112 inferbd = inferbd - 1.0;
    1113 else
    1114 {
    1115 SCIP_CONSDATA* consdata;
    1116 SCIP_Real abscoef;
    1117
    1118 consdata = SCIPconsGetData(cons);
    1119 assert(consdata != NULL);
    1120
    1121 /* vbdvar can never be of non-integral type */
    1122 assert(infervar == consdata->var);
    1123
    1124 abscoef = REALABS(consdata->vbdcoef);
    1125
    1126 /* due to resolving a the propagation and dividing by the vbdcoef we need to make sure the the relaxed bound
    1127 * is big enough, therefore we multiply here with the vbdcoef
    1128 */
    1129 inferbd = inferbd - 2*SCIPfeastol(scip) * MAX(1, abscoef);
    1130 }
    1131 }
    1132 else
    1133 {
    1134 SCIP_CALL( SCIPaddConflictLb(scip, infervar, NULL) );
    1135 }
    1136 }
    1137
    1138 /* add the reason for the violated of the bound */
    1139 SCIP_CALL( resolvePropagation(scip, cons, infervar, proprule, boundtype, NULL, inferbd, usebdwidening) );
    1140
    1141 /* analyze the conflict */
    1143
    1144 return SCIP_OKAY;
    1145}
    1146
    1147/** separates the given variable bound constraint */
    1148static
    1150 SCIP* scip, /**< SCIP data structure */
    1151 SCIP_CONS* cons, /**< variable bound constraint */
    1152 SCIP_Bool usebdwidening, /**< should bound widening be used to in conflict analysis? */
    1153 SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
    1154 SCIP_RESULT* result /**< pointer to store the result of the separation call */
    1155 )
    1156{
    1157 SCIP_CONSHDLR* conshdlr;
    1158 SCIP_CONSDATA* consdata;
    1159 SCIP_VAR* vbdvar;
    1160 SCIP_VAR* var;
    1161 SCIP_Real vbdcoef;
    1162 SCIP_Real feasibility;
    1163
    1164 assert(cons != NULL);
    1165 assert(result != NULL);
    1166
    1167 consdata = SCIPconsGetData(cons);
    1168 assert(consdata != NULL);
    1169
    1170 /* find the variable bound constraint handler */
    1171 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    1172 if( conshdlr == NULL )
    1173 {
    1174 SCIPerrorMessage("variable bound constraint handler not found\n");
    1175 return SCIP_PLUGINNOTFOUND;
    1176 }
    1177
    1178 SCIPdebugMsg(scip, "separating variable bound constraint <%s>\n", SCIPconsGetName(cons));
    1179
    1180 var = consdata->var;
    1181 vbdvar = consdata->vbdvar;
    1182 vbdcoef = consdata->vbdcoef;
    1183 assert(SCIPvarIsIntegral(vbdvar));
    1184
    1185 /* if x is not multiaggregated and y is fixed, propagate bounds on x */
    1186 if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_MULTAGGR && SCIPvarGetLbLocal(vbdvar) + 0.5 > SCIPvarGetUbLocal(vbdvar) )
    1187 {
    1188 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(vbdvar), SCIPvarGetUbLocal(vbdvar)));
    1189
    1190 if( !SCIPisInfinity(scip, -consdata->lhs) )
    1191 {
    1192 SCIP_Real newlb;
    1193 SCIP_Real QUAD(tmp);
    1194 SCIP_Bool cutoff;
    1195 SCIP_Bool tightened;
    1196
    1197 SCIPquadprecProdDD(tmp, vbdcoef, SCIPvarGetLbLocal(vbdvar)); /*lint !e666*/
    1198 SCIPquadprecSumQD(tmp, -tmp, consdata->lhs);
    1199
    1200 newlb = QUAD_TO_DBL(tmp);
    1201
    1202 SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, (int)PROPRULE_1, TRUE,
    1203 &cutoff, &tightened) );
    1204
    1205 if( cutoff )
    1206 {
    1207 assert(SCIPisInfinity(scip, newlb) || SCIPisGT(scip, newlb, SCIPvarGetUbLocal(var)));
    1208
    1209 /* analyze infeasibility */
    1210 SCIP_CALL( analyzeConflict(scip, cons, var, newlb, PROPRULE_1, SCIP_BOUNDTYPE_LOWER, usebdwidening) );
    1211 *result = SCIP_CUTOFF;
    1212
    1213 return SCIP_OKAY;
    1214 }
    1215 else if( tightened )
    1216 {
    1217 *result = SCIP_REDUCEDDOM;
    1218 }
    1219 }
    1220
    1221 if( !SCIPisInfinity(scip, consdata->rhs) )
    1222 {
    1223 SCIP_Real newub;
    1224 SCIP_Real QUAD(tmp);
    1225 SCIP_Bool cutoff;
    1226 SCIP_Bool tightened;
    1227
    1228 SCIPquadprecProdDD(tmp, vbdcoef, SCIPvarGetLbLocal(vbdvar)); /*lint !e666*/
    1229 SCIPquadprecSumQD(tmp, -tmp, consdata->rhs);
    1230
    1231 newub = QUAD_TO_DBL(tmp);
    1232
    1233 SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, (int)PROPRULE_3, TRUE,
    1234 &cutoff, &tightened) );
    1235
    1236 if( cutoff )
    1237 {
    1238 assert(SCIPisInfinity(scip, -newub) || SCIPisLT(scip, newub, SCIPvarGetLbLocal(var)));
    1239
    1240 /* analyze infeasibility */
    1241 SCIP_CALL( analyzeConflict(scip, cons, var, newub, PROPRULE_3, SCIP_BOUNDTYPE_UPPER, usebdwidening) );
    1242 *result = SCIP_CUTOFF;
    1243
    1244 return SCIP_OKAY;
    1245 }
    1246 else if( tightened )
    1247 {
    1248 *result = SCIP_REDUCEDDOM;
    1249 }
    1250 }
    1251 }
    1252
    1253 /* if we already changed a bound or the coefficient is too large to put the row into the LP, stop here */
    1254 if( *result == SCIP_REDUCEDDOM )
    1255 return SCIP_OKAY;
    1256
    1257 /* check constraint for feasibility and create row if constraint is violated */
    1258 if( !checkCons(scip, cons, sol, (sol != NULL)) )
    1259 {
    1260 /* create LP relaxation if not yet existing */
    1261 if( consdata->row == NULL )
    1262 {
    1264 }
    1265 assert(consdata->row != NULL);
    1266
    1267 /* check non-LP rows for feasibility and add them as cut, if violated */
    1268 if( !SCIProwIsInLP(consdata->row) )
    1269 {
    1270 feasibility = SCIPgetRowSolFeasibility(scip, consdata->row, sol);
    1271 if( SCIPisFeasNegative(scip, feasibility) )
    1272 {
    1273 SCIP_Bool infeasible;
    1274
    1275 SCIP_CALL( SCIPaddRow(scip, consdata->row, FALSE, &infeasible) );
    1276 if ( infeasible )
    1277 *result = SCIP_CUTOFF;
    1278 else
    1279 *result = SCIP_SEPARATED;
    1280 }
    1281 }
    1282 }
    1283
    1284 return SCIP_OKAY;
    1285}
    1286
    1287/** sets left hand side of varbound constraint */
    1288static
    1290 SCIP* scip, /**< SCIP data structure */
    1291 SCIP_CONS* cons, /**< linear constraint */
    1292 SCIP_Real lhs /**< new left hand side */
    1293 )
    1294{
    1295 SCIP_CONSDATA* consdata;
    1296
    1297 assert(scip != NULL);
    1298 assert(cons != NULL);
    1299 assert(!SCIPisInfinity(scip, lhs));
    1300
    1301 /* adjust value to not be smaller than -inf */
    1302 if( SCIPisInfinity(scip, -lhs) )
    1303 lhs = -SCIPinfinity(scip);
    1304
    1305 consdata = SCIPconsGetData(cons);
    1306 assert(consdata != NULL);
    1307 assert(consdata->var != NULL && consdata->vbdvar != NULL);
    1308 assert(!SCIPisInfinity(scip, consdata->lhs));
    1309
    1310 /* check whether the side is not changed */
    1311 if( SCIPisEQ(scip, consdata->lhs, lhs) )
    1312 return SCIP_OKAY;
    1313
    1314 assert(consdata->row == NULL);
    1315
    1316 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
    1317 if( SCIPisEQ(scip, lhs, consdata->rhs) )
    1318 consdata->rhs = lhs;
    1319
    1320 /* update the rounding locks of variables */
    1321
    1322 /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
    1323 if( SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -lhs) )
    1324 {
    1325 SCIP_CALL( SCIPlockVarCons(scip, consdata->var, cons, TRUE, FALSE) );
    1326
    1327 if( consdata->vbdcoef > 0.0 )
    1328 {
    1329 SCIP_CALL( SCIPlockVarCons(scip, consdata->vbdvar, cons, TRUE, FALSE) );
    1330 }
    1331 else
    1332 {
    1333 SCIP_CALL( SCIPlockVarCons(scip, consdata->vbdvar, cons, FALSE, TRUE) );
    1334 }
    1335 }
    1336 /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
    1337 else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -lhs) )
    1338 {
    1339 SCIP_CALL( SCIPunlockVarCons(scip, consdata->var, cons, TRUE, FALSE) );
    1340
    1341 if( consdata->vbdcoef > 0.0 )
    1342 {
    1343 SCIP_CALL( SCIPunlockVarCons(scip, consdata->vbdvar, cons, TRUE, FALSE) );
    1344 }
    1345 else
    1346 {
    1347 SCIP_CALL( SCIPunlockVarCons(scip, consdata->vbdvar, cons, FALSE, TRUE) );
    1348 }
    1349 }
    1350
    1351 /* if left hand side got tighter, we want to do additional presolving on this constraint */
    1352 if( SCIPisLT(scip, consdata->lhs, lhs) )
    1353 {
    1354 consdata->varboundsadded = FALSE;
    1355 consdata->tightened = FALSE;
    1356
    1358 }
    1359
    1360 consdata->presolved = FALSE;
    1361 consdata->lhs = lhs;
    1362 consdata->changed = TRUE;
    1363
    1364 return SCIP_OKAY;
    1365}
    1366
    1367/** sets right hand side of varbound constraint */
    1368static
    1370 SCIP* scip, /**< SCIP data structure */
    1371 SCIP_CONS* cons, /**< linear constraint */
    1372 SCIP_Real rhs /**< new right hand side */
    1373 )
    1374{
    1375 SCIP_CONSDATA* consdata;
    1376
    1377 assert(scip != NULL);
    1378 assert(cons != NULL);
    1379 assert(!SCIPisInfinity(scip, -rhs));
    1380
    1381 /* adjust value to not be larger than inf */
    1382 if( SCIPisInfinity(scip, rhs) )
    1383 rhs = SCIPinfinity(scip);
    1384
    1385 consdata = SCIPconsGetData(cons);
    1386 assert(consdata != NULL);
    1387 assert(consdata->var != NULL && consdata->vbdvar != NULL);
    1388 assert(!SCIPisInfinity(scip, -consdata->rhs));
    1389
    1390 /* check whether the side is not changed */
    1391 if( SCIPisEQ(scip, consdata->rhs, rhs) )
    1392 return SCIP_OKAY;
    1393
    1394 assert(consdata->row == NULL);
    1395
    1396 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
    1397 if( SCIPisEQ(scip, rhs, consdata->lhs) )
    1398 consdata->lhs = rhs;
    1399
    1400 /* update the locks of variables */
    1401 assert(SCIPconsIsTransformed(cons));
    1402
    1403 /* the right hand side switched from infinity to a non-infinite value -> install locks */
    1404 if( SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, rhs) )
    1405 {
    1406 SCIP_CALL( SCIPlockVarCons(scip, consdata->var, cons, FALSE, TRUE) );
    1407
    1408 if( consdata->vbdcoef > 0.0 )
    1409 {
    1410 SCIP_CALL( SCIPlockVarCons(scip, consdata->vbdvar, cons, FALSE, TRUE) );
    1411 }
    1412 else
    1413 {
    1414 SCIP_CALL( SCIPlockVarCons(scip, consdata->vbdvar, cons, TRUE, FALSE) );
    1415 }
    1416 }
    1417 /* the right hand side switched from a non-infinite value to infinity -> remove locks */
    1418 else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, rhs) )
    1419 {
    1420 SCIP_CALL( SCIPunlockVarCons(scip, consdata->var, cons, FALSE, TRUE) );
    1421
    1422 if( consdata->vbdcoef > 0.0 )
    1423 {
    1424 SCIP_CALL( SCIPunlockVarCons(scip, consdata->vbdvar, cons, FALSE, TRUE) );
    1425 }
    1426 else
    1427 {
    1428 SCIP_CALL( SCIPunlockVarCons(scip, consdata->vbdvar, cons, TRUE, FALSE) );
    1429 }
    1430 }
    1431
    1432 /* if right hand side got tighter, we want to do additional presolving on this constraint */
    1433 if( SCIPisGT(scip, consdata->rhs, rhs) )
    1434 {
    1435 consdata->varboundsadded = FALSE;
    1436 consdata->tightened = FALSE;
    1437
    1439 }
    1440
    1441 consdata->presolved = FALSE;
    1442 consdata->rhs = rhs;
    1443 consdata->changed = TRUE;
    1444
    1445 return SCIP_OKAY;
    1446}
    1447
    1448/** propagation method for variable bound constraint */
    1449static
    1451 SCIP* scip, /**< SCIP data structure */
    1452 SCIP_CONS* cons, /**< variable bound constraint */
    1453 SCIP_Bool usebdwidening, /**< should bound widening be used to in conflict analysis? */
    1454 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    1455 int* nchgbds, /**< pointer to count number of bound changes */
    1456 int* nchgsides, /**< pointer to count number of side changes */
    1457 int* ndelconss /**< pointer to count number of deleted constraints, or NULL */
    1458 )
    1459{
    1460 SCIP_VAR** vars;
    1461 SCIP_CONSDATA* consdata;
    1463 SCIP_Real xlb;
    1464 SCIP_Real xub;
    1465 SCIP_Real ylb;
    1466 SCIP_Real yub;
    1467 SCIP_Real newlb;
    1468 SCIP_Real newub;
    1469 SCIP_Real constant;
    1471 SCIP_Real QUAD(activity);
    1472 SCIP_Bool tightened;
    1473 SCIP_Bool tightenedround;
    1474 SCIP_Bool islhsredundant;
    1475 SCIP_Bool isrhsredundant;
    1476 int nvars;
    1477 int requiredsize;
    1478 int i;
    1479
    1480 assert(cutoff != NULL);
    1481 assert(nchgbds != NULL);
    1482
    1483 consdata = SCIPconsGetData(cons);
    1484 assert(consdata != NULL);
    1485 assert(!SCIPisInfinity(scip, -consdata->lhs) || !SCIPisInfinity(scip, consdata->rhs));
    1486
    1487 SCIPdebugMsg(scip, "propagating variable bound constraint <%s>: %.15g <= <%s>[%.9g, %.9g] + %.15g<%s>[%.9g, %.9g] <= %.15g\n",
    1488 SCIPconsGetName(cons), consdata->lhs, SCIPvarGetName(consdata->var), SCIPvarGetLbLocal(consdata->var),
    1489 SCIPvarGetUbLocal(consdata->var), consdata->vbdcoef, SCIPvarGetName(consdata->vbdvar),
    1490 SCIPvarGetLbLocal(consdata->vbdvar), SCIPvarGetUbLocal(consdata->vbdvar), consdata->rhs);
    1491
    1492 *cutoff = FALSE;
    1493
    1494 /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
    1496 {
    1497 SCIP_CALL( SCIPincConsAge(scip, cons) );
    1498 }
    1499
    1500 /* get current bounds of variables */
    1501 xlb = SCIPvarGetLbLocal(consdata->var);
    1502 xub = SCIPvarGetUbLocal(consdata->var);
    1503 ylb = SCIPvarGetLbLocal(consdata->vbdvar);
    1504 yub = SCIPvarGetUbLocal(consdata->vbdvar);
    1505
    1506 /* it can happen that constraint is of form lhs <= x <= rhs */
    1507 if( SCIPisZero(scip, consdata->vbdcoef) && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
    1508 {
    1509 SCIP_Bool infeasible;
    1510 SCIP_Bool fixed;
    1511
    1512 SCIP_CALL( SCIPfixVar(scip, consdata->var, consdata->lhs, &infeasible, &fixed) );
    1513
    1514 if( infeasible )
    1515 {
    1516 SCIPdebugMsg(scip, "> constraint <%s> is infeasible.\n", SCIPconsGetName(cons));
    1517 *cutoff = TRUE;
    1518 return SCIP_OKAY;
    1519 }
    1520 }
    1521
    1522 /* tighten bounds of variables as long as possible */
    1523 do
    1524 {
    1525 tightenedround = FALSE;
    1526
    1527 /* propagate left hand side inequality: lhs <= x + c*y */
    1528 if( !SCIPisInfinity(scip, -consdata->lhs) )
    1529 {
    1530 assert(!(*cutoff));
    1531
    1532 /* propagate bounds on x:
    1533 * (1) left hand side and bounds on y -> lower bound on x
    1534 */
    1535 if( SCIPvarGetStatus(consdata->var) != SCIP_VARSTATUS_MULTAGGR ) /* cannot change bounds of multaggr vars */
    1536 {
    1537 if( consdata->vbdcoef > 0.0 )
    1538 {
    1539 if( !SCIPisInfinity(scip, yub) )
    1540 {
    1541 SCIP_Real QUAD(tmp);
    1542
    1543 SCIPquadprecProdDD(tmp, consdata->vbdcoef, yub);
    1544 SCIPquadprecSumQD(tmp, -tmp, consdata->lhs);
    1545
    1546 newlb = SCIPadjustedVarLb(scip, consdata->var, QUAD_TO_DBL(tmp));
    1547 }
    1548 else
    1549 {
    1550 newlb = -SCIPinfinity(scip);
    1551 }
    1552 }
    1553 else
    1554 {
    1555 if( !SCIPisInfinity(scip, -ylb) )
    1556 {
    1557 SCIP_Real QUAD(tmp);
    1558
    1559 SCIPquadprecProdDD(tmp, consdata->vbdcoef, ylb);
    1560 SCIPquadprecSumQD(tmp, -tmp, consdata->lhs);
    1561
    1562 newlb = SCIPadjustedVarLb(scip, consdata->var, QUAD_TO_DBL(tmp));
    1563 }
    1564 else
    1565 {
    1566 newlb = -SCIPinfinity(scip);
    1567 }
    1568 }
    1569
    1570 SCIP_CALL( SCIPinferVarLbCons(scip, consdata->var, newlb, cons, (int)PROPRULE_1, yub < ylb + 0.5, cutoff, &tightened) );
    1571
    1572 if( *cutoff )
    1573 {
    1574 SCIPdebugMsg(scip, "cutoff while tightening <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->var), xlb, xub, newlb, xub);
    1575 assert(SCIPisInfinity(scip, newlb) || SCIPisGT(scip, newlb, SCIPvarGetUbLocal(consdata->var)));
    1576
    1578
    1579 /* analyze infeasibility */
    1580 SCIP_CALL( analyzeConflict(scip, cons, consdata->var, newlb, PROPRULE_1, SCIP_BOUNDTYPE_LOWER, usebdwidening) );
    1581 break;
    1582 }
    1583
    1584 if( tightened )
    1585 {
    1586 SCIPdebugMsg(scip, " -> tighten <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->var), xlb, xub, newlb, xub);
    1587 tightenedround = TRUE;
    1588 (*nchgbds)++;
    1590 }
    1591 xlb = SCIPvarGetLbLocal(consdata->var);
    1592 }
    1593
    1594 assert(!*cutoff);
    1595
    1596 /* propagate bounds on y:
    1597 * (2) left hand side and upper bound on x -> bound on y
    1598 */
    1599 if( SCIPvarGetStatus(consdata->vbdvar) != SCIP_VARSTATUS_MULTAGGR && !SCIPisInfinity(scip, xub) ) /* cannot change bounds of multaggr vars */
    1600 {
    1601 if( consdata->vbdcoef > 0.0 )
    1602 {
    1603 SCIP_Real QUAD(tmp);
    1604
    1605 SCIPquadprecSumDD(tmp, consdata->lhs, -xub);
    1606 SCIPquadprecDivQD(tmp, tmp, consdata->vbdcoef);
    1607
    1608 newlb = SCIPadjustedVarLb(scip, consdata->vbdvar, QUAD_TO_DBL(tmp));
    1609 if( newlb > ylb + 0.5 )
    1610 {
    1611 SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vbdvar, newlb, cons, (int)PROPRULE_2, FALSE, cutoff, &tightened) );
    1612
    1613 if( *cutoff )
    1614 {
    1615 SCIPdebugMsg(scip, "cutoff while tightening <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->vbdvar), ylb, yub, newlb, yub);
    1616 assert(SCIPisInfinity(scip, newlb) || SCIPisGT(scip, newlb, SCIPvarGetUbLocal(consdata->vbdvar)));
    1617
    1618 /* analyze infeasibility */
    1619 SCIP_CALL( analyzeConflict(scip, cons, consdata->vbdvar, newlb, PROPRULE_2, SCIP_BOUNDTYPE_LOWER, usebdwidening) );
    1620 break;
    1621 }
    1622
    1623 if( tightened )
    1624 {
    1625 SCIPdebugMsg(scip, " -> tighten <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->vbdvar), ylb, yub, newlb, yub);
    1626 tightenedround = TRUE;
    1627 (*nchgbds)++;
    1628 }
    1629 ylb = SCIPvarGetLbLocal(consdata->vbdvar);
    1630 }
    1631 }
    1632 else
    1633 {
    1634 SCIP_Real QUAD(tmp);
    1635
    1636 SCIPquadprecSumDD(tmp, consdata->lhs, -xub);
    1637 SCIPquadprecDivQD(tmp, tmp, consdata->vbdcoef);
    1638
    1639 newub = SCIPadjustedVarUb(scip, consdata->vbdvar, QUAD_TO_DBL(tmp));
    1640
    1641 if( newub < yub - 0.5 )
    1642 {
    1643 SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vbdvar, newub, cons, (int)PROPRULE_2, FALSE, cutoff, &tightened) );
    1644
    1645 if( *cutoff )
    1646 {
    1647 SCIPdebugMsg(scip, "cutoff while tightening <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->vbdvar), ylb, yub, ylb, newub);
    1648 assert(SCIPisInfinity(scip, -newub) || SCIPisLT(scip, newub, SCIPvarGetLbLocal(consdata->vbdvar)));
    1649
    1651
    1652 /* analyze infeasibility */
    1653 SCIP_CALL( analyzeConflict(scip, cons, consdata->vbdvar, newub, PROPRULE_2, SCIP_BOUNDTYPE_UPPER, usebdwidening) );
    1654 break;
    1655 }
    1656
    1657 if( tightened )
    1658 {
    1659 SCIPdebugMsg(scip, " -> tighten <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->vbdvar), ylb, yub, ylb, newub);
    1660 tightenedround = TRUE;
    1661 (*nchgbds)++;
    1663 }
    1664 yub = SCIPvarGetUbLocal(consdata->vbdvar);
    1665 }
    1666 }
    1667 }
    1668 }
    1669
    1670 assert(!*cutoff);
    1671
    1672 /* propagate right hand side inequality: x + c*y <= rhs */
    1673 if( !SCIPisInfinity(scip, consdata->rhs) )
    1674 {
    1675 /* propagate bounds on x:
    1676 * (3) right hand side and bounds on y -> upper bound on x
    1677 */
    1678 if( SCIPvarGetStatus(consdata->var) != SCIP_VARSTATUS_MULTAGGR ) /* cannot change bounds of multaggr vars */
    1679 {
    1680 if( consdata->vbdcoef > 0.0 )
    1681 {
    1682 if( !SCIPisInfinity(scip, -ylb) )
    1683 {
    1684 SCIP_Real QUAD(tmp);
    1685
    1686 SCIPquadprecProdDD(tmp, consdata->vbdcoef, ylb);
    1687 SCIPquadprecSumQD(tmp, -tmp, consdata->rhs);
    1688
    1689 newub = SCIPadjustedVarUb(scip, consdata->var, QUAD_TO_DBL(tmp));
    1690 }
    1691 else
    1692 {
    1693 newub = SCIPinfinity(scip);
    1694 }
    1695 }
    1696 else
    1697 {
    1698 if( !SCIPisInfinity(scip, yub) )
    1699 {
    1700 SCIP_Real QUAD(tmp);
    1701
    1702 SCIPquadprecProdDD(tmp, consdata->vbdcoef, yub);
    1703 SCIPquadprecSumQD(tmp, -tmp, consdata->rhs);
    1704
    1705 newub = SCIPadjustedVarUb(scip, consdata->var, QUAD_TO_DBL(tmp));
    1706 }
    1707 else
    1708 {
    1709 newub = SCIPinfinity(scip);
    1710 }
    1711 }
    1712
    1713 SCIP_CALL( SCIPinferVarUbCons(scip, consdata->var, newub, cons, (int)PROPRULE_3, yub < ylb + 0.5, cutoff, &tightened) );
    1714
    1715 if( *cutoff )
    1716 {
    1717 SCIPdebugMsg(scip, "cutoff while tightening <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->var), xlb, xub, xlb, newub);
    1718 assert(SCIPisInfinity(scip, -newub) || SCIPisLT(scip, newub, SCIPvarGetLbLocal(consdata->var)));
    1719
    1721
    1722 /* analyze infeasibility */
    1723 SCIP_CALL( analyzeConflict(scip, cons, consdata->var, newub, PROPRULE_3, SCIP_BOUNDTYPE_UPPER, usebdwidening) );
    1724 break;
    1725 }
    1726
    1727 if( tightened )
    1728 {
    1729 SCIPdebugMsg(scip, " -> tighten <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->var), xlb, xub, xlb, newub);
    1730 tightenedround = TRUE;
    1731 (*nchgbds)++;
    1733 }
    1734 xub = SCIPvarGetUbLocal(consdata->var);
    1735 }
    1736
    1737 assert(!*cutoff);
    1738
    1739 /* propagate bounds on y:
    1740 * (4) right hand side and lower bound on x -> bound on y
    1741 */
    1742 if( SCIPvarGetStatus(consdata->vbdvar) != SCIP_VARSTATUS_MULTAGGR && !SCIPisInfinity(scip, -xlb) ) /* cannot change bounds of multaggr vars */
    1743 {
    1744 if( consdata->vbdcoef > 0.0 )
    1745 {
    1746 SCIP_Real QUAD(tmp);
    1747
    1748 SCIPquadprecSumDD(tmp, consdata->rhs, -xlb);
    1749 SCIPquadprecDivQD(tmp, tmp, consdata->vbdcoef);
    1750
    1751 newub = SCIPadjustedVarUb(scip, consdata->vbdvar, QUAD_TO_DBL(tmp));
    1752 if( newub < yub - 0.5 )
    1753 {
    1754 SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vbdvar, newub, cons, (int)PROPRULE_4, FALSE, cutoff, &tightened) );
    1755
    1756 if( *cutoff )
    1757 {
    1758 SCIPdebugMsg(scip, "cutoff while tightening <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->vbdvar), ylb, yub, ylb, newub);
    1759 assert(SCIPisInfinity(scip, -newub) || SCIPisLT(scip, newub, SCIPvarGetLbLocal(consdata->vbdvar)));
    1760
    1762
    1763 /* analyze infeasibility */
    1764 SCIP_CALL( analyzeConflict(scip, cons, consdata->vbdvar, newub, PROPRULE_4, SCIP_BOUNDTYPE_UPPER, usebdwidening) );
    1765 break;
    1766 }
    1767
    1768 if( tightened )
    1769 {
    1770 SCIPdebugMsg(scip, " -> tighten <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->vbdvar), ylb, yub, ylb, newub);
    1771 tightenedround = TRUE;
    1772 (*nchgbds)++;
    1774 }
    1775 yub = SCIPvarGetUbLocal(consdata->vbdvar);
    1776 }
    1777 }
    1778 else
    1779 {
    1780 SCIP_Real QUAD(tmp);
    1781
    1782 SCIPquadprecSumDD(tmp, consdata->rhs, -xlb);
    1783 SCIPquadprecDivQD(tmp, tmp, consdata->vbdcoef);
    1784
    1785 newlb = SCIPadjustedVarLb(scip, consdata->vbdvar, QUAD_TO_DBL(tmp));
    1786 if( newlb > ylb + 0.5 )
    1787 {
    1788 SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vbdvar, newlb, cons, (int)PROPRULE_4, FALSE, cutoff, &tightened) );
    1789
    1790 if( *cutoff )
    1791 {
    1792 SCIPdebugMsg(scip, "cutoff while tightening <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->vbdvar), ylb, yub, newlb, yub);
    1793 assert(SCIPisInfinity(scip, newlb) || SCIPisGT(scip, newlb, SCIPvarGetUbLocal(consdata->vbdvar)));
    1794
    1796
    1797 /* analyze infeasibility */
    1798 SCIP_CALL( analyzeConflict(scip, cons, consdata->vbdvar, newlb, PROPRULE_4, SCIP_BOUNDTYPE_LOWER, usebdwidening) );
    1799 break;
    1800 }
    1801
    1802 if( tightened )
    1803 {
    1804 SCIPdebugMsg(scip, " -> tighten <%s>[%.15g,%.15g] -> [%.15g,%.15g]\n", SCIPvarGetName(consdata->vbdvar), ylb, yub, newlb, yub);
    1805 tightenedround = TRUE;
    1806 (*nchgbds)++;
    1808 }
    1809 ylb = SCIPvarGetLbLocal(consdata->vbdvar);
    1810 }
    1811 }
    1812 }
    1813 }
    1814 assert(!(*cutoff));
    1815 }
    1816 while( tightenedround );
    1817
    1818 /* check for redundant sides */
    1819 if( !(*cutoff) )
    1820 {
    1821 islhsredundant = TRUE;
    1822 isrhsredundant = TRUE;
    1823 nvars = 2;
    1824
    1825 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
    1827
    1828 constant = 0.0;
    1829 vars[0] = consdata->var;
    1830 vars[1] = consdata->vbdvar;
    1831 scalars[0] = 1.0;
    1832 scalars[1] = consdata->vbdcoef;
    1833 SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, &nvars, nvars, &constant, &requiredsize) );
    1834
    1835 if( requiredsize > nvars )
    1836 {
    1837 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
    1838 SCIP_CALL( SCIPreallocBufferArray(scip, &scalars, requiredsize) );
    1839
    1840 SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, &nvars, requiredsize, &constant, &requiredsize) );
    1841 assert(requiredsize <= nvars);
    1842 }
    1843
    1844 if( !SCIPisInfinity(scip, -consdata->lhs) )
    1845 {
    1846 QUAD_ASSIGN(activity, constant);
    1847
    1848 for( i = 0; i < nvars; ++i )
    1849 {
    1850 assert(scalars[i] != 0.0);
    1851 if( scalars[i] > 0.0 )
    1852 {
    1853 bound = SCIPvarGetLbLocal(vars[i]);
    1854
    1855 if( SCIPisInfinity(scip, -bound) )
    1856 {
    1857 islhsredundant = FALSE;
    1858 break;
    1859 }
    1860 }
    1861 else
    1862 {
    1863 bound = SCIPvarGetUbLocal(vars[i]);
    1864
    1865 if( SCIPisInfinity(scip, bound) )
    1866 {
    1867 islhsredundant = FALSE;
    1868 break;
    1869 }
    1870 }
    1871
    1872 SCIPquadprecSumQD(activity, activity, scalars[i] * bound);
    1873 }
    1874
    1875 if( islhsredundant && SCIPisLT(scip, QUAD_TO_DBL(activity), consdata->lhs) )
    1876 islhsredundant = FALSE;
    1877 }
    1878
    1879 if( !SCIPisInfinity(scip, consdata->rhs) )
    1880 {
    1881 QUAD_ASSIGN(activity, constant);
    1882
    1883 for( i = 0; i < nvars; ++i )
    1884 {
    1885 assert(scalars[i] != 0.0);
    1886 if( scalars[i] > 0.0 )
    1887 {
    1888 bound = SCIPvarGetUbLocal(vars[i]);
    1889
    1890 if( SCIPisInfinity(scip, bound) )
    1891 {
    1892 isrhsredundant = FALSE;
    1893 break;
    1894 }
    1895 }
    1896 else
    1897 {
    1898 bound = SCIPvarGetLbLocal(vars[i]);
    1899
    1900 if( SCIPisInfinity(scip, -bound) )
    1901 {
    1902 isrhsredundant = FALSE;
    1903 break;
    1904 }
    1905 }
    1906
    1907 SCIPquadprecSumQD(activity, activity, scalars[i] * bound);
    1908 }
    1909
    1910 if( isrhsredundant && SCIPisGT(scip, QUAD_TO_DBL(activity), consdata->rhs) )
    1911 isrhsredundant = FALSE;
    1912 }
    1913
    1915 SCIPfreeBufferArray(scip, &vars);
    1916
    1917 /* check varbound constraint for redundancy */
    1918 if( islhsredundant && isrhsredundant )
    1919 {
    1920 SCIPdebugMsg(scip, "variable bound constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
    1921 SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
    1922
    1923 /* remove the constraint locally unless it has become empty, in which case it is removed globally */
    1924 if( nvars > 0 )
    1926 else
    1927 SCIP_CALL( SCIPdelCons(scip, cons) );
    1928
    1929 /* this did not seem to help but should be tested again, there might also still be a bug in there */
    1930#ifdef SCIP_DISABLED_CODE
    1931 /* local duality fixing of variables in the constraint */
    1932 if( !SCIPisNegative(scip, SCIPvarGetObj(consdata->vbdvar))
    1933 && SCIPvarGetNLocksDownType(consdata->vbdvar, SCIP_LOCKTYPE_MODEL) == 1
    1934 && !SCIPisInfinity(scip, -SCIPvarGetLbLocal(consdata->vbdvar))
    1935 && SCIPisFeasLT(scip, SCIPvarGetLbLocal(consdata->vbdvar), SCIPvarGetUbLocal(consdata->vbdvar))
    1936 && ((consdata->vbdcoef > 0.0 && !SCIPisInfinity(scip, -consdata->lhs))
    1937 || (consdata->vbdcoef < 0.0 && !SCIPisInfinity(scip, consdata->rhs))) )
    1938 {
    1939 SCIPdebugMsg(scip, " --> fixing <%s>[%.15g,%.15g] to %.15g\n", SCIPvarGetName(consdata->vbdvar),
    1940 SCIPvarGetLbLocal(consdata->vbdvar), SCIPvarGetUbLocal(consdata->vbdvar), SCIPvarGetLbLocal(consdata->vbdvar));
    1941 SCIP_CALL( SCIPchgVarUb(scip, consdata->vbdvar, SCIPvarGetLbLocal(consdata->vbdvar)) );
    1942 }
    1943 else if( !SCIPisPositive(scip, SCIPvarGetObj(consdata->vbdvar))
    1944 && SCIPvarGetNLocksUpType(consdata->vbdvar, SCIP_LOCKTYPE_MODEL) == 1
    1945 && !SCIPisInfinity(scip, SCIPvarGetUbLocal(consdata->vbdvar))
    1946 && SCIPisFeasLT(scip, SCIPvarGetLbLocal(consdata->vbdvar), SCIPvarGetUbLocal(consdata->vbdvar))
    1947 && ((consdata->vbdcoef < 0.0 && !SCIPisInfinity(scip, -consdata->lhs))
    1948 || (consdata->vbdcoef > 0.0 && !SCIPisInfinity(scip, consdata->rhs))) )
    1949 {
    1950 SCIPdebugMsg(scip, " --> fixing <%s>[%.15g,%.15g] to %.15g\n", SCIPvarGetName(consdata->vbdvar),
    1951 SCIPvarGetLbLocal(consdata->vbdvar), SCIPvarGetUbLocal(consdata->vbdvar), SCIPvarGetUbLocal(consdata->vbdvar));
    1952 SCIP_CALL( SCIPchgVarLb(scip, consdata->vbdvar, SCIPvarGetUbLocal(consdata->vbdvar)) );
    1953 }
    1954 if( !SCIPisNegative(scip, SCIPvarGetObj(consdata->var))
    1955 && SCIPvarGetNLocksDownType(consdata->var, SCIP_LOCKTYPE_MODEL) == 1
    1956 && !SCIPisInfinity(scip, -SCIPvarGetLbLocal(consdata->var))
    1957 && SCIPisFeasLT(scip, SCIPvarGetLbLocal(consdata->var), SCIPvarGetUbLocal(consdata->var))
    1958 && !SCIPisInfinity(scip, -consdata->lhs) )
    1959 {
    1960 SCIPdebugMsg(scip, " --> fixing <%s>[%.15g,%.15g] to %.15g\n", SCIPvarGetName(consdata->var),
    1961 SCIPvarGetLbLocal(consdata->var), SCIPvarGetUbLocal(consdata->var), SCIPvarGetLbLocal(consdata->var));
    1962 SCIP_CALL( SCIPchgVarUb(scip, consdata->var, SCIPvarGetLbLocal(consdata->var)) );
    1963 }
    1964 else if( !SCIPisPositive(scip, SCIPvarGetObj(consdata->var))
    1965 && SCIPvarGetNLocksUpType(consdata->var, SCIP_LOCKTYPE_MODEL) == 1
    1966 && !SCIPisInfinity(scip, SCIPvarGetUbLocal(consdata->var))
    1967 && SCIPisFeasLT(scip, SCIPvarGetLbLocal(consdata->var), SCIPvarGetUbLocal(consdata->var))
    1968 && !SCIPisInfinity(scip, consdata->rhs) )
    1969 {
    1970 SCIPdebugMsg(scip, " --> fixing <%s>[%.15g,%.15g] to %.15g\n", SCIPvarGetName(consdata->var),
    1971 SCIPvarGetLbLocal(consdata->var), SCIPvarGetUbLocal(consdata->var), SCIPvarGetUbLocal(consdata->var));
    1972 SCIP_CALL( SCIPchgVarLb(scip, consdata->var, SCIPvarGetUbLocal(consdata->var)) );
    1973 }
    1974#endif
    1975 if( ndelconss != NULL )
    1976 ++(*ndelconss);
    1977 }
    1979 {
    1980 /* check left hand side for redundancy */
    1981 if( islhsredundant )
    1982 {
    1983 assert(!isrhsredundant);
    1984
    1985 if( !SCIPisInfinity(scip, -consdata->lhs) )
    1986 {
    1987 SCIPdebugMsg(scip, "left hand side of variable bound constraint <%s> is redundant\n", SCIPconsGetName(cons));
    1988
    1989 SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
    1990
    1991 if( nchgsides != NULL )
    1992 ++(*nchgsides);
    1993 }
    1994 }
    1995 /* check right hand side for redundancy */
    1996 else if( isrhsredundant )
    1997 {
    1998 assert(!islhsredundant);
    1999
    2000 if( !SCIPisInfinity(scip, consdata->rhs) )
    2001 {
    2002 SCIPdebugMsg(scip, "right hand side of variable bound constraint <%s> is redundant\n", SCIPconsGetName(cons));
    2003
    2005
    2006 if( nchgsides != NULL )
    2007 ++(*nchgsides);
    2008 }
    2009 }
    2010 }
    2011 }
    2012
    2014
    2015 return SCIP_OKAY;
    2016}
    2017
    2018/* check whether one constraint side is redundant to another constraint side by calculating extreme values for
    2019 * variables
    2020 */
    2021static
    2023 SCIP* scip, /**< SCIP data structure */
    2024 SCIP_VAR* var, /**< variable x that has variable bound */
    2025 SCIP_VAR* vbdvar, /**< binary, integer or implicit integer bounding variable y */
    2026 SCIP_Real coef0, /**< coefficient c0 of bounding variable y for constraint 0 */
    2027 SCIP_Real coef1, /**< coefficient c1 of bounding variable y for constraint 1 */
    2028 SCIP_Real side0, /**< one side of variable bound inequality for constraint 0 */
    2029 SCIP_Real side1, /**< one side of variable bound inequality for constraint 1 */
    2030 SCIP_Bool* sideequal, /**< pointer to store if both constraints have the same redundancy on the
    2031 * given side */
    2032 SCIP_Bool* cons0sidered, /**< pointer to store if side of constraint 0 is redundant */
    2033 SCIP_Bool* cons1sidered, /**< pointer to store if side of constraint 1 is redundant */
    2034 SCIP_Bool islhs /**< do we check the left or the right hand side */
    2035 )
    2036{
    2037 SCIP_Real lbvar;
    2038 SCIP_Real ubvar;
    2039 SCIP_Real lbvbdvar;
    2040 SCIP_Real ubvbdvar;
    2041 SCIP_Real boundxlb1;
    2042 SCIP_Real boundxlb2;
    2043 SCIP_Real boundylb1;
    2044 SCIP_Real boundylb2;
    2045 SCIP_Real boundxub1;
    2046 SCIP_Real boundxub2;
    2047 SCIP_Real boundyub1;
    2048 SCIP_Real boundyub2;
    2049 SCIP_Real boundvaluex1;
    2050 SCIP_Real boundvaluex2;
    2051 SCIP_Real boundvaluey1;
    2052 SCIP_Real boundvaluey2;
    2053 SCIP_Real valuex1;
    2054 SCIP_Real valuex2;
    2055 SCIP_Real valuey1;
    2056 SCIP_Real valuey2;
    2057 SCIP_Bool* redundant0;
    2058 SCIP_Bool* redundant1;
    2059
    2060 assert(scip != NULL);
    2061 assert(var != NULL);
    2062 assert(vbdvar != NULL);
    2063 assert(sideequal != NULL);
    2064 assert(cons0sidered != NULL);
    2065 assert(cons1sidered != NULL);
    2066 assert(coef0 * coef1 > 0.0);
    2067
    2068 *cons0sidered = SCIPisInfinity(scip, islhs ? -side0 : side0);
    2069 *cons1sidered = SCIPisInfinity(scip, islhs ? -side1 : side1);
    2070 *sideequal = FALSE;
    2071
    2072 if( islhs )
    2073 {
    2074 redundant0 = cons1sidered;
    2075 redundant1 = cons0sidered;
    2076 }
    2077 else
    2078 {
    2079 redundant0 = cons0sidered;
    2080 redundant1 = cons1sidered;
    2081 }
    2082
    2083 lbvar = SCIPvarGetLbGlobal(var);
    2084 assert(!SCIPisInfinity(scip, lbvar));
    2085 ubvar = SCIPvarGetUbGlobal(var);
    2086 assert(!SCIPisInfinity(scip, -ubvar));
    2087 lbvbdvar = SCIPvarGetLbGlobal(vbdvar);
    2088 assert(!SCIPisInfinity(scip, lbvbdvar));
    2089 ubvbdvar = SCIPvarGetUbGlobal(vbdvar);
    2090 assert(!SCIPisInfinity(scip, -ubvbdvar));
    2091
    2092 /* if both constraints have this side */
    2093 if( !*redundant0 && !*redundant1 )
    2094 {
    2095 /* calculate extreme values, which are reached by setting the other variable to their lower/upper bound */
    2096 if( SCIPisInfinity(scip, -lbvbdvar) )
    2097 {
    2098 if( coef0 > 0.0 )
    2099 {
    2100 boundxlb1 = SCIPinfinity(scip);
    2101 boundxlb2 = SCIPinfinity(scip);
    2102 }
    2103 else
    2104 {
    2105 boundxlb1 = -SCIPinfinity(scip);
    2106 boundxlb2 = -SCIPinfinity(scip);
    2107 }
    2108 }
    2109 else
    2110 {
    2111 boundxlb1 = side0 - lbvbdvar * coef0;
    2112 boundxlb2 = side1 - lbvbdvar * coef1;
    2113 }
    2114 if( SCIPisInfinity(scip, -lbvar) )
    2115 {
    2116 if( coef0 > 0.0 )
    2117 {
    2118 boundylb1 = SCIPinfinity(scip);
    2119 boundylb2 = SCIPinfinity(scip);
    2120 }
    2121 else
    2122 {
    2123 boundylb1 = -SCIPinfinity(scip);
    2124 boundylb2 = -SCIPinfinity(scip);
    2125 }
    2126 }
    2127 else
    2128 {
    2129 boundylb1 = (side0 - lbvar) / coef0;
    2130 boundylb2 = (side1 - lbvar) / coef1;
    2131 }
    2132 if( SCIPisInfinity(scip, ubvbdvar) )
    2133 {
    2134 if( coef0 > 0.0 )
    2135 {
    2136 boundxub1 = -SCIPinfinity(scip);
    2137 boundxub2 = -SCIPinfinity(scip);
    2138 }
    2139 else
    2140 {
    2141 boundxub1 = SCIPinfinity(scip);
    2142 boundxub2 = SCIPinfinity(scip);
    2143 }
    2144 }
    2145 else
    2146 {
    2147 boundxub1 = side0 - ubvbdvar * coef0;
    2148 boundxub2 = side1 - ubvbdvar * coef1;
    2149 }
    2150 if( SCIPisInfinity(scip, ubvar) )
    2151 {
    2152 if( coef0 > 0.0 )
    2153 {
    2154 boundyub1 = -SCIPinfinity(scip);
    2155 boundyub2 = -SCIPinfinity(scip);
    2156 }
    2157 else
    2158 {
    2159 boundyub1 = SCIPinfinity(scip);
    2160 boundyub2 = SCIPinfinity(scip);
    2161 }
    2162 }
    2163 else
    2164 {
    2165 boundyub1 = (side0 - ubvar) / coef0;
    2166 boundyub2 = (side1 - ubvar) / coef1;
    2167 }
    2168
    2169 if( islhs )
    2170 {
    2171 boundvaluex1 = MAX(boundxlb1, boundxlb2);
    2172 boundvaluex2 = MAX(boundxub1, boundxub2);
    2173 }
    2174 else
    2175 {
    2176 boundvaluex1 = MIN(boundxlb1, boundxlb2);
    2177 boundvaluex2 = MIN(boundxub1, boundxub2);
    2178 }
    2179
    2180 /* calculate important values for variables */
    2181 if( coef0 > 0.0 )
    2182 {
    2183 valuex1 = MIN(boundvaluex1, ubvar);
    2184 valuex1 = MAX(valuex1, lbvar);
    2185 valuex2 = MAX(boundvaluex2, lbvar);
    2186 valuex2 = MIN(valuex2, ubvar);
    2187
    2188 /* if variable is of integral type make values integral too */
    2189 if( SCIPvarIsIntegral(var) )
    2190 {
    2191 valuex1 = SCIPfeasFloor(scip, valuex1);
    2192 valuex2 = SCIPfeasCeil(scip, valuex2);
    2193 }
    2194 }
    2195 else
    2196 {
    2197 valuex1 = MAX(boundvaluex1, lbvar);
    2198 valuex1 = MIN(valuex1, ubvar);
    2199 valuex2 = MIN(boundvaluex2, ubvar);
    2200 valuex2 = MAX(valuex2, lbvar);
    2201
    2202 /* if variable is of integral type make values integral too */
    2203 if( SCIPvarIsIntegral(var) )
    2204 {
    2205 valuex1 = SCIPfeasCeil(scip, valuex1);
    2206 valuex2 = SCIPfeasFloor(scip, valuex2);
    2207 }
    2208 }
    2209
    2210 /* calculate resulting values of variable y by setting x to valuex1 */
    2211 if( SCIPisInfinity(scip, ABS(valuex1)) )
    2212 {
    2213 /* only consider sides if coefficients are equal */
    2214 if( SCIPisEQ(scip, coef0, coef1) )
    2215 {
    2216 valuey1 = side0 / coef0;
    2217 valuey2 = side1 / coef1;
    2218 }
    2219 /* only consider original coefficients if otherwise x approaches plus infinity */
    2220 else if( valuex1 > 0.0 )
    2221 {
    2222 valuey1 = coef0;
    2223 valuey2 = coef1;
    2224 }
    2225 /* only consider swapped coefficients if otherwise x approaches minus infinity */
    2226 else
    2227 {
    2228 valuey1 = coef1;
    2229 valuey2 = coef0;
    2230 }
    2231 }
    2232 else
    2233 {
    2234 valuey1 = (side0 - valuex1) / coef0;
    2235 valuey2 = (side1 - valuex1) / coef1;
    2236 }
    2237
    2238 /* determine redundancy of one constraints side */
    2239 if( SCIPisEQ(scip, valuey1, valuey2) )
    2240 *sideequal = TRUE;
    2241 else if( coef0 > 0.0 )
    2242 {
    2243 if( valuey1 < valuey2 )
    2244 *redundant1 = TRUE;
    2245 else
    2246 *redundant0 = TRUE;
    2247 }
    2248 else
    2249 {
    2250 if( valuey1 < valuey2 )
    2251 *redundant0 = TRUE;
    2252 else
    2253 *redundant1 = TRUE;
    2254 }
    2255
    2256 /* calculate resulting values of variable y by setting x to valuex2 */
    2257 if( SCIPisInfinity(scip, ABS(valuex2)) )
    2258 {
    2259 /* only consider sides if coefficients are equal */
    2260 if( SCIPisEQ(scip, coef0, coef1) )
    2261 {
    2262 valuey1 = side0 / coef0;
    2263 valuey2 = side1 / coef1;
    2264 }
    2265 /* only consider original coefficients if otherwise x approaches plus infinity */
    2266 else if( valuex2 > 0.0 )
    2267 {
    2268 valuey1 = coef0;
    2269 valuey2 = coef1;
    2270 }
    2271 /* only consider swapped coefficients if otherwise x approaches minus infinity */
    2272 else
    2273 {
    2274 valuey1 = coef1;
    2275 valuey2 = coef0;
    2276 }
    2277 }
    2278 else
    2279 {
    2280 valuey1 = (side0 - valuex2) / coef0;
    2281 valuey2 = (side1 - valuex2) / coef1;
    2282 }
    2283
    2284 /* determine redundancy of one constraints side by checking for the first valuex2 */
    2285 if( coef0 > 0.0 )
    2286 {
    2287 /* if both constraints are equal on one value, only consider the other value */
    2288 if( *sideequal )
    2289 {
    2290 assert(!(*redundant0));
    2291 assert(!(*redundant1));
    2292
    2293 if( SCIPisLT(scip, valuey1, valuey2) )
    2294 {
    2295 *sideequal = FALSE;
    2296 *redundant1 = TRUE;
    2297 }
    2298 else if( SCIPisGT(scip, valuey1, valuey2) )
    2299 {
    2300 *sideequal = FALSE;
    2301 *redundant0 = TRUE;
    2302 }
    2303 }
    2304 /* if both constraints are weaker than the other on one value, we have no redundancy */
    2305 else if( ( *redundant1 && SCIPisGT(scip, valuey1, valuey2) )
    2306 || ( *redundant0 && SCIPisLT(scip, valuey1, valuey2) ) )
    2307 {
    2308 *redundant0 = FALSE;
    2309 *redundant1 = FALSE;
    2310 return;
    2311 }
    2312 }
    2313 else
    2314 {
    2315 /* if both constraints are equal on one value, only consider the other value */
    2316 if( *sideequal )
    2317 {
    2318 assert(!(*redundant0));
    2319 assert(!(*redundant1));
    2320
    2321 if( SCIPisLT(scip, valuey1, valuey2) )
    2322 {
    2323 *sideequal = FALSE;
    2324 *redundant0 = TRUE;
    2325 }
    2326 else if( SCIPisGT(scip, valuey1, valuey2) )
    2327 {
    2328 *sideequal = FALSE;
    2329 *redundant1 = TRUE;
    2330 }
    2331 }
    2332 /* if both constraints are weaker than the other one on one value, we have no redundancy */
    2333 else if( ( *redundant0 && SCIPisGT(scip, valuey1, valuey2) )
    2334 || ( *redundant1 && SCIPisLT(scip, valuey1, valuey2) ) )
    2335 {
    2336 *redundant0 = FALSE;
    2337 *redundant1 = FALSE;
    2338 return;
    2339 }
    2340 }
    2341 assert(*sideequal || *redundant0 || *redundant1);
    2342
    2343 /* calculate feasibility domain values for variable y concerning these both constraints */
    2344 if( coef0 > 0.0 )
    2345 {
    2346 if( islhs )
    2347 {
    2348 boundvaluey1 = MAX(boundylb1, boundylb2);
    2349 boundvaluey2 = MAX(boundyub1, boundyub2);
    2350 }
    2351 else
    2352 {
    2353 boundvaluey1 = MIN(boundylb1, boundylb2);
    2354 boundvaluey2 = MIN(boundyub1, boundyub2);
    2355 }
    2356
    2357 valuey1 = MIN(boundvaluey1, ubvbdvar);
    2358 valuey1 = MAX(valuey1, lbvbdvar);
    2359 valuey2 = MAX(boundvaluey2, lbvbdvar);
    2360 valuey2 = MIN(valuey2, ubvbdvar);
    2361
    2362 valuey1 = SCIPfeasFloor(scip, valuey1);
    2363 valuey2 = SCIPfeasCeil(scip, valuey2);
    2364 }
    2365 else
    2366 {
    2367 if( islhs )
    2368 {
    2369 boundvaluey1 = MIN(boundylb1, boundylb2);
    2370 boundvaluey2 = MIN(boundyub1, boundyub2);
    2371 }
    2372 else
    2373 {
    2374 boundvaluey1 = MAX(boundylb1, boundylb2);
    2375 boundvaluey2 = MAX(boundyub1, boundyub2);
    2376 }
    2377
    2378 valuey1 = MAX(boundvaluey1, lbvbdvar);
    2379 valuey1 = MIN(valuey1, ubvbdvar);
    2380 valuey2 = MIN(boundvaluey2, ubvbdvar);
    2381 valuey2 = MAX(valuey2, lbvbdvar);
    2382
    2383 valuey1 = SCIPfeasCeil(scip, valuey1);
    2384 valuey2 = SCIPfeasFloor(scip, valuey2);
    2385 }
    2386
    2387 /* calculate resulting values of variable x by setting y to valuey1 */
    2388 if( SCIPisInfinity(scip, ABS(valuey1)) )
    2389 {
    2390 /* only consider sides if coefficients are equal */
    2391 if( SCIPisEQ(scip, coef0, coef1) )
    2392 {
    2393 valuex1 = side0;
    2394 valuex2 = side1;
    2395 }
    2396 /* only consider swapped coefficients if otherwise y approaches plus infinity */
    2397 else if( valuey1 > 0.0 )
    2398 {
    2399 valuex1 = coef1;
    2400 valuex2 = coef0;
    2401 }
    2402 /* only consider original coefficients if otherwise y approaches minus infinity */
    2403 else
    2404 {
    2405 valuex1 = coef0;
    2406 valuex2 = coef1;
    2407 }
    2408 }
    2409 else
    2410 {
    2411 valuex1 = side0 - valuey1 * coef0;
    2412 valuex2 = side1 - valuey1 * coef1;
    2413 }
    2414
    2415 /* determine redundancy of one constraints side by checking for the first valuey1 */
    2416 if( *sideequal )
    2417 {
    2418 assert(!(*redundant0));
    2419 assert(!(*redundant1));
    2420
    2421 if( SCIPisLT(scip, valuex1, valuex2) )
    2422 {
    2423 *sideequal = FALSE;
    2424 *redundant1 = TRUE;
    2425 }
    2426 else if( SCIPisGT(scip, valuex1, valuex2) )
    2427 {
    2428 *sideequal = FALSE;
    2429 *redundant0 = TRUE;
    2430 }
    2431 }
    2432 else if( ( *redundant1 && SCIPisGT(scip, valuex1, valuex2) )
    2433 || ( *redundant0 && SCIPisLT(scip, valuex1, valuex2) ) )
    2434 {
    2435 *redundant0 = FALSE;
    2436 *redundant1 = FALSE;
    2437 return;
    2438 }
    2439
    2440 /* calculate resulting values of variable x by setting y to valuey2 */
    2441 if( SCIPisInfinity(scip, ABS(valuey2)) )
    2442 {
    2443 /* only consider sides if coefficients are equal */
    2444 if( SCIPisEQ(scip, coef0, coef1) )
    2445 {
    2446 valuex1 = side0;
    2447 valuex2 = side1;
    2448 }
    2449 /* only consider swapped coefficients if otherwise y approaches plus infinity */
    2450 else if( valuey2 > 0.0 )
    2451 {
    2452 valuex1 = coef1;
    2453 valuex2 = coef0;
    2454 }
    2455 /* only consider original coefficients if otherwise y approaches minus infinity */
    2456 else
    2457 {
    2458 valuex1 = coef0;
    2459 valuex2 = coef1;
    2460 }
    2461 }
    2462 else
    2463 {
    2464 valuex1 = side0 - valuey2 * coef0;
    2465 valuex2 = side1 - valuey2 * coef1;
    2466 }
    2467
    2468 /* determine redundancy of one constraints side by checking for the second valuey2 */
    2469 if( *sideequal )
    2470 {
    2471 assert(!(*redundant0));
    2472 assert(!(*redundant1));
    2473
    2474 if( SCIPisLT(scip, valuex1, valuex2) )
    2475 {
    2476 *sideequal = FALSE;
    2477 *redundant1 = TRUE;
    2478 }
    2479 else if( SCIPisGT(scip, valuex1, valuex2) )
    2480 {
    2481 *sideequal = FALSE;
    2482 *redundant0 = TRUE;
    2483 }
    2484 }
    2485 else if( ( *redundant1 && SCIPisGT(scip, valuex1, valuex2) )
    2486 || ( *redundant0 && SCIPisLT(scip, valuex1, valuex2) ) )
    2487 {
    2488 *redundant0 = FALSE;
    2489 *redundant1 = FALSE;
    2490 return;
    2491 }
    2492 assert(*redundant0 || *redundant1 || *sideequal);
    2493 }
    2494}
    2495
    2496/** compares each constraint with all other constraints for possible redundancy and removes or changes constraint
    2497 *
    2498 * we will order all constraint to have constraints with same variables next to each other to speed up presolving
    2499 *
    2500 * consider two constraints like lhs1 <= x + b1*y <= rhs1 and lhs2 <= x + b2*y <= rhs2
    2501 * we are doing the following presolving steps:
    2502 *
    2503 * if( b1 == b2 )
    2504 * newlhs = MAX(lhs1, lhs2)
    2505 * newrhs = MIN(rhs1, rhs2)
    2506 * updateSides
    2507 * delete one constraint
    2508 * else if( ((b1 > 0) == (b2 > 0)) && (lhs1 != -inf && lhs2 != -inf) || (rhs1 != inf && rhs2 != inf) )
    2509 *
    2510 * (i.e. both constraint have either a valid lhs or a valid rhs and infinity is on the same side and the
    2511 * coeffcients have the same size )
    2512 *
    2513 * if( y is binary )
    2514 * if( lhs1 != -inf )
    2515 * newlhs = MAX(lhs1, lhs2)
    2516 * newb = newlhs - MAX(lhs1 - b1, lhs2 - b2)
    2517 * else
    2518 * newrhs = MIN(lhs1, lhs2)
    2519 * newb = newrhs - MIN(rhs1 - b1, rhs2 - b2)
    2520 * updateSidesAndCoef
    2521 * delete one constraint
    2522 * else
    2523 * we calculate possible values for both variables and check which constraint is tighter
    2524 * else
    2525 * nothing possible
    2526 *
    2527 * We also try to tighten bounds in the case of two constraints lhs1 <= x + b1*y <= rhs1 and lhs2 <= y + b2*x <= rhs2.
    2528 * Eliminiating one variable and inserting into the second yields the following bounds:
    2529 * If b2 > 0:
    2530 * (1 - b1 * b2) * y >= lhs2 - b2 * rhs1
    2531 * (1 - b1 * b2) * y <= rhs2 - b2 * lhs1
    2532 * If b2 < 0:
    2533 * (1 - b1 * b2) * y >= lhs2 - b2 * lhs1
    2534 * (1 - b1 * b2) * y <= rhs2 - b2 * rhs1
    2535 * The case of x is similar.
    2536 */
    2537static
    2539 SCIP* scip, /**< SCIP data structure */
    2540 SCIP_CONS** conss, /**< constraint set */
    2541 int nconss, /**< number of constraints in constraint set */
    2542 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    2543 int* nchgbds, /**< pointer to count number of bound changes */
    2544 int* ndelconss, /**< pointer to count number of deleted constraints */
    2545 int* nchgcoefs, /**< pointer to count the number of changed coefficients */
    2546 int* nchgsides /**< pointer to count number of changed left/right hand sides */
    2547 )
    2548{
    2549 SCIP_CONS** sortedconss;
    2550 int c;
    2551 int s;
    2552
    2553 assert(scip != NULL);
    2554 assert(conss != NULL);
    2555 assert(cutoff != NULL);
    2556 assert(nchgbds != NULL);
    2557 assert(ndelconss != NULL);
    2558 assert(nchgcoefs != NULL);
    2559 assert(nchgsides != NULL);
    2560
    2561 /* create our temporary working array */
    2562 SCIP_CALL( SCIPduplicateBufferArray(scip, &sortedconss, conss, nconss) );
    2563
    2564 /* sort all constraints, so that all constraints with same variables stand next to each other */
    2565 SCIPsortPtr((void**)sortedconss, consVarboundComp, nconss);
    2566
    2567 /* check all constraints for redundancy */
    2568 for( c = nconss - 1; c > 0 && !(*cutoff); --c )
    2569 {
    2570 SCIP_CONS* cons0;
    2571 SCIP_CONSDATA* consdata0;
    2572
    2573 cons0 = sortedconss[c];
    2574
    2575 if( !SCIPconsIsActive(cons0) || SCIPconsIsModifiable(cons0) )
    2576 continue;
    2577
    2578 consdata0 = SCIPconsGetData(cons0);
    2579 assert(consdata0 != NULL);
    2580 assert(consdata0->var != NULL);
    2581 assert(consdata0->vbdvar != NULL);
    2582
    2583 /* do not check for already redundant constraints */
    2584 assert(!SCIPisZero(scip, consdata0->vbdcoef));
    2585 assert(!SCIPisInfinity(scip, -consdata0->lhs) || !SCIPisInfinity(scip, consdata0->rhs));
    2586
    2587 if( !consdata0->changed )
    2588 continue;
    2589
    2590 consdata0->changed = FALSE;
    2591
    2592 for( s = c - 1; s >= 0; --s )
    2593 {
    2594 SCIP_CONS* cons1;
    2595 SCIP_CONSDATA* consdata1;
    2596 SCIP_Real lhs;
    2597 SCIP_Real rhs;
    2598 SCIP_Real coef;
    2599 SCIP_Bool deletecons1;
    2600
    2601 cons1 = sortedconss[s];
    2602
    2603 if( !SCIPconsIsActive(cons1) || SCIPconsIsModifiable(cons1) )
    2604 continue;
    2605
    2606 consdata1 = SCIPconsGetData(cons1);
    2607 assert(consdata1 != NULL);
    2608 assert(consdata1->var != NULL);
    2609 assert(consdata1->vbdvar != NULL);
    2610
    2611 /* do not check for already redundant constraints */
    2612 assert(!SCIPisZero(scip, consdata1->vbdcoef));
    2613 assert(!SCIPisInfinity(scip, -consdata1->lhs) || !SCIPisInfinity(scip, consdata1->rhs));
    2614
    2615 lhs = consdata0->lhs;
    2616 rhs = consdata0->rhs;
    2617 coef = consdata0->vbdcoef;
    2618
    2619 /* check for propagation in the case: lhs1 <= x + b1*y <= rhs1 and lhs2 <= y + b2*x <= rhs2. */
    2620 if ( consdata0->var == consdata1->vbdvar && consdata0->vbdvar == consdata1->var &&
    2621 !SCIPisFeasZero(scip, 1.0 - coef * consdata1->vbdcoef) )
    2622 {
    2623 SCIP_Bool tightened = FALSE;
    2624 SCIP_Real bnd = SCIP_UNKNOWN;
    2625 SCIP_Real scalar;
    2626 SCIP_Real newbnd;
    2627
    2628 scalar = (1.0 - coef * consdata1->vbdcoef);
    2629
    2630 assert( ! SCIPisInfinity(scip, REALABS(scalar)) );
    2631 assert( ! SCIPisZero(scip, consdata0->vbdcoef) );
    2632 assert( ! SCIPisZero(scip, consdata1->vbdcoef) );
    2633
    2634 /* lower bounds for consdata0->var */
    2635 if ( ! SCIPisInfinity(scip, -lhs) )
    2636 {
    2637 if ( SCIPisPositive(scip, coef) )
    2638 {
    2639 if ( ! SCIPisInfinity(scip, consdata1->rhs) )
    2640 bnd = (lhs - coef * consdata1->rhs)/scalar;
    2641 }
    2642 else
    2643 {
    2644 assert( SCIPisNegative(scip, coef) );
    2645 if ( ! SCIPisInfinity(scip, consdata1->lhs) )
    2646 bnd = (lhs - coef * consdata1->lhs)/scalar;
    2647 }
    2648
    2649 if ( bnd != SCIP_UNKNOWN ) /*lint !e777*/
    2650 {
    2651 if ( SCIPisFeasPositive(scip, scalar) )
    2652 {
    2653 newbnd = SCIPadjustedVarLb(scip, consdata0->var, bnd);
    2654 SCIP_CALL( SCIPtightenVarLb(scip, consdata0->var, newbnd, FALSE, cutoff, &tightened) );
    2655 if ( *cutoff )
    2656 {
    2657 SCIPdebugMsg(scip, "<%s>, <%s> -> tightening <%s> >= %.15g infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2658 SCIPvarGetName(consdata0->var), newbnd);
    2659 break;
    2660 }
    2661 if ( tightened )
    2662 {
    2663 SCIPdebugMsg(scip, "<%s>, <%s> -> tightened lower bound: <%s> >= %.15g\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2664 SCIPvarGetName(consdata0->var), SCIPvarGetLbGlobal(consdata0->var));
    2665 (*nchgbds)++;
    2666 }
    2667 }
    2668 else if ( SCIPisFeasNegative(scip, scalar) )
    2669 {
    2670 newbnd = SCIPadjustedVarUb(scip, consdata0->var, bnd);
    2671 SCIP_CALL( SCIPtightenVarUb(scip, consdata0->var, newbnd, FALSE, cutoff, &tightened) );
    2672 if ( *cutoff )
    2673 {
    2674 SCIPdebugMsg(scip, "<%s>, <%s> -> tightening <%s> <= %.15g infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2675 SCIPvarGetName(consdata0->var), newbnd);
    2676 break;
    2677 }
    2678 if ( tightened )
    2679 {
    2680 SCIPdebugMsg(scip, "<%s>, <%s> -> tightened upper bound: <%s> <= %.15g\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2681 SCIPvarGetName(consdata0->var), SCIPvarGetUbGlobal(consdata0->var));
    2682 (*nchgbds)++;
    2683 }
    2684 }
    2685 }
    2686 }
    2687
    2688 /* upper bound for consdata0>var */
    2689 if ( ! SCIPisInfinity(scip, rhs) )
    2690 {
    2691 bnd = SCIP_UNKNOWN;
    2692 if ( SCIPisPositive(scip, coef) )
    2693 {
    2694 if ( ! SCIPisInfinity(scip, consdata1->lhs) )
    2695 bnd = (rhs - coef * consdata1->lhs)/scalar;
    2696 }
    2697 else
    2698 {
    2699 assert( SCIPisNegative(scip, coef) );
    2700 if ( ! SCIPisInfinity(scip, consdata1->rhs) )
    2701 bnd = (rhs - coef * consdata1->rhs)/scalar;
    2702 }
    2703
    2704 if ( bnd != SCIP_UNKNOWN ) /*lint !e777*/
    2705 {
    2706 if ( SCIPisFeasPositive(scip, scalar) )
    2707 {
    2708 newbnd = SCIPadjustedVarUb(scip, consdata0->var, bnd);
    2709 SCIP_CALL( SCIPtightenVarUb(scip, consdata0->var, newbnd, FALSE, cutoff, &tightened) );
    2710 if ( *cutoff )
    2711 {
    2712 SCIPdebugMsg(scip, "<%s>, <%s> -> tightening <%s> <= %.15g infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2713 SCIPvarGetName(consdata0->var), newbnd);
    2714 break;
    2715 }
    2716 if ( tightened )
    2717 {
    2718 SCIPdebugMsg(scip, "<%s>, <%s> -> tightened upper bound: <%s> <= %.15g\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2719 SCIPvarGetName(consdata0->var), SCIPvarGetUbGlobal(consdata0->var));
    2720 (*nchgbds)++;
    2721 }
    2722 }
    2723 else if ( SCIPisFeasNegative(scip, scalar) )
    2724 {
    2725 newbnd = SCIPadjustedVarLb(scip, consdata0->var, bnd);
    2726 SCIP_CALL( SCIPtightenVarLb(scip, consdata0->var, newbnd, FALSE, cutoff, &tightened) );
    2727 if ( *cutoff )
    2728 {
    2729 SCIPdebugMsg(scip, "<%s>, <%s> -> tightening <%s> >= %.15g infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2730 SCIPvarGetName(consdata0->var), newbnd);
    2731 break;
    2732 }
    2733 if ( tightened )
    2734 {
    2735 SCIPdebugMsg(scip, "<%s>, <%s> -> tightened lower bound: <%s> >= %.15g\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2736 SCIPvarGetName(consdata0->var), SCIPvarGetLbGlobal(consdata0->var));
    2737 (*nchgbds)++;
    2738 }
    2739 }
    2740 }
    2741 }
    2742
    2743 /* lower bounds for consdata1->var */
    2744 if ( ! SCIPisInfinity(scip, -consdata1->lhs) )
    2745 {
    2746 bnd = SCIP_UNKNOWN;
    2747 if ( SCIPisPositive(scip, consdata1->vbdcoef) )
    2748 {
    2749 if ( ! SCIPisInfinity(scip, rhs) )
    2750 bnd = (consdata1->lhs - consdata1->vbdcoef * rhs)/scalar;
    2751 }
    2752 else
    2753 {
    2754 assert( SCIPisNegative(scip, consdata1->vbdcoef) );
    2755 if ( ! SCIPisInfinity(scip, lhs) )
    2756 bnd = (consdata1->lhs - consdata1->vbdcoef * lhs)/scalar;
    2757 }
    2758
    2759 if ( bnd != SCIP_UNKNOWN ) /*lint !e777*/
    2760 {
    2761 if ( SCIPisFeasPositive(scip, scalar) )
    2762 {
    2763 newbnd = SCIPadjustedVarLb(scip, consdata1->var, bnd);
    2764 SCIP_CALL( SCIPtightenVarLb(scip, consdata1->var, newbnd, FALSE, cutoff, &tightened) );
    2765 if ( *cutoff )
    2766 {
    2767 SCIPdebugMsg(scip, "<%s>, <%s> -> tightening <%s> >= %.15g infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2768 SCIPvarGetName(consdata1->var), newbnd);
    2769 break;
    2770 }
    2771 if ( tightened )
    2772 {
    2773 SCIPdebugMsg(scip, "<%s>, <%s> -> tightened lower bound: <%s> >= %.15g\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2774 SCIPvarGetName(consdata1->var), SCIPvarGetLbGlobal(consdata1->var));
    2775 (*nchgbds)++;
    2776 }
    2777 }
    2778 else if ( SCIPisFeasNegative(scip, scalar) )
    2779 {
    2780 newbnd = SCIPadjustedVarUb(scip, consdata1->var, bnd);
    2781 SCIP_CALL( SCIPtightenVarUb(scip, consdata1->var, newbnd, FALSE, cutoff, &tightened) );
    2782 if ( *cutoff )
    2783 {
    2784 SCIPdebugMsg(scip, "<%s>, <%s> -> tightening <%s> <= %.15g infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2785 SCIPvarGetName(consdata1->var), newbnd);
    2786 break;
    2787 }
    2788 if ( tightened )
    2789 {
    2790 SCIPdebugMsg(scip, "<%s>, <%s> -> tightened upper bound: <%s> <= %.15g\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2791 SCIPvarGetName(consdata1->var), SCIPvarGetUbGlobal(consdata1->var));
    2792 (*nchgbds)++;
    2793 }
    2794 }
    2795 }
    2796 }
    2797
    2798 /* upper bound for consdata1->var */
    2799 if ( ! SCIPisInfinity(scip, consdata1->rhs) )
    2800 {
    2801 bnd = SCIP_UNKNOWN;
    2802 if ( SCIPisPositive(scip, consdata1->vbdcoef) )
    2803 {
    2804 if ( ! SCIPisInfinity(scip, lhs) )
    2805 bnd = (consdata1->rhs - consdata1->vbdcoef * lhs)/scalar;
    2806 }
    2807 else
    2808 {
    2809 assert( SCIPisNegative(scip, consdata1->vbdcoef) );
    2810 if ( ! SCIPisInfinity(scip, rhs) )
    2811 bnd = (consdata1->rhs - consdata1->vbdcoef * rhs)/scalar;
    2812 }
    2813
    2814 if ( bnd != SCIP_UNKNOWN ) /*lint !e777*/
    2815 {
    2816 if ( SCIPisFeasPositive(scip, scalar) )
    2817 {
    2818 newbnd = SCIPadjustedVarUb(scip, consdata1->var, bnd);
    2819 SCIP_CALL( SCIPtightenVarUb(scip, consdata1->var, newbnd, FALSE, cutoff, &tightened) );
    2820 if ( *cutoff )
    2821 {
    2822 SCIPdebugMsg(scip, "<%s>, <%s> -> tightening <%s> <= %.15g infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2823 SCIPvarGetName(consdata1->var), newbnd);
    2824 break;
    2825 }
    2826 if ( tightened )
    2827 {
    2828 SCIPdebugMsg(scip, "<%s>, <%s> -> tightened upper bound: <%s> <= %.15g\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2829 SCIPvarGetName(consdata1->var), SCIPvarGetUbGlobal(consdata1->var));
    2830 (*nchgbds)++;
    2831 }
    2832 }
    2833 else if ( SCIPisFeasNegative(scip, scalar) )
    2834 {
    2835 newbnd = SCIPadjustedVarLb(scip, consdata1->var, bnd);
    2836 SCIP_CALL( SCIPtightenVarLb(scip, consdata1->var, newbnd, FALSE, cutoff, &tightened) );
    2837 if ( *cutoff )
    2838 {
    2839 SCIPdebugMsg(scip, "<%s>, <%s> -> tightening <%s> >= %.15g infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2840 SCIPvarGetName(consdata1->var), newbnd);
    2841 break;
    2842 }
    2843 if ( tightened )
    2844 {
    2845 SCIPdebugMsg(scip, "<%s>, <%s> -> tightened lower bound: <%s> >= %.15g\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1),
    2846 SCIPvarGetName(consdata1->var), SCIPvarGetLbGlobal(consdata1->var));
    2847 (*nchgbds)++;
    2848 }
    2849 }
    2850 }
    2851 }
    2852 }
    2853
    2854 /* check for equal variables */
    2855 if( consdata0->var != consdata1->var || consdata0->vbdvar != consdata1->vbdvar )
    2856 break;
    2857
    2858 /* mark constraint1 for deletion if possible */
    2859 deletecons1 = TRUE;
    2860
    2861 /* the coefficients of both constraints are equal */
    2862 if( SCIPisEQ(scip, coef, consdata1->vbdcoef) )
    2863 {
    2864 lhs = MAX(consdata1->lhs, lhs);
    2865 rhs = MIN(consdata1->rhs, rhs);
    2866 }
    2867 /* now only one side and in both constraints the same side should be infinity and the vbdvar should be binary
    2868 * then we neither do not need to have the same side nor the same coefficient
    2869 */
    2870 else if( SCIPvarIsBinary(consdata0->vbdvar)
    2871 && (SCIPisInfinity(scip, -lhs) || SCIPisInfinity(scip, rhs))
    2872 && (SCIPisInfinity(scip, -consdata1->lhs) || SCIPisInfinity(scip, consdata1->rhs))
    2873 && (SCIPisInfinity(scip, -lhs) == SCIPisInfinity(scip, -consdata1->lhs)) )
    2874 {
    2875 /* lhs <= x + b*y <= +inf */
    2876 if( !SCIPisInfinity(scip, -lhs) )
    2877 {
    2878 lhs = MAX(consdata1->lhs, lhs);
    2879 coef = lhs - MAX(consdata1->lhs - consdata1->vbdcoef, consdata0->lhs - coef);
    2880 }
    2881 /* -inf <= x + b*y <= rhs */
    2882 else
    2883 {
    2884 rhs = MIN(consdata1->rhs, rhs);
    2885 coef = rhs - MIN(consdata1->rhs - consdata1->vbdcoef, consdata0->rhs - coef);
    2886 }
    2887
    2889 }
    2890 else if( SCIPisPositive(scip, coef) == SCIPisPositive(scip, consdata1->vbdcoef)
    2891 && ((!SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, -consdata1->lhs))
    2892 || (!SCIPisInfinity(scip, rhs) && !SCIPisInfinity(scip, consdata1->rhs))) )
    2893 {
    2894 SCIP_Bool cons0lhsred;
    2895 SCIP_Bool cons0rhsred;
    2896 SCIP_Bool cons1lhsred;
    2897 SCIP_Bool cons1rhsred;
    2898 SCIP_Bool lhsequal;
    2899 SCIP_Bool rhsequal;
    2900
    2901 assert(!SCIPisInfinity(scip, lhs));
    2902 assert(!SCIPisInfinity(scip, consdata1->lhs));
    2903 assert(!SCIPisInfinity(scip, -rhs));
    2904 assert(!SCIPisInfinity(scip, -consdata1->rhs));
    2905
    2906 /* check if a left hand side of one constraints is redundant */
    2907 checkRedundancySide(scip, consdata0->var, consdata0->vbdvar, coef, consdata1->vbdcoef, lhs, consdata1->lhs, &lhsequal, &cons0lhsred, &cons1lhsred, TRUE);
    2908
    2909 /* check if a right hand side of one constraints is redundant */
    2910 checkRedundancySide(scip, consdata0->var, consdata0->vbdvar, coef, consdata1->vbdcoef, rhs, consdata1->rhs, &rhsequal, &cons0rhsred, &cons1rhsred, FALSE);
    2911
    2912 /* if cons0 is redundant, update cons1 and delete cons0 */
    2913 if( (lhsequal || cons0lhsred) && (rhsequal || cons0rhsred) )
    2914 {
    2915 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    2916 SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
    2917
    2918 SCIPdebugMsg(scip, "constraint: ");
    2919 SCIPdebugPrintCons(scip, cons0, NULL);
    2920 SCIPdebugMsg(scip, "is redundant to constraint: ");
    2921 SCIPdebugPrintCons(scip, cons1, NULL);
    2922
    2923 SCIP_CALL( SCIPdelCons(scip, cons0) );
    2924 ++(*ndelconss);
    2925
    2926 /* get next cons0 */
    2927 break;
    2928 }
    2929 /* if cons1 is redundant, update cons0 and delete cons1 */
    2930 else if( cons1lhsred && cons1rhsred )
    2931 {
    2932 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    2933 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
    2934
    2935 SCIPdebugMsg(scip, "constraint: ");
    2936 SCIPdebugPrintCons(scip, cons1, NULL);
    2937 SCIPdebugMsg(scip, "is redundant to constraint: ");
    2938 SCIPdebugPrintCons(scip, cons0, NULL);
    2939
    2940 SCIP_CALL( SCIPdelCons(scip, cons1) );
    2941 ++(*ndelconss);
    2942
    2943 /* get next cons1 */
    2944 continue;
    2945 }
    2946 /* if left hand side of cons0 is redundant set it to -infinity */
    2947 else if( (lhsequal || cons0lhsred) && !SCIPisInfinity(scip, -lhs) )
    2948 {
    2949 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    2950 SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
    2951
    2952 lhs = -SCIPinfinity(scip);
    2953
    2954 /* if right hand side of cons1 is redundant too, set it to infinity */
    2955 if( cons1rhsred && !SCIPisInfinity(scip, consdata1->rhs) )
    2956 {
    2957 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    2958 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
    2959
    2960 SCIP_CALL( chgRhs(scip, cons1, SCIPinfinity(scip)) );
    2961 ++(*nchgsides);
    2962
    2963 SCIPdebugMsg(scip, "deleted rhs of constraint: ");
    2964 SCIPdebugPrintCons(scip, cons1, NULL);
    2965 SCIPdebugMsg(scip, "due to constraint: ");
    2966 SCIPdebugPrintCons(scip, cons0, NULL);
    2967 }
    2968
    2969 /* later on we do not want to delete cons1 */
    2970 deletecons1 = FALSE;
    2971 }
    2972 /* if right hand side of cons0 is redundant set it to infinity */
    2973 else if( (rhsequal || cons0rhsred) && !SCIPisInfinity(scip, rhs) )
    2974 {
    2975 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    2976 SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
    2977
    2978 rhs = SCIPinfinity(scip);
    2979
    2980 /* if left hand side of cons1 is redundant too, set it to -infinity */
    2981 if( cons1lhsred && !SCIPisInfinity(scip, -consdata1->lhs) )
    2982 {
    2983 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    2984 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
    2985
    2986 SCIP_CALL( chgLhs(scip, cons1, -SCIPinfinity(scip)) );
    2987 ++(*nchgsides);
    2988
    2989 SCIPdebugMsg(scip, "deleted lhs of constraint: ");
    2990 SCIPdebugPrintCons(scip, cons1, NULL);
    2991 SCIPdebugMsg(scip, "due to constraint: ");
    2992 SCIPdebugPrintCons(scip, cons0, NULL);
    2993 }
    2994
    2995 /* later on we do not want to delete cons1 */
    2996 deletecons1 = FALSE;
    2997 }
    2998 /* if left hand side of cons1 is redundant set it to -infinity */
    2999 else if( cons1lhsred && !SCIPisInfinity(scip, -consdata1->lhs) )
    3000 {
    3001 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    3002 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
    3003
    3004 SCIP_CALL( chgLhs(scip, cons1, -SCIPinfinity(scip)) );
    3005 ++(*nchgsides);
    3006
    3007 SCIPdebugMsg(scip, "deleted lhs of constraint: ");
    3008 SCIPdebugPrintCons(scip, cons1, NULL);
    3009 SCIPdebugMsg(scip, "due to constraint: ");
    3010 SCIPdebugPrintCons(scip, cons0, NULL);
    3011
    3012 continue;
    3013 }
    3014 /* if right hand side of cons1 is redundant set it to infinity */
    3015 else if( cons1rhsred && !SCIPisInfinity(scip, consdata1->rhs) )
    3016 {
    3017 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    3018 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
    3019
    3020 SCIP_CALL( chgRhs(scip, cons1, SCIPinfinity(scip)) );
    3021 ++(*nchgsides);
    3022
    3023 SCIPdebugMsg(scip, "deleted rhs of constraint: ");
    3024 SCIPdebugPrintCons(scip, cons1, NULL);
    3025 SCIPdebugMsg(scip, "due to constraint: ");
    3026 SCIPdebugPrintCons(scip, cons0, NULL);
    3027
    3028 continue;
    3029 }
    3030 else /* nothing was redundant */
    3031 continue;
    3032 }
    3033 else
    3034 {
    3035 /* there is no redundancy in both constraints with same variables */
    3036 continue;
    3037 }
    3038
    3039 if( SCIPisFeasLT(scip, rhs, lhs) )
    3040 {
    3041 SCIPdebugMsg(scip, "constraint <%s> and <%s> lead to infeasibility due to their sides\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    3042 *cutoff = TRUE;
    3043 break;
    3044 }
    3045
    3046 /* ensure that lhs <= rhs holds without tolerances as we only allow such rows to enter the LP */
    3047 if( lhs > rhs )
    3048 {
    3049 rhs = (lhs + rhs)/2;
    3050 lhs = rhs;
    3051 }
    3052
    3053 /* we decide to let constraint cons0 stay, so update data structure consdata0 */
    3054
    3055 /* update coefficient of cons0 */
    3056
    3057 /* special case if new coefficient becomes zero, both constraints are redundant but we may tighten the bounds */
    3058 if( SCIPisZero(scip, coef) )
    3059 {
    3060 SCIP_Bool tightened;
    3061
    3062 SCIPdebugMsg(scip, "constraint: ");
    3063 SCIPdebugPrintCons(scip, cons1, NULL);
    3064 SCIPdebugMsg(scip, "and constraint: ");
    3065 SCIPdebugPrintCons(scip, cons0, NULL);
    3066 SCIPdebugMsg(scip, "are both redundant and lead to bounding of <%s> in [%g, %g]\n", SCIPvarGetName(consdata0->var), lhs, rhs);
    3067
    3068 /* delete cons1 */
    3069 SCIP_CALL( SCIPdelCons(scip, cons1) );
    3070 ++(*ndelconss);
    3071
    3072 /* update upper bound if possible
    3073 *
    3074 * @note we need to force the bound change since we are deleting the constraint afterwards
    3075 */
    3076 SCIP_CALL( SCIPtightenVarUb(scip, consdata0->var, rhs, TRUE, cutoff, &tightened) );
    3077 if( *cutoff )
    3078 break;
    3079 if( tightened )
    3080 ++(*nchgbds);
    3081
    3082 /* update lower bound if possible
    3083 *
    3084 * @note we need to force the bound change since we are deleting the constraint afterwards
    3085 */
    3086 SCIP_CALL( SCIPtightenVarLb(scip, consdata0->var, lhs, TRUE, cutoff, &tightened) );
    3087 if( *cutoff )
    3088 break;
    3089 if( tightened )
    3090 ++(*nchgbds);
    3091
    3092 /* delete cons0 */
    3093 SCIP_CALL( SCIPdelCons(scip, cons0) );
    3094 ++(*ndelconss);
    3095
    3096 /* get next cons0 */
    3097 break;
    3098 }
    3099
    3100 SCIPdebugMsg(scip, "constraint: ");
    3101 SCIPdebugPrintCons(scip, cons1, NULL);
    3102 SCIPdebugMsg(scip, "and constraint: ");
    3103 SCIPdebugPrintCons(scip, cons0, NULL);
    3104
    3105 /* if sign of coefficient switches, update the locks of the variable */
    3106 if( consdata0->vbdcoef * coef < 0.0 )
    3107 {
    3108 assert(SCIPconsIsTransformed(cons0));
    3109
    3110 /* remove locks for variable with old coefficient and install locks for variable with new
    3111 * coefficient
    3112 */
    3113 if( consdata0->vbdcoef > 0.0 )
    3114 {
    3115 SCIP_CALL( SCIPunlockVarCons(scip, consdata0->vbdvar, cons0, !SCIPisInfinity(scip, -consdata0->lhs),
    3116 !SCIPisInfinity(scip, consdata0->rhs)) );
    3117 SCIP_CALL( SCIPlockVarCons(scip, consdata0->vbdvar, cons0, !SCIPisInfinity(scip, consdata0->rhs),
    3118 !SCIPisInfinity(scip, -consdata0->lhs)) );
    3119 }
    3120 else
    3121 {
    3122 SCIP_CALL( SCIPunlockVarCons(scip, consdata0->vbdvar, cons0, !SCIPisInfinity(scip, consdata0->rhs),
    3123 !SCIPisInfinity(scip, -consdata0->lhs)) );
    3124 SCIP_CALL( SCIPlockVarCons(scip, consdata0->vbdvar, cons0, !SCIPisInfinity(scip, -consdata0->lhs),
    3125 !SCIPisInfinity(scip, consdata0->rhs)) );
    3126 }
    3127 }
    3128
    3129 /* now change the coefficient */
    3130 if( !SCIPisEQ(scip, consdata0->vbdcoef, coef) )
    3131 {
    3132 ++(*nchgcoefs);
    3133
    3134 /* mark to add new varbound information */
    3135 consdata0->varboundsadded = FALSE;
    3136 consdata0->tightened = FALSE;
    3137 consdata0->presolved = FALSE;
    3138 consdata0->changed = FALSE;
    3139
    3140 consdata0->vbdcoef = coef;
    3141
    3143 }
    3144
    3145 /* update lhs and rhs of cons0 */
    3146 if( !SCIPisEQ(scip, consdata0->lhs, lhs) )
    3147 {
    3148 SCIP_CALL( chgLhs(scip, cons0, lhs) );
    3149 ++(*nchgsides);
    3150 }
    3151 if( !SCIPisEQ(scip, consdata0->rhs, rhs) )
    3152 {
    3153 SCIP_CALL( chgRhs(scip, cons0, rhs) );
    3154 ++(*nchgsides);
    3155 }
    3156
    3157 SCIPdebugMsg(scip, "lead to new constraint: ");
    3158 SCIPdebugPrintCons(scip, cons0, NULL);
    3159
    3160 /* if cons1 is still marked for deletion, delete it */
    3161 if( deletecons1 )
    3162 {
    3163 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    3164 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
    3165
    3166 /* delete cons1 */
    3167 SCIP_CALL( SCIPdelCons(scip, cons1) );
    3168 ++(*ndelconss);
    3169 }
    3170
    3171 assert(SCIPconsIsActive(cons0));
    3172 }
    3173 }
    3174
    3175 /* free temporary memory */
    3176 SCIPfreeBufferArray(scip, &sortedconss);
    3177
    3178 return SCIP_OKAY;
    3179}
    3180
    3181/** for all varbound constraints with two integer variables make the coefficients integral */
    3182static
    3184 SCIP* scip, /**< SCIP data structure */
    3185 SCIP_CONS** conss, /**< constraint set */
    3186 int nconss, /**< number of constraints in constraint set */
    3187 int* nchgcoefs, /**< pointer to count the number of changed coefficients */
    3188 int* nchgsides /**< pointer to count number of changed left/right hand sides */
    3189 )
    3190{
    3191 SCIP_CONSDATA* consdata;
    3192 int c;
    3193
    3194 assert(scip != NULL);
    3195 assert(conss != NULL || nconss == 0);
    3196 assert(nchgcoefs != NULL);
    3197 assert(nchgsides != NULL);
    3198
    3199 /* if we cannot find any constraint for prettifying, stop */
    3201 return;
    3202
    3203 for( c = nconss - 1; c >= 0; --c )
    3204 {
    3205 assert(conss != NULL);
    3206
    3207 if( SCIPconsIsDeleted(conss[c]) )
    3208 continue;
    3209
    3210 consdata = SCIPconsGetData(conss[c]);
    3211 assert(consdata != NULL);
    3212
    3213 /* check for integer variables and one coefficient with an absolute value smaller than 1 */
    3214 /* @note: we allow that the variable type of the bounded variable can be smaller than the variable type of the
    3215 * bounding variable
    3216 */
    3217 if( SCIPvarIsIntegral(consdata->var) && SCIPvarIsIntegral(consdata->vbdvar)
    3218 && SCIPvarGetType(consdata->vbdvar) != SCIP_VARTYPE_BINARY
    3219 && SCIPisLT(scip, REALABS(consdata->vbdcoef), 1.0) )
    3220 {
    3221 SCIP_Real epsilon;
    3224 SCIP_Longint maxmult;
    3225 SCIP_Bool success;
    3226
    3228 maxmult = MIN(maxmult, MAXSCALEDCOEF);
    3229
    3230 /* this ensures that one coefficient in the scaled constraint will be one as asserted below; 0.9 to be safe */
    3231 epsilon = SCIPepsilon(scip) / (SCIP_Real)maxmult;
    3232 epsilon *= 0.9;
    3233
    3234 success = SCIPrealToRational(consdata->vbdcoef, -epsilon, epsilon , maxmult, &numerator, &denominator);
    3235
    3236 if( success )
    3237 {
    3238 /* it is possible that the dominator is a multiple of the numerator */
    3240 {
    3242 numerator = 1;
    3243 }
    3244
    3245 success = success && (denominator <= maxmult);
    3246
    3247 /* scale the constraint denominator/numerator */
    3248 if( success && ABS(denominator) > 1 && numerator == 1 )
    3249 {
    3250 SCIP_VAR* swapvar;
    3251
    3252 /* print constraint before scaling */
    3253 SCIPdebugPrintCons(scip, conss[c], NULL);
    3254
    3255 assert(SCIPisEQ(scip, consdata->vbdcoef * denominator, 1.0));
    3256
    3257 /* need to switch sides if coefficient is smaller then 0 */
    3258 if( consdata->vbdcoef < 0 )
    3259 {
    3260 assert(denominator < 0);
    3261
    3262 /* compute new sides */
    3263
    3264 /* only right hand side exists */
    3265 if( SCIPisInfinity(scip, -consdata->lhs) )
    3266 {
    3267 consdata->lhs = consdata->rhs * denominator;
    3268 assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->lhs));
    3269
    3270 consdata->rhs = SCIPinfinity(scip);
    3271 }
    3272 /* only left hand side exists */
    3273 else if( SCIPisInfinity(scip, consdata->rhs) )
    3274 {
    3275 consdata->rhs = consdata->lhs * denominator;
    3276 assert(!SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->rhs));
    3277
    3278 consdata->lhs = -SCIPinfinity(scip);
    3279 }
    3280 /* both sides exist */
    3281 else
    3282 {
    3283 SCIP_Real tmp;
    3284
    3285 tmp = consdata->lhs;
    3286 consdata->lhs = consdata->rhs * denominator;
    3287 consdata->rhs = tmp * denominator;
    3288 consdata->tightened = FALSE;
    3289
    3290 assert(!SCIPisInfinity(scip, consdata->lhs) && !SCIPisInfinity(scip, -consdata->lhs));
    3291 assert(SCIPisGE(scip, consdata->rhs, consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
    3292 }
    3293 *nchgsides += 2;
    3294 }
    3295 /* coefficient > 0 */
    3296 else
    3297 {
    3298 assert(denominator > 0);
    3299
    3300 /* compute new left hand side */
    3301 if( !SCIPisInfinity(scip, -consdata->lhs) )
    3302 {
    3303 consdata->lhs *= denominator;
    3304 assert(!SCIPisInfinity(scip, consdata->lhs) && !SCIPisInfinity(scip, -consdata->lhs));
    3305 ++(*nchgsides);
    3306 }
    3307
    3308 /* compute new right hand side */
    3309 if( !SCIPisInfinity(scip, consdata->rhs) )
    3310 {
    3311 consdata->rhs *= denominator;
    3312 assert(!SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->rhs));
    3313 ++(*nchgsides);
    3314 }
    3315
    3316 assert(SCIPisGE(scip, consdata->rhs, consdata->lhs));
    3317 }
    3318
    3319 /* swap both variables */
    3320 swapvar = consdata->var;
    3321 consdata->var = consdata->vbdvar;
    3322 consdata->vbdvar = swapvar;
    3323
    3324 /* swap coefficient */
    3325 consdata->vbdcoef = (SCIP_Real)denominator;
    3326 ++(*nchgcoefs);
    3327
    3328 /* mark to add new varbound information */
    3329 consdata->varboundsadded = FALSE;
    3330 consdata->tightened = FALSE;
    3331
    3332 /* print constraint after scaling */
    3333 SCIPdebugMsg(scip, "transformed into:");
    3334 SCIPdebugPrintCons(scip, conss[c], NULL);
    3335 }
    3336 }
    3337 }
    3338 }
    3339}
    3340
    3341/** replaces fixed and aggregated variables in variable bound constraint by active problem variables */
    3342static
    3344 SCIP* scip, /**< SCIP data structure */
    3345 SCIP_CONS* cons, /**< variable bound constraint */
    3346 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    3347 SCIP_Bool* cutoff, /**< pointer to store whether an infeasibility was detected */
    3348 int* nchgbds, /**< pointer to count number of bound changes */
    3349 int* ndelconss, /**< pointer to count number of deleted constraints */
    3350 int* naddconss /**< pointer to count number of added constraints */
    3351 )
    3352{
    3353 SCIP_CONSDATA* consdata;
    3354 SCIP_VAR* var;
    3355 SCIP_VAR* vbdvar;
    3356 SCIP_Real varscalar;
    3357 SCIP_Real varconstant;
    3358 SCIP_Real vbdvarscalar;
    3359 SCIP_Real vbdvarconstant;
    3360 SCIP_Real newbnd;
    3361 SCIP_Bool varschanged;
    3362 SCIP_Bool redundant;
    3363
    3364 assert(scip != NULL);
    3365 assert(cons != NULL);
    3366 assert(cutoff != NULL);
    3367 assert(nchgbds != NULL);
    3368 assert(ndelconss != NULL);
    3369 assert(naddconss != NULL);
    3370
    3371 *cutoff = FALSE;
    3372 redundant = FALSE;
    3373
    3374 /* the variable bound constraint is: lhs <= x + c*y <= rhs */
    3375 consdata = SCIPconsGetData(cons);
    3376 assert(consdata != NULL);
    3377
    3378 /* get active problem variables of x and y */
    3379 var = consdata->var;
    3380 varscalar = 1.0;
    3381 varconstant = 0.0;
    3382 SCIP_CALL( SCIPgetProbvarSum(scip, &var, &varscalar, &varconstant) );
    3383 vbdvar = consdata->vbdvar;
    3384 vbdvarscalar = 1.0;
    3385 vbdvarconstant = 0.0;
    3386 SCIP_CALL( SCIPgetProbvarSum(scip, &vbdvar, &vbdvarscalar, &vbdvarconstant) );
    3387 varschanged = (var != consdata->var || vbdvar != consdata->vbdvar);
    3388
    3389 /* if the variables are equal, the variable bound constraint reduces to standard bounds on the single variable */
    3390 if( var == vbdvar && SCIPvarGetStatus(var) != SCIP_VARSTATUS_MULTAGGR )
    3391 {
    3392 SCIP_Real scalar;
    3393 SCIP_Real constant;
    3394
    3395 SCIPdebugMsg(scip, "variable bound constraint <%s> has equal variable and vbd variable <%s>\n",
    3396 SCIPconsGetName(cons), SCIPvarGetName(var));
    3397
    3398 /* lhs <= a1*z + b1 + c(a2*z + b2) <= rhs
    3399 * <=> lhs <= (a1 + c*a2)z + (b1 + c*b2) <= rhs
    3400 */
    3401 scalar = varscalar + consdata->vbdcoef * vbdvarscalar;
    3402 constant = varconstant + consdata->vbdcoef * vbdvarconstant;
    3403 if( SCIPisZero(scip, scalar) )
    3404 {
    3405 /* no variable is left: the constraint is redundant or infeasible */
    3406 if( SCIPisFeasLT(scip, constant, consdata->lhs) || SCIPisFeasGT(scip, constant, consdata->rhs) )
    3407 {
    3408 *cutoff = TRUE;
    3409 return SCIP_OKAY;
    3410 }
    3411 }
    3412 else if( scalar > 0.0 )
    3413 {
    3414 if( !SCIPisInfinity(scip, -consdata->lhs) )
    3415 {
    3416 SCIP_Bool tightened;
    3417
    3418 newbnd = (consdata->lhs - constant) / scalar;
    3419 SCIP_CALL( SCIPtightenVarLb(scip, var, newbnd, TRUE, cutoff, &tightened) );
    3420 if( *cutoff )
    3421 {
    3422 SCIPdebugMsg(scip, " -> tightening <%s> >= %.15g infeasible\n", SCIPvarGetName(var), newbnd);
    3423 return SCIP_OKAY;
    3424 }
    3425 if( tightened )
    3426 {
    3427 SCIPdebugMsg(scip, " -> tightened lower bound: <%s> >= %.15g\n", SCIPvarGetName(var), SCIPvarGetLbGlobal(var));
    3428 (*nchgbds)++;
    3429 }
    3430 }
    3431 if( !SCIPisInfinity(scip, consdata->rhs) )
    3432 {
    3433 SCIP_Bool tightened;
    3434
    3435 newbnd = (consdata->rhs - constant) / scalar;
    3436 SCIP_CALL( SCIPtightenVarUb(scip, var, newbnd, TRUE, cutoff, &tightened) );
    3437 if( *cutoff )
    3438 {
    3439 SCIPdebugMsg(scip, " -> tightening <%s> <= %.15g infeasible\n", SCIPvarGetName(var), newbnd);
    3440 return SCIP_OKAY;
    3441 }
    3442 if( tightened )
    3443 {
    3444 SCIPdebugMsg(scip, " -> tightened upper bound: <%s> <= %.15g\n", SCIPvarGetName(var), SCIPvarGetUbGlobal(var));
    3445 (*nchgbds)++;
    3446 }
    3447 }
    3448 }
    3449 else
    3450 {
    3451 if( !SCIPisInfinity(scip, -consdata->lhs) )
    3452 {
    3453 SCIP_Bool tightened;
    3454
    3455 newbnd = (consdata->lhs - constant) / scalar;
    3456 SCIP_CALL( SCIPtightenVarUb(scip, var, newbnd, TRUE, cutoff, &tightened) );
    3457 if( *cutoff )
    3458 {
    3459 SCIPdebugMsg(scip, " -> tightening <%s> <= %.15g infeasible\n", SCIPvarGetName(var), newbnd);
    3460 return SCIP_OKAY;
    3461 }
    3462 if( tightened )
    3463 {
    3464 SCIPdebugMsg(scip, " -> tightened upper bound: <%s> <= %.15g\n", SCIPvarGetName(var), SCIPvarGetUbGlobal(var));
    3465 (*nchgbds)++;
    3466 }
    3467 }
    3468 if( !SCIPisInfinity(scip, consdata->rhs) )
    3469 {
    3470 SCIP_Bool tightened;
    3471
    3472 newbnd = (consdata->rhs - constant) / scalar;
    3473 SCIP_CALL( SCIPtightenVarLb(scip, var, newbnd, TRUE, cutoff, &tightened) );
    3474 if( *cutoff )
    3475 {
    3476 SCIPdebugMsg(scip, " -> tightening <%s> >= %.15g infeasible\n", SCIPvarGetName(var), newbnd);
    3477 return SCIP_OKAY;
    3478 }
    3479 if( tightened )
    3480 {
    3481 SCIPdebugMsg(scip, " -> tightened lower bound: <%s> >= %.15g\n", SCIPvarGetName(var), SCIPvarGetLbGlobal(var));
    3482 (*nchgbds)++;
    3483 }
    3484 }
    3485 }
    3486 redundant = TRUE;
    3487 }
    3488 else
    3489 {
    3490 /* if the variables should be replaced, drop the events and catch the events on the new variables afterwards */
    3491 if( varschanged )
    3492 {
    3493 SCIP_CALL( dropEvents(scip, cons, eventhdlr) );
    3494 }
    3495
    3496 /* apply aggregation on x */
    3497 if( SCIPisZero(scip, varscalar) )
    3498 {
    3499 /* the variable being fixed or corresponding to an aggregation might lead to numerical difficulties */
    3500 if( SCIPisZero(scip, consdata->vbdcoef * vbdvarscalar) )
    3501 {
    3502 SCIP_Real activity = varconstant + consdata->vbdcoef * vbdvarconstant;
    3503
    3504 SCIPdebugMsg(scip, "variable bound constraint <%s>: variable <%s> is fixed to %.15g\n",
    3505 SCIPconsGetName(cons), SCIPvarGetName(consdata->var), varconstant);
    3506
    3507 assert(SCIPisGE(scip, varconstant, SCIPvarGetLbGlobal(consdata->var)));
    3508 assert(SCIPisLE(scip, varconstant, SCIPvarGetUbGlobal(consdata->var)));
    3509 assert(SCIPisGE(scip, vbdvarconstant, SCIPvarGetLbGlobal(consdata->vbdvar)));
    3510 assert(SCIPisLE(scip, vbdvarconstant, SCIPvarGetUbGlobal(consdata->vbdvar)));
    3511
    3512 if( ( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisFeasLT(scip, activity, consdata->lhs) )
    3513 || ( !SCIPisInfinity(scip, consdata->rhs) && SCIPisFeasGT(scip, activity, consdata->rhs) ) )
    3514 *cutoff = TRUE;
    3515
    3516 redundant = TRUE;
    3517 }
    3518 /* cannot change bounds on multi-aggregated variables */
    3519 else if( SCIPvarGetStatus(vbdvar) != SCIP_VARSTATUS_MULTAGGR )
    3520 {
    3521 assert( consdata->vbdcoef != 0.0 );
    3522 assert( vbdvarscalar != 0.0 );
    3523
    3524 /* x is fixed to varconstant: update bounds of y and delete the variable bound constraint */
    3525 if( !(*cutoff) && !SCIPisInfinity(scip, -consdata->lhs) )
    3526 {
    3527 if( consdata->vbdcoef > 0.0 )
    3528 {
    3529 SCIP_Bool tightened;
    3530
    3531 newbnd = (consdata->lhs - varconstant) / consdata->vbdcoef;
    3532 SCIP_CALL( SCIPtightenVarLb(scip, consdata->vbdvar, newbnd, TRUE, cutoff, &tightened) );
    3533 if( *cutoff )
    3534 {
    3535 SCIPdebugMsg(scip, " -> tightening <%s> >= %.15g infeasible\n", SCIPvarGetName(consdata->vbdvar), newbnd);
    3536 }
    3537 else if( tightened )
    3538 {
    3539 SCIPdebugMsg(scip, " -> tightened lower bound: <%s> >= %.15g\n", SCIPvarGetName(consdata->vbdvar), SCIPvarGetLbGlobal(consdata->vbdvar));
    3540 (*nchgbds)++;
    3541 }
    3542 }
    3543 else
    3544 {
    3545 SCIP_Bool tightened;
    3546
    3547 newbnd = (consdata->lhs - varconstant) / consdata->vbdcoef;
    3548 SCIP_CALL( SCIPtightenVarUb(scip, consdata->vbdvar, newbnd, TRUE, cutoff, &tightened) );
    3549 if( *cutoff )
    3550 {
    3551 SCIPdebugMsg(scip, " -> tightening <%s> <= %.15g infeasible\n", SCIPvarGetName(consdata->vbdvar), newbnd);
    3552 }
    3553 else if( tightened )
    3554 {
    3555 SCIPdebugMsg(scip, " -> tightened upper bound: <%s> <= %.15g\n", SCIPvarGetName(consdata->vbdvar), SCIPvarGetUbGlobal(consdata->vbdvar));
    3556 (*nchgbds)++;
    3557 }
    3558 }
    3559 }
    3560 if( !(*cutoff) && !SCIPisInfinity(scip, consdata->rhs) )
    3561 {
    3562 if( consdata->vbdcoef > 0.0 )
    3563 {
    3564 SCIP_Bool tightened;
    3565
    3566 newbnd = (consdata->rhs - varconstant) / consdata->vbdcoef;
    3567 SCIP_CALL( SCIPtightenVarUb(scip, consdata->vbdvar, newbnd, TRUE, cutoff, &tightened) );
    3568 if( *cutoff )
    3569 {
    3570 SCIPdebugMsg(scip, " -> tightening <%s> <= %.15g infeasible\n", SCIPvarGetName(consdata->vbdvar), newbnd);
    3571 }
    3572 else if( tightened )
    3573 {
    3574 SCIPdebugMsg(scip, " -> tightened upper bound: <%s> <= %.15g\n", SCIPvarGetName(consdata->vbdvar), SCIPvarGetUbGlobal(consdata->vbdvar));
    3575 (*nchgbds)++;
    3576 }
    3577 }
    3578 else
    3579 {
    3580 SCIP_Bool tightened;
    3581
    3582 newbnd = (consdata->rhs - varconstant) / consdata->vbdcoef;
    3583 SCIP_CALL( SCIPtightenVarLb(scip, consdata->vbdvar, newbnd, TRUE, cutoff, &tightened) );
    3584 if( *cutoff )
    3585 {
    3586 SCIPdebugMsg(scip, " -> tightening <%s> >= %.15g infeasible\n", SCIPvarGetName(consdata->vbdvar), newbnd);
    3587 }
    3588 else if( tightened )
    3589 {
    3590 SCIPdebugMsg(scip, " -> tightened lower bound: <%s> >= %.15g\n", SCIPvarGetName(consdata->vbdvar), SCIPvarGetLbGlobal(consdata->vbdvar));
    3591 (*nchgbds)++;
    3592 }
    3593 }
    3594 }
    3595 redundant = TRUE;
    3596 }
    3597 }
    3598 else if( var != consdata->var )
    3599 {
    3600 /* release and unlock old variable */
    3601 SCIP_CALL( SCIPunlockVarCons(scip, consdata->var, cons, !SCIPisInfinity(scip, -consdata->lhs),
    3602 !SCIPisInfinity(scip, consdata->rhs)) );
    3603 SCIP_CALL( SCIPreleaseVar(scip, &(consdata->var)) );
    3604
    3605 /* unlock vbdvar, because we possibly change lhs/rhs/vbdcoef */
    3606 if( consdata->vbdcoef > 0.0 )
    3607 {
    3608 SCIP_CALL( SCIPunlockVarCons(scip, consdata->vbdvar, cons, !SCIPisInfinity(scip, -consdata->lhs),
    3609 !SCIPisInfinity(scip, consdata->rhs)) );
    3610 }
    3611 else
    3612 {
    3613 SCIP_CALL( SCIPunlockVarCons(scip, consdata->vbdvar, cons, !SCIPisInfinity(scip, consdata->rhs),
    3614 !SCIPisInfinity(scip, -consdata->lhs)) );
    3615 }
    3616
    3617 /* replace aggregated variable x in the constraint by its aggregation */
    3618 if( varscalar > 0.0 )
    3619 {
    3620 /* lhs := (lhs - varconstant) / varscalar
    3621 * rhs := (rhs - varconstant) / varscalar
    3622 * c := c / varscalar
    3623 */
    3624 if( !SCIPisInfinity(scip, -consdata->lhs) )
    3625 consdata->lhs = (consdata->lhs - varconstant)/varscalar;
    3626 if( !SCIPisInfinity(scip, consdata->rhs) )
    3627 consdata->rhs = (consdata->rhs - varconstant)/varscalar;
    3628 consdata->vbdcoef /= varscalar;
    3629
    3630 /* try to avoid numerical troubles */
    3631 if( SCIPisIntegral(scip, consdata->vbdcoef) )
    3632 consdata->vbdcoef = SCIPround(scip, consdata->vbdcoef);
    3633
    3634 consdata->tightened = FALSE;
    3635 }
    3636 else
    3637 {
    3638 SCIP_Real lhs;
    3639
    3640 assert(varscalar != 0.0);
    3641
    3642 /* lhs := (rhs - varconstant) / varscalar
    3643 * rhs := (lhs - varconstant) / varscalar
    3644 * c := c / varscalar
    3645 */
    3646 lhs = consdata->lhs;
    3647 consdata->lhs = -consdata->rhs;
    3648 consdata->rhs = -lhs;
    3649 if( !SCIPisInfinity(scip, -consdata->lhs) )
    3650 consdata->lhs = (consdata->lhs + varconstant)/(-varscalar);
    3651 if( !SCIPisInfinity(scip, consdata->rhs) )
    3652 consdata->rhs = (consdata->rhs + varconstant)/(-varscalar);
    3653 consdata->vbdcoef /= varscalar;
    3654
    3655 /* try to avoid numerical troubles */
    3656 if( SCIPisIntegral(scip, consdata->vbdcoef) )
    3657 consdata->vbdcoef = SCIPround(scip, consdata->vbdcoef);
    3658
    3659 consdata->tightened = FALSE;
    3660 }
    3661
    3662 consdata->var = var;
    3663
    3664 /* capture and lock new variable */
    3665 SCIP_CALL( SCIPcaptureVar(scip, consdata->var) );
    3666 SCIP_CALL( SCIPlockVarCons(scip, consdata->var, cons, !SCIPisInfinity(scip, -consdata->lhs),
    3667 !SCIPisInfinity(scip, consdata->rhs)) );
    3668
    3669 /* lock vbdvar */
    3670 if( consdata->vbdcoef > 0.0 )
    3671 {
    3672 SCIP_CALL( SCIPlockVarCons(scip, consdata->vbdvar, cons, !SCIPisInfinity(scip, -consdata->lhs),
    3673 !SCIPisInfinity(scip, consdata->rhs)) );
    3674 }
    3675 else
    3676 {
    3677 SCIP_CALL( SCIPlockVarCons(scip, consdata->vbdvar, cons, !SCIPisInfinity(scip, consdata->rhs),
    3678 !SCIPisInfinity(scip, -consdata->lhs)) );
    3679 }
    3680 }
    3681
    3682 /* apply aggregation on y */
    3683 if( SCIPisZero(scip, consdata->vbdcoef * vbdvarscalar) )
    3684 {
    3685 SCIPdebugMsg(scip, "variable bound constraint <%s>: vbd variable <%s> is fixed to %.15g\n",
    3686 SCIPconsGetName(cons), SCIPvarGetName(consdata->vbdvar), vbdvarconstant);
    3687
    3688 /* cannot change bounds on multi-aggregated variables */
    3689 if( !redundant && SCIPvarGetStatus(var) != SCIP_VARSTATUS_MULTAGGR )
    3690 {
    3691 assert( SCIPvarGetStatus(var) != SCIP_VARSTATUS_FIXED );
    3692 assert( !SCIPisZero(scip, varscalar) );
    3693
    3694 /* y is fixed to vbdvarconstant: update bounds of x and delete the variable bound constraint */
    3695 if( !(*cutoff) && !SCIPisInfinity(scip, -consdata->lhs) )
    3696 {
    3697 SCIP_Bool tightened;
    3698
    3699 newbnd = consdata->lhs - consdata->vbdcoef * vbdvarconstant;
    3700 SCIP_CALL( SCIPtightenVarLb(scip, consdata->var, newbnd, TRUE, cutoff, &tightened) );
    3701 if( *cutoff )
    3702 {
    3703 SCIPdebugMsg(scip, " -> tightening <%s> >= %.15g infeasible\n", SCIPvarGetName(consdata->var), newbnd);
    3704 }
    3705 else if( tightened )
    3706 {
    3707 SCIPdebugMsg(scip, " -> tightened lower bound: <%s> >= %.15g\n", SCIPvarGetName(consdata->var), SCIPvarGetLbGlobal(consdata->var));
    3708 (*nchgbds)++;
    3709 }
    3710 }
    3711 if( !(*cutoff) && !SCIPisInfinity(scip, consdata->rhs) )
    3712 {
    3713 SCIP_Bool tightened;
    3714
    3715 newbnd = consdata->rhs - consdata->vbdcoef * vbdvarconstant;
    3716 SCIP_CALL( SCIPtightenVarUb(scip, consdata->var, newbnd, TRUE, cutoff, &tightened) );
    3717 if( *cutoff )
    3718 {
    3719 SCIPdebugMsg(scip, " -> tightening <%s> <= %.15g infeasible\n", SCIPvarGetName(consdata->var), newbnd);
    3720 }
    3721 else if( tightened )
    3722 {
    3723 SCIPdebugMsg(scip, " -> tightened upper bound: <%s> <= %.15g\n", SCIPvarGetName(consdata->var), SCIPvarGetUbGlobal(consdata->var));
    3724 (*nchgbds)++;
    3725 }
    3726 }
    3727 redundant = TRUE;
    3728 }
    3729 }
    3730 else if( !(*cutoff) && vbdvar != consdata->vbdvar )
    3731 {
    3732 /* release and unlock old variable */
    3733 if( consdata->vbdcoef > 0.0 )
    3734 {
    3735 SCIP_CALL( SCIPunlockVarCons(scip, consdata->vbdvar, cons, !SCIPisInfinity(scip, -consdata->lhs),
    3736 !SCIPisInfinity(scip, consdata->rhs)) );
    3737 }
    3738 else
    3739 {
    3740 SCIP_CALL( SCIPunlockVarCons(scip, consdata->vbdvar, cons, !SCIPisInfinity(scip, consdata->rhs),
    3741 !SCIPisInfinity(scip, -consdata->lhs)) );
    3742 }
    3743 SCIP_CALL( SCIPreleaseVar(scip, &(consdata->vbdvar)) );
    3744
    3745 /* also unlock var, because we possibly change lhs/rhs/vbdcoef */
    3746 SCIP_CALL( SCIPunlockVarCons(scip, consdata->var, cons, !SCIPisInfinity(scip, -consdata->lhs),
    3747 !SCIPisInfinity(scip, consdata->rhs)) );
    3748
    3749 /* replace aggregated variable y in the constraint by its aggregation:
    3750 * lhs := lhs - c * vbdvarconstant
    3751 * rhs := rhs - c * vbdvarconstant
    3752 * c := c * vbdvarscalar
    3753 */
    3754 if( !SCIPisInfinity(scip, -consdata->lhs) )
    3755 consdata->lhs -= consdata->vbdcoef * vbdvarconstant;
    3756 if( !SCIPisInfinity(scip, consdata->rhs) )
    3757 consdata->rhs -= consdata->vbdcoef * vbdvarconstant;
    3758
    3759 consdata->tightened = FALSE;
    3760 consdata->vbdcoef *= vbdvarscalar;
    3761 consdata->vbdvar = vbdvar;
    3762
    3763 /* capture and lock new variable */
    3764 SCIP_CALL( SCIPcaptureVar(scip, consdata->vbdvar) );
    3765 if( consdata->vbdcoef > 0.0 )
    3766 {
    3767 SCIP_CALL( SCIPlockVarCons(scip, consdata->vbdvar, cons, !SCIPisInfinity(scip, -consdata->lhs),
    3768 !SCIPisInfinity(scip, consdata->rhs)) );
    3769 }
    3770 else
    3771 {
    3772 SCIP_CALL( SCIPlockVarCons(scip, consdata->vbdvar, cons, !SCIPisInfinity(scip, consdata->rhs),
    3773 !SCIPisInfinity(scip, -consdata->lhs)) );
    3774 }
    3775 SCIP_CALL( SCIPlockVarCons(scip, consdata->var, cons, !SCIPisInfinity(scip, -consdata->lhs),
    3776 !SCIPisInfinity(scip, consdata->rhs)) );
    3777 }
    3778
    3779 /* catch the events again on the new variables */
    3780 if( varschanged )
    3781 {
    3782 SCIP_CALL( catchEvents(scip, cons, eventhdlr) );
    3783 }
    3784
    3785 /* terminate on cutoff after catching events */
    3786 if( *cutoff )
    3787 return SCIP_OKAY;
    3788 }
    3789
    3790 /* mark constraint changed, if a variable was exchanged */
    3791 if( varschanged )
    3792 {
    3793 consdata->changed = TRUE;
    3794 }
    3795
    3796 /* active multi aggregations are now resolved by creating a new linear constraint */
    3797 if( !redundant && (SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR || SCIPvarGetStatus(vbdvar) == SCIP_VARSTATUS_MULTAGGR) )
    3798 {
    3799 SCIP_CONS* newcons;
    3800 SCIP_Real lhs;
    3801 SCIP_Real rhs;
    3802
    3803 lhs = consdata->lhs;
    3804 rhs = consdata->rhs;
    3805
    3806 /* create upgraded linear constraint */
    3807 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, SCIPconsGetName(cons), 0, NULL, NULL, lhs, rhs,
    3812
    3813 /* if var was fixed, then the case that vbdvar was multi-aggregated, was not yet resolved */
    3814 if( var != consdata->var )
    3815 {
    3816 assert(SCIPvarGetStatus(vbdvar) == SCIP_VARSTATUS_MULTAGGR);
    3817 assert(SCIPisZero(scip, varscalar)); /* this means that var was fixed */
    3818
    3819 /* add offset that results from the fixed variable */
    3820 if( ! SCIPisZero(scip, varconstant) )
    3821 {
    3822 if( !SCIPisInfinity(scip, rhs) )
    3823 {
    3824 SCIP_CALL( SCIPchgRhsLinear(scip, newcons, rhs - varconstant) );
    3825 }
    3826 if( !SCIPisInfinity(scip, -lhs) )
    3827 {
    3828 SCIP_CALL( SCIPchgLhsLinear(scip, newcons, lhs - varconstant) );
    3829 }
    3830 }
    3831 }
    3832 else
    3833 {
    3834 assert(var == consdata->var);
    3835
    3836 SCIP_CALL( SCIPaddCoefLinear(scip, newcons, consdata->var, 1.0) );
    3837 }
    3838
    3839 /* if vbdvar was fixed, then the case that var was multi-aggregated, was not yet resolved */
    3840 if( vbdvar != consdata->vbdvar )
    3841 {
    3843 assert(SCIPisZero(scip, vbdvarscalar)); /* this means that var was fixed */
    3844
    3845 /* add offset that results from the fixed variable */
    3846 if( ! SCIPisZero(scip, vbdvarconstant) )
    3847 {
    3848 if( !SCIPisInfinity(scip, rhs) )
    3849 {
    3850 SCIP_CALL( SCIPchgRhsLinear(scip, newcons, rhs - consdata->vbdcoef * vbdvarconstant) );
    3851 }
    3852 if( !SCIPisInfinity(scip, -lhs) )
    3853 {
    3854 SCIP_CALL( SCIPchgLhsLinear(scip, newcons, lhs - consdata->vbdcoef * vbdvarconstant) );
    3855 }
    3856 }
    3857 }
    3858 else
    3859 {
    3860 assert(vbdvar == consdata->vbdvar);
    3861
    3862 SCIP_CALL( SCIPaddCoefLinear(scip, newcons, consdata->vbdvar, consdata->vbdcoef) );
    3863 }
    3864
    3865 SCIPdebugMsg(scip, "resolved multi aggregation in varbound constraint <%s> by creating a new linear constraint\n", SCIPconsGetName(cons));
    3866 SCIPdebugPrintCons(scip, newcons, NULL);
    3867
    3868 SCIP_CALL( SCIPaddCons(scip, newcons) );
    3869 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    3870
    3871 redundant = TRUE;
    3872 ++(*naddconss);
    3873 }
    3874
    3875 /* delete a redundant constraint */
    3876 if( redundant )
    3877 {
    3878 SCIPdebugMsg(scip, " -> variable bound constraint <%s> is redundant\n", SCIPconsGetName(cons));
    3879 SCIP_CALL( SCIPdelCons(scip, cons) );
    3880 (*ndelconss)++;
    3881 }
    3882
    3883 return SCIP_OKAY;
    3884}
    3885
    3886/** tightens variable bound coefficient by inspecting the global bounds of the involved variables; note: this is also
    3887 * performed by the linear constraint handler - only necessary if the user directly creates variable bound constraints
    3888 */
    3889static
    3891 SCIP* scip, /**< SCIP data structure */
    3892 SCIP_CONS* cons, /**< variable bound constraint */
    3893 int* nchgcoefs, /**< pointer to count the number of changed coefficients */
    3894 int* nchgsides, /**< pointer to count the number of left and right hand sides */
    3895 int* ndelconss, /**< pointer to count number of deleted constraints */
    3896 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    3897 int* nchgbds /**< pointer to count number of bound changes */
    3898 )
    3899{
    3900 SCIP_CONSDATA* consdata;
    3901 SCIP_Real xlb;
    3902 SCIP_Real xub;
    3903 SCIP_Real oldcoef;
    3904 int oldnchgcoefs;
    3905 int oldnchgsides;
    3906
    3907 assert(nchgcoefs != NULL);
    3908 assert(nchgsides != NULL);
    3909 assert(ndelconss != NULL);
    3910
    3911 consdata = SCIPconsGetData(cons);
    3912 assert(consdata != NULL);
    3913
    3914 /* tightening already done */
    3915 if( consdata->tightened )
    3916 return SCIP_OKAY;
    3917
    3918 SCIPdebugMsg(scip, "tightening coefficients on variable bound constraint <%s>\n", SCIPconsGetName(cons));
    3919
    3920 consdata->tightened = TRUE;
    3921
    3922 /* if values and variable are integral the sides should it be too */
    3923 if( SCIPvarIsIntegral(consdata->var) && SCIPvarIsIntegral(consdata->vbdvar)
    3924 && SCIPisIntegral(scip, consdata->vbdcoef) )
    3925 {
    3926 if( !SCIPisIntegral(scip, consdata->lhs) )
    3927 {
    3928 consdata->lhs = SCIPfeasCeil(scip, consdata->lhs);
    3929 ++(*nchgsides);
    3930 consdata->changed = TRUE;
    3931 }
    3932 if( !SCIPisIntegral(scip, consdata->rhs) )
    3933 {
    3934 consdata->rhs = SCIPfeasFloor(scip, consdata->rhs);
    3935 ++(*nchgsides);
    3936 consdata->changed = TRUE;
    3937 }
    3938 }
    3939
    3940 /* coefficient tightening only works for binary bound variable */
    3941 if( !SCIPvarIsBinary(consdata->vbdvar) )
    3942 return SCIP_OKAY;
    3943
    3944 oldnchgcoefs = *nchgcoefs;
    3945 oldnchgsides = *nchgsides;
    3946 oldcoef = consdata->vbdcoef;
    3947
    3948 /* coefficients tightening when all variables are integer */
    3949 /* we consider the following varbound constraint: lhs <= x + b*y <= rhs (sides are possibly infinity)
    3950 * y should always be binary and x of integral type and b not integral, we also need at least one side with infinity
    3951 * or not integral value.
    3952 *
    3953 * 1. if( (lhs is integral and not -infinity) and ((rhs is infinity) or (b - floor(b) <= rhs - floor(rhs))) ):
    3954 *
    3955 * lhs <= x + b*y <= rhs => lhs <= x + floor(b)*y <= floor(rhs)
    3956 *
    3957 * 2. if( (rhs is integral and not infinity) and ((lhs is -infinity) or (b - floor(b) >= lhs - floor(lhs))) ):
    3958 *
    3959 * lhs <= x + b*y <= rhs => ceil(lhs) <= x + ceil(b)*y <= rhs
    3960 *
    3961 * 3. if( ((lhs is -infinity) or (b - floor(b) >= lhs - floor(lhs)))
    3962 * and ((rhs is infinity) or (b - floor(b) > rhs - floor(rhs))) ):
    3963 *
    3964 * lhs <= x + b*y <= rhs => ceil(lhs) <= x + ceil(b)*y <= floor(rhs)
    3965 *
    3966 * 4. if( ((lhs is -infinity) or (b - floor(b) < lhs - floor(lhs)))
    3967 * and ((rhs is infinity) or (b - floor(b) <= rhs - floor(rhs))) ):
    3968 *
    3969 * lhs <= x + b*y <= rhs => ceil(lhs) <= x + floor(b)*y <= floor(rhs)
    3970 *
    3971 * 5. if( (lhs is not integral) or (rhs is not integral) )
    3972 *
    3973 * if (lhs is not -infinity)
    3974 * if (b - floor(b) < lhs - floor(lhs)):
    3975 *
    3976 * lhs <= x + b*y => ceil(lhs) <= x + b*y
    3977 *
    3978 * else if (b - floor(b) > lhs - floor(lhs)):
    3979 *
    3980 * lhs <= x + b*y => floor(lhs) + b - floor(b) <= x + b*y
    3981 *
    3982 * if (rhs is not infinity)
    3983 * if (b - floor(b) < rhs - floor(rhs)):
    3984 *
    3985 * x + b*y <= rhs => x + b*y <= floor(rhs) + b - floor(b)
    3986 *
    3987 * else if (b - floor(b) > rhs - floor(rhs)):
    3988 *
    3989 * x + b*y <= rhs => x + b*y <= floor(rhs)
    3990 */
    3991 if( SCIPvarIsIntegral(consdata->var) && !SCIPisIntegral(scip, consdata->vbdcoef)
    3992 && ( !SCIPisIntegral(scip, consdata->lhs) || SCIPisInfinity(scip, -consdata->lhs)
    3993 || !SCIPisIntegral(scip, consdata->rhs) || SCIPisInfinity(scip, consdata->rhs) ) )
    3994 {
    3995 /* infinity should be an integral value */
    3996 assert(!SCIPisInfinity(scip, -consdata->lhs) || SCIPisIntegral(scip, consdata->lhs));
    3997 assert(!SCIPisInfinity(scip, consdata->rhs) || SCIPisIntegral(scip, consdata->rhs));
    3998
    3999 /* should not be a redundant constraint */
    4000 assert(!SCIPisInfinity(scip, consdata->rhs) || !SCIPisInfinity(scip, -consdata->lhs));
    4001
    4002 /* case 1 */
    4003 if( SCIPisIntegral(scip, consdata->lhs) && !SCIPisInfinity(scip, -consdata->lhs) &&
    4004 (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasLE(scip, consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef), consdata->rhs - SCIPfeasFloor(scip, consdata->rhs))) )
    4005 {
    4006 consdata->vbdcoef = SCIPfeasFloor(scip, consdata->vbdcoef);
    4007 ++(*nchgcoefs);
    4008
    4009 if( !SCIPisInfinity(scip, consdata->rhs) )
    4010 {
    4011 consdata->rhs = SCIPfeasFloor(scip, consdata->rhs);
    4012 ++(*nchgsides);
    4013 }
    4014 }
    4015 /* case 2 */
    4016 else if( SCIPisIntegral(scip, consdata->rhs) && !SCIPisInfinity(scip, consdata->rhs) &&
    4017 (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasGE(scip, consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef), consdata->lhs - SCIPfeasFloor(scip, consdata->lhs))) )
    4018 {
    4019 consdata->vbdcoef = SCIPfeasCeil(scip, consdata->vbdcoef);
    4020 ++(*nchgcoefs);
    4021
    4022 if( !SCIPisInfinity(scip, -consdata->lhs) )
    4023 {
    4024 if( !SCIPisIntegral(scip, consdata->lhs) )
    4025 ++(*nchgsides);
    4026
    4027 consdata->lhs = SCIPfeasCeil(scip, consdata->lhs);
    4028 }
    4029 }
    4030 /* case 3 */
    4031 else if( (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasGE(scip, consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef), consdata->lhs - SCIPfeasFloor(scip, consdata->lhs))) && (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasGT(scip, consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef), consdata->rhs - SCIPfeasFloor(scip, consdata->rhs))) )
    4032 {
    4033 consdata->vbdcoef = SCIPfeasCeil(scip, consdata->vbdcoef);
    4034 ++(*nchgcoefs);
    4035
    4036 if( !SCIPisInfinity(scip, -consdata->lhs) )
    4037 {
    4038 if( !SCIPisIntegral(scip, consdata->lhs) )
    4039 ++(*nchgsides);
    4040
    4041 consdata->lhs = SCIPfeasCeil(scip, consdata->lhs);
    4042 }
    4043 if( !SCIPisInfinity(scip, consdata->rhs) )
    4044 {
    4045 if( !SCIPisIntegral(scip, consdata->rhs) )
    4046 ++(*nchgsides);
    4047
    4048 consdata->rhs = SCIPfeasFloor(scip, consdata->rhs);
    4049 }
    4050 }
    4051 /* case 4 */
    4052 else if( (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasLT(scip, consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef), consdata->lhs - SCIPfeasFloor(scip, consdata->lhs))) && (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasLE(scip, consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef), consdata->rhs - SCIPfeasFloor(scip, consdata->rhs))) )
    4053 {
    4054 consdata->vbdcoef = SCIPfeasFloor(scip, consdata->vbdcoef);
    4055 ++(*nchgcoefs);
    4056
    4057 if( !SCIPisInfinity(scip, -consdata->lhs) )
    4058 {
    4059 if( !SCIPisIntegral(scip, consdata->lhs) )
    4060 ++(*nchgsides);
    4061
    4062 consdata->lhs = SCIPfeasCeil(scip, consdata->lhs);
    4063 }
    4064 if( !SCIPisInfinity(scip, consdata->rhs) )
    4065 {
    4066 if( !SCIPisIntegral(scip, consdata->rhs) )
    4067 ++(*nchgsides);
    4068
    4069 consdata->rhs = SCIPfeasFloor(scip, consdata->rhs);
    4070 }
    4071 }
    4072 /* case 5 */
    4073 if( !SCIPisFeasIntegral(scip, consdata->lhs) || !SCIPisFeasIntegral(scip, consdata->rhs) )
    4074 {
    4075 if( !SCIPisInfinity(scip, -consdata->lhs) )
    4076 {
    4077 if( SCIPisFeasLT(scip, consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef), consdata->lhs - SCIPfeasFloor(scip, consdata->lhs)) )
    4078 {
    4079 consdata->lhs = SCIPfeasCeil(scip, consdata->lhs);
    4080 ++(*nchgsides);
    4081 }
    4082 else if( SCIPisFeasGT(scip, consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef), consdata->lhs - SCIPfeasFloor(scip, consdata->lhs)) )
    4083 {
    4084 consdata->lhs = SCIPfeasFloor(scip, consdata->lhs) + (consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef));
    4085 ++(*nchgsides);
    4086 }
    4087 }
    4088 if( !SCIPisInfinity(scip, consdata->rhs) )
    4089 {
    4090 if( SCIPisFeasLT(scip, consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef), consdata->rhs - SCIPfeasFloor(scip, consdata->rhs)) )
    4091 {
    4092 consdata->rhs = SCIPfeasFloor(scip, consdata->rhs) + (consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef));
    4093 ++(*nchgsides);
    4094 }
    4095 else if( SCIPisFeasGT(scip, consdata->vbdcoef - SCIPfeasFloor(scip, consdata->vbdcoef), consdata->rhs - SCIPfeasFloor(scip, consdata->rhs)) )
    4096 {
    4097 consdata->rhs = SCIPfeasFloor(scip, consdata->rhs);
    4098 ++(*nchgsides);
    4099 }
    4100 }
    4101 }
    4102 }
    4103
    4104 /* check if due to tightening the constraint got redundant */
    4105 if( SCIPisZero(scip, consdata->vbdcoef) )
    4106 {
    4107 /* we have to make sure that the induced bound(s) is (are) actually applied;
    4108 * if the relative change is too small, this may have been skipped in propagation
    4109 */
    4110 if( SCIPisLT(scip, SCIPvarGetLbGlobal(consdata->var), consdata->lhs) )
    4111 {
    4112 SCIP_Bool tightened;
    4113
    4114 SCIP_CALL( SCIPtightenVarLbGlobal(scip, consdata->var, consdata->lhs, TRUE, cutoff, &tightened) );
    4115 if( *cutoff )
    4116 {
    4117 SCIPdebugMsg(scip, " -> tightening lower bound of <%s> to %.15g infeasible\n", SCIPvarGetName(consdata->var),
    4118 consdata->lhs);
    4119 return SCIP_OKAY;
    4120 }
    4121 if( tightened )
    4122 {
    4123 SCIPdebugMsg(scip, " -> tighten domain of <%s> to [%.15g,%.15g]\n", SCIPvarGetName(consdata->var),
    4124 SCIPvarGetLbGlobal(consdata->var), SCIPvarGetUbGlobal(consdata->var));
    4125 (*nchgbds)++;
    4126 }
    4127 }
    4128 if( SCIPisGT(scip, SCIPvarGetUbGlobal(consdata->var), consdata->rhs) )
    4129 {
    4130 SCIP_Bool tightened;
    4131
    4132 SCIP_CALL( SCIPtightenVarUbGlobal(scip, consdata->var, consdata->rhs, TRUE, cutoff, &tightened) );
    4133 if( *cutoff )
    4134 {
    4135 SCIPdebugMsg(scip, " -> tightening upper bound of <%s> to %.15g infeasible\n", SCIPvarGetName(consdata->var),
    4136 consdata->rhs);
    4137 return SCIP_OKAY;
    4138 }
    4139 if( tightened )
    4140 {
    4141 SCIPdebugMsg(scip, " -> tighten domain of <%s> to [%.15g,%.15g]\n", SCIPvarGetName(consdata->var),
    4142 SCIPvarGetLbGlobal(consdata->var), SCIPvarGetUbGlobal(consdata->var));
    4143 (*nchgbds)++;
    4144 }
    4145 }
    4146
    4147 SCIPdebugMsg(scip, " -> variable bound constraint <%s> is redundant\n", SCIPconsGetName(cons));
    4148
    4149 /* in order to correctly update the rounding locks, we need the coefficient to have the same sign as before the
    4150 * coefficient tightening
    4151 */
    4152 consdata->vbdcoef = oldcoef;
    4153
    4154 SCIP_CALL( SCIPdelCons(scip, cons) );
    4155 ++(*ndelconss);
    4156
    4157 return SCIP_OKAY;
    4158 }
    4159
    4160 /* get bounds of variable x */
    4161 xlb = SCIPvarGetLbGlobal(consdata->var);
    4162 xub = SCIPvarGetUbGlobal(consdata->var);
    4163
    4164 /* it can happen that var is not of varstatus SCIP_VARSTATUS_FIXED but the bounds are equal, in this case we need to
    4165 * stop
    4166 */
    4167 if( SCIPisEQ(scip, xlb, xub) )
    4168 return SCIP_OKAY;
    4169
    4170 /* modification of coefficient checking for slack in constraints */
    4171 if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs) )
    4172 {
    4173 /* lhs <= x + c*y <= rhs => lhs - c*y <= x <= rhs - c*y */
    4174 if( consdata->vbdcoef > 0.0 && SCIPisFeasGT(scip, xlb, consdata->lhs - consdata->vbdcoef) && SCIPisFeasLT(scip, xub, consdata->rhs) )
    4175 {
    4176 SCIP_Real newcoef;
    4177 SCIP_Real newrhs;
    4178 SCIP_Real oldrhs;
    4179
    4180 oldrhs = consdata->rhs;
    4181
    4182 /* constraint has positive slack for both non-restricting cases y = 0, or y = 1, respectively
    4183 * -> modify coefficients such that constraint is tight in at least one of the non-restricting cases
    4184 * -> c' = MAX(c - rhs + xub, lhs - xlb), rhs' = rhs - c + c'
    4185 */
    4186 newcoef = MAX(consdata->vbdcoef - consdata->rhs + xub, consdata->lhs - xlb);
    4187
    4188 /* in this case both sides are redundant and the constraint can be removed */
    4189 if( SCIPisLE(scip, newcoef, 0.0) )
    4190 {
    4191 assert(SCIPisFeasGE(scip, xlb, consdata->lhs) && SCIPisFeasGE(scip, xlb + consdata->vbdcoef, consdata->lhs));
    4192 assert(SCIPisFeasLE(scip, xub, consdata->rhs) && SCIPisFeasLE(scip, xub + consdata->vbdcoef, consdata->rhs));
    4193
    4194 SCIPdebugMsg(scip, "delete cons <%s>\n", SCIPconsGetName(cons));
    4195 SCIP_CALL( SCIPdelCons(scip, cons) );
    4196 ++(*ndelconss);
    4197 }
    4198 else
    4199 {
    4200 newrhs = consdata->rhs - consdata->vbdcoef + newcoef;
    4201
    4203 "tighten varbound %.15g <= <%s>[%.15g,%.15g] %+.15g<%s> <= %.15g to %.15g <= <%s> %+.15g<%s> <= %.15g\n",
    4204 consdata->lhs, SCIPvarGetName(consdata->var), xlb, xub, consdata->vbdcoef,
    4205 SCIPvarGetName(consdata->vbdvar), consdata->rhs,
    4206 consdata->lhs, SCIPvarGetName(consdata->var), newcoef, SCIPvarGetName(consdata->vbdvar),
    4207 newrhs);
    4208
    4209 /* we cannot allow that the coefficient changes the sign because of the rounding locks */
    4210 assert(consdata->vbdcoef * newcoef > 0);
    4211
    4212 consdata->vbdcoef = newcoef;
    4213 consdata->rhs = MAX(newrhs, consdata->lhs);
    4214 (*nchgcoefs)++;
    4215 (*nchgsides)++;
    4216
    4217 /* some of the cases 1. to 5. might be applicable after changing the rhs to an integral value; one example is
    4218 * the varbound constraint 0.225 <= x - 1.225 y <= 0.775 for which none of the above cases apply but after
    4219 * tightening the lhs to 0.0 it is possible to reduce the rhs by applying the 1. reduction
    4220 */
    4221 if( !SCIPisFeasIntegral(scip, oldrhs) && SCIPisFeasIntegral(scip, newrhs))
    4222 {
    4223 consdata->tightened = FALSE;
    4224 SCIP_CALL( tightenCoefs(scip, cons, nchgcoefs, nchgsides, ndelconss, cutoff, nchgbds) );
    4225 assert(consdata->tightened);
    4226 assert(!(*cutoff));
    4227 }
    4228 else
    4229 consdata->tightened = (SCIPisIntegral(scip, consdata->vbdcoef) && SCIPisIntegral(scip, consdata->rhs));
    4230 }
    4231 }
    4232 else if( consdata->vbdcoef < 0.0 && SCIPisFeasGT(scip, xlb, consdata->lhs) && SCIPisFeasLT(scip, xub, consdata->rhs - consdata->vbdcoef) )
    4233 {
    4234 SCIP_Real newcoef;
    4235 SCIP_Real newlhs;
    4236 SCIP_Real oldlhs;
    4237
    4238 oldlhs = consdata->lhs;
    4239
    4240 /* constraint has positive slack for both non-restricting cases y = 0, or y = 1, respectively
    4241 * -> modify coefficients such that constraint is tight in at least one of the non-restricting cases
    4242 * -> c' = MIN(c - lhs + xlb, rhs - xub), lhs' = lhs - c + c'
    4243 */
    4244 newcoef = MIN(consdata->vbdcoef - consdata->lhs + xlb, consdata->rhs - xub);
    4245
    4246 /* in this case both sides are redundant and the constraint can be removed */
    4247 if( SCIPisGE(scip, newcoef, 0.0) )
    4248 {
    4249 assert(SCIPisFeasGE(scip, xlb, consdata->lhs) && SCIPisFeasGE(scip, xlb + consdata->vbdcoef, consdata->lhs));
    4250 assert(SCIPisFeasLE(scip, xub, consdata->rhs) && SCIPisFeasLE(scip, xub + consdata->vbdcoef, consdata->rhs));
    4251
    4252 SCIPdebugMsg(scip, "delete cons <%s>\n", SCIPconsGetName(cons));
    4253 SCIP_CALL( SCIPdelCons(scip, cons) );
    4254 ++(*ndelconss);
    4255 }
    4256 else
    4257 {
    4258 newlhs = consdata->lhs - consdata->vbdcoef + newcoef;
    4259
    4261 "tighten varbound %.15g <= <%s>[%.15g,%.15g] %+.15g<%s> <= %.15g to %.15g <= <%s> %+.15g<%s> <= %.15g\n",
    4262 consdata->lhs, SCIPvarGetName(consdata->var), xlb, xub, consdata->vbdcoef,
    4263 SCIPvarGetName(consdata->vbdvar), consdata->rhs,
    4264 newlhs, SCIPvarGetName(consdata->var), newcoef, SCIPvarGetName(consdata->vbdvar),
    4265 consdata->rhs);
    4266
    4267 /* we cannot allow that the coefficient changes the sign because of the rounding locks */
    4268 assert(consdata->vbdcoef * newcoef > 0);
    4269
    4270 consdata->vbdcoef = newcoef;
    4271 consdata->lhs = MIN(newlhs, consdata->rhs);
    4272 (*nchgcoefs)++;
    4273 (*nchgsides)++;
    4274
    4275 /* some of the cases 1. to 5. might be applicable after changing the rhs to an integral value; one example is
    4276 * the varbound constraint 0.225 <= x - 1.225 y <= 0.775 for which none of the above cases apply but after
    4277 * tightening the lhs to 0.0 it is possible to reduce the rhs by applying the 1. reduction
    4278 */
    4279 if( !SCIPisFeasIntegral(scip, oldlhs) && SCIPisFeasIntegral(scip, newlhs))
    4280 {
    4281 consdata->tightened = FALSE;
    4282 SCIP_CALL( tightenCoefs(scip, cons, nchgcoefs, nchgsides, ndelconss, cutoff, nchgbds) );
    4283 assert(consdata->tightened);
    4284 assert(!(*cutoff));
    4285 }
    4286 else
    4287 consdata->tightened = (SCIPisIntegral(scip, consdata->vbdcoef) && SCIPisIntegral(scip, consdata->lhs));
    4288 }
    4289 }
    4290 }
    4291 else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, consdata->rhs) )
    4292 {
    4293 /* lhs <= x + c*y => x >= lhs - c*y */
    4294 if( consdata->vbdcoef > 0.0 && SCIPisFeasGT(scip, xlb, consdata->lhs - consdata->vbdcoef) )
    4295 {
    4296 SCIP_Real newcoef;
    4297
    4298 /* constraint has positive slack for the non-restricting case y = 1
    4299 * -> modify coefficients such that constraint is tight in the non-restricting case y = 1 and equivalent in the restricting case y = 0
    4300 * -> c' = lhs - xlb
    4301 */
    4302 newcoef = consdata->lhs - xlb;
    4303
    4304 /* in this case the constraint is redundant and can be removed */
    4305 if( SCIPisLE(scip, newcoef, 0.0) )
    4306 {
    4307 assert(SCIPisFeasGE(scip, xlb, consdata->lhs) && SCIPisFeasGE(scip, xlb + consdata->vbdcoef, consdata->lhs));
    4308
    4309 SCIPdebugMsg(scip, "delete cons <%s>\n", SCIPconsGetName(cons));
    4310 SCIP_CALL( SCIPdelCons(scip, cons) );
    4311 ++(*ndelconss);
    4312 }
    4313 else
    4314 {
    4315 SCIPdebugMsg(scip, "tighten binary VLB <%s>[%.15g,%.15g] %+.15g<%s> >= %.15g to <%s> %+.15g<%s> >= %.15g\n",
    4316 SCIPvarGetName(consdata->var), xlb, xub, consdata->vbdcoef, SCIPvarGetName(consdata->vbdvar),
    4317 consdata->lhs,
    4318 SCIPvarGetName(consdata->var), consdata->lhs - xlb, SCIPvarGetName(consdata->vbdvar),
    4319 consdata->lhs);
    4320
    4321 /* we cannot allow that the coefficient changes the sign because of the rounding locks */
    4322 assert(consdata->vbdcoef * newcoef > 0);
    4323
    4324 consdata->vbdcoef = newcoef;
    4325 (*nchgcoefs)++;
    4326 }
    4327 }
    4328 else if( consdata->vbdcoef < 0.0 && SCIPisFeasGT(scip, xlb, consdata->lhs) )
    4329 {
    4330 SCIP_Real newcoef;
    4331
    4332 /* constraint has positive slack for the non-restricting case y = 0
    4333 * -> modify coefficients such that constraint is tight in the non-restricting case y = 0 and equivalent in the restricting case y = 1
    4334 * -> c' = c - lhs + xlb, lhs' = xlb
    4335 */
    4336 newcoef = consdata->vbdcoef - consdata->lhs + xlb;
    4337
    4338 /* in this case the constraint is redundant and can be removed */
    4339 if( SCIPisGE(scip, newcoef, 0.0) )
    4340 {
    4341 assert(SCIPisFeasGE(scip, xlb, consdata->lhs) && SCIPisFeasGE(scip, xlb + consdata->vbdcoef, consdata->lhs));
    4342
    4343 SCIPdebugMsg(scip, "delete cons <%s>\n", SCIPconsGetName(cons));
    4344 SCIP_CALL( SCIPdelCons(scip, cons) );
    4345 ++(*ndelconss);
    4346 }
    4347 else
    4348 {
    4349 SCIPdebugMsg(scip, "tighten binary VLB <%s>[%.15g,%.15g] %+.15g<%s> >= %.15g to <%s> %+.15g<%s> >= %.15g\n",
    4350 SCIPvarGetName(consdata->var), xlb, xub, consdata->vbdcoef, SCIPvarGetName(consdata->vbdvar),
    4351 consdata->lhs,
    4352 SCIPvarGetName(consdata->var), consdata->vbdcoef - consdata->lhs + xlb,
    4353 SCIPvarGetName(consdata->vbdvar), xlb);
    4354
    4355 /* we cannot allow that the coefficient changes the sign because of the rounding locks */
    4356 assert(consdata->vbdcoef * newcoef > 0);
    4357
    4358 consdata->vbdcoef = newcoef;
    4359 consdata->lhs = xlb;
    4360 (*nchgcoefs)++;
    4361 (*nchgsides)++;
    4362 }
    4363 }
    4364 }
    4365 else if( SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs) )
    4366 {
    4367 /* x + c*y <= rhs => x <= rhs - c*y */
    4368 if( consdata->vbdcoef > 0.0 && SCIPisFeasLT(scip, xub, consdata->rhs) )
    4369 {
    4370 SCIP_Real newcoef;
    4371
    4372 /* constraint has positive slack for the non-restricting case y = 0
    4373 * -> modify coefficients such that constraint is tight in the non-restricting case y = 0 and equivalent in the restricting case y = 1
    4374 * -> c' = c - rhs + xub, rhs' = xub
    4375 */
    4376 newcoef = consdata->vbdcoef - consdata->rhs + xub;
    4377
    4378 /* in this case the constraint is redundant and can be removed */
    4379 if( SCIPisLE(scip, newcoef, 0.0) )
    4380 {
    4381 assert(SCIPisFeasLE(scip, xub, consdata->rhs) && SCIPisFeasLE(scip, xub + consdata->vbdcoef, consdata->rhs));
    4382
    4383 SCIPdebugMsg(scip, "delete cons <%s>\n", SCIPconsGetName(cons));
    4384 SCIP_CALL( SCIPdelCons(scip, cons) );
    4385 ++(*ndelconss);
    4386 }
    4387 else
    4388 {
    4389 SCIPdebugMsg(scip, "tighten binary VUB <%s>[%.15g,%.15g] %+.15g<%s> <= %.15g to <%s> %+.15g<%s> <= %.15g\n",
    4390 SCIPvarGetName(consdata->var), xlb, xub, consdata->vbdcoef, SCIPvarGetName(consdata->vbdvar),
    4391 consdata->rhs,
    4392 SCIPvarGetName(consdata->var), consdata->vbdcoef - consdata->rhs + xub,
    4393 SCIPvarGetName(consdata->vbdvar), xub);
    4394
    4395 /* we cannot allow that the coefficient changes the sign because of the rounding locks */
    4396 assert(consdata->vbdcoef * newcoef > 0);
    4397
    4398 consdata->vbdcoef = newcoef;
    4399 consdata->rhs = xub;
    4400 (*nchgcoefs)++;
    4401 (*nchgsides)++;
    4402 }
    4403 }
    4404 else if( consdata->vbdcoef < 0.0 && SCIPisFeasLT(scip, xub, consdata->rhs - consdata->vbdcoef) )
    4405 {
    4406 SCIP_Real newcoef;
    4407
    4408 /* constraint has positive slack for the non-restricting case y = 1
    4409 * -> modify coefficients such that constraint is tight in the non-restricting case y = 1 and equivalent in the restricting case y = 0
    4410 * -> c' = rhs - xub
    4411 */
    4412 newcoef = consdata->rhs - xub;
    4413
    4414 /* in this case the constraint is redundant and can be removed */
    4415 if( SCIPisGE(scip, newcoef, 0.0) )
    4416 {
    4417 assert(SCIPisFeasLE(scip, xub, consdata->rhs) && SCIPisFeasLE(scip, xub + consdata->vbdcoef, consdata->rhs));
    4418
    4419 SCIPdebugMsg(scip, "delete cons <%s>\n", SCIPconsGetName(cons));
    4420 SCIP_CALL( SCIPdelCons(scip, cons) );
    4421 ++(*ndelconss);
    4422 }
    4423 else
    4424 {
    4425 SCIPdebugMsg(scip, "tighten binary VUB <%s>[%.15g,%.15g] %+.15g<%s> <= %.15g to <%s> %+.15g<%s> <= %.15g\n",
    4426 SCIPvarGetName(consdata->var), xlb, xub, consdata->vbdcoef, SCIPvarGetName(consdata->vbdvar), consdata->rhs,
    4427 SCIPvarGetName(consdata->var), consdata->rhs - xub, SCIPvarGetName(consdata->vbdvar), consdata->rhs);
    4428
    4429 /* we cannot allow that the coefficient changes the sign because of the rounding locks */
    4430 assert(consdata->vbdcoef * newcoef > 0);
    4431
    4432 consdata->vbdcoef = newcoef;
    4433 (*nchgcoefs)++;
    4434 }
    4435 }
    4436 }
    4437
    4438 /* if something a coefficient or side of the varbound constraint was changed, ensure that the variable lower or
    4439 * upper bounds of the variables are informed
    4440 */
    4441 if( *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides )
    4442 {
    4443 consdata->varboundsadded = FALSE;
    4444 consdata->changed = TRUE;
    4445
    4447 }
    4448
    4449 return SCIP_OKAY;
    4450}
    4451
    4452/** check if we can upgrade to a set-packing constraint */
    4453static
    4455 SCIP* scip, /**< SCIP data structure */
    4456 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    4457 SCIP_CONS** conss, /**< constraint set */
    4458 int nconss, /**< number of constraints in constraint set */
    4459 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    4460 int* naggrvars, /**< pointer to count the number of aggregated variables */
    4461 int* nchgbds, /**< pointer to count number of bound changes */
    4462 int* nchgcoefs, /**< pointer to count the number of changed coefficients */
    4463 int* nchgsides, /**< pointer to count the number of left and right hand sides */
    4464 int* ndelconss, /**< pointer to count the number of deleted constraints */
    4465 int* naddconss /**< pointer to count the number of added constraints */
    4466 )
    4467{
    4468 SCIP_VAR* vars[2];
    4469 SCIP_CONS* newcons;
    4470 SCIP_CONS* cons;
    4471 SCIP_CONSDATA* consdata;
    4472 int c;
    4473
    4474 assert(scip != NULL);
    4475 assert(conshdlrdata != NULL);
    4476 assert(conss != NULL || nconss == 0);
    4477 assert(cutoff != NULL);
    4478 assert(naggrvars != NULL);
    4479 assert(nchgbds != NULL);
    4480 assert(nchgcoefs != NULL);
    4481 assert(nchgsides != NULL);
    4482 assert(ndelconss != NULL);
    4483 assert(naddconss != NULL);
    4484
    4485 /* if we cannot find any constraint for upgrading, stop */
    4487 return SCIP_OKAY;
    4488
    4489 if( nconss == 0 )
    4490 return SCIP_OKAY;
    4491
    4492 assert(conss != NULL);
    4493
    4494 for( c = nconss - 1; c >= 0; --c )
    4495 {
    4496 cons = conss[c];
    4497 assert(cons != NULL);
    4498
    4499 if( !SCIPconsIsActive(cons) || SCIPconsGetNUpgradeLocks(cons) >= 1 )
    4500 continue;
    4501
    4502 consdata = SCIPconsGetData(cons);
    4503 assert(consdata != NULL);
    4504 assert(SCIPisLE(scip, consdata->lhs, consdata->rhs));
    4505
    4506 if( !consdata->presolved )
    4507 {
    4508 /* incorporate fixings and aggregations in constraint */
    4509 SCIP_CALL( applyFixings(scip, cons, conshdlrdata->eventhdlr, cutoff, nchgbds, ndelconss, naddconss) );
    4510
    4511 if( *cutoff )
    4512 return SCIP_OKAY;
    4513 if( !SCIPconsIsActive(cons) )
    4514 continue;
    4515 }
    4516
    4517 if( SCIPconsIsMarkedPropagate(cons) )
    4518 {
    4519 /* propagate constraint */
    4520 SCIP_CALL( propagateCons(scip, cons, conshdlrdata->usebdwidening, cutoff, nchgbds, nchgsides, ndelconss) );
    4521
    4522 if( *cutoff )
    4523 return SCIP_OKAY;
    4524 if( !SCIPconsIsActive(cons) )
    4525 continue;
    4526 }
    4527
    4528 if( !consdata->tightened )
    4529 {
    4530 /* tighten variable bound coefficient */
    4531 SCIP_CALL( tightenCoefs(scip, cons, nchgcoefs, nchgsides, ndelconss, cutoff, nchgbds) );
    4532
    4533 if( *cutoff )
    4534 return SCIP_OKAY;
    4535 if( !SCIPconsIsActive(cons) )
    4536 continue;
    4537
    4538 assert(SCIPisLE(scip, consdata->lhs, consdata->rhs));
    4539 }
    4540
    4541 /* check if both variables are of binary type */
    4542 if( SCIPvarIsBinary(consdata->vbdvar) && SCIPvarIsBinary(consdata->var) )
    4543 {
    4544 /* coefficient and sides should be tightened and we assume that the constraint is not redundant */
    4545 assert(SCIPisEQ(scip, REALABS(consdata->vbdcoef), 1.0));
    4546 assert(SCIPisZero(scip, consdata->rhs) || SCIPisEQ(scip, consdata->rhs, 1.0) || SCIPisInfinity(scip, consdata->rhs));
    4547 assert(SCIPisZero(scip, consdata->lhs) || SCIPisEQ(scip, consdata->lhs, 1.0) || SCIPisInfinity(scip, -consdata->lhs));
    4548 assert(!SCIPisInfinity(scip, consdata->rhs) || !SCIPisInfinity(scip, -consdata->lhs));
    4549
    4550 /* the case x + y <= 1 or x + y >= 1 */
    4551 if( consdata->vbdcoef > 0.0 )
    4552 {
    4553 if( SCIPisEQ(scip, consdata->rhs, 1.0) )
    4554 {
    4555 /* check for aggregations like x + y == 1 */
    4556 if( SCIPisEQ(scip, consdata->lhs, 1.0) )
    4557 {
    4558 SCIP_Bool infeasible;
    4559 SCIP_Bool redundant;
    4560 SCIP_Bool aggregated;
    4561
    4562 SCIPdebugMsg(scip, "varbound constraint <%s>: aggregate <%s> + <%s> == 1\n",
    4563 SCIPconsGetName(cons), SCIPvarGetName(consdata->var), SCIPvarGetName(consdata->vbdvar));
    4564
    4565 /* aggregate both variables */
    4566 SCIP_CALL( SCIPaggregateVars(scip, consdata->var, consdata->vbdvar, 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
    4567 assert(!infeasible);
    4568 ++(*naggrvars);
    4569
    4570 SCIP_CALL( SCIPdelCons(scip, cons) );
    4571 ++(*ndelconss);
    4572
    4573 continue;
    4574 }
    4575 assert(consdata->lhs < 0.5);
    4576
    4577 vars[0] = consdata->var;
    4578 vars[1] = consdata->vbdvar;
    4579 }
    4580 else
    4581 {
    4582 assert(SCIPisEQ(scip, consdata->lhs, 1.0));
    4583
    4584 SCIP_CALL( SCIPgetNegatedVar(scip, consdata->var, &vars[0]) );
    4585 SCIP_CALL( SCIPgetNegatedVar(scip, consdata->vbdvar, &vars[1]) );
    4586 }
    4587 }
    4588 /* the case x - y <= 0 or x - y >= 0 */
    4589 else
    4590 {
    4591 /* the case x - y <= 0 */
    4592 if( SCIPisZero(scip, consdata->rhs) )
    4593 {
    4594 /* check for aggregations like x - y == 0 */
    4595 if( SCIPisZero(scip, consdata->lhs) )
    4596 {
    4597 SCIP_Bool infeasible;
    4598 SCIP_Bool redundant;
    4599 SCIP_Bool aggregated;
    4600
    4601 SCIPdebugMsg(scip, "varbound constraint <%s>: aggregate <%s> - <%s> == 0\n",
    4602 SCIPconsGetName(cons), SCIPvarGetName(consdata->var), SCIPvarGetName(consdata->vbdvar));
    4603
    4604 /* aggregate both variables */
    4605 SCIP_CALL( SCIPaggregateVars(scip, consdata->var, consdata->vbdvar, 1.0, -1.0, 0.0, &infeasible, &redundant, &aggregated) );
    4606 assert(!infeasible);
    4607 ++(*naggrvars);
    4608
    4609 SCIP_CALL( SCIPdelCons(scip, cons) );
    4610 ++(*ndelconss);
    4611
    4612 continue;
    4613 }
    4614 assert(consdata->lhs < -0.5);
    4615
    4616 vars[0] = consdata->var;
    4617 SCIP_CALL( SCIPgetNegatedVar(scip, consdata->vbdvar, &vars[1]) );
    4618 }
    4619 /* the case x - y >= 0 */
    4620 else
    4621 {
    4622 assert(SCIPisZero(scip, consdata->lhs));
    4623
    4624 SCIP_CALL( SCIPgetNegatedVar(scip, consdata->var, &vars[0]) );
    4625 vars[1] = consdata->vbdvar;
    4626 }
    4627 }
    4628
    4629 SCIP_CALL( SCIPcreateConsSetpack(scip, &newcons, SCIPconsGetName(cons), 2, vars,
    4634
    4635 SCIPdebugMsg(scip, "upgraded varbound constraint <%s> to a set-packing constraint\n", SCIPconsGetName(cons));
    4636 SCIPdebugPrintCons(scip, newcons, NULL);
    4637
    4638 SCIP_CALL( SCIPaddConsUpgrade(scip, cons, &newcons) );
    4639 ++(*naddconss);
    4640
    4641 SCIP_CALL( SCIPdelCons(scip, cons) );
    4642 ++(*ndelconss);
    4643 }
    4644 }
    4645
    4646 return SCIP_OKAY;
    4647}
    4648
    4649/**@} */
    4650
    4651
    4652/**@name Linear constraint upgrading
    4653 *
    4654 * @{
    4655 */
    4656
    4657/** tries to upgrade a linear constraint into a variable bound constraint */
    4658static
    4659SCIP_DECL_LINCONSUPGD(linconsUpgdVarbound)
    4660{ /*lint --e{715}*/
    4661 SCIP_Bool upgrade;
    4662
    4663 assert(upgdcons != NULL);
    4664
    4665 /* check, if linear constraint can be upgraded to a variable bound constraint lhs <= x + a*y <= rhs
    4666 * - there are exactly two variables
    4667 * - one of the variables is non-binary (called the bounded variable x)
    4668 * - one of the variables is non-continuous (called the bounding variable y)
    4669 */
    4670 upgrade = (nvars == 2) && (nposbin + nnegbin <= 1) && (nposcont + nnegcont <= 1);
    4671
    4672 if( upgrade )
    4673 {
    4674 SCIP_VAR* var;
    4675 SCIP_VAR* vbdvar;
    4676 SCIP_Real vbdcoef;
    4677 SCIP_Real vbdlhs;
    4678 SCIP_Real vbdrhs;
    4681 int vbdind;
    4682
    4683 /* decide which variable we want to use as bounding variable y */
    4684 if( zerotype < onetype )
    4685 vbdind = 0;
    4686 else if( zerotype > onetype )
    4687 vbdind = 1;
    4688 else if( SCIPisIntegral(scip, vals[0]) && !SCIPisIntegral(scip, vals[1]) )
    4689 vbdind = 0;
    4690 else if( !SCIPisIntegral(scip, vals[0]) && SCIPisIntegral(scip, vals[1]) )
    4691 vbdind = 1;
    4692 else if( REALABS(REALABS(vals[0]) - 1.0) < REALABS(REALABS(vals[1]) - 1.0) )
    4693 vbdind = 1;
    4694 else
    4695 vbdind = 0;
    4696
    4697 /* do not upgrade when it is numerical unstable */
    4698 if( SCIPisZero(scip, vals[vbdind]/vals[1-vbdind]) )
    4699 return SCIP_OKAY;
    4700
    4701 SCIPdebugMsg(scip, "upgrading constraint <%s> to variable bound constraint\n", SCIPconsGetName(cons));
    4702
    4703 var = vars[1-vbdind];
    4704 vbdvar = vars[vbdind];
    4705
    4706 assert(!SCIPisZero(scip, vals[1-vbdind]));
    4707 vbdcoef = vals[vbdind]/vals[1-vbdind];
    4708
    4709 if( vals[1-vbdind] > 0.0 )
    4710 {
    4711 vbdlhs = SCIPisInfinity(scip, -lhs) ? -SCIPinfinity(scip) : lhs/vals[1-vbdind];
    4712 vbdrhs = SCIPisInfinity(scip, rhs) ? SCIPinfinity(scip) : rhs/vals[1-vbdind];
    4713 }
    4714 else
    4715 {
    4716 vbdlhs = SCIPisInfinity(scip, rhs) ? -SCIPinfinity(scip) : rhs/vals[1-vbdind];
    4717 vbdrhs = SCIPisInfinity(scip, -lhs) ? SCIPinfinity(scip) : lhs/vals[1-vbdind];
    4718 }
    4719
    4720 /* create the bin variable bound constraint (an automatically upgraded constraint is always unmodifiable) */
    4721 assert(!SCIPconsIsModifiable(cons));
    4722 SCIP_CALL( SCIPcreateConsVarbound(scip, upgdcons, SCIPconsGetName(cons), var, vbdvar, vbdcoef, vbdlhs, vbdrhs,
    4727 }
    4728
    4729 return SCIP_OKAY;
    4730}
    4731
    4732/** adds symmetry information of constraint to a symmetry detection graph */
    4733static
    4735 SCIP* scip, /**< SCIP pointer */
    4736 SYM_SYMTYPE symtype, /**< type of symmetries that need to be added */
    4737 SCIP_CONS* cons, /**< constraint */
    4738 SYM_GRAPH* graph, /**< symmetry detection graph */
    4739 SCIP_Bool* success /**< pointer to store whether symmetry information could be added */
    4740 )
    4741{
    4742 SCIP_VAR** vars;
    4743 SCIP_Real* vals;
    4744 SCIP_Real constant = 0.0;
    4745 SCIP_Real lhs;
    4746 SCIP_Real rhs;
    4747 int nlocvars;
    4748 int nvars;
    4749
    4750 assert(scip != NULL);
    4751 assert(cons != NULL);
    4752 assert(graph != NULL);
    4753 assert(success != NULL);
    4754
    4755 /* get active variables of the constraint */
    4756 nvars = SCIPgetNVars(scip);
    4757 nlocvars = 2;
    4758
    4759 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
    4760 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
    4761
    4762 vars[0] = SCIPgetVarVarbound(scip, cons);
    4763 vars[1] = SCIPgetVbdvarVarbound(scip, cons);
    4764 vals[0] = 1.0;
    4765 vals[1] = SCIPgetVbdcoefVarbound(scip, cons);
    4766
    4767 SCIP_CALL( SCIPgetSymActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant, SCIPisTransformed(scip)) );
    4768 lhs = SCIPgetLhsVarbound(scip, cons) - constant;
    4769 rhs = SCIPgetRhsVarbound(scip, cons) - constant;
    4770
    4771 SCIP_CALL( SCIPextendPermsymDetectionGraphLinear(scip, graph, vars, vals, nlocvars,
    4772 cons, lhs, rhs, success) );
    4773
    4774 SCIPfreeBufferArray(scip, &vals);
    4775 SCIPfreeBufferArray(scip, &vars);
    4776
    4777 return SCIP_OKAY;
    4778}
    4779
    4780/**@} */
    4781
    4782
    4783/**@name Callback methods
    4784 *
    4785 * @{
    4786 */
    4787
    4788/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    4789static
    4790SCIP_DECL_CONSHDLRCOPY(conshdlrCopyVarbound)
    4791{ /*lint --e{715}*/
    4792 assert(scip != NULL);
    4793 assert(conshdlr != NULL);
    4794 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    4795
    4796 /* call inclusion method of constraint handler */
    4798
    4799 *valid = TRUE;
    4800
    4801 return SCIP_OKAY;
    4802}
    4803
    4804/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
    4805static
    4806SCIP_DECL_CONSFREE(consFreeVarbound)
    4807{ /*lint --e{715}*/
    4808 SCIP_CONSHDLRDATA* conshdlrdata;
    4809
    4810 assert(scip != NULL);
    4811 assert(conshdlr != NULL);
    4812 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    4813
    4814 /* free constraint handler data */
    4815 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    4816 assert(conshdlrdata != NULL);
    4817
    4818 conshdlrdataFree(scip, &conshdlrdata);
    4819
    4820 SCIPconshdlrSetData(conshdlr, NULL);
    4821
    4822 return SCIP_OKAY;
    4823}
    4824
    4825/** solving process initialization method of constraint handler */
    4826static
    4827SCIP_DECL_CONSINITSOL(consInitsolVarbound)
    4828{ /*lint --e{715}*/
    4829 /* add nlrow representation to NLP, if NLP had been constructed */
    4831 {
    4832 int c;
    4833 for( c = 0; c < nconss; ++c )
    4834 {
    4835 SCIP_CALL( addNlrow(scip, conss[c]) );
    4836 }
    4837 }
    4838
    4839 return SCIP_OKAY;
    4840}
    4841
    4842/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
    4843static
    4844SCIP_DECL_CONSEXITSOL(consExitsolVarbound)
    4845{ /*lint --e{715}*/
    4846 SCIP_CONSDATA* consdata;
    4847 int c;
    4848
    4849 /* release the rows and nlrows of all constraints */
    4850 for( c = 0; c < nconss; ++c )
    4851 {
    4852 consdata = SCIPconsGetData(conss[c]);
    4853 assert(consdata != NULL);
    4854
    4855 if( consdata->row != NULL )
    4856 {
    4857 SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
    4858 }
    4859
    4860 if( consdata->nlrow != NULL )
    4861 {
    4862 SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow) );
    4863 }
    4864 }
    4865
    4866 return SCIP_OKAY;
    4867}
    4868
    4869
    4870/** frees specific constraint data */
    4871static
    4872SCIP_DECL_CONSDELETE(consDeleteVarbound)
    4873{ /*lint --e{715}*/
    4874 SCIP_CONSHDLRDATA* conshdlrdata;
    4875
    4876 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    4877 assert(conshdlrdata != NULL);
    4878
    4879 /* drop events */
    4880 if( SCIPisTransformed(scip) )
    4881 {
    4882 SCIP_CALL( dropEvents(scip, cons, conshdlrdata->eventhdlr) );
    4883 }
    4884
    4885 SCIP_CALL( consdataFree(scip, consdata) );
    4886
    4887 return SCIP_OKAY;
    4888}
    4889
    4890
    4891/** transforms constraint data into data belonging to the transformed problem */
    4892static
    4893SCIP_DECL_CONSTRANS(consTransVarbound)
    4894{ /*lint --e{715}*/
    4895 SCIP_CONSHDLRDATA* conshdlrdata;
    4896 SCIP_CONSDATA* sourcedata;
    4897 SCIP_CONSDATA* targetdata;
    4898
    4899 assert(conshdlr != NULL);
    4900
    4901 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    4902 assert(conshdlrdata != NULL);
    4903
    4904 sourcedata = SCIPconsGetData(sourcecons);
    4905 assert(sourcedata != NULL);
    4906
    4907 /* create target constraint data */
    4908 SCIP_CALL( consdataCreate(scip, &targetdata,
    4909 sourcedata->var, sourcedata->vbdvar, sourcedata->vbdcoef, sourcedata->lhs, sourcedata->rhs) );
    4910
    4911 /* create target constraint */
    4912 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
    4913 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    4914 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
    4915 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
    4916 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
    4917
    4918 /* catch events for variables */
    4919 SCIP_CALL( catchEvents(scip, *targetcons, conshdlrdata->eventhdlr) );
    4920
    4921 return SCIP_OKAY;
    4922}
    4923
    4924
    4925/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
    4926static
    4927SCIP_DECL_CONSINITLP(consInitlpVarbound)
    4928{ /*lint --e{715}*/
    4929 int i;
    4930
    4931 *infeasible = FALSE;
    4932
    4933 for( i = 0; i < nconss && !(*infeasible); i++ )
    4934 {
    4935 assert(SCIPconsIsInitial(conss[i]));
    4936 SCIP_CALL( addRelaxation(scip, conss[i], infeasible) );
    4937 }
    4938
    4939 return SCIP_OKAY;
    4940}
    4941
    4942
    4943/** separation method of constraint handler for LP solutions */
    4944static
    4945SCIP_DECL_CONSSEPALP(consSepalpVarbound)
    4946{ /*lint --e{715}*/
    4947 SCIP_CONSHDLRDATA* conshdlrdata;
    4948 int i;
    4949
    4950 assert(conshdlr != NULL);
    4951
    4952 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    4953 assert(conshdlrdata != NULL);
    4954
    4955 *result = SCIP_DIDNOTFIND;
    4956
    4957 /* separate useful constraints */
    4958 for( i = 0; i < nusefulconss; ++i )
    4959 {
    4960 SCIP_CALL( separateCons(scip, conss[i], conshdlrdata->usebdwidening, NULL, result) );
    4961 }
    4962
    4963 /* separate remaining constraints */
    4964 for( i = nusefulconss; i < nconss && *result == SCIP_DIDNOTFIND; ++i )
    4965 {
    4966 SCIP_CALL( separateCons(scip, conss[i], conshdlrdata->usebdwidening, NULL, result) );
    4967 }
    4968
    4969 return SCIP_OKAY;
    4970}
    4971
    4972
    4973/** separation method of constraint handler for arbitrary primal solutions */
    4974static
    4975SCIP_DECL_CONSSEPASOL(consSepasolVarbound)
    4976{ /*lint --e{715}*/
    4977 SCIP_CONSHDLRDATA* conshdlrdata;
    4978 int i;
    4979
    4980 assert(conshdlr != NULL);
    4981
    4982 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    4983 assert(conshdlrdata != NULL);
    4984
    4985 *result = SCIP_DIDNOTFIND;
    4986
    4987 /* separate useful constraints */
    4988 for( i = 0; i < nusefulconss; ++i )
    4989 {
    4990 SCIP_CALL( separateCons(scip, conss[i], conshdlrdata->usebdwidening, sol, result) );
    4991 }
    4992
    4993 /* separate remaining constraints */
    4994 for( i = nusefulconss; i < nconss && *result == SCIP_DIDNOTFIND; ++i )
    4995 {
    4996 SCIP_CALL( separateCons(scip, conss[i], conshdlrdata->usebdwidening, sol, result) );
    4997 }
    4998
    4999 return SCIP_OKAY;
    5000}
    5001
    5002
    5003/** constraint enforcing method of constraint handler for LP solutions */
    5004static
    5005SCIP_DECL_CONSENFOLP(consEnfolpVarbound)
    5006{ /*lint --e{715}*/
    5007 SCIP_CONSHDLRDATA* conshdlrdata;
    5008 int i;
    5009
    5010 assert(conshdlr != NULL);
    5011
    5012 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5013 assert(conshdlrdata != NULL);
    5014
    5015 *result = SCIP_FEASIBLE;
    5016
    5017 for( i = 0; i < nconss; i++ )
    5018 {
    5019 if( !checkCons(scip, conss[i], NULL, FALSE) )
    5020 {
    5021 assert((*result) == SCIP_INFEASIBLE || (*result) == SCIP_FEASIBLE);
    5022 (*result) = SCIP_INFEASIBLE;
    5023
    5024 SCIP_CALL( SCIPresetConsAge(scip, conss[i]) );
    5025
    5026 SCIP_CALL( separateCons(scip, conss[i], conshdlrdata->usebdwidening, NULL, result) );
    5027 assert((*result) != SCIP_FEASIBLE);
    5028
    5029 if( (*result) != SCIP_INFEASIBLE )
    5030 break;
    5031 }
    5032 else
    5033 {
    5034 /* increase age of constraint */
    5035 SCIP_CALL( SCIPincConsAge(scip, conss[i]) );
    5036 }
    5037 }
    5038
    5039 return SCIP_OKAY;
    5040}
    5041
    5042
    5043/** constraint enforcing method of constraint handler for relaxation solutions */
    5044static
    5045SCIP_DECL_CONSENFORELAX(consEnforelaxVarbound)
    5046{ /*lint --e{715}*/
    5047 SCIP_CONSHDLRDATA* conshdlrdata;
    5048 int i;
    5049
    5050 assert(conshdlr != NULL);
    5051
    5052 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5053 assert(conshdlrdata != NULL);
    5054
    5055 *result = SCIP_FEASIBLE;
    5056
    5057 for( i = 0; i < nconss; i++ )
    5058 {
    5059 if( !checkCons(scip, conss[i], sol, FALSE) )
    5060 {
    5061 assert((*result) == SCIP_INFEASIBLE || (*result) == SCIP_FEASIBLE);
    5062 (*result) = SCIP_INFEASIBLE;
    5063
    5064 SCIP_CALL( SCIPresetConsAge(scip, conss[i]) );
    5065
    5066 SCIP_CALL( separateCons(scip, conss[i], conshdlrdata->usebdwidening, sol, result) );
    5067 assert((*result) != SCIP_FEASIBLE);
    5068
    5069 if( (*result) != SCIP_INFEASIBLE )
    5070 break;
    5071 }
    5072 else
    5073 {
    5074 /* increase age of constraint */
    5075 SCIP_CALL( SCIPincConsAge(scip, conss[i]) );
    5076 }
    5077 }
    5078
    5079 return SCIP_OKAY;
    5080}
    5081
    5082
    5083/** constraint enforcing method of constraint handler for pseudo solutions */
    5084static
    5085SCIP_DECL_CONSENFOPS(consEnfopsVarbound)
    5086{ /*lint --e{715}*/
    5087 int i;
    5088
    5089 for( i = 0; i < nconss; i++ )
    5090 {
    5091 if( !checkCons(scip, conss[i], NULL, TRUE) )
    5092 {
    5093 SCIP_CALL( SCIPresetConsAge(scip, conss[i]) );
    5094
    5095 *result = SCIP_INFEASIBLE;
    5096 return SCIP_OKAY;
    5097 }
    5098 else
    5099 {
    5100 /* increase age of constraint */
    5101 SCIP_CALL( SCIPincConsAge(scip, conss[i]) );
    5102 }
    5103 }
    5104 *result = SCIP_FEASIBLE;
    5105
    5106 return SCIP_OKAY;
    5107}
    5108
    5109
    5110/** feasibility check method of constraint handler for integral solutions */
    5111static
    5112SCIP_DECL_CONSCHECK(consCheckVarbound)
    5113{ /*lint --e{715}*/
    5114 int i;
    5115
    5116 *result = SCIP_FEASIBLE;
    5117
    5118 for( i = 0; i < nconss && (*result == SCIP_FEASIBLE || completely); i++ )
    5119 {
    5120 if( !checkCons(scip, conss[i], sol, checklprows) )
    5121 {
    5122 *result = SCIP_INFEASIBLE;
    5123
    5124 if( printreason )
    5125 {
    5126 SCIP_CONSDATA* consdata;
    5127 SCIP_Real sum;
    5128
    5129 consdata = SCIPconsGetData(conss[i]);
    5130 assert( consdata != NULL );
    5131
    5132 sum = SCIPgetSolVal(scip, sol, consdata->var) + consdata->vbdcoef * SCIPgetSolVal(scip, sol, consdata->vbdvar);
    5133
    5134 SCIP_CALL( SCIPprintCons(scip, conss[i], NULL) );
    5135 SCIPinfoMessage(scip, NULL, ";\n");
    5136
    5137 if( !SCIPisFeasGE(scip, sum, consdata->lhs) )
    5138 {
    5139 SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", consdata->lhs - sum);
    5140 }
    5141 if( !SCIPisFeasLE(scip, sum, consdata->rhs) )
    5142 {
    5143 SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", sum - consdata->rhs);
    5144 }
    5145 }
    5146 }
    5147 }
    5148
    5149 return SCIP_OKAY;
    5150}
    5151
    5152
    5153/** domain propagation method of constraint handler */
    5154static
    5155SCIP_DECL_CONSPROP(consPropVarbound)
    5156{ /*lint --e{715}*/
    5157 SCIP_CONSHDLRDATA* conshdlrdata;
    5158 SCIP_Bool cutoff;
    5159 int nchgbds = 0;
    5160 int nchgsides = 0;
    5161 int i;
    5162
    5163 assert(conshdlr != NULL);
    5164
    5165 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5166 assert(conshdlrdata != NULL);
    5167
    5168 cutoff = FALSE;
    5169
    5170 SCIPdebugMsg(scip, "propagating %d variable bound constraints\n", nmarkedconss);
    5171
    5172 /* process constraints marked for propagation */
    5173 for( i = 0; i < nmarkedconss && !cutoff; i++ )
    5174 {
    5175 SCIP_CALL( propagateCons(scip, conss[i], conshdlrdata->usebdwidening, &cutoff, &nchgbds, &nchgsides, NULL) );
    5176 }
    5177
    5178 if( cutoff )
    5179 *result = SCIP_CUTOFF;
    5180 else if( nchgbds > 0 )
    5181 *result = SCIP_REDUCEDDOM;
    5182 else
    5183 *result = SCIP_DIDNOTFIND;
    5184
    5185 return SCIP_OKAY;
    5186}
    5187
    5188
    5189/** presolving method of constraint handler */
    5190static
    5191SCIP_DECL_CONSPRESOL(consPresolVarbound)
    5192{ /*lint --e{715}*/
    5193 SCIP_CONSHDLRDATA* conshdlrdata;
    5194 SCIP_CONS* cons;
    5195 SCIP_CONSDATA* consdata;
    5196 SCIP_Bool cutoff;
    5197 int oldnchgbds;
    5198 int oldndelconss;
    5199 int oldnaddconss;
    5200 int oldnchgcoefs;
    5201 int oldnchgsides;
    5202 int oldnaggrvars;
    5203 int i;
    5204
    5205 assert(scip != NULL);
    5206 assert(conshdlr != NULL);
    5207 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5208 assert(result != NULL);
    5209
    5210 /* get constraint handler data */
    5211 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5212 assert(conshdlrdata != NULL);
    5213
    5214 cutoff = FALSE;
    5215 oldnchgbds = *nchgbds;
    5216 oldndelconss = *ndelconss;
    5217 oldnaddconss = *naddconss;
    5218 oldnchgcoefs = *nchgcoefs;
    5219 oldnchgsides = *nchgsides;
    5220 oldnaggrvars = *naggrvars;
    5221
    5222 for( i = 0; i < nconss; i++ )
    5223 {
    5224 cons = conss[i];
    5225 assert(cons != NULL);
    5226
    5227 assert(!SCIPconsIsModifiable(cons));
    5228
    5229 consdata = SCIPconsGetData(cons);
    5230 assert(consdata != NULL);
    5231
    5232 if( i % 1000 == 0 && SCIPisStopped(scip) )
    5233 break;
    5234
    5235 /* force presolving the constraint in the initial round */
    5236 if( nrounds == 0 )
    5237 consdata->presolved = FALSE;
    5238
    5239 if( consdata->presolved )
    5240 continue;
    5241 consdata->presolved = TRUE;
    5242
    5243 /* incorporate fixings and aggregations in constraint */
    5244 SCIP_CALL( applyFixings(scip, cons, conshdlrdata->eventhdlr, &cutoff, nchgbds, ndelconss, naddconss) );
    5245
    5246 if( cutoff )
    5247 break;
    5248 if( !SCIPconsIsActive(cons) )
    5249 continue;
    5250
    5251 /* propagate constraint */
    5252 SCIP_CALL( propagateCons(scip, cons, conshdlrdata->usebdwidening, &cutoff, nchgbds, nchgsides, ndelconss) );
    5253
    5254 if( cutoff )
    5255 break;
    5256 if( !SCIPconsIsActive(cons) )
    5257 continue;
    5258
    5259 /* tighten variable bound coefficient */
    5260 SCIP_CALL( tightenCoefs(scip, cons, nchgcoefs, nchgsides, ndelconss, &cutoff, nchgbds) );
    5261 if( cutoff )
    5262 break;
    5263 if( !SCIPconsIsActive(cons) )
    5264 continue;
    5265
    5266 /* informs once variable x about a globally valid variable lower or upper bound */
    5267 if( !consdata->varboundsadded )
    5268 {
    5269 SCIP_Bool infeasible;
    5270 int nlocalchgbds;
    5271 int localoldnchgbds;
    5272
    5273 localoldnchgbds = *nchgbds;
    5274
    5275 /* if lhs is finite, we have a variable lower bound: lhs <= x + c*y => x >= -c*y + lhs */
    5276 if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, REALABS(consdata->vbdcoef)) )
    5277 {
    5278 SCIPdebugMsg(scip, "adding variable lower bound <%s> >= %g<%s> + %g (and potentially also <%s> %s %g<%s> + %g)\n",
    5279 SCIPvarGetName(consdata->var), -consdata->vbdcoef, SCIPvarGetName(consdata->vbdvar), consdata->lhs,
    5280 SCIPvarGetName(consdata->vbdvar), (consdata->vbdcoef > 0 ? ">=" : "<="), 1.0/-consdata->vbdcoef,
    5281 SCIPvarGetName(consdata->var), consdata->lhs/consdata->vbdcoef);
    5282
    5283 SCIP_CALL( SCIPaddVarVlb(scip, consdata->var, consdata->vbdvar, -consdata->vbdcoef, consdata->lhs,
    5284 &infeasible, &nlocalchgbds) );
    5285 assert(!infeasible);
    5286
    5287 *nchgbds += nlocalchgbds;
    5288 }
    5289
    5290 /* if rhs is finite, we have a variable upper bound: x + c*y <= rhs => x <= -c*y + rhs */
    5291 if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, REALABS(consdata->vbdcoef)) )
    5292 {
    5293 SCIPdebugMsg(scip, "adding variable upper bound <%s> <= %g<%s> + %g (and potentially also <%s> %s %g<%s> + %g)\n",
    5294 SCIPvarGetName(consdata->var), -consdata->vbdcoef, SCIPvarGetName(consdata->vbdvar), consdata->rhs,
    5295 SCIPvarGetName(consdata->vbdvar), (consdata->vbdcoef > 0 ? "<=" : ">="), 1.0/-consdata->vbdcoef,
    5296 SCIPvarGetName(consdata->var), consdata->rhs/consdata->vbdcoef);
    5297
    5298 SCIP_CALL( SCIPaddVarVub(scip, consdata->var, consdata->vbdvar, -consdata->vbdcoef, consdata->rhs,
    5299 &infeasible, &nlocalchgbds) );
    5300 assert(!infeasible);
    5301
    5302 *nchgbds += nlocalchgbds;
    5303 }
    5304 consdata->varboundsadded = TRUE;
    5305
    5306 if( *nchgbds > localoldnchgbds )
    5307 {
    5308 /* tighten variable bound coefficient */
    5309 SCIP_CALL( tightenCoefs(scip, cons, nchgcoefs, nchgsides, ndelconss, &cutoff, nchgbds) );
    5310 if( cutoff )
    5311 break;
    5312 }
    5313 }
    5314 }
    5315
    5316 if( !cutoff )
    5317 {
    5318 /* for varbound constraint with two integer variables make coefficients integral */
    5319 prettifyConss(scip, conss, nconss, nchgcoefs, nchgsides);
    5320
    5321 /* check if we can upgrade to a set-packing constraint */
    5322 SCIP_CALL( upgradeConss(scip, conshdlrdata, conss, nconss, &cutoff, naggrvars, nchgbds, nchgcoefs, nchgsides, ndelconss, naddconss) );
    5323
    5324 if( !cutoff && conshdlrdata->presolpairwise && (presoltiming & SCIP_PRESOLTIMING_MEDIUM) != 0 )
    5325 {
    5326 /* preprocess pairs of variable bound constraints */
    5327 SCIP_CALL( preprocessConstraintPairs(scip, conss, nconss, &cutoff, nchgbds, ndelconss, nchgcoefs, nchgsides) );
    5328 }
    5329 }
    5330
    5331 /* return the correct result code */
    5332 if( cutoff )
    5333 *result = SCIP_CUTOFF;
    5334 else if( *nchgbds > oldnchgbds || *ndelconss > oldndelconss || *naddconss > oldnaddconss
    5335 || *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides || *naggrvars > oldnaggrvars )
    5336 *result = SCIP_SUCCESS;
    5337 else
    5338 *result = SCIP_DIDNOTFIND;
    5339
    5340 return SCIP_OKAY;
    5341}
    5342
    5343
    5344/** propagation conflict resolving method of constraint handler */
    5345static
    5346SCIP_DECL_CONSRESPROP(consRespropVarbound)
    5347{ /*lint --e{715}*/
    5348 SCIP_CONSHDLRDATA* conshdlrdata;
    5349
    5350 assert(conshdlr != NULL);
    5351
    5352 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5353 assert(conshdlrdata != NULL);
    5354
    5355 SCIP_CALL( resolvePropagation(scip, cons, infervar, (PROPRULE)inferinfo, boundtype, bdchgidx, relaxedbd, conshdlrdata->usebdwidening) );
    5356
    5357 *result = SCIP_SUCCESS;
    5358
    5359 return SCIP_OKAY;
    5360}
    5361
    5362
    5363/** variable rounding lock method of constraint handler */
    5364static
    5365SCIP_DECL_CONSLOCK(consLockVarbound)
    5366{ /*lint --e{715}*/
    5367 SCIP_CONSDATA* consdata;
    5368
    5369 consdata = SCIPconsGetData(cons);
    5370 assert(consdata != NULL);
    5371
    5372 if( !SCIPisInfinity(scip, -consdata->lhs) )
    5373 {
    5374 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->var, locktype, nlockspos, nlocksneg) );
    5375 if( consdata->vbdcoef > 0.0 )
    5376 {
    5377 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vbdvar, locktype, nlockspos, nlocksneg) );
    5378 }
    5379 else
    5380 {
    5381 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vbdvar, locktype, nlocksneg, nlockspos) );
    5382 }
    5383 }
    5384
    5385 if( !SCIPisInfinity(scip, consdata->rhs) )
    5386 {
    5387 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->var, locktype, nlocksneg, nlockspos) );
    5388 if( consdata->vbdcoef > 0.0 )
    5389 {
    5390 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vbdvar, locktype, nlocksneg, nlockspos) );
    5391 }
    5392 else
    5393 {
    5394 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vbdvar, locktype, nlockspos, nlocksneg) );
    5395 }
    5396 }
    5397
    5398 return SCIP_OKAY;
    5399}
    5400
    5401/** constraint activation notification method of constraint handler */
    5402static
    5403SCIP_DECL_CONSACTIVE(consActiveVarbound)
    5404{ /*lint --e{715}*/
    5406 {
    5407 SCIP_CALL( addNlrow(scip, cons) );
    5408 }
    5409
    5410 return SCIP_OKAY;
    5411}
    5412
    5413/** constraint deactivation notification method of constraint handler */
    5414static
    5415SCIP_DECL_CONSDEACTIVE(consDeactiveVarbound)
    5416{ /*lint --e{715}*/
    5417 SCIP_CONSDATA* consdata;
    5418
    5419 assert(cons != NULL);
    5420
    5421 consdata = SCIPconsGetData(cons);
    5422 assert(consdata != NULL);
    5423
    5424 /* remove row from NLP, if still in solving
    5425 * if we are in exitsolve, the whole NLP will be freed anyway
    5426 */
    5427 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && consdata->nlrow != NULL )
    5428 {
    5429 SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow) );
    5430 }
    5431
    5432 return SCIP_OKAY;
    5433}
    5434
    5435/** constraint display method of constraint handler */
    5436static
    5437SCIP_DECL_CONSPRINT(consPrintVarbound)
    5438{ /*lint --e{715}*/
    5439 SCIP_CONSDATA* consdata;
    5440
    5441 assert(scip != NULL);
    5442 assert(conshdlr != NULL);
    5443 assert(cons != NULL);
    5444
    5445 consdata = SCIPconsGetData(cons);
    5446 assert(consdata != NULL);
    5447
    5448 /* print left hand side for ranged rows */
    5449 if( !SCIPisInfinity(scip, -consdata->lhs)
    5450 && !SCIPisInfinity(scip, consdata->rhs)
    5451 && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
    5452 SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
    5453
    5454 /* print variables and coefficient */
    5455 SCIP_CALL( SCIPwriteVarName(scip, file, consdata->var, TRUE) );
    5456 SCIPinfoMessage(scip, file, " %+.15g", consdata->vbdcoef);
    5457 SCIP_CALL( SCIPwriteVarName(scip, file, consdata->vbdvar, TRUE) );
    5458
    5459 /* print right hand side */
    5460 if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
    5461 SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
    5462 else if( !SCIPisInfinity(scip, consdata->rhs) )
    5463 SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
    5464 else if( !SCIPisInfinity(scip, -consdata->lhs) )
    5465 SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
    5466 else
    5467 SCIPinfoMessage(scip, file, " [free]");
    5468
    5469 return SCIP_OKAY;
    5470}
    5471
    5472/** constraint copying method of constraint handler */
    5473static
    5474SCIP_DECL_CONSCOPY(consCopyVarbound)
    5475{ /*lint --e{715}*/
    5476 SCIP_VAR** vars;
    5477 SCIP_Real* coefs;
    5478 const char* consname;
    5479
    5480 SCIP_CALL( SCIPallocBufferArray(scip, &vars, 2) );
    5481 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, 2) );
    5482
    5483 vars[0] = SCIPgetVarVarbound(sourcescip, sourcecons);
    5484 vars[1] = SCIPgetVbdvarVarbound(sourcescip, sourcecons);
    5485
    5486 coefs[0] = 1.0;
    5487 coefs[1] = SCIPgetVbdcoefVarbound(sourcescip, sourcecons);
    5488
    5489 if( name != NULL )
    5490 consname = name;
    5491 else
    5492 consname = SCIPconsGetName(sourcecons);
    5493
    5494 /* copy the varbound using the linear constraint copy method */
    5495 SCIP_CALL( SCIPcopyConsLinear(scip, cons, sourcescip, consname, 2, vars, coefs,
    5496 SCIPgetLhsVarbound(sourcescip, sourcecons), SCIPgetRhsVarbound(sourcescip, sourcecons), varmap, consmap,
    5497 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
    5498
    5499 SCIPfreeBufferArray(scip, &coefs);
    5500 SCIPfreeBufferArray(scip, &vars);
    5501
    5502 return SCIP_OKAY;
    5503}
    5504
    5505/** constraint parsing method of constraint handler */
    5506static
    5507SCIP_DECL_CONSPARSE(consParseVarbound)
    5508{ /*lint --e{715}*/
    5509 SCIP_VAR** vars;
    5510 SCIP_Real* coefs;
    5511 SCIP_Real lhs;
    5512 SCIP_Real rhs;
    5513 char* endstr;
    5514 int requiredsize;
    5515 int nvars;
    5516
    5517 assert(scip != NULL);
    5518 assert(success != NULL);
    5519 assert(str != NULL);
    5520 assert(name != NULL);
    5521 assert(cons != NULL);
    5522
    5523 /* set left and right hand side to their default values */
    5524 lhs = -SCIPinfinity(scip);
    5525 rhs = SCIPinfinity(scip);
    5526
    5527 (*success) = FALSE;
    5528
    5529 /* return of string empty */
    5530 if( !*str )
    5531 return SCIP_OKAY;
    5532
    5533 /* ignore whitespace */
    5534 SCIP_CALL( SCIPskipSpace((char**)&str) );
    5535
    5536 if( isdigit((unsigned char)str[0]) || ((str[0] == '-' || str[0] == '+') && isdigit((unsigned char)str[1])) )
    5537 {
    5538 if( !SCIPparseReal(scip, str, &lhs, &endstr) )
    5539 {
    5540 SCIPerrorMessage("error parsing left hand side\n");
    5541 return SCIP_OKAY;
    5542 }
    5543
    5544 /* ignore whitespace */
    5545 SCIP_CALL( SCIPskipSpace(&endstr) );
    5546
    5547 if( endstr[0] != '<' || endstr[1] != '=' )
    5548 {
    5549 SCIPerrorMessage("missing \"<=\" after left hand side(, found %c%c)\n", endstr[0], endstr[1]);
    5550 return SCIP_OKAY;
    5551 }
    5552
    5553 SCIPdebugMsg(scip, "found left hand side <%g>\n", lhs);
    5554
    5555 /* it was indeed a left-hand-side, so continue parsing after it */
    5556 str = endstr + 2;
    5557 }
    5558
    5559 /* pares x + c*y as linear sum */
    5560 SCIP_CALL( SCIPallocBufferArray(scip, &vars, 2) );
    5561 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, 2) );
    5562
    5563 /* parse linear sum to get variables and coefficients */
    5564 SCIP_CALL( SCIPparseVarsLinearsum(scip, str, vars, coefs, &nvars, 2, &requiredsize, &endstr, success) );
    5565
    5566 if( requiredsize == 2 && *success )
    5567 {
    5568 SCIP_Real value;
    5569
    5570 assert(nvars == 2);
    5571 assert(SCIPisEQ(scip, coefs[0], 1.0));
    5572
    5573 SCIPdebugMsg(scip, "found linear sum <%s> + %g <%s>\n", SCIPvarGetName(vars[0]), coefs[1], SCIPvarGetName(vars[1]));
    5574
    5575 /* ignore whitespace */
    5576 SCIP_CALL( SCIPskipSpace(&endstr) );
    5577
    5578 str = endstr;
    5579
    5580 if( *str != '\0' && *(str+1) != '\0' && SCIPparseReal(scip, str+2, &value, &endstr) )
    5581 {
    5582 /* search for end of linear sum: either '<=', '>=', '==', or '[free]' */
    5583 switch( *str )
    5584 {
    5585 case '<':
    5586 assert(str[1] == '=');
    5587 rhs = value;
    5588 break;
    5589 case '=':
    5590 assert(str[1] == '=');
    5591 assert(SCIPisInfinity(scip, -lhs));
    5592 lhs = value;
    5593 rhs = value;
    5594 break;
    5595 case '>':
    5596 assert(str[1] == '=');
    5597 assert(SCIPisInfinity(scip, -lhs));
    5598 lhs = value;
    5599 break;
    5600 default:
    5601 SCIPerrorMessage("missing relation symbol after linear sum\n");
    5602 *success = FALSE;
    5603 }
    5604 }
    5605 else if( strncmp(str, "[free]", 6) != 0 )
    5606 *success = FALSE;
    5607 }
    5608
    5609 if( *success )
    5610 {
    5611 SCIP_CALL( SCIPcreateConsVarbound(scip, cons, name, vars[0], vars[1], coefs[1], lhs, rhs,
    5612 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    5613 }
    5614
    5615 /* free buffer arrays */
    5616 SCIPfreeBufferArray(scip, &coefs);
    5617 SCIPfreeBufferArray(scip, &vars);
    5618
    5619 return SCIP_OKAY;
    5620}
    5621
    5622/** constraint method of constraint handler which returns the variables (if possible) */
    5623static
    5624SCIP_DECL_CONSGETVARS(consGetVarsVarbound)
    5625{ /*lint --e{715}*/
    5626 assert( success != NULL );
    5627
    5628 if( varssize < 2 )
    5629 (*success) = FALSE;
    5630 else
    5631 {
    5632 SCIP_CONSDATA* consdata;
    5633 assert(cons != NULL);
    5634 assert(vars != NULL);
    5635
    5636 consdata = SCIPconsGetData(cons);
    5637 assert(consdata != NULL);
    5638
    5639 vars[0] = consdata->var;
    5640 vars[1] = consdata->vbdvar;
    5641 (*success) = TRUE;
    5642 }
    5643
    5644 return SCIP_OKAY;
    5645}
    5646
    5647/** constraint method of constraint handler which returns the number of variables (if possible) */
    5648static
    5649SCIP_DECL_CONSGETNVARS(consGetNVarsVarbound)
    5650{ /*lint --e{715}*/
    5651 (*nvars) = 2;
    5652 (*success) = TRUE;
    5653
    5654 return SCIP_OKAY;
    5655}
    5656
    5657/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
    5658static
    5659SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphVarbound)
    5660{ /*lint --e{715}*/
    5661 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_PERM, cons, graph, success) );
    5662
    5663 return SCIP_OKAY;
    5664}
    5665
    5666/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
    5667static
    5668SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphVarbound)
    5669{ /*lint --e{715}*/
    5670 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_SIGNPERM, cons, graph, success) );
    5671
    5672 return SCIP_OKAY;
    5673}
    5674
    5675/*
    5676 * Event Handler
    5677 */
    5678
    5679/** execution method of bound change event handler */
    5680static
    5681SCIP_DECL_EVENTEXEC(eventExecVarbound)
    5682{ /*lint --e{715}*/
    5683 SCIP_CONS* cons;
    5684 SCIP_CONSDATA* consdata;
    5685
    5686 assert(event != NULL);
    5687 cons = (SCIP_CONS*)eventdata;
    5688 assert(cons != NULL);
    5689 consdata = SCIPconsGetData(cons);
    5690 assert(consdata != NULL);
    5691
    5693 {
    5694 consdata->presolved = FALSE;
    5695 }
    5696 else
    5697 {
    5698 assert((SCIPeventGetType(event) & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0);
    5699
    5700 consdata->presolved = FALSE;
    5701 consdata->tightened = FALSE;
    5702
    5704 }
    5705
    5706 return SCIP_OKAY;
    5707}
    5708
    5709/**@} */
    5710
    5711
    5712/** creates the handler for variable bound constraints and includes it in SCIP */
    5714 SCIP* scip /**< SCIP data structure */
    5715 )
    5716{
    5717 SCIP_CONSHDLRDATA* conshdlrdata;
    5718 SCIP_EVENTHDLR* eventhdlr;
    5719 SCIP_CONSHDLR* conshdlr;
    5720
    5721 /* include event handler for bound change events */
    5723 eventExecVarbound, NULL) );
    5724
    5725 /* create variable bound constraint handler data */
    5726 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
    5727
    5728 /* include constraint handler */
    5731 consEnfolpVarbound, consEnfopsVarbound, consCheckVarbound, consLockVarbound,
    5732 conshdlrdata) );
    5733 assert(conshdlr != NULL);
    5734
    5735 /* set non-fundamental callbacks via specific setter functions */
    5736 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyVarbound, consCopyVarbound) );
    5737 SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveVarbound) );
    5738 SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveVarbound) );
    5739 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteVarbound) );
    5740 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolVarbound) );
    5741 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolVarbound) );
    5742 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeVarbound) );
    5743 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsVarbound) );
    5744 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsVarbound) );
    5745 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpVarbound) );
    5746 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseVarbound) );
    5748 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintVarbound) );
    5751 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropVarbound) );
    5752 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpVarbound, consSepasolVarbound, CONSHDLR_SEPAFREQ,
    5754 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransVarbound) );
    5755 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxVarbound) );
    5756 SCIP_CALL( SCIPsetConshdlrGetPermsymGraph(scip, conshdlr, consGetPermsymGraphVarbound) );
    5757 SCIP_CALL( SCIPsetConshdlrGetSignedPermsymGraph(scip, conshdlr, consGetSignedPermsymGraphVarbound) );
    5758
    5759 if( SCIPfindConshdlr(scip,"linear") != NULL )
    5760 {
    5761 /* include the linear constraint to varbound constraint upgrade in the linear constraint handler */
    5763 }
    5764
    5765 /* add varbound constraint handler parameters */
    5767 "constraints/" CONSHDLR_NAME "/presolpairwise",
    5768 "should pairwise constraint comparison be performed in presolving?",
    5769 &conshdlrdata->presolpairwise, TRUE, DEFAULT_PRESOLPAIRWISE, NULL, NULL) );
    5771 "constraints/" CONSHDLR_NAME "/maxlpcoef",
    5772 "maximum coefficient in varbound constraint to be added as a row into LP",
    5773 &conshdlrdata->maxlpcoef, TRUE, DEFAULT_MAXLPCOEF, 0.0, 1e+20, NULL, NULL) );
    5775 "constraints/" CONSHDLR_NAME "/usebdwidening", "should bound widening be used in conflict analysis?",
    5776 &conshdlrdata->usebdwidening, FALSE, DEFAULT_USEBDWIDENING, NULL, NULL) );
    5777
    5778 return SCIP_OKAY;
    5779}
    5780
    5781/** creates and captures a variable bound constraint: lhs <= x + c*y <= rhs
    5782 *
    5783 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    5784 */
    5786 SCIP* scip, /**< SCIP data structure */
    5787 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    5788 const char* name, /**< name of constraint */
    5789 SCIP_VAR* var, /**< variable x that has variable bound */
    5790 SCIP_VAR* vbdvar, /**< binary, integer or implicit integer bounding variable y */
    5791 SCIP_Real vbdcoef, /**< coefficient c of bounding variable y */
    5792 SCIP_Real lhs, /**< left hand side of variable bound inequality */
    5793 SCIP_Real rhs, /**< right hand side of variable bound inequality */
    5794 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    5795 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    5796 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    5797 * Usually set to TRUE. */
    5798 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    5799 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    5800 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    5801 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    5802 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    5803 * Usually set to TRUE. */
    5804 SCIP_Bool local, /**< is constraint only valid locally?
    5805 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    5806 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    5807 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    5808 * adds coefficients to this constraint. */
    5809 SCIP_Bool dynamic, /**< is constraint subject to aging?
    5810 * Usually set to FALSE. Set to TRUE for own cuts which
    5811 * are separated as constraints. */
    5812 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    5813 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    5814 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    5815 * if it may be moved to a more global node?
    5816 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    5817 )
    5818{
    5819 SCIP_CONSHDLR* conshdlr;
    5820 SCIP_CONSHDLRDATA* conshdlrdata;
    5821 SCIP_CONSDATA* consdata;
    5822
    5823 /* check that the given parameters are sensible, i.e., not nan or inf */
    5824 assert( SCIPisFinite(vbdcoef) );
    5825 assert( SCIPisFinite(lhs) );
    5826 assert( SCIPisFinite(rhs) );
    5827
    5828 /* find the variable bound constraint handler */
    5829 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    5830 if( conshdlr == NULL )
    5831 {
    5832 SCIPerrorMessage("variable bound constraint handler not found\n");
    5833 return SCIP_PLUGINNOTFOUND;
    5834 }
    5835
    5836 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5837 assert(conshdlrdata != NULL);
    5838
    5839 /* create constraint data */
    5840 SCIP_CALL( consdataCreate(scip, &consdata, var, vbdvar, vbdcoef, lhs, rhs) );
    5841
    5842 /* create constraint */
    5843 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
    5844 local, modifiable, dynamic, removable, stickingatnode) );
    5845
    5846 if( SCIPisTransformed(scip) )
    5847 {
    5848 /* catch events for variables */
    5849 SCIP_CALL( catchEvents(scip, *cons, conshdlrdata->eventhdlr) );
    5850 }
    5851
    5852 return SCIP_OKAY;
    5853}
    5854
    5855/** creates and captures a variable bound constraint: lhs <= x + c*y <= rhs
    5856 * with all constraint flags set to their default values
    5857 *
    5858 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    5859 */
    5861 SCIP* scip, /**< SCIP data structure */
    5862 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    5863 const char* name, /**< name of constraint */
    5864 SCIP_VAR* var, /**< variable x that has variable bound */
    5865 SCIP_VAR* vbdvar, /**< binary, integer or implicit integer bounding variable y */
    5866 SCIP_Real vbdcoef, /**< coefficient c of bounding variable y */
    5867 SCIP_Real lhs, /**< left hand side of variable bound inequality */
    5868 SCIP_Real rhs /**< right hand side of variable bound inequality */
    5869 )
    5870{
    5871 SCIP_CALL( SCIPcreateConsVarbound(scip, cons, name, var, vbdvar,vbdcoef, lhs, rhs,
    5873
    5874 return SCIP_OKAY;
    5875}
    5876
    5877/** gets left hand side of variable bound constraint lhs <= x + c*y <= rhs */
    5879 SCIP* scip, /**< SCIP data structure */
    5880 SCIP_CONS* cons /**< constraint data */
    5881 )
    5882{
    5883 SCIP_CONSDATA* consdata;
    5884
    5885 assert(scip != NULL);
    5886
    5887 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    5888 {
    5889 SCIPerrorMessage("constraint is not a variable bound constraint\n");
    5890 SCIPABORT();
    5891 return SCIP_INVALID; /*lint !e527*/
    5892 }
    5893
    5894 consdata = SCIPconsGetData(cons);
    5895 assert(consdata != NULL);
    5896
    5897 return consdata->lhs;
    5898}
    5899
    5900/** gets right hand side of variable bound constraint lhs <= x + c*y <= rhs */
    5902 SCIP* scip, /**< SCIP data structure */
    5903 SCIP_CONS* cons /**< constraint data */
    5904 )
    5905{
    5906 SCIP_CONSDATA* consdata;
    5907
    5908 assert(scip != NULL);
    5909
    5910 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    5911 {
    5912 SCIPerrorMessage("constraint is not a variable bound constraint\n");
    5913 SCIPABORT();
    5914 return SCIP_INVALID; /*lint !e527*/
    5915 }
    5916
    5917 consdata = SCIPconsGetData(cons);
    5918 assert(consdata != NULL);
    5919
    5920 return consdata->rhs;
    5921}
    5922
    5923/** gets bounded variable x of variable bound constraint lhs <= x + c*y <= rhs */
    5925 SCIP* scip, /**< SCIP data structure */
    5926 SCIP_CONS* cons /**< constraint data */
    5927 )
    5928{
    5929 SCIP_CONSDATA* consdata;
    5930
    5931 assert(scip != NULL);
    5932
    5933 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    5934 {
    5935 SCIPerrorMessage("constraint is not a variable bound constraint\n");
    5936 SCIPABORT();
    5937 return NULL; /*lint !e527*/
    5938 }
    5939
    5940 consdata = SCIPconsGetData(cons);
    5941 assert(consdata != NULL);
    5942
    5943 return consdata->var;
    5944}
    5945
    5946/** gets bounding variable y of variable bound constraint lhs <= x + c*y <= rhs */
    5948 SCIP* scip, /**< SCIP data structure */
    5949 SCIP_CONS* cons /**< constraint data */
    5950 )
    5951{
    5952 SCIP_CONSDATA* consdata;
    5953
    5954 assert(scip != NULL);
    5955
    5956 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    5957 {
    5958 SCIPerrorMessage("constraint is not a variable bound constraint\n");
    5959 SCIPABORT();
    5960 return NULL; /*lint !e527*/
    5961 }
    5962
    5963 consdata = SCIPconsGetData(cons);
    5964 assert(consdata != NULL);
    5965
    5966 return consdata->vbdvar;
    5967}
    5968
    5969/** gets bound coefficient c of variable bound constraint lhs <= x + c*y <= rhs */
    5971 SCIP* scip, /**< SCIP data structure */
    5972 SCIP_CONS* cons /**< constraint data */
    5973 )
    5974{
    5975 SCIP_CONSDATA* consdata;
    5976
    5977 assert(scip != NULL);
    5978
    5979 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    5980 {
    5981 SCIPerrorMessage("constraint is not a variable bound constraint\n");
    5982 SCIPABORT();
    5983 return SCIP_INVALID; /*lint !e527*/
    5984 }
    5985
    5986 consdata = SCIPconsGetData(cons);
    5987 assert(consdata != NULL);
    5988
    5989 return consdata->vbdcoef;
    5990}
    5991
    5992/** gets the dual solution of the variable bound constraint in the current LP */
    5994 SCIP* scip, /**< SCIP data structure */
    5995 SCIP_CONS* cons /**< constraint data */
    5996 )
    5997{
    5998 SCIP_CONSDATA* consdata;
    5999
    6000 assert(scip != NULL);
    6001
    6002 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    6003 {
    6004 SCIPerrorMessage("constraint is not a variable bound constraint\n");
    6005 SCIPABORT();
    6006 return SCIP_INVALID; /*lint !e527*/
    6007 }
    6008
    6009 consdata = SCIPconsGetData(cons);
    6010 assert(consdata != NULL);
    6011
    6012 if( consdata->row != NULL )
    6013 return SCIProwGetDualsol(consdata->row);
    6014 else
    6015 return 0.0;
    6016}
    6017
    6018/** gets the dual Farkas value of the variable bound constraint in the current infeasible LP */
    6020 SCIP* scip, /**< SCIP data structure */
    6021 SCIP_CONS* cons /**< constraint data */
    6022 )
    6023{
    6024 SCIP_CONSDATA* consdata;
    6025
    6026 assert(scip != NULL);
    6027
    6028 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    6029 {
    6030 SCIPerrorMessage("constraint is not a variable bound constraint\n");
    6031 SCIPABORT();
    6032 return SCIP_INVALID; /*lint !e527*/
    6033 }
    6034
    6035 consdata = SCIPconsGetData(cons);
    6036 assert(consdata != NULL);
    6037
    6038 if( consdata->row != NULL )
    6039 return SCIProwGetDualfarkas(consdata->row);
    6040 else
    6041 return 0.0;
    6042}
    6043
    6044/** returns the linear relaxation of the given variable bound constraint; may return NULL if no LP row was yet created;
    6045 * the user must not modify the row!
    6046 */
    6048 SCIP* scip, /**< SCIP data structure */
    6049 SCIP_CONS* cons /**< constraint data */
    6050 )
    6051{
    6052 SCIP_CONSDATA* consdata;
    6053
    6054 assert(scip != NULL);
    6055
    6056 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    6057 {
    6058 SCIPerrorMessage("constraint is not a variable bound constraint\n");
    6059 SCIPABORT();
    6060 return NULL; /*lint !e527*/
    6061 }
    6062
    6063 consdata = SCIPconsGetData(cons);
    6064 assert(consdata != NULL);
    6065
    6066 return consdata->row;
    6067}
    6068
    6069/** creates and returns the row of the given varbound constraint */
    6071 SCIP* scip, /**< SCIP data structure */
    6072 SCIP_CONS* cons /**< constraint data */
    6073 )
    6074{
    6075 SCIP_CONSDATA* consdata;
    6076
    6077 assert(scip != NULL);
    6078
    6079 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    6080 {
    6081 SCIPerrorMessage("constraint is not a variable bound constraint\n");
    6082 SCIPABORT();
    6083 return SCIP_ERROR; /*lint !e527*/
    6084 }
    6085
    6086 consdata = SCIPconsGetData(cons);
    6087 assert(consdata != NULL);
    6088 assert(consdata->row == NULL);
    6089
    6090 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, cons, SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
    6092 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, consdata->var, 1.0) );
    6093 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, consdata->vbdvar, consdata->vbdcoef) );
    6094
    6095 return SCIP_OKAY;
    6096}
    6097
    6098/** cleans up (multi-)aggregations and fixings from varbound constraints */
    6100 SCIP* scip, /**< SCIP data structure */
    6101 SCIP_Bool onlychecked, /**< should only checked constraints be cleaned up? */
    6102 SCIP_Bool* infeasible, /**< pointer to return whether the problem was detected to be infeasible */
    6103 int* naddconss, /**< pointer to count number of added (linear) constraints */
    6104 int* ndelconss, /**< pointer to count number of deleted (varbound) constraints */
    6105 int* nchgbds /**< pointer to count number of bound changes */
    6106 )
    6107{
    6108 SCIP_CONSHDLR* conshdlr;
    6109 SCIP_CONSHDLRDATA* conshdlrdata;
    6110 SCIP_EVENTHDLR* eventhdlr;
    6111 SCIP_CONS** conss;
    6112 int nconss;
    6113 int i;
    6114
    6115 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    6116 if( conshdlr == NULL )
    6117 return SCIP_OKAY;
    6118
    6119 assert(infeasible != NULL);
    6120 *infeasible = FALSE;
    6121
    6122 assert(naddconss != NULL);
    6123 assert(ndelconss != NULL);
    6124 assert(nchgbds != NULL);
    6125
    6126 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    6127 assert(conshdlrdata != NULL);
    6128
    6129 eventhdlr = conshdlrdata->eventhdlr;
    6130 nconss = onlychecked ? SCIPconshdlrGetNCheckConss(conshdlr) : SCIPconshdlrGetNActiveConss(conshdlr);
    6131 conss = onlychecked ? SCIPconshdlrGetCheckConss(conshdlr) : SCIPconshdlrGetConss(conshdlr);
    6132
    6133 /* loop backwards since then deleted constraints do not interfere with the loop */
    6134 for( i = nconss - 1; i >= 0; --i )
    6135 {
    6136 SCIP_CALL( applyFixings(scip, conss[i], eventhdlr, infeasible, nchgbds, ndelconss, naddconss) );
    6137
    6138 if( *infeasible )
    6139 break;
    6140 }
    6141
    6142 return SCIP_OKAY;
    6143}
    static long bound
    enum Proprule PROPRULE
    Definition: cons_and.c:173
    Proprule
    Definition: cons_and.c:166
    Constraint handler for linear constraints in their most general form, .
    Constraint handler for the set partitioning / packing / covering constraints .
    static SCIP_DECL_CONSCHECK(consCheckVarbound)
    static SCIP_RETCODE addRelaxation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
    static SCIP_DECL_CONSRESPROP(consRespropVarbound)
    enum Proprule PROPRULE
    static SCIP_DECL_SORTPTRCOMP(consVarboundComp)
    static SCIP_RETCODE dropEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
    #define DEFAULT_USEBDWIDENING
    #define CONSHDLR_NEEDSCONS
    #define CONSHDLR_SEPAFREQ
    Definition: cons_varbound.c:93
    static SCIP_DECL_EVENTEXEC(eventExecVarbound)
    static SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphVarbound)
    static SCIP_DECL_CONSACTIVE(consActiveVarbound)
    #define CONSHDLR_CHECKPRIORITY
    Definition: cons_varbound.c:92
    #define CONSHDLR_DESC
    Definition: cons_varbound.c:89
    static SCIP_DECL_CONSINITSOL(consInitsolVarbound)
    static SCIP_DECL_CONSPROP(consPropVarbound)
    static SCIP_DECL_CONSLOCK(consLockVarbound)
    static SCIP_RETCODE upgradeConss(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONS **conss, int nconss, SCIP_Bool *cutoff, int *naggrvars, int *nchgbds, int *nchgcoefs, int *nchgsides, int *ndelconss, int *naddconss)
    static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *cutoff, int *nchgbds, int *ndelconss, int *naddconss)
    static SCIP_DECL_CONSPRESOL(consPresolVarbound)
    static SCIP_DECL_CONSGETNVARS(consGetNVarsVarbound)
    static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_VAR *var, SCIP_VAR *vbdvar, SCIP_Real vbdcoef, SCIP_Real lhs, SCIP_Real rhs)
    static SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphVarbound)
    static SCIP_RETCODE tightenCoefs(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides, int *ndelconss, SCIP_Bool *cutoff, int *nchgbds)
    static SCIP_RETCODE createRelaxation(SCIP *scip, SCIP_CONS *cons)
    static SCIP_DECL_CONSEXITSOL(consExitsolVarbound)
    #define CONSHDLR_PROP_TIMING
    static void checkRedundancySide(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vbdvar, SCIP_Real coef0, SCIP_Real coef1, SCIP_Real side0, SCIP_Real side1, SCIP_Bool *sideequal, SCIP_Bool *cons0sidered, SCIP_Bool *cons1sidered, SCIP_Bool islhs)
    static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
    static SCIP_DECL_CONSGETVARS(consGetVarsVarbound)
    static SCIP_DECL_CONSCOPY(consCopyVarbound)
    #define CONSHDLR_MAXPREROUNDS
    Definition: cons_varbound.c:97
    static SCIP_Bool checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checklprows)
    #define DEFAULT_PRESOLPAIRWISE
    static SCIP_DECL_CONSSEPASOL(consSepasolVarbound)
    static SCIP_DECL_CONSFREE(consFreeVarbound)
    #define CONSHDLR_SEPAPRIORITY
    Definition: cons_varbound.c:90
    #define DEFAULT_MAXLPCOEF
    static SCIP_DECL_CONSPRINT(consPrintVarbound)
    static void prettifyConss(SCIP *scip, SCIP_CONS **conss, int nconss, int *nchgcoefs, int *nchgsides)
    static SCIP_RETCODE addSymmetryInformation(SCIP *scip, SYM_SYMTYPE symtype, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
    static SCIP_RETCODE preprocessConstraintPairs(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool *cutoff, int *nchgbds, int *ndelconss, int *nchgcoefs, int *nchgsides)
    static SCIP_RETCODE chgLhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
    static SCIP_DECL_CONSDEACTIVE(consDeactiveVarbound)
    @ PROPRULE_2
    @ PROPRULE_1
    @ PROPRULE_3
    @ PROPRULE_4
    static SCIP_DECL_CONSSEPALP(consSepalpVarbound)
    static SCIP_DECL_CONSDELETE(consDeleteVarbound)
    static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_Real inferbd, PROPRULE proprule, SCIP_BOUNDTYPE boundtype, SCIP_Bool usebdwidening)
    static SCIP_DECL_CONSTRANS(consTransVarbound)
    static SCIP_RETCODE chgRhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
    #define CONSHDLR_PROPFREQ
    Definition: cons_varbound.c:94
    static SCIP_DECL_CONSPARSE(consParseVarbound)
    static SCIP_DECL_CONSENFOPS(consEnfopsVarbound)
    static SCIP_RETCODE resolvePropagation(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, PROPRULE proprule, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Real inferbd, SCIP_Bool usebdwidening)
    static SCIP_DECL_CONSENFORELAX(consEnforelaxVarbound)
    static SCIP_RETCODE propagateCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool usebdwidening, SCIP_Bool *cutoff, int *nchgbds, int *nchgsides, int *ndelconss)
    #define CONSHDLR_PRESOLTIMING
    static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
    static SCIP_DECL_LINCONSUPGD(linconsUpgdVarbound)
    static SCIP_DECL_CONSINITLP(consInitlpVarbound)
    static SCIP_RETCODE addNlrow(SCIP *scip, SCIP_CONS *cons)
    #define CONSHDLR_EAGERFREQ
    Definition: cons_varbound.c:95
    #define EVENTHDLR_DESC
    static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
    static SCIP_DECL_CONSENFOLP(consEnfolpVarbound)
    #define CONSHDLR_ENFOPRIORITY
    Definition: cons_varbound.c:91
    static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyVarbound)
    static SCIP_RETCODE catchEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
    #define LINCONSUPGD_PRIORITY
    static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool usebdwidening, SCIP_SOL *sol, SCIP_RESULT *result)
    #define CONSHDLR_DELAYSEPA
    Definition: cons_varbound.c:98
    #define MAXSCALEDCOEF
    #define CONSHDLR_NAME
    Definition: cons_varbound.c:88
    #define EVENTHDLR_NAME
    #define CONSHDLR_DELAYPROP
    Definition: cons_varbound.c:99
    Constraint handler for variable bound constraints .
    defines macros for basic operations in double-double arithmetic giving roughly twice the precision of...
    #define SCIPquadprecDivQD(r, a, b)
    Definition: dbldblarith.h:65
    #define SCIPquadprecProdDD(r, a, b)
    Definition: dbldblarith.h:58
    #define SCIPquadprecProdQD(r, a, b)
    Definition: dbldblarith.h:63
    #define SCIPquadprecSumQD(r, a, b)
    Definition: dbldblarith.h:62
    #define QUAD_ASSIGN(a, constant)
    Definition: dbldblarith.h:51
    #define QUAD(x)
    Definition: dbldblarith.h:47
    #define SCIPquadprecSumDD(r, a, b)
    Definition: dbldblarith.h:60
    #define SCIPquadprecSumQQ(r, a, b)
    Definition: dbldblarith.h:67
    #define QUAD_TO_DBL(x)
    Definition: dbldblarith.h:49
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define SCIP_UNKNOWN
    Definition: def.h:179
    #define ABS(x)
    Definition: def.h:216
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIPABORT()
    Definition: def.h:327
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPincludeLinconsUpgrade(SCIP *scip, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority, const char *conshdlrname)
    SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
    SCIP_Real SCIPgetDualfarkasVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    SCIP_RETCODE SCIPcreateConsBasicVarbound(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *var, SCIP_VAR *vbdvar, SCIP_Real vbdcoef, SCIP_Real lhs, SCIP_Real rhs)
    SCIP_ROW * SCIPgetRowVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetVbdvarVarbound(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:9460
    SCIP_RETCODE SCIPcleanupConssVarbound(SCIP *scip, SCIP_Bool onlychecked, SCIP_Bool *infeasible, int *naddconss, int *ndelconss, int *nchgbds)
    SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcopyConsLinear(SCIP *scip, SCIP_CONS **cons, SCIP *sourcescip, const char *name, int nvars, SCIP_VAR **sourcevars, SCIP_Real *sourcecoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool global, SCIP_Bool *valid)
    SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
    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_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetDualsolVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsVarbound(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *var, SCIP_VAR *vbdvar, SCIP_Real vbdcoef, 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 SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
    SCIP_RETCODE SCIPcreateRowVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPincludeConshdlrVarbound(SCIP *scip)
    SCIP_Bool SCIPisTransformed(SCIP *scip)
    Definition: scip_general.c:647
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:759
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    SCIP_RETCODE SCIPaddConsUpgrade(SCIP *scip, SCIP_CONS *oldcons, SCIP_CONS **newcons)
    Definition: scip_prob.c:3368
    int SCIPgetNImplVars(SCIP *scip)
    Definition: scip_prob.c:2387
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3420
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:4067
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *numerator, SCIP_Longint *denominator)
    Definition: misc.c:9470
    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
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
    SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
    SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
    SCIP_RETCODE SCIPaddConflictRelaxedLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Real relaxedlb)
    SCIP_RETCODE SCIPaddConflictRelaxedUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Real relaxedub)
    SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
    SCIP_Real SCIPgetConflictVarUb(SCIP *scip, SCIP_VAR *var)
    SCIP_Real SCIPgetConflictVarLb(SCIP *scip, SCIP_VAR *var)
    SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
    int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4798
    SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
    Definition: scip_cons.c:808
    void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: cons.c:4346
    SCIP_CONS ** SCIPconshdlrGetCheckConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4755
    SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
    Definition: scip_cons.c:540
    SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
    Definition: scip_cons.c:831
    SCIP_RETCODE SCIPsetConshdlrSepa(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSSEPALP((*conssepalp)), SCIP_DECL_CONSSEPASOL((*conssepasol)), int sepafreq, int sepapriority, SCIP_Bool delaysepa)
    Definition: scip_cons.c:235
    SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
    Definition: scip_cons.c:281
    SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: scip_cons.c:181
    SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
    Definition: scip_cons.c:693
    SCIP_RETCODE SCIPsetConshdlrGetPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETPERMSYMGRAPH((*consgetpermsymgraph)))
    Definition: scip_cons.c:900
    SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
    Definition: scip_cons.c:578
    SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
    Definition: scip_cons.c:372
    SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
    Definition: scip_cons.c:323
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
    Definition: scip_cons.c:347
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_RETCODE SCIPsetConshdlrGetSignedPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH((*consgetsignedpermsymgraph)))
    Definition: scip_cons.c:924
    SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
    Definition: scip_cons.c:468
    SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
    Definition: scip_cons.c:624
    SCIP_RETCODE SCIPsetConshdlrInitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITSOL((*consinitsol)))
    Definition: scip_cons.c:444
    SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4336
    SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
    Definition: scip_cons.c:601
    SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
    Definition: scip_cons.c:647
    int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4812
    SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
    Definition: scip_cons.c:854
    SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4735
    SCIP_RETCODE SCIPsetConshdlrActive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSACTIVE((*consactive)))
    Definition: scip_cons.c:670
    SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
    Definition: scip_cons.c:785
    SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
    Definition: cons.c:8419
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8648
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8558
    SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
    Definition: scip_cons.c:2536
    int SCIPconsGetNUpgradeLocks(SCIP_CONS *cons)
    Definition: cons.c:8841
    SCIP_Bool SCIPconsIsMarkedPropagate(SCIP_CONS *cons)
    Definition: cons.c:8598
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8588
    SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
    Definition: cons.c:8518
    SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
    Definition: cons.c:8698
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8578
    SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:2042
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8450
    SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: scip_cons.c:997
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8608
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8628
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1812
    SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:2014
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8638
    SCIP_RETCODE SCIPupdateConsFlags(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1)
    Definition: scip_cons.c:1524
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8668
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8568
    SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1784
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8658
    SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
    Definition: scip_cut.c:225
    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
    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
    #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 SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_RETCODE SCIPdelNlRow(SCIP *scip, SCIP_NLROW *nlrow)
    Definition: scip_nlp.c:424
    SCIP_RETCODE SCIPaddNlRow(SCIP *scip, SCIP_NLROW *nlrow)
    Definition: scip_nlp.c:396
    SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
    Definition: scip_nlp.c:110
    SCIP_RETCODE SCIPreleaseNlRow(SCIP *scip, SCIP_NLROW **nlrow)
    Definition: scip_nlp.c:1058
    SCIP_Bool SCIPnlrowIsInNLP(SCIP_NLROW *nlrow)
    Definition: nlp.c:1953
    SCIP_RETCODE SCIPcreateNlRow(SCIP *scip, SCIP_NLROW **nlrow, const char *name, SCIP_Real constant, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_EXPRCURV curvature)
    Definition: scip_nlp.c:954
    SCIP_Bool SCIPinProbing(SCIP *scip)
    Definition: scip_probing.c:98
    SCIP_RETCODE SCIPcreateEmptyRowCons(SCIP *scip, SCIP_ROW **row, SCIP_CONS *cons, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
    Definition: scip_lp.c:1398
    SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_lp.c:1646
    SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
    Definition: scip_lp.c:2176
    SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
    Definition: scip_lp.c:2131
    SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
    Definition: scip_lp.c:1508
    SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
    Definition: lp.c:17719
    SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
    Definition: lp.c:17917
    SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
    Definition: lp.c:17706
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    void SCIPupdateSolLPConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
    Definition: scip_sol.c:469
    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 SCIPisIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeastol(SCIP *scip)
    SCIP_Real SCIPgetHugeValue(SCIP *scip)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPepsilon(SCIP *scip)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPparseReal(SCIP *scip, const char *str, SCIP_Real *value, char **endptr)
    SCIP_Bool SCIPinRepropagation(SCIP *scip)
    Definition: scip_tree.c:146
    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 SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5210
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:8257
    SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:5697
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4386
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23498
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
    Definition: scip_var.c:10550
    SCIP_RETCODE SCIPinferVarUbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:7069
    SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:5875
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
    Definition: var.c:17550
    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_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: scip_var.c:2499
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    SCIP_RETCODE SCIPaddVarVub(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vubvar, SCIP_Real vubcoef, SCIP_Real vubconstant, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8680
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23652
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    SCIP_RETCODE SCIPaddVarVlb(SCIP *scip, SCIP_VAR *var, SCIP_VAR *vlbvar, SCIP_Real vlbcoef, SCIP_Real vlbconstant, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8621
    SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5296
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
    Definition: scip_var.c:5634
    SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
    Definition: scip_var.c:899
    SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
    Definition: scip_var.c:2378
    SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
    Definition: scip_var.c:5570
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    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:24234
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
    Definition: scip_var.c:10318
    SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6964
    SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
    Definition: scip_var.c:361
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4328
    SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
    Definition: scip_var.c:2078
    SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:8026
    void SCIPsortPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
    SCIP_RETCODE SCIPskipSpace(char **s)
    Definition: misc.c:10816
    SCIP_RETCODE SCIPgetSymActiveVariables(SCIP *scip, SYM_SYMTYPE symtype, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
    SCIP_RETCODE SCIPextendPermsymDetectionGraphLinear(SCIP *scip, SYM_GRAPH *graph, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_CONS *cons, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool *success)
    static const SCIP_Real scalars[]
    Definition: lp.c:5959
    memory allocation routines
    SCIP_Longint denominator(Rational &r)
    SCIP_Longint numerator(Rational &r)
    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
    methods for sorting joint arrays of various types
    public methods for problem variables
    public methods for conflict handler plugins and conflict analysis
    public methods for constraint handler plugins and constraints
    public methods for cuts and aggregation rows
    public methods for event handler plugins and event handlers
    general public methods
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for message handling
    public methods for nonlinear relaxation
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for the probing mode
    public methods for solutions
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1221
    structs for symmetry computations
    methods for dealing with symmetry detection graphs
    @ SCIP_CONFTYPE_PROPAGATION
    Definition: type_conflict.h:62
    struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
    Definition: type_cons.h:64
    struct SCIP_ConsData SCIP_CONSDATA
    Definition: type_cons.h:65
    struct SCIP_EventData SCIP_EVENTDATA
    Definition: type_event.h:179
    #define SCIP_EVENTTYPE_VARFIXED
    Definition: type_event.h:72
    #define SCIP_EVENTTYPE_BOUNDTIGHTENED
    Definition: type_event.h:125
    @ SCIP_EXPRCURV_LINEAR
    Definition: type_expr.h:65
    @ 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_CUTOFF
    Definition: type_result.h:48
    @ SCIP_FEASIBLE
    Definition: type_result.h:45
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_INFEASIBLE
    Definition: type_result.h:46
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_PRESOLVING
    Definition: type_set.h:49
    @ SCIP_STAGE_SOLVING
    Definition: type_set.h:53
    enum SYM_Symtype SYM_SYMTYPE
    Definition: type_symmetry.h:64
    @ SYM_SYMTYPE_SIGNPERM
    Definition: type_symmetry.h:62
    @ SYM_SYMTYPE_PERM
    Definition: type_symmetry.h:61
    #define SCIP_PRESOLTIMING_MEDIUM
    Definition: type_timing.h:53
    #define SCIP_DEPRECATED_VARTYPE_IMPLINT
    Definition: type_var.h:79
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141
    enum SCIP_Vartype SCIP_VARTYPE
    Definition: type_var.h:73