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