Scippy

    SCIP

    Solving Constraint Integer Programs

    cons_exactlinear.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file cons_exactlinear.c
    26 * @ingroup DEFPLUGINS_CONS
    27 * @brief Constraint handler for exact linear constraints in their most general form, \f$lhs <= a^T x <= rhs\f$.
    28 * @author Leon Eifler
    29 * @author Sander Borst
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    34#include "scip/clock.h"
    35#include "scip/def.h"
    36#include "scip/struct_stat.h"
    37#include "scip/type_retcode.h"
    39#include "scip/cons_knapsack.h"
    41#include "scip/cons_linear.h"
    42#include "scip/cons_nonlinear.h"
    43#include "scip/debug.h"
    44#include "scip/intervalarith.h"
    45#include "scip/pub_conflict.h"
    46#include "scip/pub_cons.h"
    47#include "scip/pub_event.h"
    48#include "scip/pub_lp.h"
    49#include "scip/pub_lpexact.h"
    50#include "scip/pub_message.h"
    51#include "scip/pub_misc.h"
    52#include "scip/pub_misc_sort.h"
    53#include "scip/pub_var.h"
    54#include "scip/rational.h"
    55#include "scip/scip_branch.h"
    57#include "scip/scip_conflict.h"
    58#include "scip/scip_cons.h"
    59#include "scip/scip_copy.h"
    60#include "scip/scip_cut.h"
    61#include "scip/scip_event.h"
    62#include "scip/scip_exact.h"
    63#include "scip/scip_general.h"
    64#include "scip/scip_lp.h"
    65#include "scip/scip_lpexact.h"
    66#include "scip/scip_mem.h"
    67#include "scip/scip_message.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"
    73#include "scip/scip_tree.h"
    74#include "scip/scip_var.h"
    75#include "scip/var.h"
    76#include "scip/sepastoreexact.h"
    77#include <ctype.h>
    78#include <string.h>
    79#ifndef _WIN32
    80#include <strings.h> /*lint --e{766}*/
    81#endif
    82
    83
    84#define CONSHDLR_NAME "exactlinear"
    85#define CONSHDLR_DESC "exact linear constraints of the form lhs <= a^T x <= rhs"
    86#define CONSHDLR_SEPAPRIORITY +100000 /**< priority of the constraint handler for separation */
    87#define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
    88#define CONSHDLR_CHECKPRIORITY -1000000 /**< priority of the constraint handler for checking feasibility */
    89#define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
    90#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
    91#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
    92 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
    93#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
    94#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    95#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
    96
    97#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
    98
    99#define EVENTHDLR_NAME "exactlinear"
    100#define EVENTHDLR_DESC "bound change event handler for exact linear constraints"
    101
    102#define DEFAULT_TIGHTENBOUNDSFREQ 1 /**< multiplier on propagation frequency, how often the bounds are tightened */
    103#define DEFAULT_MAXROUNDS 5 /**< maximal number of separation rounds per node (-1: unlimited) */
    104#define DEFAULT_MAXROUNDSROOT -1 /**< maximal number of separation rounds in the root node (-1: unlimited) */
    105#define DEFAULT_MAXSEPACUTS 50 /**< maximal number of cuts separated per separation round */
    106#define DEFAULT_MAXSEPACUTSROOT 200 /**< maximal number of cuts separated per separation round in root node */
    107#define DEFAULT_SORTVARS TRUE /**< should variables be sorted after presolve w.r.t their coefficient absolute for faster
    108 * propagation? */
    109#define DEFAULT_LIMITDENOM FALSE /**< should denominator sizes for continuous variables be controlled?*/
    110#define DEFAULT_BOUNDMAXDENOM 256L /**< maximal denominator for rational bounds on continuous variables after propagation */
    111
    112
    113/** constraint data for linear constraints */
    114struct SCIP_ConsData
    115{
    116 SCIP_RATIONAL* lhs; /**< left hand side of row (for ranged rows) */
    117 SCIP_RATIONAL* rhs; /**< right hand side of row */
    118 SCIP_Real lhsreal; /**< real relaxation of lhs */
    119 SCIP_Real rhsreal; /**< real relaxation of rhs */
    120 SCIP_RATIONAL* violation; /**< used to store violation */
    121 SCIP_RATIONAL* activity; /**< used to store activity */
    122 SCIP_Real maxabsval; /**< maximum absolute value of all coefficients */
    123 SCIP_Real minabsval; /**< minimal absolute value of all coefficients */
    124 SCIP_Real minactivity; /**< minimal value w.r.t. the variable's local bounds for the constraint's
    125 * activity, ignoring the coefficients contributing with infinite value */
    126 SCIP_Real maxactivity; /**< maximal value w.r.t. the variable's local bounds for the constraint's
    127 * activity, ignoring the coefficients contributing with infinite value */
    128 SCIP_Real lastminactivity; /**< last minimal activity which was computed by complete summation
    129 * over all contributing values */
    130 SCIP_Real lastmaxactivity; /**< last maximal activity which was computed by complete summation
    131 * over all contributing values */
    132 SCIP_Real glbminactivity; /**< minimal value w.r.t. the variable's global bounds for the constraint's
    133 * activity, ignoring the coefficients contributing with infinite value */
    134 SCIP_Real glbmaxactivity; /**< maximal value w.r.t. the variable's global bounds for the constraint's
    135 * activity, ignoring the coefficients contributing with infinite value */
    136 SCIP_Real lastglbminactivity; /**< last global minimal activity which was computed by complete summation
    137 * over all contributing values */
    138 SCIP_Real lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
    139 * over all contributing values */
    140 SCIP_Real maxactdelta; /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
    141 SCIP_VAR* maxactdeltavar; /**< variable with maximal activity contribution, or NULL if invalid */
    142 SCIP_RATIONAL* maxabsvalexact; /**< exact maximum absolute value of all coefficients */
    143 SCIP_RATIONAL* minabsvalexact; /**< exact minimal absolute value of all coefficients */
    144 SCIP_ROW* rowlhs; /**< LP row, if constraint is already stored in LP row format; represents fp-relaxation of lhs-part of rowexact;
    145 only this row will be added to the exact LP, rowrhs is used for safe aggregation of rows */
    146 SCIP_ROW* rowrhs; /**< LP row, if constraint is already stored in LP row format; represents fp-relaxation of rhs-part of rowexact */
    147 SCIP_ROWEXACT* rowexact; /**< Exact rational lp row */
    148 SCIP_VAR** vars; /**< variables of constraint entries */
    149 SCIP_RATIONAL** vals; /**< coefficients of constraint entries */
    150 SCIP_INTERVAL* valsreal; /**< values of val rounded up/down to closest fp-representable numbers */
    151 SCIP_EVENTDATA** eventdata; /**< event data for bound change events of the variables */
    152 int minactivityneginf; /**< number of coefficients contributing with neg. infinite value to minactivity */
    153 int minactivityposinf; /**< number of coefficients contributing with pos. infinite value to minactivity */
    154 int maxactivityneginf; /**< number of coefficients contributing with neg. infinite value to maxactivity */
    155 int maxactivityposinf; /**< number of coefficients contributing with pos. infinite value to maxactivity */
    156 int minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
    157 int minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
    158 int maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
    159 int maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
    160 int glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
    161 int glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
    162 int glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
    163 int glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
    164 int glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
    165 int glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
    166 int glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
    167 int glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
    168 int varssize; /**< size of the vars- and vals-arrays */
    169 int nvars; /**< number of nonzeros in constraint */
    170 int nbinvars; /**< the number of binary variables in the constraint, only valid after
    171 * sorting in stage >= SCIP_STAGE_INITSOLVE
    172 */
    173 unsigned int boundstightened:2; /**< is constraint already propagated with bound tightening? */
    174 unsigned int rangedrowpropagated:2; /**< did we perform ranged row propagation on this constraint?
    175 * (0: no, 1: yes, 2: with potentially adding artificial constraint */
    176 unsigned int validmaxabsval:1; /**< is the maximum absolute value valid? */
    177 unsigned int validminabsval:1; /**< is the minimum absolute value valid? */
    178 unsigned int validactivities:1; /**< are the activity bounds (local and global) valid? */
    179 unsigned int validminact:1; /**< is the local minactivity valid? */
    180 unsigned int validmaxact:1; /**< is the local maxactivity valid? */
    181 unsigned int validglbminact:1; /**< is the global minactivity valid? */
    182 unsigned int validglbmaxact:1; /**< is the global maxactivity valid? */
    183 unsigned int presolved:1; /**< is constraint already presolved? */
    184 unsigned int removedfixings:1; /**< are all fixed variables removed from the constraint? */
    185 unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
    186 unsigned int normalized:1; /**< is the constraint in normalized form? */
    187 unsigned int coefsorted :1; /**< are the constraint's variables sorted? */
    188 unsigned int merged:1; /**< are the constraint's equal variables already merged? */
    189 unsigned int cliquesadded:1; /**< were the cliques of the constraint already extracted? */
    190 unsigned int implsadded:1; /**< were the implications of the constraint already extracted? */
    191 unsigned int indexsorted:1; /**< are binary variables sorted w.r.t. the absolute value of their coefficient? */
    192 unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
    193 unsigned int hascontvar:1; /**< does the constraint contain at least one continuous variable? */
    194 unsigned int hasnonbinvar:1; /**< does the constraint contain at least one non-binary variable? */
    195 unsigned int hasnonbinvalid:1; /**< is the information stored in hasnonbinvar and hascontvar valid? */
    196 unsigned int onerowrelax:1; /**< is one floating-point row enough for the fp-relaxation? if so only rowlhs is used */
    197 unsigned int hasfprelax:1; /**< is the constraint possible to be represented as a fp relaxation (only false if var without bound is present) */
    198};
    199
    200/** event data for bound change event */
    201struct SCIP_EventData
    202{
    203 SCIP_CONS* cons; /**< linear constraint to process the bound change for */
    204 int varpos; /**< position of variable in vars array */
    205 bool rowvar; /**< is the event a row event? */
    206 int filterpos; /**< position of event in variable's event filter */
    207};
    208
    209/** constraint handler data */
    210struct SCIP_ConshdlrData
    211{
    212 SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
    213 SCIP_RATIONAL* maxaggrnormscale; /**< maximal allowed relative gain in maximum norm for constraint aggregation
    214 * (0.0: disable constraint aggregation) */
    215 SCIP_RATIONAL* maxcardbounddist; /**< maximal relative distance from current node's dual bound to primal bound compared
    216 * to best node's dual bound for separating knapsack cardinality cuts */
    217 SCIP_RATIONAL* mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
    218 SCIP_RATIONAL* maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
    219 * (faster, but numerically less stable) */
    220 int tightenboundsfreq; /**< multiplier on propagation frequency, how often the bounds are tightened */
    221 int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
    222 int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
    223 int maxsepacuts; /**< maximal number of cuts separated per separation round */
    224 int maxsepacutsroot; /**< maximal number of cuts separated per separation round in root node */
    225 int naddconss; /**< number of added constraints */
    226 SCIP_Longint ncheckserrorbound; /**< number of times running error analyis activity computation was called */
    227 SCIP_Longint nsuccesserrorbound; /**< number of times running error analyis activity computation could determine feasibility */
    228 SCIP_Longint nabotserrorbound; /**< number of times running error analysis activity computation not appliccable (e.g. row->len != fprow->len) */
    229 SCIP_Longint nconsprop; /**< number of times a constraint was propagated */
    230 SCIP_Longint nconspropnoninit; /**< number of times a non-initial (conflict) constraint was propagated */
    231 SCIP_Longint propnonzeros; /**< number of nonzeros in propagated rows */
    232 SCIP_Longint propnonzerosnoninit;/**< number of nonzeros in propagated rows in non-initial (conflict) propagations */
    233 SCIP_Bool sortvars; /**< should binary variables be sorted for faster propagation? */
    234 SCIP_Bool propcont; /**< should bounds on continuous variables be tightened by propagation?*/
    235 SCIP_Bool limitdenom; /**< should denominator sizes for continuous variables be controlled?*/
    236 SCIP_Longint boundmaxdenom; /**< maximal denominator for rational bounds on continuous variables after propagation */
    237};
    238
    239
    240/*
    241 * Propagation rules
    242 */
    243
    244/*lint --e{749} */
    246{
    247 PROPRULE_1_RHS = 1, /**< activity residuals of all other variables tighten bounds of single
    248 * variable due to the right hand side of the inequality */
    249 PROPRULE_1_LHS = 2, /**< activity residuals of all other variables tighten bounds of single
    250 * variable due to the left hand side of the inequality */
    251 PROPRULE_1_RANGEDROW = 3, /**< fixed variables and gcd of all left variables tighten bounds of a
    252 * single variable in this reanged row */
    253 PROPRULE_INVALID = 0 /**< propagation was applied without a specific propagation rule */
    255typedef enum Proprule PROPRULE;
    256
    257/** inference information */
    258struct InferInfo
    259{
    260 union
    261 {
    262 struct
    263 {
    264 unsigned int proprule:8; /**< propagation rule that was applied */
    265 unsigned int pos:24; /**< variable position, the propagation rule was applied at */
    266 } asbits;
    267 int asint; /**< inference information as a single int value */
    268 } val;
    269};
    270
    271typedef struct InferInfo INFERINFO;
    272
    273
    274/** converts an inference information into an int */
    275static
    277 INFERINFO inferinfo /**< inference information to convert */
    278 )
    279{
    280 return inferinfo.val.asint;
    281}
    282
    283
    284/** constructs an inference information out of a propagation rule and a position number */
    285static
    287 PROPRULE proprule, /**< propagation rule that deduced the value */
    288 int pos /**< variable position, the propagation rule was applied at */
    289 )
    290{
    291 INFERINFO inferinfo;
    292
    293 assert(pos >= 0);
    294 /* in the inferinfo struct only 24 bits for 'pos' are reserved */
    295 assert(pos < (1<<24));
    296
    297 inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
    298 inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
    299
    300 return inferinfo;
    301}
    302
    303/** constructs an inference information out of a propagation rule and a position number, returns info as int */
    304static
    306 PROPRULE proprule, /**< propagation rule that deduced the value */
    307 int pos /**< variable position, the propagation rule was applied at */
    308 )
    309{
    310 return inferInfoToInt(getInferInfo(proprule, pos));
    311}
    312
    313/** ensures, that vars and vals arrays can store at least num entries */
    314static
    316 SCIP* scip, /**< SCIP data structure */
    317 SCIP_CONSDATA* consdata, /**< linear constraint data */
    318 int num /**< minimum number of entries to store */
    319 )
    320{
    321 int k;
    322 assert(scip != NULL);
    323 assert(consdata != NULL);
    324 assert(consdata->nvars <= consdata->varssize);
    325
    326 if( num > consdata->varssize )
    327 {
    328 int newsize;
    329
    330 newsize = SCIPcalcMemGrowSize(scip, num);
    331 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
    332 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
    333 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->valsreal, consdata->varssize, newsize) );
    334 for( k = consdata->varssize; k < newsize; ++k )
    335 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &consdata->vals[k]) );
    336
    337 if( consdata->eventdata != NULL )
    338 {
    339 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
    340 }
    341 consdata->varssize = newsize;
    342 }
    343 assert(num <= consdata->varssize);
    344
    345 return SCIP_OKAY;
    346}
    347
    348
    349/*
    350 * local methods for managing linear constraint update methods
    351 */
    352
    353
    354/** creates constraint handler data for linear constraint handler */
    355static
    357 SCIP* scip, /**< SCIP data structure */
    358 SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
    359 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    360 )
    361{
    362 assert(scip != NULL);
    363 assert(conshdlrdata != NULL);
    364 assert(eventhdlr != NULL);
    365
    366 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
    367 (*conshdlrdata)->naddconss = 0;
    368 (*conshdlrdata)->ncheckserrorbound = 0;
    369 (*conshdlrdata)->nabotserrorbound = 0;
    370 (*conshdlrdata)->nsuccesserrorbound = 0;
    371 (*conshdlrdata)->nconsprop = 0;
    372 (*conshdlrdata)->nconspropnoninit = 0;
    373 (*conshdlrdata)->propnonzeros = 0;
    374 (*conshdlrdata)->propnonzerosnoninit = 0;
    375 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxaggrnormscale) );
    376 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxcardbounddist) );
    377 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxeasyactivitydelta) );
    378 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->mingainpernmincomp) );
    379
    380 /* set event handler for updating linear constraint activity bounds */
    381 (*conshdlrdata)->eventhdlr = eventhdlr;
    382
    383 return SCIP_OKAY;
    384}
    385
    386/** frees constraint handler data for linear constraint handler */
    387static
    389 SCIP* scip, /**< SCIP data structure */
    390 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
    391 )
    392{
    393 assert(scip != NULL);
    394 assert(conshdlrdata != NULL);
    395 assert(*conshdlrdata != NULL);
    396
    397 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxaggrnormscale);
    398 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxcardbounddist);
    399 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxeasyactivitydelta);
    400 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->mingainpernmincomp);
    401
    402 SCIPfreeBlockMemory(scip, conshdlrdata);
    403}
    404
    405/*
    406 * local methods
    407 */
    408
    409/** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
    410static
    412 SCIP* scip, /**< SCIP data structure */
    413 SCIP_CONS* cons, /**< linear constraint */
    414 SCIP_VAR* var, /**< variable of constraint entry */
    415 SCIP_RATIONAL* val /**< coefficient of constraint entry */
    416 )
    417{
    418 SCIP_CONSDATA* consdata;
    419
    420 assert(scip != NULL);
    421 assert(cons != NULL);
    422 assert(var != NULL);
    423
    424 consdata = SCIPconsGetData(cons);
    425 assert(consdata != NULL);
    426 assert(!SCIPrationalIsZero(val));
    427
    428 if( SCIPrationalIsPositive(val) )
    429 {
    430 SCIP_CALL( SCIPlockVarCons(scip, var, cons,
    431 !SCIPrationalIsNegInfinity(consdata->lhs), !SCIPrationalIsInfinity(consdata->rhs)) );
    432 }
    433 else
    434 {
    435 SCIP_CALL( SCIPlockVarCons(scip, var, cons,
    436 !SCIPrationalIsInfinity(consdata->rhs), !SCIPrationalIsNegInfinity(consdata->lhs)) );
    437 }
    438
    439 return SCIP_OKAY;
    440}
    441
    442/** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
    443static
    445 SCIP* scip, /**< SCIP data structure */
    446 SCIP_CONS* cons, /**< linear constraint */
    447 SCIP_VAR* var, /**< variable of constraint entry */
    448 SCIP_RATIONAL* val /**< coefficient of constraint entry */
    449 )
    450{
    451 SCIP_CONSDATA* consdata;
    452
    453 assert(scip != NULL);
    454 assert(cons != NULL);
    455 assert(var != NULL);
    456
    457 consdata = SCIPconsGetData(cons);
    458 assert(consdata != NULL);
    459 assert(!SCIPrationalIsZero(val));
    460
    461 if( SCIPrationalIsPositive(val) )
    462 {
    463 SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPrationalIsNegInfinity(consdata->lhs),
    464 !SCIPrationalIsInfinity(consdata->rhs)) );
    465 }
    466 else
    467 {
    468 SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPrationalIsInfinity(consdata->rhs),
    469 !SCIPrationalIsNegInfinity(consdata->lhs)) );
    470 }
    471
    472 return SCIP_OKAY;
    473}
    474
    475/** creates event data for variable at given position, and catches events */
    476/**! [SnippetDebugAssertions] */
    477static
    479 SCIP* scip, /**< SCIP data structure */
    480 SCIP_CONS* cons, /**< linear constraint */
    481 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    482 int pos /**< array position of variable to catch bound change events for */
    483 )
    484{
    485 SCIP_CONSDATA* consdata;
    486 assert(scip != NULL);
    487 assert(cons != NULL);
    488 assert(eventhdlr != NULL);
    489
    490 consdata = SCIPconsGetData(cons);
    491 assert(consdata != NULL);
    492
    493 assert(0 <= pos && pos < consdata->nvars);
    494 assert(consdata->vars != NULL);
    495 assert(consdata->vars[pos] != NULL);
    496 assert(SCIPvarIsTransformed(consdata->vars[pos]));
    497 assert(consdata->eventdata != NULL);
    498 assert(consdata->eventdata[pos] == NULL);
    499
    500 SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
    501 consdata->eventdata[pos]->cons = cons;
    502 consdata->eventdata[pos]->varpos = pos;
    503 consdata->eventdata[pos]->rowvar = false;
    504
    505 SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
    508 eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
    509
    510 consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(consdata->vars[pos]);
    511
    512 return SCIP_OKAY;
    513}
    514
    515/**! [SnippetDebugAssertions] */
    516
    517/** deletes event data for variable at given position, and drops events */
    518static
    520 SCIP* scip, /**< SCIP data structure */
    521 SCIP_CONS* cons, /**< linear constraint */
    522 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    523 int pos /**< array position of variable to catch bound change events for */
    524 )
    525{
    526 SCIP_CONSDATA* consdata;
    527 assert(scip != NULL);
    528 assert(cons != NULL);
    529 assert(eventhdlr != NULL);
    530
    531 consdata = SCIPconsGetData(cons);
    532 assert(consdata != NULL);
    533
    534 assert(0 <= pos && pos < consdata->nvars);
    535 assert(consdata->vars[pos] != NULL);
    536 assert(consdata->eventdata != NULL);
    537 assert(consdata->eventdata[pos] != NULL);
    538 assert(consdata->eventdata[pos]->cons == cons);
    539 assert(consdata->eventdata[pos]->varpos == pos);
    540
    541 SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
    544 eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
    545
    546 SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
    547
    548 return SCIP_OKAY;
    549}
    550
    551/** catches bound change events for all variables in transformed linear constraint */
    552static
    554 SCIP* scip, /**< SCIP data structure */
    555 SCIP_CONS* cons, /**< linear constraint */
    556 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
    557 )
    558{
    559 SCIP_CONSDATA* consdata;
    560 int i;
    561
    562 assert(scip != NULL);
    563 assert(cons != NULL);
    564
    565 consdata = SCIPconsGetData(cons);
    566 assert(consdata != NULL);
    567 assert(consdata->eventdata == NULL);
    568
    569 /* allocate eventdata array */
    570 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
    571 assert(consdata->eventdata != NULL);
    572 BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
    573
    574 /* catch event for every single variable */
    575 for( i = 0; i < consdata->nvars; ++i )
    576 {
    577 SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
    578 }
    579
    580 return SCIP_OKAY;
    581}
    582
    583/** drops bound change events for all variables in transformed linear constraint */
    584static
    586 SCIP* scip, /**< SCIP data structure */
    587 SCIP_CONS* cons, /**< linear constraint */
    588 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
    589 )
    590{
    591 SCIP_CONSDATA* consdata;
    592 int i;
    593
    594 assert(scip != NULL);
    595 assert(cons != NULL);
    596
    597 consdata = SCIPconsGetData(cons);
    598 assert(consdata != NULL);
    599 assert(consdata->eventdata != NULL);
    600
    601 /* drop event of every single variable */
    602 for( i = consdata->nvars - 1; i >= 0; --i )
    603 {
    604 SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
    605 }
    606
    607 /* free eventdata array */
    608 SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
    609 assert(consdata->eventdata == NULL);
    610
    611 return SCIP_OKAY;
    612}
    613
    614/** creates a linear constraint data */
    615static
    617 SCIP* scip, /**< SCIP data structure */
    618 SCIP_CONSDATA** consdata, /**< pointer to linear constraint data */
    619 int nvars, /**< number of nonzeros in the constraint */
    620 SCIP_VAR** vars, /**< array with variables of constraint entries */
    621 SCIP_RATIONAL** vals, /**< array with coefficients of constraint entries */
    622 SCIP_RATIONAL* lhs, /**< left hand side of row */
    623 SCIP_RATIONAL* rhs /**< right hand side of row */
    624 )
    625{
    626 int v;
    627 SCIP_RATIONAL* constant;
    628 SCIP_Real lhsrel;
    629 SCIP_Real rhsrel;
    630
    631 assert(scip != NULL);
    632 assert(consdata != NULL);
    633 assert(nvars == 0 || vars != NULL);
    634 assert(nvars == 0 || vals != NULL);
    635
    636 if( SCIPrationalIsGT(lhs, rhs) )
    637 {
    638 SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
    639 SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", SCIPrationalGetReal(lhs), SCIPrationalGetReal(rhs));
    640 }
    641
    642 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
    643
    644 (*consdata)->varssize = 0;
    645 (*consdata)->nvars = nvars;
    646 (*consdata)->hascontvar = FALSE;
    647 (*consdata)->hasnonbinvar = FALSE;
    648 (*consdata)->hasnonbinvalid = TRUE;
    649 (*consdata)->vars = NULL;
    650 (*consdata)->vals = NULL;
    651 (*consdata)->valsreal = NULL;
    652
    654 if( nvars > 0 )
    655 {
    656 int k;
    657
    658 SCIP_VAR** varsbuffer;
    659 SCIP_RATIONAL** valsbuffer;
    660 SCIP_INTERVAL* valsrealbuffer;
    661
    662 /* copy variables into temporary buffer */
    663 SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
    665 SCIP_CALL( SCIPallocBufferArray(scip, &valsrealbuffer, nvars) );
    666 k = 0;
    667
    668 /* loop over variables and sort out fixed ones */
    669 for( v = 0; v < nvars; ++v )
    670 {
    671 SCIP_VAR* var;
    672
    673 var = vars[v];
    674 assert(var != NULL);
    675 assert(!SCIPrationalIsAbsInfinity(vals[v]));
    676
    677 if( !SCIPrationalIsZero(vals[v]) )
    678 {
    679 /* treat fixed variable as a constant if problem compression is enabled */
    681 {
    682 SCIPrationalAddProd(constant, vals[v], SCIPvarGetLbGlobalExact(var));
    683 }
    684 else
    685 {
    686 varsbuffer[k] = var;
    687 SCIPrationalSetRational(valsbuffer[k], vals[v]);
    688 SCIPintervalSetRational(&(valsrealbuffer[k]), vals[v]);
    689 k++;
    690
    691 /* update hascontvar and hasnonbinvar flags */
    692 if( !(*consdata)->hascontvar )
    693 {
    694 SCIP_VARTYPE vartype = SCIPvarGetType(var);
    695
    696 if( vartype != SCIP_VARTYPE_BINARY )
    697 {
    698 (*consdata)->hasnonbinvar = TRUE;
    699
    700 if( vartype == SCIP_VARTYPE_CONTINUOUS )
    701 (*consdata)->hascontvar = TRUE;
    702 }
    703 }
    704 }
    705 }
    706 }
    707 (*consdata)->nvars = k;
    708
    709 if( k > 0 )
    710 {
    711 /* copy the possibly reduced buffer arrays into block */
    712 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
    713 SCIP_CALL( SCIPrationalCopyBlockArray(SCIPblkmem(scip), &(*consdata)->vals, valsbuffer, k) );
    714 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->valsreal, valsrealbuffer, k) );
    715 (*consdata)->varssize = k;
    716 }
    717
    718 SCIPfreeBufferArray(scip, &valsrealbuffer);
    719 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &valsbuffer, nvars);
    720 SCIPfreeBufferArray(scip, &varsbuffer);
    721 }
    722
    723 (*consdata)->eventdata = NULL;
    724
    727
    728 /* due to compressed copying, we may have fixed variables contributing to the left and right hand side */
    729 if( !SCIPrationalIsZero(constant) )
    730 {
    731 if( !SCIPrationalIsAbsInfinity(lhs) )
    732 SCIPrationalDiff(lhs, lhs, constant);
    733
    734 if( !SCIPrationalIsAbsInfinity(rhs) )
    735 SCIPrationalDiff(rhs, rhs, constant);
    736 }
    737
    738 (*consdata)->rowlhs = NULL;
    739 (*consdata)->rowrhs = NULL;
    740 (*consdata)->rowexact = NULL;
    741 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &(*consdata)->lhs, lhs) );
    742 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &(*consdata)->rhs, rhs) );
    743 (*consdata)->lhsreal = lhsrel;
    744 (*consdata)->rhsreal = rhsrel;
    745 SCIP_CALL( SCIPrationalCreateString(SCIPblkmem(scip), &(*consdata)->maxabsvalexact, "inf") );
    746 SCIP_CALL( SCIPrationalCreateString(SCIPblkmem(scip), &(*consdata)->minabsvalexact, "inf") );
    747 (*consdata)->maxabsval = SCIP_INVALID;
    748 (*consdata)->minabsval = SCIP_INVALID;
    749 (*consdata)->minactivity = SCIP_INVALID;
    750 (*consdata)->maxactivity = SCIP_INVALID;
    751 (*consdata)->lastminactivity = SCIP_INVALID;
    752 (*consdata)->lastmaxactivity = SCIP_INVALID;
    753 (*consdata)->maxactdelta = SCIP_INVALID;
    754 (*consdata)->maxactdeltavar = NULL;
    755 (*consdata)->minactivityneginf = -1;
    756 (*consdata)->minactivityposinf = -1;
    757 (*consdata)->maxactivityneginf = -1;
    758 (*consdata)->maxactivityposinf = -1;
    759 (*consdata)->minactivityneghuge = -1;
    760 (*consdata)->minactivityposhuge = -1;
    761 (*consdata)->maxactivityneghuge = -1;
    762 (*consdata)->maxactivityposhuge = -1;
    763 (*consdata)->glbminactivity = SCIP_INVALID;
    764 (*consdata)->glbmaxactivity = SCIP_INVALID;
    765 (*consdata)->lastglbminactivity = SCIP_INVALID;
    766 (*consdata)->lastglbmaxactivity = SCIP_INVALID;
    767 (*consdata)->glbminactivityneginf = -1;
    768 (*consdata)->glbminactivityposinf = -1;
    769 (*consdata)->glbmaxactivityneginf = -1;
    770 (*consdata)->glbmaxactivityposinf = -1;
    771 (*consdata)->glbminactivityneghuge = -1;
    772 (*consdata)->glbminactivityposhuge = -1;
    773 (*consdata)->glbmaxactivityneghuge = -1;
    774 (*consdata)->glbmaxactivityposhuge = -1;
    775 (*consdata)->validmaxabsval = FALSE;
    776 (*consdata)->validminabsval = FALSE;
    777 (*consdata)->validactivities = FALSE;
    778 (*consdata)->validminact = FALSE;
    779 (*consdata)->validmaxact = FALSE;
    780 (*consdata)->validglbminact = FALSE;
    781 (*consdata)->validglbmaxact = FALSE;
    782 (*consdata)->boundstightened = 0;
    783 (*consdata)->presolved = FALSE;
    784 (*consdata)->removedfixings = FALSE;
    785 (*consdata)->changed = TRUE;
    786 (*consdata)->normalized = FALSE;
    787 (*consdata)->indexsorted = (nvars <= 1);
    788 (*consdata)->merged = (nvars <= 1);
    789 (*consdata)->cliquesadded = FALSE;
    790 (*consdata)->implsadded = FALSE;
    791 (*consdata)->coefsorted = FALSE;
    792 (*consdata)->nbinvars = -1;
    793 (*consdata)->varsdeleted = FALSE;
    794 (*consdata)->rangedrowpropagated = 0;
    795 (*consdata)->onerowrelax = FALSE;
    796 (*consdata)->hasfprelax = FALSE;
    797
    798 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*consdata)->activity) );
    799 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*consdata)->violation) );
    800
    802 {
    803 /* get transformed variables */
    804 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
    805 }
    806
    807 /* capture variables */
    808 for( v = 0; v < (*consdata)->nvars; v++ )
    809 {
    810 assert((*consdata)->vars[v] != NULL);
    811 assert(!SCIPrationalIsZero((*consdata)->vals[v]));
    812 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
    813 }
    814
    816
    817 return SCIP_OKAY;
    818}
    819
    820/** frees a linear constraint data */
    821static
    823 SCIP* scip, /**< SCIP data structure */
    824 SCIP_CONSDATA** consdata /**< pointer to linear constraint data */
    825 )
    826{
    827 int v;
    828
    829 assert(scip != NULL);
    830 assert(consdata != NULL);
    831 assert(*consdata != NULL);
    832 assert((*consdata)->varssize >= 0);
    833
    834 /* release the row */
    835 if( (*consdata)->rowlhs != NULL )
    836 {
    837 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->rowlhs) );
    838 }
    839 if( (*consdata)->rowrhs != NULL && !(*consdata)->onerowrelax )
    840 {
    841 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->rowrhs) );
    842 }
    843
    844 /* release variables */
    845 for( v = 0; v < (*consdata)->nvars; v++ )
    846 {
    847 assert((*consdata)->vars[v] != NULL);
    848 assert(!SCIPrationalIsZero((*consdata)->vals[v]));
    849 SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
    850 }
    851
    852 SCIPrationalFreeBlockArray(SCIPblkmem(scip), &(*consdata)->vals, (*consdata)->varssize);
    853
    854 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
    855 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
    856 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->valsreal, (*consdata)->varssize);
    857
    858 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->lhs);
    859 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->rhs);
    860 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->maxabsvalexact);
    861 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->minabsvalexact);
    862 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->violation);
    863 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->activity);
    864
    865 SCIPfreeBlockMemory(scip, consdata);
    866 return SCIP_OKAY;
    867}
    868/** prints linear constraint in CIP format to file stream */
    869static
    871 SCIP* scip, /**< SCIP data structure */
    872 SCIP_CONSDATA* consdata, /**< linear constraint data */
    873 FILE* file /**< output file (or NULL for standard output) */
    874 )
    875{
    876 assert(scip != NULL);
    877 assert(consdata != NULL);
    878
    879 /* print left hand side for ranged rows */
    880 if( !SCIPrationalIsNegInfinity(consdata->lhs)
    881 && !SCIPrationalIsInfinity(consdata->rhs)
    882 && !SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    883 {
    884 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    885 SCIPinfoMessage(scip, file, " <= ");
    886 }
    887
    888 /* print coefficients and variables */
    889 if( consdata->nvars == 0 )
    890 SCIPinfoMessage(scip, file, "0");
    891 else
    892 {
    893 /* post linear sum of the linear constraint */
    894 SCIP_CALL( SCIPwriteVarsLinearsumExact(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
    895 }
    896
    897 /* print right hand side */
    898 if( SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    899 {
    900 SCIPinfoMessage(scip, file, " == ");
    901 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    902 }
    903 else if( !SCIPrationalIsInfinity(consdata->rhs) )
    904 {
    905 SCIPinfoMessage(scip, file, " <= ");
    906 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->rhs);
    907 }
    908 else if( !SCIPrationalIsNegInfinity(consdata->lhs) )
    909 {
    910 SCIPinfoMessage(scip, file, " >= ");
    911 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    912 }
    913 else
    914 SCIPinfoMessage(scip, file, " [free]");
    915
    916 return SCIP_OKAY;
    917}
    918
    919/** prints linear constraint and contained solution values of variables to file stream */
    920static
    922 SCIP* scip, /**< SCIP data structure */
    923 SCIP_CONS* cons, /**< linear constraint */
    924 SCIP_SOL* sol, /**< solution to print */
    925 SCIP_Bool useexactsol, /**< should the exact sol be used */
    926 FILE* file /**< output file (or NULL for standard output) */
    927 )
    928{
    929 SCIP_CONSDATA* consdata;
    930
    931 assert(scip != NULL);
    932 assert(cons != NULL);
    933
    934 consdata = SCIPconsGetData(cons);
    935 assert(consdata != NULL);
    936
    938
    939 /* print left hand side for ranged rows */
    940 /* print left hand side for ranged rows */
    941 if( !SCIPrationalIsNegInfinity(consdata->lhs)
    942 && !SCIPrationalIsInfinity(consdata->rhs)
    943 && !SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    944 {
    945 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    946 SCIPinfoMessage(scip, file, " <= ");
    947 }
    948
    949 /* print coefficients and variables */
    950 if( consdata->nvars == 0 )
    951 SCIPinfoMessage(scip, file, "0");
    952 else
    953 {
    954 int v;
    955
    956 /* post linear sum of the linear constraint */
    957 for( v = 0; v < consdata->nvars; ++v )
    958 {
    959 if( consdata->vals != NULL )
    960 {
    961 if( SCIPrationalIsEQReal(consdata->vals[v], 1.0) )
    962 {
    963 if( v > 0 )
    964 SCIPinfoMessage(scip, file, " +");
    965 }
    966 else if( SCIPrationalIsEQReal(consdata->vals[v], -1.0) )
    967 SCIPinfoMessage(scip, file, " -");
    968 else
    969 {
    970 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->vals[v]);
    971 }
    972 }
    973 else if( consdata->nvars > 0 )
    974 SCIPinfoMessage(scip, file, " +");
    975
    976 /* print variable name */
    977 SCIP_CALL( SCIPwriteVarName(scip, file, consdata->vars[v], TRUE) );
    978
    979 if( sol != NULL )
    980 {
    981 SCIPinfoMessage(scip, file, " (");
    982 if( useexactsol )
    983 {
    984 SCIP_RATIONAL* tmp;
    986 SCIPgetSolValExact(scip, sol, consdata->vars[v], tmp);
    989 }
    990 else
    991 SCIPinfoMessage(scip, file, "%+.9g", SCIPgetSolVal(scip, sol, consdata->vars[v]));
    992 SCIPinfoMessage(scip, file, ")");
    993 }
    994 }
    995 }
    996
    997 /* print right hand side */
    998 if( SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    999 {
    1000 SCIPinfoMessage(scip, file, " == ");
    1001 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    1002 }
    1003 else if( !SCIPrationalIsInfinity(consdata->rhs) )
    1004 {
    1005 SCIPinfoMessage(scip, file, " <= ");
    1006 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->rhs);
    1007 }
    1008 else if( !SCIPrationalIsNegInfinity(consdata->lhs) )
    1009 {
    1010 SCIPinfoMessage(scip, file, " >= ");
    1011 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    1012 }
    1013 else
    1014 SCIPinfoMessage(scip, file, " [free]");
    1015
    1016 SCIPinfoMessage(scip, file, ";\n");
    1017
    1018 return SCIP_OKAY;
    1019}
    1020
    1021/** invalidates activity bounds, such that they are recalculated in next get */
    1022static
    1024 SCIP_CONSDATA* consdata /**< linear constraint */
    1025 )
    1026{
    1027 assert(consdata != NULL);
    1028
    1029 consdata->validactivities = FALSE;
    1030 consdata->validminact = FALSE;
    1031 consdata->validmaxact = FALSE;
    1032 consdata->validglbminact = FALSE;
    1033 consdata->validglbmaxact = FALSE;
    1034 consdata->validmaxabsval = FALSE;
    1035 consdata->validminabsval = FALSE;
    1036 consdata->hasnonbinvalid = FALSE;
    1037 consdata->minactivity = SCIP_INVALID;
    1038 consdata->maxactivity = SCIP_INVALID;
    1039 consdata->lastminactivity = SCIP_INVALID;
    1040 consdata->lastmaxactivity = SCIP_INVALID;
    1041 consdata->maxabsval = SCIP_INVALID;
    1042 consdata->minabsval = SCIP_INVALID;
    1043 consdata->maxactdelta = SCIP_INVALID;
    1044 SCIPrationalSetInfinity(consdata->maxabsvalexact);
    1045 SCIPrationalSetInfinity(consdata->minabsvalexact);
    1046 consdata->maxactdeltavar = NULL;
    1047 consdata->minactivityneginf = -1;
    1048 consdata->minactivityposinf = -1;
    1049 consdata->maxactivityneginf = -1;
    1050 consdata->maxactivityposinf = -1;
    1051 consdata->minactivityneghuge = -1;
    1052 consdata->minactivityposhuge = -1;
    1053 consdata->maxactivityneghuge = -1;
    1054 consdata->maxactivityposhuge = -1;
    1055 consdata->glbminactivity = SCIP_INVALID;
    1056 consdata->glbmaxactivity = SCIP_INVALID;
    1057 consdata->lastglbminactivity = SCIP_INVALID;
    1058 consdata->lastglbmaxactivity = SCIP_INVALID;
    1059 consdata->glbminactivityneginf = -1;
    1060 consdata->glbminactivityposinf = -1;
    1061 consdata->glbmaxactivityneginf = -1;
    1062 consdata->glbmaxactivityposinf = -1;
    1063 consdata->glbminactivityneghuge = -1;
    1064 consdata->glbminactivityposhuge = -1;
    1065 consdata->glbmaxactivityneghuge = -1;
    1066 consdata->glbmaxactivityposhuge = -1;
    1067}
    1068
    1069/** computes the pseudo activity of a constraint */
    1070static
    1072 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1073 SCIP_RATIONAL* pseudoactivity /**< buffer to store pseudoactivity */
    1074 )
    1075{
    1076 int i;
    1077 int pseudoactivityposinf;
    1078 int pseudoactivityneginf;
    1080 SCIP_RATIONAL* val;
    1081
    1082 SCIPrationalSetFraction(pseudoactivity, 0LL, 1LL);
    1083
    1084 pseudoactivityposinf = 0;
    1085 pseudoactivityneginf = 0;
    1086
    1087 for( i = consdata->nvars - 1; i >= 0; --i )
    1088 {
    1089 bound = SCIPvarGetBestBoundLocalExact(consdata->vars[i]);
    1090 val = consdata->vals[i];
    1091 assert(!SCIPrationalIsZero(val));
    1092
    1094 {
    1095 if( SCIPrationalIsNegative(val) )
    1096 ++pseudoactivityposinf;
    1097 else
    1098 ++pseudoactivityneginf;
    1099 }
    1100 else if( SCIPrationalIsInfinity(bound) )
    1101 {
    1102 if( SCIPrationalIsNegative(val) )
    1103 ++pseudoactivityneginf;
    1104 else
    1105 ++pseudoactivityposinf;
    1106 }
    1107 else
    1108 SCIPrationalAddProd(pseudoactivity, val, bound);
    1109 }
    1110
    1111 /* set pseudo activity to infeasible infinity for contradicting contributions */
    1112 if( pseudoactivityneginf > 0 && ( pseudoactivityposinf == 0 || !SCIPrationalIsNegInfinity(consdata->lhs) ) )
    1113 SCIPrationalSetNegInfinity(pseudoactivity);
    1114 else if( pseudoactivityposinf > 0 && ( pseudoactivityneginf == 0 || !SCIPrationalIsInfinity(consdata->rhs) ) )
    1115 SCIPrationalSetInfinity(pseudoactivity);
    1116}
    1117
    1118/** recompute the minactivity of a constraint */
    1119static
    1121 SCIP* scip, /**< SCIP data structure */
    1122 SCIP_CONSDATA* consdata /**< linear constraint data */
    1123 )
    1124{
    1125 SCIP_ROUNDMODE prevmode;
    1126 SCIP_Real contribution;
    1127 int i;
    1128
    1129 consdata->minactivity = 0.0;
    1130 prevmode = SCIPintervalGetRoundingMode();
    1132
    1133 for( i = consdata->nvars - 1; i >= 0; --i )
    1134 {
    1135 if( consdata->valsreal[i].sup < 0.0 )
    1136 {
    1137 assert(consdata->valsreal[i].inf <= 0.0);
    1138
    1139 contribution = SCIPvarGetUbLocal(consdata->vars[i]);
    1140
    1141 if( SCIPisInfinity(scip, contribution) )
    1142 continue;
    1143 }
    1144 else
    1145 {
    1146 assert(consdata->valsreal[i].inf >= 0.0);
    1147
    1148 contribution = SCIPvarGetLbLocal(consdata->vars[i]);
    1149
    1150 if( SCIPisInfinity(scip, -contribution) )
    1151 continue;
    1152 }
    1153
    1154 contribution *= contribution < 0.0 ? consdata->valsreal[i].sup : consdata->valsreal[i].inf;
    1155
    1156 if( SCIPisHugeValue(scip, REALABS(contribution)) )
    1157 continue;
    1158
    1159 consdata->minactivity += contribution;
    1160 }
    1161
    1162 /* the activity was just computed from scratch and is valid now */
    1163 consdata->validminact = TRUE;
    1164
    1165 /* the activity was just computed from scratch, mark it to be reliable */
    1166 consdata->lastminactivity = consdata->minactivity;
    1168}
    1169
    1170/** recompute the maxactivity of a constraint */
    1171static
    1173 SCIP* scip, /**< SCIP data structure */
    1174 SCIP_CONSDATA* consdata /**< linear constraint data */
    1175 )
    1176{
    1177 SCIP_ROUNDMODE prevmode;
    1178 SCIP_Real contribution;
    1179 int i;
    1180
    1181 consdata->maxactivity = 0.0;
    1182 prevmode = SCIPintervalGetRoundingMode();
    1184
    1185 for( i = consdata->nvars - 1; i >= 0; --i )
    1186 {
    1187 if( consdata->valsreal[i].sup < 0.0 )
    1188 {
    1189 assert(consdata->valsreal[i].inf <= 0.0);
    1190
    1191 contribution = SCIPvarGetLbLocal(consdata->vars[i]);
    1192
    1193 if( SCIPisInfinity(scip, -contribution) )
    1194 continue;
    1195 }
    1196 else
    1197 {
    1198 assert(consdata->valsreal[i].inf >= 0.0);
    1199
    1200 contribution = SCIPvarGetUbLocal(consdata->vars[i]);
    1201
    1202 if( SCIPisInfinity(scip, contribution) )
    1203 continue;
    1204 }
    1205
    1206 contribution *= contribution < 0.0 ? consdata->valsreal[i].inf : consdata->valsreal[i].sup;
    1207
    1208 if( SCIPisHugeValue(scip, REALABS(contribution)) )
    1209 continue;
    1210
    1211 consdata->maxactivity += contribution;
    1212 }
    1213
    1214 /* the activity was just computed from scratch and is valid now */
    1215 consdata->validmaxact = TRUE;
    1216
    1217 /* the activity was just computed from scratch, mark it to be reliable */
    1218 consdata->lastmaxactivity = consdata->maxactivity;
    1219
    1221}
    1222
    1223/** recompute the global minactivity of a constraint */
    1224static
    1226 SCIP* scip, /**< SCIP data structure */
    1227 SCIP_CONSDATA* consdata /**< linear constraint data */
    1228 )
    1229{
    1230 SCIP_ROUNDMODE prevmode;
    1231 SCIP_Real contribution;
    1232 int i;
    1233
    1234 consdata->glbminactivity = 0.0;
    1235 prevmode = SCIPintervalGetRoundingMode();
    1237
    1238 for( i = consdata->nvars - 1; i >= 0; --i )
    1239 {
    1240 if( consdata->valsreal[i].sup < 0.0 )
    1241 {
    1242 assert(consdata->valsreal[i].inf <= 0.0);
    1243
    1244 contribution = SCIPvarGetUbGlobal(consdata->vars[i]);
    1245
    1246 if( SCIPisInfinity(scip, contribution) )
    1247 continue;
    1248 }
    1249 else
    1250 {
    1251 assert(consdata->valsreal[i].inf >= 0.0);
    1252
    1253 contribution = SCIPvarGetLbGlobal(consdata->vars[i]);
    1254
    1255 if( SCIPisInfinity(scip, -contribution) )
    1256 continue;
    1257 }
    1258
    1259 contribution *= contribution < 0.0 ? consdata->valsreal[i].sup : consdata->valsreal[i].inf;
    1260
    1261 if( SCIPisHugeValue(scip, REALABS(contribution)) )
    1262 continue;
    1263
    1264 consdata->glbminactivity += contribution;
    1265 }
    1266
    1267 /* the activity was just computed from scratch and is valid now */
    1268 consdata->validglbminact = TRUE;
    1269
    1270 /* the activity was just computed from scratch, mark it to be reliable */
    1271 consdata->lastglbminactivity = consdata->glbminactivity;
    1272
    1274}
    1275
    1276/** recompute the global maxactivity of a constraint */
    1277static
    1279 SCIP* scip, /**< SCIP data structure */
    1280 SCIP_CONSDATA* consdata /**< linear constraint data */
    1281 )
    1282{
    1283 SCIP_ROUNDMODE prevmode;
    1284 SCIP_Real contribution;
    1285 int i;
    1286
    1287 consdata->glbmaxactivity = 0.0;
    1288 prevmode = SCIPintervalGetRoundingMode();
    1290
    1291 for( i = consdata->nvars - 1; i >= 0; --i )
    1292 {
    1293 if( consdata->valsreal[i].sup < 0.0 )
    1294 {
    1295 assert(consdata->valsreal[i].inf <= 0.0);
    1296
    1297 contribution = SCIPvarGetLbGlobal(consdata->vars[i]);
    1298
    1299 if( SCIPisInfinity(scip, -contribution) )
    1300 continue;
    1301 }
    1302 else
    1303 {
    1304 assert(consdata->valsreal[i].inf >= 0.0);
    1305
    1306 contribution = SCIPvarGetUbGlobal(consdata->vars[i]);
    1307
    1308 if( SCIPisInfinity(scip, contribution) )
    1309 continue;
    1310 }
    1311
    1312 contribution *= contribution < 0.0 ? consdata->valsreal[i].inf : consdata->valsreal[i].sup;
    1313
    1314 if( SCIPisHugeValue(scip, REALABS(contribution)) )
    1315 continue;
    1316
    1317 consdata->glbmaxactivity += contribution;
    1318 }
    1319
    1320 /* the activity was just computed from scratch and is valid now */
    1321 consdata->validglbmaxact = TRUE;
    1322
    1323 /* the activity was just computed from scratch, mark it to be reliable */
    1324 consdata->lastglbmaxactivity = consdata->glbmaxactivity;
    1326}
    1327
    1328/** calculates minimum absolute value of coefficients */
    1329static
    1331 SCIP_CONSDATA* consdata /**< linear constraint data */
    1332 )
    1333{
    1334 int i;
    1335 assert(consdata != NULL);
    1336 assert(!consdata->validminabsval);
    1337
    1338 consdata->validminabsval = TRUE;
    1339
    1340 if( consdata->nvars > 0 )
    1341 {
    1342 SCIPrationalAbs(consdata->minabsvalexact, consdata->vals[0]);
    1343 assert(!SCIPrationalIsZero(consdata->vals[0]));
    1344 }
    1345 else
    1346 SCIPrationalSetReal(consdata->minabsvalexact, 0.0);
    1347
    1348 for( i = 1; i < consdata->nvars; ++i )
    1349 {
    1350 assert(!SCIPrationalIsZero(consdata->vals[i]));
    1351
    1352 if( SCIPrationalIsAbsGT(consdata->minabsvalexact, consdata->vals[i]) )
    1353 SCIPrationalAbs(consdata->minabsvalexact, consdata->vals[i]);
    1354 }
    1355}
    1356
    1357/** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
    1358static
    1360 SCIP_CONSDATA* consdata /**< linear constraint data */
    1361 )
    1362{
    1363 int v;
    1364
    1365 assert(!consdata->hasnonbinvalid);
    1366 consdata->hasnonbinvar = FALSE;
    1367 consdata->hascontvar = FALSE;
    1368
    1369 for( v = consdata->nvars - 1; v >= 0; --v )
    1370 {
    1371 SCIP_VARTYPE vartype = SCIPvarGetType(consdata->vars[v]);
    1372
    1373 if( vartype != SCIP_VARTYPE_BINARY )
    1374 {
    1375 consdata->hasnonbinvar = TRUE;
    1376
    1377 if( vartype == SCIP_VARTYPE_CONTINUOUS )
    1378 {
    1379 consdata->hascontvar = TRUE;
    1380 break;
    1381 }
    1382 }
    1383 }
    1384 assert(consdata->hascontvar || v < 0);
    1385
    1386 consdata->hasnonbinvalid = TRUE;
    1387}
    1388
    1389#ifdef SCIP_MORE_DEBUG
    1390/* checks that the stored maximal activity delta (if not invalid) is correct */
    1391static
    1393 SCIP* scip, /**< SCIP data structure */
    1394 SCIP_CONSDATA* consdata /**< linear constraint data */
    1395 )
    1396{
    1397 if( consdata->maxactdelta != SCIP_INVALID )
    1398 {
    1399 SCIP_Rational* maxactdelta;
    1400 SCIP_Rational* domain;
    1401 SCIP_Rational* delta;
    1402 SCIP_RATIONAL* lb;
    1403 SCIP_RATIONAL* ub;
    1404 int v;
    1405
    1409
    1410 for( v = consdata->nvars - 1; v >= 0; --v )
    1411 {
    1412 lb = SCIPvarGetLbLocalExact(consdata->vars[v]);
    1413 ub = SCIPvarGetUbLocalExact(consdata->vars[v]);
    1414
    1416 {
    1417 SCIPrationalSetInfinity(maxactdelta);
    1418 break;
    1419 }
    1420
    1421 SCIPrationalDiff(domain, ub, lb);
    1422 SCIPrationalAbs(delta, consdata->vals[v]);
    1423 SCIPrationalMult(delta, delta, domain);
    1424
    1425 if( SCIPrationalisGT(delta,maxactdelta) )
    1426 {
    1427 SCIPrationalSetRational(maxactdelta, delta);
    1428 }
    1429 }
    1430 assert(SCIPrationalIsEQ(maxactdelta, consdata->maxactdelta));
    1431
    1434 SCIPrationalFreeBuffer(SCIPbuffer(scip), maxactdelta);
    1435 }
    1436}
    1437#else
    1438#define checkMaxActivityDelta(scip, consdata) /**/
    1439#endif
    1440
    1441/** recompute maximal activity contribution for a single variable */
    1442static
    1444 SCIP* scip, /**< SCIP data structure */
    1445 SCIP_CONSDATA* consdata /**< linear constraint data */
    1446 )
    1447{
    1448 SCIP_Real delta;
    1449 int v;
    1450 consdata->maxactdelta = 0.0;
    1451
    1452 if( !consdata->hasnonbinvalid )
    1453 consdataCheckNonbinvar(consdata);
    1454
    1455 /* easy case, the problem consists only of binary variables */
    1456 if( !consdata->hasnonbinvar )
    1457 {
    1458 for( v = consdata->nvars - 1; v >= 0; --v )
    1459 {
    1460 if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
    1461 {
    1462 delta = SCIPintervalAbsMax(consdata->valsreal[v]);
    1463
    1464 if( delta > consdata->maxactdelta )
    1465 {
    1466 consdata->maxactdelta = delta;
    1467 consdata->maxactdeltavar = consdata->vars[v];
    1468 }
    1469 }
    1470 }
    1471 return;
    1472 }
    1473
    1474 for( v = consdata->nvars - 1; v >= 0; --v )
    1475 {
    1476 SCIP_Real domain;
    1477 SCIP_Real lb;
    1478 SCIP_Real ub;
    1479
    1480 lb = SCIPvarGetLbLocal(consdata->vars[v]);
    1481 ub = SCIPvarGetUbLocal(consdata->vars[v]);
    1482
    1483 if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
    1484 {
    1485 consdata->maxactdelta = SCIPinfinity(scip);
    1486 consdata->maxactdeltavar = consdata->vars[v];
    1487 break;
    1488 }
    1489
    1490 domain = ub - lb;
    1491 delta = SCIPintervalAbsMax(consdata->valsreal[v]) * domain;
    1492
    1493 if( delta > consdata->maxactdelta )
    1494 {
    1495 consdata->maxactdelta = delta;
    1496 consdata->maxactdeltavar = consdata->vars[v];
    1497 }
    1498 }
    1499}
    1500
    1501/** updates activities for a change in a bound */
    1502static
    1504 SCIP* scip, /**< SCIP data structure */
    1505 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1506 SCIP_VAR* var, /**< variable that has been changed; can be NULL for global bound changes */
    1507 SCIP_Real oldbound, /**< old bound of variable */
    1508 SCIP_Real newbound, /**< new bound of variable */
    1509 SCIP_INTERVAL valrange, /**< coefficient of constraint entry */
    1510 SCIP_BOUNDTYPE boundtype, /**< type of the bound change */
    1511 SCIP_Bool global /**< is it a global or a local bound change? */
    1512 )
    1513{
    1514 SCIP_Real* activity;
    1515 SCIP_Real* lastactivity;
    1516 int* activityposinf;
    1517 int* activityneginf;
    1518 int* activityposhuge;
    1519 int* activityneghuge;
    1520 SCIP_Real oldcontribution;
    1521 SCIP_Real newcontribution;
    1522 SCIP_Real delta;
    1523 SCIP_Bool validact;
    1524 SCIP_Bool finitenewbound;
    1525 SCIP_Bool hugevalnewcont;
    1526 SCIP_Real oldval;
    1527 SCIP_Real newval;
    1528 SCIP_ROUNDMODE prevmode;
    1529
    1530 prevmode = SCIPintervalGetRoundingMode();
    1531
    1532 assert(scip != NULL);
    1533 assert(consdata != NULL);
    1534 assert(global || (var != NULL));
    1535 assert(consdata->validactivities);
    1536 assert(consdata->minactivity < SCIP_INVALID);
    1537 assert(consdata->maxactivity < SCIP_INVALID);
    1538 assert(consdata->lastminactivity < SCIP_INVALID);
    1539 assert(consdata->lastmaxactivity < SCIP_INVALID);
    1540 assert(consdata->minactivityneginf >= 0);
    1541 assert(consdata->minactivityposinf >= 0);
    1542 assert(consdata->maxactivityneginf >= 0);
    1543 assert(consdata->maxactivityposinf >= 0);
    1544 assert(consdata->minactivityneghuge >= 0);
    1545 assert(consdata->minactivityposhuge >= 0);
    1546 assert(consdata->maxactivityneghuge >= 0);
    1547 assert(consdata->maxactivityposhuge >= 0);
    1548 assert(consdata->glbminactivity < SCIP_INVALID);
    1549 assert(consdata->glbmaxactivity < SCIP_INVALID);
    1550 assert(consdata->lastglbminactivity < SCIP_INVALID);
    1551 assert(consdata->lastglbmaxactivity < SCIP_INVALID);
    1552 assert(consdata->glbminactivityneginf >= 0);
    1553 assert(consdata->glbminactivityposinf >= 0);
    1554 assert(consdata->glbmaxactivityneginf >= 0);
    1555 assert(consdata->glbmaxactivityposinf >= 0);
    1556 assert(consdata->glbminactivityneghuge >= 0);
    1557 assert(consdata->glbminactivityposhuge >= 0);
    1558 assert(consdata->glbmaxactivityneghuge >= 0);
    1559 assert(consdata->glbmaxactivityposhuge >= 0);
    1560
    1561 delta = 0.0;
    1562
    1563 /* we are updating global activities */
    1564 if( global )
    1565 {
    1566 /* depending on the boundtype and the coefficient, we choose the activity to be updated:
    1567 * lower bound + pos. coef: update minactivity
    1568 * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
    1569 * upper bound + pos. coef: update maxactivity
    1570 * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
    1571 */
    1572 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    1573 {
    1574 if( valrange.sup < 0.0 )
    1575 {
    1576 assert(valrange.inf <= 0.0);
    1577
    1578 activity = &(consdata->glbmaxactivity);
    1579 lastactivity = &(consdata->lastglbmaxactivity);
    1580 activityposinf = &(consdata->glbmaxactivityneginf);
    1581 activityneginf = &(consdata->glbmaxactivityposinf);
    1582 activityposhuge = &(consdata->glbmaxactivityposhuge);
    1583 activityneghuge = &(consdata->glbmaxactivityneghuge);
    1584 validact = consdata->validglbmaxact;
    1586 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
    1587 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
    1588 }
    1589 else
    1590 {
    1591 assert(valrange.inf >= 0.0);
    1592
    1593 activity = &(consdata->glbminactivity);
    1594 lastactivity = &(consdata->lastglbminactivity);
    1595 activityposinf = &(consdata->glbminactivityposinf);
    1596 activityneginf = &(consdata->glbminactivityneginf);
    1597 activityposhuge = &(consdata->glbminactivityposhuge);
    1598 activityneghuge = &(consdata->glbminactivityneghuge);
    1599 validact = consdata->validglbminact;
    1601 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
    1602 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
    1603 }
    1604 }
    1605 else
    1606 {
    1607 if( valrange.sup < 0.0 )
    1608 {
    1609 assert(valrange.inf <= 0.0);
    1610
    1611 activity = &(consdata->glbminactivity);
    1612 lastactivity = &(consdata->lastglbminactivity);
    1613 activityposinf = &(consdata->glbminactivityneginf);
    1614 activityneginf = &(consdata->glbminactivityposinf);
    1615 activityposhuge = &(consdata->glbminactivityposhuge);
    1616 activityneghuge = &(consdata->glbminactivityneghuge);
    1617 validact = consdata->validglbminact;
    1619 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
    1620 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
    1621 }
    1622 else
    1623 {
    1624 assert(valrange.inf >= 0.0);
    1625
    1626 activity = &(consdata->glbmaxactivity);
    1627 lastactivity = &(consdata->lastglbmaxactivity);
    1628 activityposinf = &(consdata->glbmaxactivityposinf);
    1629 activityneginf = &(consdata->glbmaxactivityneginf);
    1630 activityposhuge = &(consdata->glbmaxactivityposhuge);
    1631 activityneghuge = &(consdata->glbmaxactivityneghuge);
    1632 validact = consdata->validglbmaxact;
    1634 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
    1635 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
    1636 }
    1637 }
    1638 }
    1639 /* we are updating local activities */
    1640 else
    1641 {
    1642 /* depending on the boundtype and the coefficient, we choose the activity to be updated:
    1643 * lower bound + pos. coef: update minactivity
    1644 * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
    1645 * upper bound + pos. coef: update maxactivity
    1646 * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
    1647 */
    1648 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    1649 {
    1650 if( valrange.sup < 0.0 )
    1651 {
    1652 assert(valrange.inf <= 0.0);
    1653
    1654 activity = &(consdata->maxactivity);
    1655 lastactivity = &(consdata->lastmaxactivity);
    1656 activityposinf = &(consdata->maxactivityneginf);
    1657 activityneginf = &(consdata->maxactivityposinf);
    1658 activityposhuge = &(consdata->maxactivityposhuge);
    1659 activityneghuge = &(consdata->maxactivityneghuge);
    1660 validact = consdata->validmaxact;
    1662 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
    1663 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
    1664 }
    1665 else
    1666 {
    1667 assert(valrange.inf >= 0.0);
    1668
    1669 activity = &(consdata->minactivity);
    1670 lastactivity = &(consdata->lastminactivity);
    1671 activityposinf = &(consdata->minactivityposinf);
    1672 activityneginf = &(consdata->minactivityneginf);
    1673 activityposhuge = &(consdata->minactivityposhuge);
    1674 activityneghuge = &(consdata->minactivityneghuge);
    1675 validact = consdata->validminact;
    1677 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
    1678 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
    1679 }
    1680 }
    1681 else
    1682 {
    1683 if( valrange.sup < 0.0 )
    1684 {
    1685 assert(valrange.inf <= 0.0);
    1686
    1687 activity = &(consdata->minactivity);
    1688 lastactivity = &(consdata->lastminactivity);
    1689 activityposinf = &(consdata->minactivityneginf);
    1690 activityneginf = &(consdata->minactivityposinf);
    1691 activityposhuge = &(consdata->minactivityposhuge);
    1692 activityneghuge = &(consdata->minactivityneghuge);
    1693 validact = consdata->validminact;
    1695 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
    1696 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
    1697 }
    1698 else
    1699 {
    1700 assert(valrange.inf >= 0.0);
    1701
    1702 activity = &(consdata->maxactivity);
    1703 lastactivity = &(consdata->lastmaxactivity);
    1704 activityposinf = &(consdata->maxactivityposinf);
    1705 activityneginf = &(consdata->maxactivityneginf);
    1706 activityposhuge = &(consdata->maxactivityposhuge);
    1707 activityneghuge = &(consdata->maxactivityneghuge);
    1708 validact = consdata->validmaxact;
    1710 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
    1711 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
    1712 }
    1713 }
    1714 }
    1715
    1716 oldcontribution = SCIPintervalNegateReal(oldval) * oldbound;
    1717 newcontribution = newval * newbound;
    1718 hugevalnewcont = SCIPisHugeValue(scip, REALABS(newcontribution));
    1719 finitenewbound = !SCIPisInfinity(scip, REALABS(newbound));
    1720
    1721 if( SCIPisInfinity(scip, REALABS(oldbound)) )
    1722 {
    1723 /* old bound was +infinity */
    1724 if( oldbound > 0.0 )
    1725 {
    1726 assert((*activityposinf) >= 1);
    1727
    1728 /* we only have to do something if the new bound is not again +infinity */
    1729 if( finitenewbound || newbound < 0.0 )
    1730 {
    1731 /* decrease the counter for positive infinite contributions */
    1732 (*activityposinf)--;
    1733
    1734 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
    1735 if( !finitenewbound && newbound < 0.0 )
    1736 (*activityneginf)++;
    1737 else if( hugevalnewcont )
    1738 {
    1739 /* if the contribution of this variable is too large, increase the counter for huge values */
    1740 if( newcontribution > 0.0 )
    1741 (*activityposhuge)++;
    1742 else
    1743 (*activityneghuge)++;
    1744 }
    1745 /* "normal case": just add the contribution to the activity */
    1746 else
    1747 delta = newcontribution;
    1748 }
    1749 }
    1750 /* old bound was -infinity */
    1751 else
    1752 {
    1753 assert(oldbound < 0.0);
    1754 assert((*activityneginf) >= 1);
    1755
    1756 /* we only have to do something ig the new bound is not again -infinity */
    1757 if( finitenewbound || newbound > 0.0 )
    1758 {
    1759 /* decrease the counter for negative infinite contributions */
    1760 (*activityneginf)--;
    1761
    1762 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
    1763 if( !finitenewbound && newbound > 0.0 )
    1764 (*activityposinf)++;
    1765 else if( hugevalnewcont )
    1766 {
    1767 /* if the contribution of this variable is too large, increase the counter for huge values */
    1768 if( newcontribution > 0.0 )
    1769 (*activityposhuge)++;
    1770 else
    1771 (*activityneghuge)++;
    1772 }
    1773 /* "normal case": just add the contribution to the activity */
    1774 else
    1775 delta = newcontribution;
    1776 }
    1777 }
    1778 }
    1779 else if( SCIPisHugeValue(scip, REALABS(oldcontribution)) )
    1780 {
    1781 /* old contribution was too large and positive */
    1782 if( -oldcontribution > 0.0 )
    1783 {
    1784 assert((*activityposhuge) >= 1);
    1785
    1786 /* decrease the counter for huge positive contributions; it might be increased again later,
    1787 * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
    1788 */
    1789 (*activityposhuge)--;
    1790
    1791 if( !finitenewbound )
    1792 {
    1793 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
    1794 if( newbound > 0.0 )
    1795 (*activityposinf)++;
    1796 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
    1797 else
    1798 (*activityneginf)++;
    1799 }
    1800 else if( hugevalnewcont )
    1801 {
    1802 /* if the contribution of this variable is too large and positive, increase the corresponding counter */
    1803 if( newcontribution > 0.0 )
    1804 (*activityposhuge)++;
    1805 /* if the contribution of this variable is too large and negative, increase the corresponding counter */
    1806 else
    1807 (*activityneghuge)++;
    1808 }
    1809 /* "normal case": just add the contribution to the activity */
    1810 else
    1811 delta = newcontribution;
    1812 }
    1813 /* old contribution was too large and negative */
    1814 else
    1815 {
    1816 assert(-oldcontribution < 0.0);
    1817 assert((*activityneghuge) >= 1);
    1818
    1819 /* decrease the counter for huge negative contributions; it might be increased again later,
    1820 * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
    1821 */
    1822 (*activityneghuge)--;
    1823
    1824 if( !finitenewbound )
    1825 {
    1826 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
    1827 if( newbound > 0.0 )
    1828 (*activityposinf)++;
    1829 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
    1830 else
    1831 (*activityneginf)++;
    1832 }
    1833 else if( hugevalnewcont )
    1834 {
    1835 /* if the contribution of this variable is too large and positive, increase the corresponding counter */
    1836 if( newcontribution > 0.0 )
    1837 (*activityposhuge)++;
    1838 /* if the contribution of this variable is too large and negative, increase the corresponding counter */
    1839 else
    1840 (*activityneghuge)++;
    1841 }
    1842 /* "normal case": just add the contribution to the activity */
    1843 else
    1844 delta = newcontribution;
    1845 }
    1846 }
    1847 /* old bound was finite and not too large */
    1848 else
    1849 {
    1850 if( !finitenewbound )
    1851 {
    1852 /* if the new bound is +infinity, the old contribution has to be subtracted
    1853 * and the counter for positive infinite contributions has to be increased
    1854 */
    1855 if( newbound > 0.0 )
    1856 {
    1857 (*activityposinf)++;
    1858 delta = oldcontribution;
    1859 }
    1860 /* if the new bound is -infinity, the old contribution has to be subtracted
    1861 * and the counter for negative infinite contributions has to be increased
    1862 */
    1863 else
    1864 {
    1865 assert(newbound < 0.0 );
    1866
    1867 (*activityneginf)++;
    1868 delta = oldcontribution;
    1869 }
    1870 }
    1871 /* if the contribution of this variable is too large, increase the counter for huge values */
    1872 else if( hugevalnewcont )
    1873 {
    1874 if( newcontribution > 0.0 )
    1875 {
    1876 (*activityposhuge)++;
    1877 delta = oldcontribution;
    1878 }
    1879 else
    1880 {
    1881 (*activityneghuge)++;
    1882 delta = oldcontribution;
    1883 }
    1884 }
    1885 /* "normal case": just update the activity */
    1886 else
    1887 delta = newcontribution + oldcontribution;
    1888 }
    1889
    1890 /* update the activity, if the current value is valid and there was a change in the finite part */
    1891 if( validact && (delta != 0.0) )
    1892 {
    1893 /* if the absolute value of the activity is increased, this is regarded as reliable,
    1894 * otherwise, we check whether we can still trust the updated value
    1895 */
    1896 (*activity) = (*activity) + delta;
    1897 assert(!SCIPisInfinity(scip, -(*activity)) && !SCIPisInfinity(scip, *activity));
    1898
    1899 if( REALABS((*lastactivity)) < REALABS(*activity) )
    1900 {
    1901 (*lastactivity) = (*activity);
    1902 }
    1903 }
    1904
    1906}
    1907/** updates minimum and maximum activity for a change in lower bound */
    1908static
    1910 SCIP* scip, /**< SCIP data structure */
    1911 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1912 SCIP_VAR* var, /**< variable that has been changed */
    1913 SCIP_Real oldlb, /**< old lower bound of variable */
    1914 SCIP_Real newlb, /**< new lower bound of variable */
    1915 SCIP_INTERVAL val /**< coefficient of constraint entry */
    1916 )
    1917{
    1918 assert(scip != NULL);
    1919 assert(consdata != NULL);
    1920 assert(var != NULL);
    1921
    1922 if( consdata->validactivities )
    1923 {
    1924 consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE);
    1925
    1926 assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
    1927 assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
    1928 }
    1929}
    1930
    1931/** updates minimum and maximum activity for a change in upper bound */
    1932static
    1934 SCIP* scip, /**< SCIP data structure */
    1935 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1936 SCIP_VAR* var, /**< variable that has been changed */
    1937 SCIP_Real oldub, /**< old upper bound of variable */
    1938 SCIP_Real newub, /**< new upper bound of variable */
    1939 SCIP_INTERVAL val /**< coefficient of constraint entry */
    1940 )
    1941{
    1942 assert(scip != NULL);
    1943 assert(consdata != NULL);
    1944 assert(var != NULL);
    1945
    1946 if( consdata->validactivities )
    1947 {
    1948 consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE);
    1949
    1950 assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
    1951 assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
    1952 }
    1953}
    1954
    1955/** updates minimum and maximum global activity for a change in the global lower bound */
    1956static
    1958 SCIP* scip, /**< SCIP data structure */
    1959 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1960 SCIP_Real oldlb, /**< old lower bound of variable */
    1961 SCIP_Real newlb, /**< new lower bound of variable */
    1962 SCIP_INTERVAL val /**< coefficient of constraint entry */
    1963 )
    1964{
    1965 assert(scip != NULL);
    1966 assert(consdata != NULL);
    1967
    1968 if( consdata->validactivities )
    1969 {
    1970 consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE);
    1971
    1972 assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
    1973 assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
    1974 }
    1975}
    1976
    1977/** updates minimum and maximum global activity for a change in global upper bound */
    1978static
    1980 SCIP* scip, /**< SCIP data structure */
    1981 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1982 SCIP_Real oldub, /**< old upper bound of variable */
    1983 SCIP_Real newub, /**< new upper bound of variable */
    1984 SCIP_INTERVAL val /**< coefficient of constraint entry */
    1985 )
    1986{
    1987 assert(scip != NULL);
    1988 assert(consdata != NULL);
    1989
    1990 if( consdata->validactivities )
    1991 {
    1992 consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE);
    1993
    1994 assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
    1995 assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
    1996 }
    1997}
    1998
    1999/** updates minimum and maximum activity and maximum absolute value for coefficient addition */
    2000static
    2002 SCIP* scip, /**< SCIP data structure */
    2003 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2004 SCIP_VAR* var, /**< variable of constraint entry */
    2005 SCIP_RATIONAL* valExact, /**< coefficient of constraint entry */
    2006 SCIP_INTERVAL val /**< coefficient of constraint entry */
    2007 )
    2008{
    2009 assert(scip != NULL);
    2010 assert(consdata != NULL);
    2011 assert(var != NULL);
    2012
    2013 /* update maximum absolute value */
    2014 if( consdata->validmaxabsval )
    2015 {
    2016 SCIP_Real absval;
    2017
    2018 assert(consdata->maxabsval < SCIP_INVALID);
    2019
    2020 absval = MAX(REALABS(val.inf), REALABS(val.sup)); /*lint !e777 !e666*/
    2021 consdata->maxabsval = MAX(consdata->maxabsval, absval);
    2022 }
    2023
    2024 if( consdata->validminabsval )
    2025 {
    2026 SCIP_Real absval;
    2027
    2028 assert(consdata->minabsval < SCIP_INVALID);
    2029
    2030 absval = MAX(REALABS(val.inf), REALABS(val.sup)); /*lint !e777 !e666*/
    2031 consdata->minabsval = MIN(consdata->minabsval, absval);
    2032 }
    2033
    2034 /* invalidate maximum absolute value, if this coefficient was the maximum */
    2035 if( consdata->validmaxabsval )
    2036 {
    2037 if( SCIPrationalIsAbsEQ(valExact, consdata->maxabsvalexact) )
    2038 {
    2039 consdata->validmaxabsval = FALSE;
    2040 SCIPrationalSetInfinity(consdata->maxabsvalexact);
    2041 }
    2042 }
    2043
    2044 /* invalidate minimum absolute value, if this coefficient was the minimum */
    2045 if( consdata->validminabsval )
    2046 {
    2047 if( SCIPrationalIsAbsEQ(valExact, consdata->minabsvalexact) )
    2048 {
    2049 consdata->validminabsval = FALSE;
    2050 SCIPrationalSetInfinity(consdata->minabsvalexact);
    2051 }
    2052 }
    2053
    2054 /* update minimal and maximal activity */
    2055 if( consdata->validactivities )
    2056 {
    2057 assert(consdata->minactivity < SCIP_INVALID);
    2058 assert(consdata->maxactivity < SCIP_INVALID);
    2059 assert(consdata->glbminactivity < SCIP_INVALID);
    2060 assert(consdata->glbmaxactivity < SCIP_INVALID);
    2061
    2062 consdataUpdateActivitiesLb(scip, consdata, var, 0.0, SCIPvarGetLbLocal(var), val);
    2063 consdataUpdateActivitiesUb(scip, consdata, var, 0.0, SCIPvarGetUbLocal(var), val);
    2064 consdataUpdateActivitiesGlbLb(scip, consdata, 0.0, SCIPvarGetLbGlobal(var), val);
    2065 consdataUpdateActivitiesGlbUb(scip, consdata, 0.0, SCIPvarGetUbGlobal(var), val);
    2066 }
    2067}
    2068
    2069/** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
    2070static
    2072 SCIP* scip, /**< SCIP data structure */
    2073 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2074 SCIP_VAR* var, /**< variable of constraint entry */
    2075 SCIP_RATIONAL* valExact, /**< exact coefficient of constraint entry */
    2076 SCIP_INTERVAL val /**< coefficient of constraint entry */
    2077 )
    2078{
    2079 assert(scip != NULL);
    2080 assert(consdata != NULL);
    2081 assert(var != NULL);
    2082
    2083 /* invalidate maximum absolute value, if this coefficient was the maximum */
    2084 if( consdata->validmaxabsval )
    2085 {
    2086 SCIP_Real absval;
    2087
    2088 absval = SCIPintervalAbsMax(val);
    2089
    2090 if( SCIPisEQ(scip, absval, consdata->maxabsval) )
    2091 {
    2092 consdata->validmaxabsval = FALSE;
    2093 consdata->maxabsval = SCIP_INVALID;
    2094 }
    2095 }
    2096
    2097 /* invalidate minimum absolute value, if this coefficient was the minimum */
    2098 if( consdata->validminabsval )
    2099 {
    2100 SCIP_Real absval;
    2101
    2102 absval = SCIPintervalAbsMax(val);
    2103
    2104 if( SCIPisEQ(scip, absval, consdata->minabsval) )
    2105 {
    2106 consdata->validminabsval = FALSE;
    2107 consdata->minabsval = SCIP_INVALID;
    2108 }
    2109 }
    2110
    2111 /* invalidate maximum absolute value, if this coefficient was the maximum */
    2112 if( consdata->validmaxabsval )
    2113 {
    2114 if( SCIPrationalIsAbsEQ(valExact, consdata->maxabsvalexact) )
    2115 {
    2116 consdata->validmaxabsval = FALSE;
    2117 SCIPrationalSetInfinity(consdata->maxabsvalexact);
    2118 }
    2119 }
    2120
    2121 /* invalidate minimum absolute value, if this coefficient was the minimum */
    2122 if( consdata->validminabsval )
    2123 {
    2124 if( SCIPrationalIsAbsEQ(valExact, consdata->minabsvalexact) )
    2125 {
    2126 consdata->validminabsval = FALSE;
    2127 SCIPrationalSetInfinity(consdata->minabsvalexact);
    2128 }
    2129 }
    2130
    2131 /* update minimal and maximal activity */
    2132 if( consdata->validactivities )
    2133 {
    2134 assert(consdata->minactivity < SCIP_INVALID);
    2135 assert(consdata->maxactivity < SCIP_INVALID);
    2136 assert(consdata->glbminactivity < SCIP_INVALID);
    2137 assert(consdata->glbmaxactivity < SCIP_INVALID);
    2138
    2139 consdataUpdateActivitiesLb(scip, consdata, var, SCIPvarGetLbLocal(var), 0.0, val);
    2140 consdataUpdateActivitiesUb(scip, consdata, var, SCIPvarGetUbLocal(var), 0.0, val);
    2141 consdataUpdateActivitiesGlbLb(scip, consdata, SCIPvarGetLbGlobal(var), 0.0, val);
    2142 consdataUpdateActivitiesGlbUb(scip, consdata, SCIPvarGetUbGlobal(var), 0.0, val);
    2143 }
    2144}
    2145
    2146/** returns the minimum absolute value of all coefficients in the constraint */
    2147static
    2149 SCIP* scip, /**< SCIP data structure */
    2150 SCIP_CONSDATA* consdata /**< linear constraint data */
    2151 )
    2152{
    2153 assert(scip != NULL);
    2154 assert(consdata != NULL);
    2155
    2156 if( !consdata->validminabsval )
    2157 consdataCalcMinAbsvalEx(consdata);
    2158 assert(consdata->validminabsval);
    2159
    2160 return consdata->minabsvalexact;
    2161}
    2162
    2163
    2164/** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
    2165static
    2167 SCIP* scip, /**< SCIP data structure */
    2168 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2169 SCIP_VAR* var, /**< variable of constraint entry */
    2170 SCIP_INTERVAL oldval, /**< old coefficient of constraint entry */
    2171 SCIP_RATIONAL* oldvalExact, /**< old exact coefficient of constraint entry */
    2172 SCIP_INTERVAL newval, /**< new coefficient of constraint entry */
    2173 SCIP_RATIONAL* newvalExact /**< new coefficient of constraint entry */
    2174 )
    2175{
    2176 assert(scip != NULL);
    2177 assert(consdata != NULL);
    2178 assert(var != NULL);
    2179
    2180 /* update maximum absolute value */
    2181 if( consdata->validmaxabsval )
    2182 {
    2183 SCIP_Real absval;
    2184
    2185 absval = SCIPintervalAbsMax(newval);
    2186
    2187 if( absval >= consdata->maxabsval )
    2188 {
    2189 consdata->maxabsval = absval;
    2190 }
    2191 else
    2192 {
    2193 absval = SCIPintervalAbsMax(oldval);
    2194
    2195 /* invalidate maximum absolute value */
    2196 if( SCIPisEQ(scip, absval, consdata->maxabsval) )
    2197 {
    2198 consdata->validmaxabsval = FALSE;
    2199 consdata->maxabsval = SCIP_INVALID;
    2200 }
    2201 }
    2202 }
    2203
    2204 /* update minimum absolute value */
    2205 if( consdata->validminabsval )
    2206 {
    2207 SCIP_Real absval;
    2208
    2209 absval = SCIPintervalAbsMax(newval);
    2210
    2211 if( absval <= consdata->minabsval )
    2212 {
    2213 consdata->minabsval = absval;
    2214 }
    2215 else
    2216 {
    2217 absval = SCIPintervalAbsMax(oldval);
    2218
    2219 /* invalidate minimum absolute value */
    2220 if( SCIPisEQ(scip, absval, consdata->minabsval) )
    2221 {
    2222 consdata->validminabsval = FALSE;
    2223 consdata->minabsval = SCIP_INVALID;
    2224 }
    2225 }
    2226 }
    2227 /* update maximum absolute value */
    2228 if( consdata->validmaxabsval )
    2229 {
    2230 if( SCIPrationalIsAbsGT(newvalExact, consdata->maxabsvalexact) )
    2231 {
    2232 SCIPrationalAbs(consdata->maxabsvalexact, newvalExact);
    2233 }
    2234 else
    2235 {
    2236 /* invalidate maximum absolute value */
    2237 if( SCIPrationalIsAbsEQ(oldvalExact, consdata->maxabsvalexact) )
    2238 {
    2239 consdata->validmaxabsval = FALSE;
    2240 SCIPrationalSetInfinity(consdata->maxabsvalexact);
    2241 }
    2242 }
    2243 }
    2244 /* update minimum absolute value */
    2245 if( consdata->validminabsval )
    2246 {
    2247 if( SCIPrationalIsAbsGT(consdata->minabsvalexact, newvalExact) )
    2248 {
    2249 SCIPrationalAbs(consdata->minabsvalexact, newvalExact);
    2250 }
    2251 else
    2252 {
    2253 /* invalidate minimum absolute value */
    2254 if( SCIPrationalIsAbsEQ(oldvalExact, consdata->minabsvalexact) )
    2255 {
    2256 consdata->validminabsval = FALSE;
    2257 SCIPrationalSetInfinity(consdata->minabsvalexact);
    2258 }
    2259 }
    2260 }
    2261
    2262 /* update maximum activity delta */
    2263 if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
    2264 {
    2265 SCIP_Real domain;
    2266 SCIP_Real delta;
    2267
    2268 assert(!SCIPisInfinity(scip, SCIPvarGetLbLocal(var)));
    2269 assert(!SCIPisInfinity(scip, SCIPvarGetUbLocal(var)));
    2270
    2271 domain = SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var);
    2272 delta = SCIPintervalAbsMax(newval) * domain;
    2273
    2274 if( delta > consdata->maxactdelta )
    2275 {
    2276 consdata->maxactdelta = delta;
    2277 consdata->maxactdeltavar = var;
    2278 }
    2279 else
    2280 {
    2281 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
    2282 if( consdata->maxactdeltavar == var )
    2283 consdata->maxactdelta = SCIP_INVALID;
    2284 }
    2285 }
    2286
    2287 /* @todo as in cons_linear, do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
    2288 consdataUpdateDelCoef(scip, consdata, var, oldvalExact, oldval);
    2289 consdataUpdateAddCoef(scip, consdata, var, newvalExact, newval);
    2290}
    2291
    2292/** ensures that every nonzero is a least minval so that we don't get problem with SCIPs 0 in floating point representation */
    2293static
    2295 SCIP* scip, /**< SCIP data structure */
    2296 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2297 SCIP_Real minval /**< minmimal value for coefficients in constraint */
    2298 )
    2299{
    2300 int i;
    2301 SCIP_RATIONAL* scalingfactor;
    2302 SCIP_RATIONAL* minabsval;
    2303
    2304 assert(scip != NULL);
    2305 assert(consdata != NULL);
    2306
    2307 minabsval = consdataGetMinAbsvalEx(scip, consdata);
    2308
    2309 assert(!SCIPrationalIsZero(minabsval) || consdata->nvars == 0);
    2310
    2311 (void) SCIPrationalCreateBuffer(SCIPbuffer(scip), &scalingfactor);
    2312
    2313 if( SCIPrationalIsLTReal(minabsval, minval) )
    2314 {
    2315 SCIPrationalSetReal(scalingfactor, minval);
    2316 SCIPrationalDiv(scalingfactor, scalingfactor, minabsval);
    2317
    2318 for( i = 0; i < consdata->nvars; i++ )
    2319 {
    2320 SCIPrationalMult(consdata->vals[i], consdata->vals[i], scalingfactor);
    2321 SCIPintervalSetRational(&(consdata->valsreal[i]), consdata->vals[i]);
    2322 }
    2323
    2324 SCIPrationalMult(consdata->rhs, consdata->rhs, scalingfactor);
    2325 consdata->rhsreal = SCIPrationalRoundReal(consdata->rhs, SCIP_R_ROUND_UPWARDS);
    2326
    2327 SCIPrationalMult(consdata->lhs, consdata->lhs, scalingfactor);
    2328 consdata->lhsreal = SCIPrationalRoundReal(consdata->lhs, SCIP_R_ROUND_DOWNWARDS);
    2329 }
    2330
    2332
    2333 SCIPrationalFreeBuffer(SCIPbuffer(scip), &scalingfactor);
    2334}
    2335
    2336/** calculates minimum and maximum local and global activity for constraint from scratch;
    2337 * additionally recalculates maximum absolute value of coefficients
    2338 */
    2339static
    2341 SCIP* scip, /**< SCIP data structure */
    2342 SCIP_CONSDATA* consdata /**< linear constraint data */
    2343 )
    2344{
    2345 int i;
    2346 assert(scip != NULL);
    2347 assert(consdata != NULL);
    2348 assert(!consdata->validactivities);
    2349 assert(consdata->minactivity >= SCIP_INVALID || consdata->validminact);
    2350 assert(consdata->maxactivity >= SCIP_INVALID || consdata->validmaxact);
    2351 assert(consdata->glbminactivity >= SCIP_INVALID || consdata->validglbminact);
    2352 assert(consdata->glbmaxactivity >= SCIP_INVALID || consdata->validglbmaxact);
    2353
    2354 consdata->validmaxabsval = TRUE;
    2355 consdata->validminabsval = TRUE;
    2356 consdata->validactivities = TRUE;
    2357 consdata->validminact = TRUE;
    2358 consdata->validmaxact = TRUE;
    2359 consdata->validglbminact = TRUE;
    2360 consdata->validglbmaxact = TRUE;
    2361 consdata->maxabsval = 0.0;
    2362 consdata->minabsval = (consdata->nvars == 0 ? 0.0 : SCIPintervalAbsMax(consdata->valsreal[0]));
    2363 consdata->minactivity = 0.0;
    2364 consdata->maxactivity = 0.0;
    2365 consdata->lastminactivity = 0.0;
    2366 consdata->lastmaxactivity = 0.0;
    2367 consdata->minactivityneginf = 0;
    2368 consdata->minactivityposinf = 0;
    2369 consdata->maxactivityneginf = 0;
    2370 consdata->maxactivityposinf = 0;
    2371 consdata->minactivityneghuge = 0;
    2372 consdata->minactivityposhuge = 0;
    2373 consdata->maxactivityneghuge = 0;
    2374 consdata->maxactivityposhuge = 0;
    2375 consdata->glbminactivity = 0.0;
    2376 consdata->glbmaxactivity = 0.0;
    2377 consdata->lastglbminactivity = 0.0;
    2378 consdata->lastglbmaxactivity = 0.0;
    2379 consdata->glbminactivityneginf = 0;
    2380 consdata->glbminactivityposinf = 0;
    2381 consdata->glbmaxactivityneginf = 0;
    2382 consdata->glbmaxactivityposinf = 0;
    2383 consdata->glbminactivityneghuge = 0;
    2384 consdata->glbminactivityposhuge = 0;
    2385 consdata->glbmaxactivityneghuge = 0;
    2386 consdata->glbmaxactivityposhuge = 0;
    2387
    2388 for( i = 0; i < consdata->nvars; ++i )
    2389 consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], consdata->valsreal[i]);
    2390 consdata->lastminactivity = consdata->minactivity;
    2391 consdata->lastmaxactivity = consdata->maxactivity;
    2392 consdata->lastglbminactivity = consdata->glbminactivity;
    2393 consdata->lastglbmaxactivity = consdata->glbmaxactivity;
    2394}
    2395
    2396/** computes the activity of a row for a given solution plus a bound on the floating-point error using running error analysis */
    2397static
    2399 SCIP* scip, /**< SCIP data structure */
    2400 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2401 SCIP_SOL* sol, /**< primal CIP solution */
    2402 SCIP_Real* activity, /**< buffer to return floating-point activity */
    2403 SCIP_Real* errorbound /**< buffer to return bound on absolute floating-point error */
    2404 )
    2405{
    2406 SCIP_Real solval;
    2407 SCIP_Real sum;
    2408 SCIP_Real mu;
    2409 SCIP_Real inf;
    2410 SCIP_Bool success;
    2411 int v;
    2412
    2413 assert(activity != NULL);
    2414 assert(errorbound != NULL);
    2415
    2416 inf = SCIPinfinity(scip);
    2417 *activity = SCIP_UNKNOWN;
    2418 *errorbound = inf;
    2419
    2420 sum = 0.0;
    2421 mu = 0.0;
    2422 /* normally we want to use the row since all fixed/aggregated variables do not appear there */
    2423 if( consdata->rowlhs == NULL )
    2424 {
    2425 for( v = 0; v < consdata->nvars; ++v )
    2426 {
    2427 if( SCIPvarGetStatus(consdata->vars[v]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(consdata->vars[v]) == SCIP_VARSTATUS_LOOSE )
    2428 solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
    2429 else
    2430 return FALSE;
    2431
    2432 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
    2433 return FALSE;
    2434
    2435 sum += consdata->valsreal[v].inf * solval;
    2436 mu += REALABS(sum);
    2437 /* the factor 3 + eps is needed to account for rounding errors in valsreal[v]/solval */
    2438 mu += (3.0 + SCIP_REAL_UNITROUNDOFF) * REALABS(consdata->valsreal[v].inf * solval);
    2439 }
    2440 }
    2441 else
    2442 {
    2443 success = SCIPgetRowSolActivityWithErrorboundExact(scip, consdata->rowexact, sol, &sum, &mu);
    2444
    2445 if( !success )
    2446 return FALSE;
    2447 }
    2448
    2449 sum = MAX(sum, -inf);
    2450 sum = MIN(sum, +inf);
    2451 *activity = sum;
    2452
    2453 if( SCIPisInfinity(scip, sum) || SCIPisInfinity(scip, -sum) )
    2454 *errorbound = inf;
    2455 else
    2456 *errorbound = mu * 1.1 * SCIP_REAL_UNITROUNDOFF;
    2457
    2458 return TRUE;
    2459}
    2460
    2461/** gets minimal activity for constraint and given values of counters for infinite and huge contributions
    2462 * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
    2463 */
    2464static
    2466 SCIP* scip, /**< SCIP data structure */
    2467 SCIP_CONSDATA* consdata, /**< linear constraint */
    2468 int posinf, /**< number of coefficients contributing pos. infinite value */
    2469 int neginf, /**< number of coefficients contributing neg. infinite value */
    2470 int poshuge, /**< number of coefficients contributing huge pos. value */
    2471 int neghuge, /**< number of coefficients contributing huge neg. value */
    2472 SCIP_Real delta, /**< value to subtract from stored minactivity
    2473 * (contribution of the variable set to zero when getting residual activity) */
    2474 SCIP_Bool global, /**< should the global or local minimal activity be returned? */
    2475 SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
    2476 SCIP_Real* minactivity, /**< pointer to store the minimal activity */
    2477 SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
    2478 * i.e. is <= the exact minactivity (in case of huge contributing values) */
    2479 SCIP_Bool* issettoinfinity /**< pointer to store whether minactivity was set to infinity or calculated */
    2480 )
    2481{
    2482 assert(scip != NULL);
    2483 assert(consdata != NULL);
    2484 assert(posinf >= 0);
    2485 assert(neginf >= 0);
    2486 assert(poshuge >= 0);
    2487 assert(neghuge >= 0);
    2488 assert(minactivity != NULL);
    2489 assert(isrelax != NULL);
    2490 assert(issettoinfinity != NULL);
    2491
    2492 /* if we have pos. infinite contributions, the minactivity is +infty */
    2493 if( posinf > 0 )
    2494 {
    2495 *minactivity = SCIPinfinity(scip);
    2496 *issettoinfinity = TRUE;
    2497 *isrelax = FALSE;
    2498 }
    2499 /* if we have neg. (and no pos.) infinite contributions, the minactivity is -infty */
    2500 else if( neginf > 0 )
    2501 {
    2502 *minactivity = -SCIPinfinity(scip);
    2503 *issettoinfinity = TRUE;
    2504 *isrelax = FALSE;
    2505 }
    2506 /* if we have neg. huge contributions, we only know that -infty is a relaxation of the minactivity */
    2507 else if( neghuge > 0 )
    2508 {
    2509 *minactivity = -SCIPinfinity(scip);
    2510 *issettoinfinity = TRUE;
    2511 *isrelax = TRUE;
    2512 }
    2513 /* we do not need a good relaxation and we have positive huge contributions, so we just return -infty as activity */
    2514 else if( !goodrelax && poshuge > 0 )
    2515 {
    2516 *minactivity = -SCIPinfinity(scip);
    2517 *issettoinfinity = TRUE;
    2518 *isrelax = TRUE;
    2519 }
    2520 else
    2521 {
    2522 SCIP_Real tmpactivity;
    2523
    2524 /* recompute minactivity if it is not valid */
    2525 if( global )
    2526 {
    2527 if( !consdata->validglbminact )
    2529 assert(consdata->validglbminact);
    2530
    2531 tmpactivity = consdata->glbminactivity;
    2532 }
    2533 else
    2534 {
    2535 if( !consdata->validminact )
    2537 assert(consdata->validminact);
    2538
    2539 tmpactivity = consdata->minactivity;
    2540 }
    2541
    2542 /* we have no infinite and no neg. huge contributions, but pos. huge contributions;
    2543 * a feasible relaxation of the minactivity is the number of positive huge contributions
    2544 * times the minimum value counting as "huge" plus finite (and non-huge) part of minactivity - delta
    2545 */
    2546 if( poshuge > 0 )
    2547 {
    2548 *minactivity = 1.0 * poshuge * SCIPgetHugeValue(scip) + (tmpactivity - delta);
    2549 *issettoinfinity = FALSE;
    2550 *isrelax = TRUE;
    2551 }
    2552 /* all counters are zero, so the minactivity is just stored and we subtract the delta */
    2553 else
    2554 {
    2555 *minactivity = tmpactivity - delta;
    2556 *issettoinfinity = FALSE;
    2557 *isrelax = FALSE;
    2558 }
    2559 }
    2560}
    2561
    2562/** gets maximal activity for constraint and given values of counters for infinite and huge contributions
    2563 * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
    2564 */
    2565static
    2567 SCIP* scip, /**< SCIP data structure */
    2568 SCIP_CONSDATA* consdata, /**< linear constraint */
    2569 int posinf, /**< number of coefficients contributing pos. infinite value */
    2570 int neginf, /**< number of coefficients contributing neg. infinite value */
    2571 int poshuge, /**< number of coefficients contributing huge pos. value */
    2572 int neghuge, /**< number of coefficients contributing huge neg. value */
    2573 SCIP_Real delta, /**< value to subtract from stored maxactivity
    2574 * (contribution of the variable set to zero when getting residual activity) */
    2575 SCIP_Bool global, /**< should the global or local maximal activity be returned? */
    2576 SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
    2577 SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
    2578 SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
    2579 * i.e. is >= the exact maxactivity (in case of huge contributing values) */
    2580 SCIP_Bool* issettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
    2581 )
    2582{
    2583 assert(scip != NULL);
    2584 assert(consdata != NULL);
    2585 assert(posinf >= 0);
    2586 assert(neginf >= 0);
    2587 assert(poshuge >= 0);
    2588 assert(neghuge >= 0);
    2589 assert(maxactivity != NULL);
    2590 assert(isrelax != NULL);
    2591 assert(issettoinfinity != NULL);
    2592
    2593 /* if we have neg. infinite contributions, the maxactivity is -infty */
    2594 if( neginf > 0 )
    2595 {
    2596 *maxactivity = -SCIPinfinity(scip);
    2597 *issettoinfinity = TRUE;
    2598 *isrelax = FALSE;
    2599 }
    2600 /* if we have pos. (and no neg.) infinite contributions, the maxactivity is +infty */
    2601 else if( posinf > 0 )
    2602 {
    2603 *maxactivity = SCIPinfinity(scip);
    2604 *issettoinfinity = TRUE;
    2605 *isrelax = FALSE;
    2606 }
    2607 /* if we have pos. huge contributions, we only know that +infty is a relaxation of the maxactivity */
    2608 else if( poshuge > 0 )
    2609 {
    2610 *maxactivity = SCIPinfinity(scip);
    2611 *issettoinfinity = TRUE;
    2612 *isrelax = TRUE;
    2613 }
    2614 /* we do not need a good relaxation and we have positve huge contributions, so we just return +infty as activity */
    2615 else if( !goodrelax && neghuge > 0 )
    2616 {
    2617 *maxactivity = SCIPinfinity(scip);
    2618 *issettoinfinity = TRUE;
    2619 *isrelax = TRUE;
    2620 }
    2621 else
    2622 {
    2623 SCIP_Real tmpactivity;
    2624
    2625 /* recompute maxactivity if it is not valid */
    2626 if( global )
    2627 {
    2628 if( !consdata->validglbmaxact )
    2630 assert(consdata->validglbmaxact);
    2631
    2632 tmpactivity = consdata->glbmaxactivity;
    2633 }
    2634 else
    2635 {
    2636 if( !consdata->validmaxact )
    2638 assert(consdata->validmaxact);
    2639
    2640 tmpactivity = consdata->maxactivity;
    2641 }
    2642
    2643 /* we have no infinite, and no pos. huge contributions, but neg. huge contributions;
    2644 * a feasible relaxation of the maxactivity is minus the number of negative huge contributions
    2645 * times the minimum value counting as "huge" plus the finite (and non-huge) part of maxactivity minus delta
    2646 */
    2647 if( neghuge > 0 )
    2648 {
    2649 *maxactivity = -1.0 * neghuge * SCIPgetHugeValue(scip) + tmpactivity - delta;
    2650 *issettoinfinity = FALSE;
    2651 *isrelax = TRUE;
    2652 }
    2653 /* all counters are zero, so the maxactivity is just stored and we subtract the delta */
    2654 else
    2655 {
    2656 *maxactivity = tmpactivity - delta;
    2657 *issettoinfinity = FALSE;
    2658 *isrelax = FALSE;
    2659 }
    2660 }
    2661}
    2662
    2663/** gets activity bounds for constraint */
    2664static
    2666 SCIP* scip, /**< SCIP data structure */
    2667 SCIP_CONSDATA* consdata, /**< linear constraint */
    2668 SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
    2669 * relaxed activities ignored, anyway? */
    2670 SCIP_Real* minactivity, /**< pointer to store the minimal activity */
    2671 SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
    2672 SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
    2673 * i.e. <= the exact minactivity (in case of huge contributions),
    2674 * or equal to the exact minimal activity */
    2675 SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
    2676 * i.e. >= the exact maxactivity (in case of huge contributions),
    2677 * or equal to the exact maximal activity */
    2678 SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minactivity was set to infinity or calculated */
    2679 SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
    2680
    2681 )
    2682{
    2683 assert(scip != NULL);
    2684 assert(consdata != NULL);
    2685 assert(minactivity != NULL);
    2686 assert(maxactivity != NULL);
    2687 assert(isminsettoinfinity != NULL);
    2688 assert(ismaxsettoinfinity != NULL);
    2689
    2690 if( !consdata->validactivities )
    2691 {
    2692 consdataCalcActivities(scip, consdata);
    2693 assert(consdata->validminact);
    2694 assert(consdata->validmaxact);
    2695 }
    2696 assert(consdata->minactivity < SCIP_INVALID);
    2697 assert(consdata->maxactivity < SCIP_INVALID);
    2698 assert(consdata->minactivityneginf >= 0);
    2699 assert(consdata->minactivityposinf >= 0);
    2700 assert(consdata->maxactivityneginf >= 0);
    2701 assert(consdata->maxactivityposinf >= 0);
    2702
    2703 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2704 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2705 minactivity, minisrelax, isminsettoinfinity);
    2706
    2707 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2708 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2709 maxactivity, maxisrelax, ismaxsettoinfinity);
    2710}
    2711
    2712/** gets activity bounds for constraint after setting variable to zero */
    2713static
    2715 SCIP* scip, /**< SCIP data structure */
    2716 SCIP_CONSDATA* consdata, /**< linear constraint */
    2717 SCIP_VAR* var, /**< variable to calculate activity residual for */
    2718 SCIP_INTERVAL val, /**< coefficient value of variable in linear constraint */
    2719 SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
    2720 * relaxed acticities ignored, anyway? */
    2721 SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity */
    2722 SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity */
    2723 SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
    2724 * relaxation, i.e. <= the exact residual minactivity (in case of huge
    2725 * contributions), or equal to the exact residual minactivity */
    2726 SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
    2727 * relaxation, i.e. <= the exact residual maxactivity (in case of huge
    2728 * contributions), or equal to the exact residual minactivity */
    2729 SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
    2730 SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
    2731 )
    2732{
    2733 SCIP_Real minactbound;
    2734 SCIP_Real maxactbound;
    2735 SCIP_Real absval;
    2736 SCIP_ROUNDMODE prevmode;
    2737 prevmode = SCIPintervalGetRoundingMode();
    2738
    2739 assert(scip != NULL);
    2740 assert(consdata != NULL);
    2741 assert(var != NULL);
    2742 assert(minresactivity != NULL);
    2743 assert(maxresactivity != NULL);
    2744 assert(minisrelax != NULL);
    2745 assert(maxisrelax != NULL);
    2746 assert(isminsettoinfinity != NULL);
    2747 assert(ismaxsettoinfinity != NULL);
    2748
    2749 /* get activity bounds of linear constraint */
    2750 if( !consdata->validactivities )
    2751 {
    2752 consdataCalcActivities(scip, consdata);
    2753 assert(consdata->validminact);
    2754 assert(consdata->validmaxact);
    2755 }
    2756 assert(consdata->minactivity < SCIP_INVALID);
    2757 assert(consdata->maxactivity < SCIP_INVALID);
    2758 assert(consdata->minactivityneginf >= 0);
    2759 assert(consdata->minactivityposinf >= 0);
    2760 assert(consdata->maxactivityneginf >= 0);
    2761 assert(consdata->maxactivityposinf >= 0);
    2762 assert(consdata->minactivityneghuge >= 0);
    2763 assert(consdata->minactivityposhuge >= 0);
    2764 assert(consdata->maxactivityneghuge >= 0);
    2765 assert(consdata->maxactivityposhuge >= 0);
    2766
    2767 if( val.sup < 0.0 )
    2768 {
    2769 assert(val.inf <= 0.0);
    2770
    2771 minactbound = -SCIPvarGetUbLocal(var);
    2772 maxactbound = -SCIPvarGetLbLocal(var);
    2773 absval = -val.inf;
    2774 }
    2775 else
    2776 {
    2777 assert(val.inf >= 0.0);
    2778
    2779 minactbound = SCIPvarGetLbLocal(var);
    2780 maxactbound = SCIPvarGetUbLocal(var);
    2781 absval = val.sup;
    2782 }
    2783
    2784 /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
    2785 * and contribution of variable set to zero that has to be subtracted from finite part of activity
    2786 */
    2787 if( SCIPisInfinity(scip, minactbound) )
    2788 {
    2789 assert(consdata->minactivityposinf >= 1);
    2790
    2791 getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
    2792 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2793 minresactivity, minisrelax, isminsettoinfinity);
    2794 }
    2795 else if( SCIPisInfinity(scip, -minactbound) )
    2796 {
    2797 assert(consdata->minactivityneginf >= 1);
    2798
    2799 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
    2800 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2801 minresactivity, minisrelax, isminsettoinfinity);
    2802 }
    2803 else if( SCIPisHugeValue(scip, minactbound * absval) )
    2804 {
    2805 assert(consdata->minactivityposhuge >= 1);
    2806
    2807 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2808 consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2809 minresactivity, minisrelax, isminsettoinfinity);
    2810 }
    2811 else if( SCIPisHugeValue(scip, -minactbound * absval) )
    2812 {
    2813 assert(consdata->minactivityneghuge >= 1);
    2814
    2815 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2816 consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
    2817 minresactivity, minisrelax, isminsettoinfinity);
    2818 }
    2819 else
    2820 {
    2821 SCIP_Real delta;
    2822 delta = absval * minactbound;
    2825 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2826 consdata->minactivityposhuge, consdata->minactivityneghuge, delta, FALSE, goodrelax,
    2827 minresactivity, minisrelax, isminsettoinfinity);
    2828 }
    2829
    2830 /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
    2831 * and contribution of variable set to zero that has to be subtracted from finite part of activity
    2832 */
    2833 if( SCIPisInfinity(scip, -maxactbound) )
    2834 {
    2835 assert(consdata->maxactivityneginf >= 1);
    2836
    2837 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
    2838 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2839 maxresactivity, maxisrelax, ismaxsettoinfinity);
    2840 }
    2841 else if( SCIPisInfinity(scip, maxactbound) )
    2842 {
    2843 assert(consdata->maxactivityposinf >= 1);
    2844
    2845 getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
    2846 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2847 maxresactivity, maxisrelax, ismaxsettoinfinity);
    2848 }
    2849 else if( SCIPisHugeValue(scip, absval * maxactbound) )
    2850 {
    2851 assert(consdata->maxactivityposhuge >= 1);
    2852
    2853 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2854 consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2855 maxresactivity, maxisrelax, ismaxsettoinfinity);
    2856 }
    2857 else if( SCIPisHugeValue(scip, -absval * maxactbound) )
    2858 {
    2859 assert(consdata->maxactivityneghuge >= 1);
    2860
    2861 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2862 consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
    2863 maxresactivity, maxisrelax, ismaxsettoinfinity);
    2864 }
    2865 else
    2866 {
    2867 SCIP_Real delta;
    2868 delta = absval * maxactbound;
    2871 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2872 consdata->maxactivityposhuge, consdata->maxactivityneghuge, delta, FALSE, goodrelax,
    2873 maxresactivity, maxisrelax, ismaxsettoinfinity);
    2874 }
    2876}
    2877
    2878/** calculates the activity of the linear constraint for given solution */
    2879static
    2881 SCIP* scip, /**< SCIP data structure */
    2882 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2883 SCIP_SOL* sol, /**< solution to get activity for, NULL to current solution */
    2884 SCIP_Bool useexact, /**< should the exact solution be used */
    2885 SCIP_RATIONAL* activity /**< pointer to store the activity */
    2886 )
    2887{
    2888 assert(scip != NULL);
    2889 assert(consdata != NULL);
    2890
    2891 if( (sol == NULL) && !SCIPhasCurrentNodeLP(scip) )
    2892 consdataComputePseudoActivity(consdata, activity);
    2893 else
    2894 {
    2895 SCIP_RATIONAL* solval;
    2896 int nposinf;
    2897 int nneginf;
    2898 SCIP_Bool negsign;
    2899 int v;
    2900
    2901 (void) SCIPrationalCreateBuffer(SCIPbuffer(scip), &solval);
    2902
    2903 SCIPrationalSetFraction(activity, 0LL, 1LL);
    2904 nposinf = 0;
    2905 nneginf = 0;
    2906
    2907 for( v = 0; v < consdata->nvars; ++v )
    2908 {
    2909 if( useexact )
    2910 SCIPgetSolValExact(scip, sol, consdata->vars[v], solval);
    2911 else
    2912 SCIPrationalSetReal(solval, SCIPgetSolVal(scip, sol, consdata->vars[v]));
    2913
    2914 assert(!SCIPrationalIsZero(consdata->vals[v]));
    2915 negsign = SCIPrationalIsNegative(consdata->vals[v]);
    2916
    2917 if( (SCIPrationalIsInfinity(solval) && !negsign) || (SCIPrationalIsNegInfinity(solval) && negsign) )
    2918 ++nposinf;
    2919 else if( (SCIPrationalIsInfinity(solval) && negsign) || (SCIPrationalIsNegInfinity(solval) && !negsign) )
    2920 ++nneginf;
    2921 else
    2922 {
    2923 SCIPrationalAddProd(activity, solval, consdata->vals[v]);
    2924 }
    2925 }
    2926 assert(nneginf >= 0 && nposinf >= 0);
    2927
    2928 SCIPdebugMsg(scip, "activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", SCIPrationalGetReal(activity), nposinf, nneginf);
    2929
    2930 /* set activity to infeasible infinity for contradicting contributions */
    2931 if( nneginf > 0 && ( nposinf == 0 || !SCIPrationalIsNegInfinity(consdata->lhs) ) )
    2933 else if( nposinf > 0 && ( nneginf == 0 || !SCIPrationalIsInfinity(consdata->rhs) ) )
    2934 SCIPrationalSetInfinity(activity);
    2935
    2936 SCIPrationalDebugMessage("corrected activity of linear constraint: %q\n", activity);
    2937
    2939 }
    2940}
    2941
    2942/** calculates the feasibility of the linear constraint for given solution */
    2943static
    2945 SCIP* scip, /**< SCIP data structure */
    2946 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2947 SCIP_SOL* sol, /**< solution to get feasibility for, NULL to current solution */
    2948 SCIP_RATIONAL* ret /**< pointer to store the result */
    2949 )
    2950{
    2951 SCIP_RATIONAL* activity;
    2952 SCIP_RATIONAL* op1;
    2953 SCIP_RATIONAL* op2;
    2954
    2955 assert(scip != NULL);
    2956 assert(consdata != NULL);
    2957
    2958 (void) SCIPrationalCreateBuffer(SCIPbuffer(scip), &activity);
    2961
    2962 consdataGetActivity(scip, consdata, sol, FALSE, activity);
    2963 SCIPrationalDiff(op1, consdata->rhs, activity);
    2964 SCIPrationalDiff(op2, activity, consdata->lhs);
    2965
    2966 SCIPrationalMin(ret, op1, op2);
    2967
    2971}
    2972
    2973/** creates an LP row in a linear constraint data */
    2974static
    2976 SCIP* scip, /**< SCIP data structure */
    2977 SCIP_CONS* cons /**< linear constraint */
    2978 );
    2979
    2980/** prints the certificate for a given original exact linear constraint */
    2982 SCIP* scip, /**< SCIP data structure */
    2983 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    2984 SCIP_CONS* cons /**< constraint */
    2985 )
    2986{
    2987 SCIP_CONSDATA* consdata;
    2988 int* varsindex;
    2989 int i;
    2990
    2991 /*lint --e{715}*/
    2992 assert(scip != NULL);
    2993 assert(conshdlr != NULL);
    2994 assert(cons != NULL);
    2995
    2996 /* print constraint into certificate output */
    2997 if( SCIPisCertified(scip) )
    2998 {
    2999 consdata = SCIPconsGetData(cons);
    3000
    3001 SCIP_CALL( SCIPallocBufferArray(scip, &varsindex, consdata->nvars) );
    3002 for( i = 0; i < consdata->nvars; ++i )
    3003 varsindex[i] = SCIPvarGetCertificateIndex(consdata->vars[i]);
    3004
    3005 /* print constraint */
    3006 if( SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    3007 {
    3008 assert(!SCIPrationalIsAbsInfinity(consdata->lhs));
    3009 SCIP_CALL( SCIPcertifyCons(scip, TRUE, NULL, 'E', consdata->lhs, consdata->nvars, varsindex, consdata->vals) );
    3010 }
    3011 else
    3012 {
    3013 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
    3014 {
    3015 SCIP_CALL( SCIPcertifyCons(scip, TRUE, NULL, 'G', consdata->lhs, consdata->nvars, varsindex, consdata->vals) );
    3016 }
    3017 if( !SCIPrationalIsInfinity(consdata->rhs) )
    3018 {
    3019 SCIP_CALL( SCIPcertifyCons(scip, TRUE, NULL, 'L', consdata->rhs, consdata->nvars, varsindex, consdata->vals) );
    3020 }
    3021 }
    3022
    3023 SCIPfreeBufferArray(scip, &varsindex);
    3024 }
    3025
    3026 return SCIP_OKAY;
    3027}
    3028
    3029/** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
    3030static
    3032{ /*lint --e{715}*/
    3033 SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
    3034
    3035 assert(consdata != NULL);
    3036 assert(0 <= ind1 && ind1 < consdata->nvars);
    3037 assert(0 <= ind2 && ind2 < consdata->nvars);
    3038
    3039 return SCIPvarCompare(consdata->vars[ind1], consdata->vars[ind2]);
    3040}
    3041
    3042/** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
    3043static
    3044SCIP_DECL_SORTINDCOMP(consdataCompVarProp)
    3045{ /*lint --e{715}*/
    3046 SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
    3047 SCIP_VAR* var1;
    3048 SCIP_VAR* var2;
    3049
    3050 assert(consdata != NULL);
    3051 assert(0 <= ind1 && ind1 < consdata->nvars);
    3052 assert(0 <= ind2 && ind2 < consdata->nvars);
    3053
    3054 var1 = consdata->vars[ind1];
    3055 var2 = consdata->vars[ind2];
    3056
    3057 /* exactly one variable is binary */
    3058 if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
    3059 {
    3060 return (SCIPvarIsBinary(var1) ? -1 : +1);
    3061 }
    3062 /* both variables are binary */
    3063 else if( SCIPvarIsBinary(var1) )
    3064 {
    3065 if( SCIPrationalIsAbsEQ(consdata->vals[ind1], consdata->vals[ind2]) ) {
    3066 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
    3067 }
    3068 if( SCIPrationalIsAbsGT(consdata->vals[ind1], consdata->vals[ind2]) )
    3069 return -1;
    3070 else
    3071 return +1;
    3072 }
    3073 else
    3074 {
    3075 SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
    3076 SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
    3077
    3078 if( vartype1 < vartype2 )
    3079 {
    3080 return -1;
    3081 }
    3082 else if( vartype1 > vartype2 )
    3083 {
    3084 return +1;
    3085 }
    3086 else
    3087 {
    3088 /* both variables are continuous */
    3089 if( !SCIPvarIsIntegral(var1) )
    3090 {
    3091 assert(!SCIPvarIsIntegral(var2));
    3092 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
    3093 }
    3094 else
    3095 {
    3096 SCIP_RATIONAL* abscont1;
    3097 SCIP_RATIONAL* abscont2;
    3098
    3099 (void) SCIPrationalCreate(&abscont1);
    3100 (void) SCIPrationalCreate(&abscont2);
    3101
    3103 SCIPrationalMult(abscont1, consdata->vals[ind1], abscont1);
    3104
    3106 SCIPrationalMult(abscont2, consdata->vals[ind2], abscont2);
    3107
    3108 if( SCIPrationalIsAbsEQ(abscont1, abscont2) ) {
    3109 SCIPrationalFree(&abscont1);
    3110 SCIPrationalFree(&abscont2);
    3111 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
    3112 }
    3113 if( SCIPrationalIsAbsGT(abscont2, abscont1) )
    3114 {
    3115 SCIPrationalFree(&abscont1);
    3116 SCIPrationalFree(&abscont2);
    3117 return 1;
    3118 }
    3119 else
    3120 {
    3121 SCIPrationalFree(&abscont1);
    3122 SCIPrationalFree(&abscont2);
    3123 return -1;
    3124 }
    3125 }
    3126 }
    3127 }
    3128}
    3129
    3130/** permutes the constraint's variables according to a given permutation. */
    3131static
    3133 SCIP_CONSDATA* consdata, /**< the constraint data */
    3134 int* perm, /**< the target permutation */
    3135 int nvars /**< the number of variables */
    3136 )
    3137{ /*lint --e{715}*/
    3138 SCIP_VAR* varv;
    3139 SCIP_EVENTDATA* eventdatav;
    3140 SCIP_INTERVAL valrealv;
    3141 SCIP_RATIONAL* valv;
    3142 int v;
    3143 int i;
    3144 int nexti;
    3145
    3146 assert(perm != NULL);
    3147 assert(consdata != NULL);
    3148
    3149 /* permute the variables in the linear constraint according to the target permutation */
    3150 eventdatav = NULL;
    3151 for( v = 0; v < nvars; ++v )
    3152 {
    3153 if( perm[v] != v )
    3154 {
    3155 varv = consdata->vars[v];
    3156 valv = consdata->vals[v];
    3157 valrealv = consdata->valsreal[v];
    3158 if( consdata->eventdata != NULL )
    3159 eventdatav = consdata->eventdata[v];
    3160 i = v;
    3161 do
    3162 {
    3163 assert(0 <= perm[i] && perm[i] < nvars);
    3164 assert(perm[i] != i);
    3165 consdata->vars[i] = consdata->vars[perm[i]];
    3166 consdata->vals[i] = consdata->vals[perm[i]];
    3167 consdata->valsreal[i] = consdata->valsreal[perm[i]];
    3168 if( consdata->eventdata != NULL )
    3169 {
    3170 consdata->eventdata[i] = consdata->eventdata[perm[i]];
    3171 consdata->eventdata[i]->varpos = i;
    3172 }
    3173 nexti = perm[i];
    3174 perm[i] = i;
    3175 i = nexti;
    3176 }
    3177 while( perm[i] != v );
    3178 consdata->vars[i] = varv;
    3179 consdata->vals[i] = valv;
    3180 consdata->valsreal[i] = valrealv;
    3181 if( consdata->eventdata != NULL )
    3182 {
    3183 consdata->eventdata[i] = eventdatav;
    3184 consdata->eventdata[i]->varpos = i;
    3185 }
    3186 perm[i] = i;
    3187 }
    3188 }
    3189#ifdef SCIP_DEBUG
    3190 /* check sorting */
    3191 for( v = 0; v < nvars; ++v )
    3192 {
    3193 assert(perm[v] == v);
    3194 assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
    3195 }
    3196#endif
    3197}
    3198
    3199/** sorts linear constraint's variables depending on the stage of the solving process:
    3200 * - during PRESOLVING
    3201 * sorts variables by binary, integer, implied integral, and continuous variables,
    3202 * and the variables of the same type by non-decreasing variable index
    3203 *
    3204 * - during SOLVING
    3205 * sorts variables of the remaining problem by binary, integer, implied integral, and continuous variables,
    3206 * and binary and integer variables by their global max activity delta (within each group),
    3207 * ties within a group are broken by problem index of the variable.
    3208 *
    3209 * This fastens the propagation time of the constraint handler.
    3210 */
    3211static
    3213 SCIP* scip, /**< SCIP data structure */
    3214 SCIP_CONSDATA* consdata /**< linear constraint data */
    3215 )
    3216{
    3217 assert(scip != NULL);
    3218 assert(consdata != NULL);
    3219
    3220 /* check if there are variables for sorting */
    3221 if( consdata->nvars <= 1 )
    3222 {
    3223 consdata->indexsorted = TRUE;
    3224 consdata->coefsorted = TRUE;
    3225 consdata->nbinvars = (consdata->nvars == 1 ? (int)SCIPvarIsBinary(consdata->vars[0]) : 0);
    3226 }
    3227 else if( (!consdata->indexsorted && SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE)
    3228 || (!consdata->coefsorted && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE) )
    3229 {
    3230 int* perm;
    3231 int v;
    3232
    3233 /* get temporary memory to store the sorted permutation */
    3234 SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
    3235
    3236 /* call sorting method */
    3238 SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
    3239 else
    3240 SCIPsort(perm, consdataCompVarProp, (void*)consdata, consdata->nvars);
    3241
    3242 permSortConsdata(consdata, perm, consdata->nvars);
    3243
    3244 /* free temporary memory */
    3245 SCIPfreeBufferArray(scip, &perm);
    3246
    3248 {
    3249 consdata->indexsorted = FALSE;
    3250 consdata->coefsorted = TRUE;
    3251
    3252 /* count binary variables in the sorted vars array */
    3253 consdata->nbinvars = 0;
    3254 for( v = 0; v < consdata->nvars; ++v )
    3255 {
    3256 if( SCIPvarIsBinary(consdata->vars[v]) )
    3257 ++consdata->nbinvars;
    3258 else
    3259 break;
    3260 }
    3261 }
    3262 else
    3263 {
    3264 consdata->indexsorted = TRUE;
    3265 consdata->coefsorted = FALSE;
    3266 }
    3267 }
    3268
    3269 return SCIP_OKAY;
    3270}
    3271
    3272
    3273/*
    3274 * local linear constraint handler methods
    3275 */
    3276
    3277/** sets left hand side of linear constraint */
    3278static
    3280 SCIP* scip, /**< SCIP data structure */
    3281 SCIP_CONS* cons, /**< linear constraint */
    3282 SCIP_RATIONAL* lhs /**< new left hand side */
    3283 )
    3284{
    3285 SCIP_CONSDATA* consdata;
    3286 SCIP_Bool locked;
    3287 int i;
    3288
    3289 assert(scip != NULL);
    3290 assert(cons != NULL);
    3291 assert(!SCIPrationalIsInfinity(lhs));
    3292
    3293 consdata = SCIPconsGetData(cons);
    3294 assert(consdata != NULL);
    3295 assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
    3296 assert(!SCIPrationalIsInfinity(consdata->lhs));
    3297
    3298 /* check whether the side is not changed */
    3299 if( SCIPrationalIsEQ(consdata->lhs, lhs) )
    3300 return SCIP_OKAY;
    3301
    3302 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
    3303 if( SCIPrationalIsEQ(lhs, consdata->rhs) )
    3304 {
    3305 SCIPrationalSetRational(consdata->rhs, lhs);
    3306 assert(consdata->rowlhs == NULL);
    3307 }
    3308
    3309 locked = FALSE;
    3310 for( i = 0; i < NLOCKTYPES && !locked; i++ )
    3311 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
    3312
    3313 /* if necessary, update the rounding locks of variables */
    3314 if( locked )
    3315 {
    3316 if( SCIPrationalIsNegInfinity(consdata->lhs) && !SCIPrationalIsNegInfinity(lhs) )
    3317 {
    3318 SCIP_VAR** vars;
    3319 SCIP_RATIONAL** vals;
    3320 int v;
    3321
    3322 /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
    3323 vars = consdata->vars;
    3324 vals = consdata->vals;
    3325
    3326 for( v = 0; v < consdata->nvars; ++v )
    3327 {
    3328 assert(vars[v] != NULL);
    3329 assert(!SCIPrationalIsZero(vals[v]));
    3330
    3331 if( SCIPrationalIsPositive(vals[v]) )
    3332 {
    3333 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3334 }
    3335 else
    3336 {
    3337 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3338 }
    3339 }
    3340 }
    3341 else if( !SCIPrationalIsNegInfinity(consdata->lhs) && SCIPrationalIsNegInfinity(lhs) )
    3342 {
    3343 SCIP_VAR** vars;
    3344 SCIP_RATIONAL** vals;
    3345 int v;
    3346
    3347 /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
    3348 vars = consdata->vars;
    3349 vals = consdata->vals;
    3350
    3351 for( v = 0; v < consdata->nvars; ++v )
    3352 {
    3353 assert(vars[v] != NULL);
    3354 assert(!SCIPrationalIsZero(vals[v]));
    3355
    3356 if( SCIPrationalIsPositive(vals[v]) )
    3357 {
    3358 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3359 }
    3360 else
    3361 {
    3362 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3363 }
    3364 }
    3365 }
    3366 }
    3367
    3368 /* check whether the left hand side is increased, if and only if that's the case we maybe can propagate, tighten and add more cliques */
    3369 if( !SCIPrationalIsNegInfinity(lhs) && SCIPrationalIsGT(lhs, consdata->lhs) )
    3370 {
    3371 consdata->boundstightened = 0;
    3372 consdata->presolved = FALSE;
    3373 consdata->cliquesadded = FALSE;
    3374 consdata->implsadded = FALSE;
    3375
    3376 /* mark the constraint for propagation */
    3377 if( SCIPconsIsTransformed(cons) )
    3378 {
    3380 }
    3381 }
    3382
    3383 /* set new left hand side and update constraint data */
    3384 SCIPrationalSetRational(consdata->lhs, lhs);
    3385 consdata->lhsreal = SCIPrationalRoundReal(lhs, SCIP_R_ROUND_DOWNWARDS);
    3386 consdata->changed = TRUE;
    3387 consdata->normalized = FALSE;
    3388 consdata->rangedrowpropagated = 0;
    3389
    3390 /* update the lhs of the LP row */
    3391 if( consdata->rowexact != NULL )
    3392 {
    3393 SCIP_CALL( SCIPchgRowExactLhs(scip, consdata->rowexact, lhs) );
    3394 }
    3395
    3396 return SCIP_OKAY;
    3397}
    3398
    3399/** sets right hand side of linear constraint */
    3400static
    3402 SCIP* scip, /**< SCIP data structure */
    3403 SCIP_CONS* cons, /**< linear constraint */
    3404 SCIP_RATIONAL* rhs /**< new right hand side */
    3405 )
    3406{
    3407 SCIP_CONSDATA* consdata;
    3408 SCIP_Bool locked;
    3409 int i;
    3410
    3411 assert(scip != NULL);
    3412 assert(cons != NULL);
    3413 assert(!SCIPrationalIsNegInfinity(rhs));
    3414
    3415 consdata = SCIPconsGetData(cons);
    3416 assert(consdata != NULL);
    3417 assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
    3418 assert(!SCIPrationalIsNegInfinity(consdata->rhs));
    3419
    3420 /* check whether the side is not changed */
    3421 if( SCIPrationalIsEQ(consdata->rhs, rhs) )
    3422 return SCIP_OKAY;
    3423
    3424 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
    3425 if( SCIPrationalIsEQ(rhs, consdata->lhs) )
    3426 {
    3427 SCIPrationalSetRational(consdata->rhs, rhs);
    3428 assert(consdata->rowlhs == NULL);
    3429 }
    3430
    3431 locked = FALSE;
    3432 for( i = 0; i < NLOCKTYPES && !locked; i++ )
    3433 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
    3434
    3435 /* if necessary, update the rounding locks of variables */
    3436 if( locked )
    3437 {
    3438 assert(SCIPconsIsTransformed(cons));
    3439
    3440 if( SCIPrationalIsInfinity(consdata->rhs) && !SCIPrationalIsInfinity(rhs) )
    3441 {
    3442 SCIP_VAR** vars;
    3443 SCIP_RATIONAL** vals;
    3444 int v;
    3445
    3446 /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
    3447 vars = consdata->vars;
    3448 vals = consdata->vals;
    3449
    3450 for( v = 0; v < consdata->nvars; ++v )
    3451 {
    3452 assert(vars[v] != NULL);
    3453 assert(!SCIPrationalIsZero(vals[v]));
    3454
    3455 if( SCIPrationalIsPositive(vals[v]) )
    3456 {
    3457 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3458 }
    3459 else
    3460 {
    3461 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3462 }
    3463 }
    3464 }
    3465 else if( !SCIPrationalIsInfinity(consdata->rhs) && SCIPrationalIsInfinity(rhs) )
    3466 {
    3467 SCIP_VAR** vars;
    3468 SCIP_RATIONAL** vals;
    3469 int v;
    3470
    3471 /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
    3472 vars = consdata->vars;
    3473 vals = consdata->vals;
    3474
    3475 for( v = 0; v < consdata->nvars; ++v )
    3476 {
    3477 assert(vars[v] != NULL);
    3478 assert(!SCIPrationalIsZero(vals[v]));
    3479
    3480 if( SCIPrationalIsPositive(vals[v]) )
    3481 {
    3482 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3483 }
    3484 else
    3485 {
    3486 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3487 }
    3488 }
    3489 }
    3490 }
    3491
    3492 /* check whether the right hand side is decreased, if and only if that's the case we maybe can propagate, tighten and add more cliques */
    3493 if( !SCIPrationalIsInfinity(rhs) && SCIPrationalIsLT(rhs, consdata->rhs) )
    3494 {
    3495 consdata->boundstightened = 0;
    3496 consdata->presolved = FALSE;
    3497 consdata->cliquesadded = FALSE;
    3498 consdata->implsadded = FALSE;
    3499
    3500 /* mark the constraint for propagation */
    3501 if( SCIPconsIsTransformed(cons) )
    3502 {
    3504 }
    3505 }
    3506
    3507 /* set new right hand side and update constraint data */
    3508 SCIPrationalSetRational(consdata->rhs, rhs);
    3509 consdata->rhsreal = SCIPrationalRoundReal(rhs, SCIP_R_ROUND_UPWARDS);
    3510 consdata->changed = TRUE;
    3511 consdata->normalized = FALSE;
    3512 consdata->rangedrowpropagated = 0;
    3513
    3514 /* update the rhs of the LP row */
    3515 if( consdata->rowexact != NULL )
    3516 {
    3517 SCIP_CALL( SCIPchgRowExactRhs(scip, consdata->rowexact, rhs) );
    3518 }
    3519
    3520 return SCIP_OKAY;
    3521}
    3522
    3523/** adds coefficient in linear constraint */
    3524static
    3526 SCIP* scip, /**< SCIP data structure */
    3527 SCIP_CONS* cons, /**< linear constraint */
    3528 SCIP_VAR* var, /**< variable of constraint entry */
    3529 SCIP_RATIONAL* val /**< coefficient of constraint entry */
    3530 )
    3531{
    3532 SCIP_CONSDATA* consdata;
    3533 SCIP_Bool transformed;
    3534
    3535 assert(scip != NULL);
    3536 assert(cons != NULL);
    3537 assert(var != NULL);
    3538
    3539 /* ignore coefficient if it is nearly zero */
    3540 if( SCIPrationalIsZero(val) )
    3541 return SCIP_OKAY;
    3542
    3543 consdata = SCIPconsGetData(cons);
    3544 assert(consdata != NULL);
    3545
    3546 /* are we in the transformed problem? */
    3547 transformed = SCIPconsIsTransformed(cons);
    3548
    3549 /* always use transformed variables in transformed constraints */
    3550 if( transformed )
    3551 {
    3552 SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
    3553 }
    3554 assert(var != NULL);
    3555 assert(transformed == SCIPvarIsTransformed(var));
    3556
    3557 SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
    3558 consdata->vars[consdata->nvars] = var;
    3559 SCIPrationalSetRational(consdata->vals[consdata->nvars], val);
    3560 SCIPintervalSetRational(&(consdata->valsreal[consdata->nvars]), val);
    3561 consdata->nvars++;
    3562
    3563 /* capture variable */
    3564 SCIP_CALL( SCIPcaptureVar(scip, var) );
    3565
    3566 /* if we are in transformed problem, the variable needs an additional event data */
    3567 if( transformed )
    3568 {
    3569 if( consdata->eventdata != NULL )
    3570 {
    3571 SCIP_CONSHDLR* conshdlr;
    3572 SCIP_CONSHDLRDATA* conshdlrdata;
    3573
    3574 /* check for event handler */
    3575 conshdlr = SCIPconsGetHdlr(cons);
    3576 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3577 assert(conshdlrdata != NULL);
    3578 assert(conshdlrdata->eventhdlr != NULL);
    3579
    3580 /* initialize eventdata array */
    3581 consdata->eventdata[consdata->nvars-1] = NULL;
    3582
    3583 /* catch bound change events of variable */
    3584 SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
    3585 }
    3586
    3587 /* update minimum and maximum activities */
    3588 consdataUpdateAddCoef(scip, consdata, var, consdata->vals[consdata->nvars - 1], consdata->valsreal[consdata->nvars - 1]);
    3589 }
    3590
    3591 /* install rounding locks for new variable */
    3592 SCIP_CALL( lockRounding(scip, cons, var, val) );
    3593
    3594 /* mark the constraint for propagation */
    3595 if( transformed )
    3596 {
    3598 }
    3599
    3600 consdata->boundstightened = 0;
    3601 consdata->presolved = FALSE;
    3602 consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
    3603
    3604 consdata->changed = TRUE;
    3605 consdata->normalized = FALSE;
    3606 consdata->cliquesadded = FALSE;
    3607 consdata->implsadded = FALSE;
    3608 consdata->rangedrowpropagated = 0;
    3609
    3610 if( consdata->nvars == 1 )
    3611 {
    3612 consdata->indexsorted = TRUE;
    3613 consdata->coefsorted = TRUE;
    3614 consdata->merged = TRUE;
    3615 }
    3616 else
    3617 {
    3618 consdata->merged = FALSE;
    3619
    3621 {
    3622 consdata->indexsorted = consdata->indexsorted && (consdataCompVar((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
    3623 consdata->coefsorted = FALSE;
    3624 }
    3625 else
    3626 {
    3627 consdata->indexsorted = FALSE;
    3628 consdata->coefsorted = consdata->coefsorted && (consdataCompVarProp((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
    3629 }
    3630 }
    3631
    3632 /* update hascontvar and hasnonbinvar flags */
    3633 if( consdata->hasnonbinvalid && !consdata->hascontvar )
    3634 {
    3635 SCIP_VARTYPE vartype = SCIPvarGetType(var);
    3636
    3637 if( vartype != SCIP_VARTYPE_BINARY )
    3638 {
    3639 consdata->hasnonbinvar = TRUE;
    3640
    3641 if( vartype == SCIP_VARTYPE_CONTINUOUS )
    3642 consdata->hascontvar = TRUE;
    3643 }
    3644 }
    3645
    3646 /* add the new coefficient to the LP row */
    3647 if( consdata->rowexact != NULL )
    3648 {
    3649 SCIP_CALL( SCIPaddVarsToRowExact(scip, consdata->rowexact, 1, &var, &val) );
    3650 }
    3651
    3652 return SCIP_OKAY;
    3653}
    3654
    3655/** deletes coefficient at given position from linear constraint data */
    3656static
    3658 SCIP* scip, /**< SCIP data structure */
    3659 SCIP_CONS* cons, /**< linear constraint */
    3660 int pos /**< position of coefficient to delete */
    3661 )
    3662{
    3663 SCIP_CONSDATA* consdata;
    3664 SCIP_VAR* var;
    3665 SCIP_RATIONAL* val;
    3666
    3667 assert(scip != NULL);
    3668 assert(cons != NULL);
    3669
    3670 consdata = SCIPconsGetData(cons);
    3671 assert(consdata != NULL);
    3672 assert(0 <= pos && pos < consdata->nvars);
    3673
    3674 var = consdata->vars[pos];
    3675 val = consdata->vals[pos];
    3676 assert(var != NULL);
    3677
    3678 /* remove rounding locks for deleted variable */
    3679 SCIP_CALL( unlockRounding(scip, cons, var, val) );
    3680
    3681 /* if we are in transformed problem, delete the event data of the variable */
    3682 if( SCIPconsIsTransformed(cons) )
    3683 {
    3684 SCIP_CONSHDLR* conshdlr;
    3685 SCIP_CONSHDLRDATA* conshdlrdata;
    3686
    3687 /* check for event handler */
    3688 conshdlr = SCIPconsGetHdlr(cons);
    3689 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3690 assert(conshdlrdata != NULL);
    3691 assert(conshdlrdata->eventhdlr != NULL);
    3692
    3693 /* drop bound change events of variable */
    3694 if( consdata->eventdata != NULL )
    3695 {
    3696 SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
    3697 assert(consdata->eventdata[pos] == NULL);
    3698 }
    3699 }
    3700
    3701 /* move the last variable to the free slot */
    3702 if( pos != consdata->nvars - 1 )
    3703 {
    3704 consdata->vars[pos] = consdata->vars[consdata->nvars-1];
    3705 SCIPrationalSetRational(consdata->vals[pos], consdata->vals[consdata->nvars - 1]);
    3706 consdata->valsreal[pos] = consdata->valsreal[consdata->nvars -1];
    3707
    3708 if( consdata->eventdata != NULL )
    3709 {
    3710 consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
    3711 assert(consdata->eventdata[pos] != NULL);
    3712 consdata->eventdata[pos]->varpos = pos;
    3713 }
    3714
    3715 consdata->indexsorted = consdata->indexsorted && (pos + 2 >= consdata->nvars);
    3716 consdata->coefsorted = consdata->coefsorted && (pos + 2 >= consdata->nvars);
    3717 }
    3718 consdata->nvars--;
    3719
    3720 /* mark the constraint for propagation */
    3721 if( SCIPconsIsTransformed(cons) )
    3722 {
    3724 }
    3725
    3726 consdata->boundstightened = 0;
    3727 consdata->presolved = FALSE;
    3728 consdata->changed = TRUE;
    3729 consdata->normalized = FALSE;
    3730 consdata->cliquesadded = FALSE;
    3731 consdata->implsadded = FALSE;
    3732 consdata->rangedrowpropagated = 0;
    3733
    3734 /* check if hasnonbinvar flag might be incorrect now */
    3735 if( consdata->hasnonbinvar && SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
    3736 {
    3737 consdata->hasnonbinvalid = FALSE;
    3738 }
    3739
    3740 /* release variable */
    3741 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    3742
    3743 return SCIP_OKAY;
    3744}
    3745
    3746/** changes coefficient value at given position of linear constraint data */
    3747static
    3749 SCIP* scip, /**< SCIP data structure */
    3750 SCIP_CONS* cons, /**< linear constraint */
    3751 int pos, /**< position of coefficient to delete */
    3752 SCIP_RATIONAL* newval /**< new value of coefficient */
    3753 )
    3754{
    3755 SCIP_CONSDATA* consdata;
    3756 SCIP_VAR* var;
    3757 SCIP_RATIONAL* val;
    3758 SCIP_Bool locked;
    3759 SCIP_INTERVAL newvalfp;
    3760 int i;
    3761
    3762 assert(scip != NULL);
    3763 assert(cons != NULL);
    3764 assert(!SCIPrationalIsZero(newval));
    3765
    3766 consdata = SCIPconsGetData(cons);
    3767 assert(consdata != NULL);
    3768 assert(0 <= pos && pos < consdata->nvars);
    3769
    3770 var = consdata->vars[pos];
    3771 val = consdata->vals[pos];
    3772 assert(var != NULL);
    3773 assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
    3774
    3775 locked = FALSE;
    3776 for( i = 0; i < NLOCKTYPES && !locked; i++ )
    3777 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
    3778
    3779 /* if necessary, update the rounding locks of the variable */
    3780 if( locked && ((SCIPrationalIsNegative(newval) && SCIPrationalIsPositive(val)) || (SCIPrationalIsNegative(val) && SCIPrationalIsPositive(newval))) )
    3781 {
    3782 assert(SCIPconsIsTransformed(cons));
    3783
    3784 /* remove rounding locks for variable with old coefficient */
    3785 SCIP_CALL( unlockRounding(scip, cons, var, val) );
    3786
    3787 /* install rounding locks for variable with new coefficient */
    3788 SCIP_CALL( lockRounding(scip, cons, var, newval) );
    3789 }
    3790 SCIPintervalSetRational(&newvalfp, newval);
    3791 /* update minimum and maximum activities */
    3792 if( SCIPconsIsTransformed(cons) )
    3793 consdataUpdateChgCoef(scip, consdata, var, consdata->valsreal[pos], val, newvalfp, newval);
    3794
    3795 /* change the value */
    3796 SCIPrationalSetRational(consdata->vals[pos], newval);
    3797 consdata->valsreal[pos] = newvalfp;
    3798 if( consdata->coefsorted )
    3799 {
    3800 if( pos > 0 )
    3801 consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos - 1, pos) <= 0);
    3802 if( consdata->coefsorted && pos < consdata->nvars - 1 )
    3803 consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos, pos + 1) <= 0);
    3804 }
    3805 /* mark the constraint for propagation */
    3806 if( SCIPconsIsTransformed(cons) )
    3807 {
    3809 }
    3810
    3811 consdata->boundstightened = 0;
    3812 consdata->presolved = FALSE;
    3813 consdata->changed = TRUE;
    3814 consdata->normalized = FALSE;
    3815 consdata->cliquesadded = FALSE;
    3816 consdata->implsadded = FALSE;
    3817 consdata->rangedrowpropagated = 0;
    3818
    3819 return SCIP_OKAY;
    3820}
    3821
    3822/* perform deletion of variables in all constraints of the constraint handler */
    3823static
    3825 SCIP* scip, /**< SCIP data structure */
    3826 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    3827 SCIP_CONS** conss, /**< array of constraints */
    3828 int nconss /**< number of constraints */
    3829 )
    3830{
    3831 SCIP_CONSDATA* consdata;
    3832 int i;
    3833 int v;
    3834
    3835 assert(scip != NULL);
    3836 assert(conshdlr != NULL);
    3837 assert(conss != NULL);
    3838 assert(nconss >= 0);
    3839 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    3840
    3841 /* iterate over all constraints */
    3842 for( i = 0; i < nconss; i++ )
    3843 {
    3844 consdata = SCIPconsGetData(conss[i]);
    3845
    3846 /* constraint is marked, that some of its variables were deleted */
    3847 if( consdata->varsdeleted )
    3848 {
    3849 /* iterate over all variables of the constraint and delete them from the constraint */
    3850 for( v = consdata->nvars - 1; v >= 0; --v )
    3851 {
    3852 if( SCIPvarIsDeleted(consdata->vars[v]) )
    3853 {
    3854 SCIP_CALL( delCoefPos(scip, conss[i], v) );
    3855 }
    3856 }
    3857 consdata->varsdeleted = FALSE;
    3858 }
    3859 }
    3860
    3861 return SCIP_OKAY;
    3862}
    3863
    3864/** replaces multiple occurrences of a variable by a single coefficient */
    3865static
    3867 SCIP* scip, /**< SCIP data structure */
    3868 SCIP_CONS* cons /**< linear constraint */
    3869 )
    3870{
    3871 SCIP_CONSDATA* consdata;
    3872 SCIP_VAR* var;
    3873 SCIP_RATIONAL* valsum;
    3874 int v;
    3875
    3876 assert(scip != NULL);
    3877 assert(cons != NULL);
    3878
    3879 consdata = SCIPconsGetData(cons);
    3880 assert(consdata != NULL);
    3881
    3882 if( consdata->merged )
    3883 return SCIP_OKAY;
    3884
    3886
    3887 /* sort the constraint */
    3888 SCIP_CALL( consdataSort(scip, consdata) );
    3889
    3890 /* go backwards through the constraint looking for multiple occurrences of the same variable;
    3891 * backward direction is necessary, since delCoefPos() modifies the given position and
    3892 * the subsequent ones
    3893 */
    3894 v = consdata->nvars-1;
    3895 while( v >= 1 )
    3896 {
    3897 var = consdata->vars[v];
    3898 if( consdata->vars[v-1] == var )
    3899 {
    3900 SCIPrationalSetRational(valsum, consdata->vals[v]);
    3901 do
    3902 {
    3903 SCIP_CALL( delCoefPos(scip, cons, v) );
    3904 --v;
    3905 SCIPrationalAdd(valsum, valsum, consdata->vals[v]);
    3906 }
    3907 while( v >= 1 && consdata->vars[v-1] == var );
    3908
    3909 /* modify the last existing occurrence of the variable */
    3910 assert(consdata->vars[v] == var);
    3911 if( SCIPrationalIsZero(valsum) )
    3912 {
    3913 SCIP_CALL( delCoefPos(scip, cons, v) );
    3914
    3915 /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
    3916 * delta needs to be recalculated on the next real propagation
    3917 */
    3918 if( consdata->maxactdeltavar == var )
    3919 {
    3920 consdata->maxactdelta = SCIP_INVALID;
    3921 consdata->maxactdeltavar = NULL;
    3922 }
    3923 }
    3924 else
    3925 {
    3926 SCIP_CALL( chgCoefPos(scip, cons, v, valsum) );
    3927 }
    3928 }
    3929 --v;
    3930 }
    3931
    3933 consdata->merged = TRUE;
    3934
    3935 return SCIP_OKAY;
    3936}
    3937
    3938/** replaces all fixed and aggregated variables by their non-fixed counterparts */
    3939static
    3941 SCIP* scip, /**< SCIP data structure */
    3942 SCIP_CONS* cons, /**< linear constraint */
    3943 SCIP_Bool* infeasible /**< pointer to store if infeasibility is detected; or NULL if this
    3944 * information is not needed; in this case, we apply all fixings
    3945 * instead of stopping after the first infeasible one */
    3946 )
    3947{
    3948 SCIP_CONSDATA* consdata;
    3949 SCIP_VAR* var;
    3950 SCIP_VAR** aggrvars;
    3951 SCIP_RATIONAL* val;
    3952 SCIP_RATIONAL** aggrscalars;
    3953 SCIP_RATIONAL* fixedval;
    3954 SCIP_RATIONAL* aggrconst;
    3955 SCIP_Real negconst;
    3956 int v;
    3957 int naggrvars;
    3958 int i;
    3959
    3960 assert(scip != NULL);
    3961 assert(cons != NULL);
    3962
    3963 if( infeasible != NULL )
    3964 *infeasible = FALSE;
    3965
    3966 consdata = SCIPconsGetData(cons);
    3967 assert(consdata != NULL);
    3968
    3969 if( consdata->eventdata == NULL )
    3970 {
    3971 SCIP_CONSHDLR* conshdlr;
    3972 SCIP_CONSHDLRDATA* conshdlrdata;
    3973
    3974 conshdlr = SCIPconsGetHdlr(cons);
    3975 assert(conshdlr != NULL);
    3976
    3977 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3978 assert(conshdlrdata != NULL);
    3979
    3980 /* catch bound change events of variables */
    3981 SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    3982 assert(consdata->eventdata != NULL);
    3983 }
    3984
    3985 if( !consdata->removedfixings )
    3986 {
    3987 SCIP_RATIONAL* lhssubtrahend;
    3988 SCIP_RATIONAL* rhssubtrahend;
    3989 SCIP_RATIONAL* tmpval;
    3990
    3994
    3995 SCIPdebugMsg(scip, "applying fixings:\n");
    3997
    3998 v = 0;
    3999 while( v < consdata->nvars )
    4000 {
    4001 var = consdata->vars[v];
    4002 val = consdata->vals[v];
    4003 assert(SCIPvarIsTransformed(var));
    4004
    4005 switch( SCIPvarGetStatus(var) )
    4006 {
    4008 SCIPerrorMessage("original variable in transformed linear constraint\n");
    4009 return SCIP_INVALIDDATA;
    4010
    4013 ++v;
    4014 break;
    4015
    4018 fixedval = SCIPvarGetLbGlobalExact(var);
    4019 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
    4020 {
    4021 if( SCIPrationalIsAbsInfinity(fixedval) )
    4022 {
    4023 if( SCIPrationalGetSign(val) == SCIPrationalGetSign(fixedval) )
    4024 {
    4026 SCIP_CALL( chgLhs(scip, cons, tmpval) );
    4027 }
    4028 else
    4029 {
    4030 if( infeasible != NULL )
    4031 {
    4032 /* if lhs gets infinity it means that the problem is infeasible */
    4033 *infeasible = TRUE;
    4034 return SCIP_OKAY;
    4035 }
    4036 else
    4037 {
    4039 SCIP_CALL( chgLhs(scip, cons, tmpval) );
    4040 }
    4041 }
    4042 }
    4043 else
    4044 SCIPrationalAddProd(lhssubtrahend, val, fixedval);
    4045 }
    4046 if( !SCIPrationalIsInfinity(consdata->rhs) )
    4047 {
    4048 if( SCIPrationalIsAbsInfinity(fixedval) )
    4049 {
    4050 if( SCIPrationalGetSign(val) == SCIPrationalGetSign(fixedval) )
    4051 {
    4052 if( infeasible != NULL )
    4053 {
    4054 /* if rhs gets -infinity it means that the problem is infeasible */
    4055 *infeasible = TRUE;
    4056 return SCIP_OKAY;
    4057 }
    4058 else
    4059 {
    4061 SCIP_CALL( chgRhs(scip, cons, tmpval) );
    4062 }
    4063 }
    4064 else
    4065 {
    4067 SCIP_CALL( chgRhs(scip, cons, tmpval) );
    4068 }
    4069 }
    4070 else
    4071 SCIPrationalAddProd(rhssubtrahend, val, fixedval);
    4072 }
    4073 SCIP_CALL( delCoefPos(scip, cons, v) );
    4074 break;
    4075
    4077 {
    4078 SCIP_VAR* activevar = SCIPvarGetAggrVar(var);
    4079 SCIP_RATIONAL* activescalar;
    4080 SCIP_RATIONAL* activeconstant;
    4081
    4083 SCIP_CALL( SCIPrationalCreateBuffer(SCIPbuffer(scip), &activeconstant) );
    4084
    4085 SCIPrationalMult(activescalar, val, SCIPvarGetAggrScalarExact(var));
    4086 SCIPrationalMult(activeconstant, val, SCIPvarGetAggrConstantExact(var));
    4087
    4088 assert(activevar != NULL);
    4089 SCIP_CALL( SCIPgetProbvarSumExact(scip, &activevar, activescalar, activeconstant) );
    4090 assert(activevar != NULL);
    4091
    4092 if( !SCIPrationalIsZero(activescalar) )
    4093 {
    4094 SCIP_CALL( addCoef(scip, cons, activevar, activescalar) );
    4095 }
    4096
    4097 if( !SCIPrationalIsZero(activeconstant) )
    4098 {
    4099 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
    4100 SCIPrationalAdd(lhssubtrahend, lhssubtrahend, activeconstant);
    4101 if( !SCIPrationalIsInfinity(consdata->rhs) )
    4102 SCIPrationalAdd(rhssubtrahend, rhssubtrahend, activeconstant);
    4103 }
    4104
    4105 SCIP_CALL( delCoefPos(scip, cons, v) );
    4106
    4107 SCIPrationalFreeBuffer(SCIPbuffer(scip), &activescalar);
    4108 SCIPrationalFreeBuffer(SCIPbuffer(scip), &activeconstant);
    4109 break;
    4110 }
    4113 naggrvars = SCIPvarGetMultaggrNVars(var);
    4114 aggrvars = SCIPvarGetMultaggrVars(var);
    4115 aggrscalars = SCIPvarGetMultaggrScalarsExact(var);
    4116 for( i = 0; i < naggrvars; ++i )
    4117 {
    4118 SCIPrationalMult(tmpval, val, aggrscalars[i]);
    4119 SCIP_CALL( addCoef(scip, cons, aggrvars[i], tmpval) );
    4120 }
    4121 aggrconst = SCIPvarGetMultaggrConstantExact(var);
    4122
    4123 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
    4124 {
    4125 SCIPrationalMult(tmpval, val, aggrconst);
    4126 SCIPrationalAdd(lhssubtrahend, lhssubtrahend, tmpval);
    4127 }
    4128 if( !SCIPrationalIsInfinity(consdata->rhs) )
    4129 {
    4130 SCIPrationalMult(tmpval, val, aggrconst);
    4131 SCIPrationalAdd(rhssubtrahend, rhssubtrahend, tmpval);
    4132 }
    4133
    4134 SCIP_CALL( delCoefPos(scip, cons, v) );
    4135 break;
    4136
    4138 SCIPrationalNegate(tmpval, val);
    4139 SCIP_CALL( addCoef(scip, cons, SCIPvarGetNegationVar(var), tmpval) );
    4140 negconst = SCIPvarGetNegationConstant(var);
    4141
    4142 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
    4143 {
    4144 SCIPrationalMultReal(tmpval, val, negconst);
    4145 SCIPrationalAdd(lhssubtrahend, lhssubtrahend, tmpval);
    4146 }
    4147 if( !SCIPrationalIsInfinity(consdata->rhs) )
    4148 {
    4149 SCIPrationalMultReal(tmpval, val, negconst);
    4150 SCIPrationalAdd(rhssubtrahend, rhssubtrahend, tmpval);
    4151 }
    4152
    4153 SCIP_CALL( delCoefPos(scip, cons, v) );
    4154 break;
    4155
    4156 default:
    4157 SCIPerrorMessage("unknown variable status\n");
    4158 SCIPABORT();
    4159 return SCIP_INVALIDDATA; /*lint !e527*/
    4160 }
    4161 }
    4162
    4163 if( !SCIPrationalIsAbsInfinity(consdata->lhs) )
    4164 {
    4165 SCIPrationalDiff(tmpval, consdata->lhs, lhssubtrahend);
    4166 SCIP_CALL( chgLhs(scip, cons, tmpval) );
    4167 }
    4168 if( !SCIPrationalIsAbsInfinity(consdata->rhs) )
    4169 {
    4170 SCIPrationalDiff(tmpval, consdata->rhs, rhssubtrahend);
    4171 SCIP_CALL( chgRhs(scip, cons, tmpval) );
    4172 }
    4173
    4174 consdata->removedfixings = TRUE;
    4175
    4176 SCIPdebugMsg(scip, "after fixings:\n");
    4178
    4179 /* if aggregated variables have been replaced, multiple entries of the same variable are possible and we have
    4180 * to clean up the constraint
    4181 */
    4182 SCIP_CALL( mergeMultiples(scip, cons) );
    4183
    4184 SCIPdebugMsg(scip, "after merging:\n");
    4186
    4188 SCIPrationalFreeBuffer(SCIPbuffer(scip), &rhssubtrahend);
    4189 SCIPrationalFreeBuffer(SCIPbuffer(scip), &lhssubtrahend);
    4190 }
    4191 assert(consdata->removedfixings);
    4192
    4193#ifndef NDEBUG
    4194 /* check, if all fixings are applied */
    4195 for( v = 0; v < consdata->nvars; ++v )
    4196 assert(SCIPvarIsActive(consdata->vars[v]));
    4197#endif
    4198
    4199 return SCIP_OKAY;
    4200}
    4201
    4202/** prints activity conflict to certificate file */
    4203static
    4205 SCIP* scip, /**< SCIP data structure */
    4206 SCIP_CONS* cons, /**< constraint */
    4207 SCIP_CONSDATA* consdata, /**< constraint data */
    4208 SCIP_Bool rhs /**< right-hand side */
    4209 )
    4210{
    4211 SCIP_Real side;
    4212 SCIP_Real activity;
    4213 SCIP_RATIONAL* diff;
    4214 int nvals;
    4215 SCIP_RATIONAL** vals;
    4216
    4217 if( !SCIPisCertified(scip) )
    4218 return SCIP_OKAY;
    4219
    4221
    4222 if( rhs )
    4223 {
    4225 side = consdata->rhsreal;
    4226 activity = consdata->minactivity;
    4227 assert( activity > side );
    4228 }
    4229 else
    4230 {
    4232 side = consdata->lhsreal;
    4233 activity = consdata->maxactivity;
    4234 assert( activity < side );
    4235 }
    4236
    4237 if( consdata->rowexact != NULL )
    4238 {
    4239 nvals = SCIProwExactGetNNonz(consdata->rowexact);
    4240 vals = SCIProwExactGetVals(consdata->rowexact);
    4241 }
    4242 else
    4243 {
    4244 nvals = consdata->nvars;
    4245 vals = consdata->vals;
    4246 }
    4247 SCIPrationalSetReal(diff, activity);
    4248 SCIPrationalDiffReal(diff, diff, side);
    4249
    4250 SCIP_CALL( SCIPcertifyActivityConflict(scip, cons, consdata->rowexact, consdata->lhs, consdata->rhs,
    4251 nvals, vals, consdata->vars, diff, rhs) );
    4252
    4254
    4255 return SCIP_OKAY;
    4256}
    4257
    4258/** tightens bounds of a single variable due to activity bounds */
    4259static
    4261 SCIP* scip, /**< SCIP data structure */
    4262 SCIP_CONS* cons, /**< linear constraint */
    4263 int pos, /**< position of the variable in the vars array */
    4264 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    4265 int* nchgbds, /**< pointer to count the total number of tightened bounds */
    4266 SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
    4267 )
    4268{
    4269 SCIP_CONSDATA* consdata;
    4270 SCIP_VAR* var;
    4271 SCIP_INTERVAL valrange;
    4272 SCIP_Real lb;
    4273 SCIP_Real ub;
    4274 SCIP_Real minresactivity;
    4275 SCIP_Real maxresactivity;
    4276 SCIP_Real lhs;
    4277 SCIP_Real rhs;
    4278 SCIP_Bool infeasible;
    4279 SCIP_Bool tightened;
    4280 SCIP_Bool minisrelax;
    4281 SCIP_Bool maxisrelax;
    4282 SCIP_Bool isminsettoinfinity;
    4283 SCIP_Bool ismaxsettoinfinity;
    4284 SCIP_ROUNDMODE prevmode;
    4285 SCIP_RATIONAL* tmpbound;
    4286 SCIP_CONSHDLR* conshdlr;
    4287 SCIP_CONSHDLRDATA* conshdlrdata;
    4288
    4289 conshdlr = SCIPconsGetHdlr(cons);
    4290 assert(conshdlr != NULL);
    4291
    4292 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    4293 assert(conshdlrdata != NULL);
    4294
    4295 prevmode = SCIPintervalGetRoundingMode();
    4296
    4297 assert(scip != NULL);
    4298 assert(cons != NULL);
    4299 assert(cutoff != NULL);
    4300 assert(nchgbds != NULL);
    4301
    4302 /* we cannot tighten variables' bounds, if the constraint may be not complete */
    4303 if( SCIPconsIsModifiable(cons) )
    4304 goto RETURN_SCIP_OKAY;
    4305
    4306 consdata = SCIPconsGetData(cons);
    4307 assert(consdata != NULL);
    4308
    4309 *cutoff = FALSE;
    4310
    4311 var = consdata->vars[pos];
    4312
    4313 /* we cannot tighten bounds of multi-aggregated variables */
    4315 {
    4316 return SCIP_OKAY;
    4317 }
    4318 else
    4319 {
    4320 SCIP_VAR* tmpVar;
    4321 SCIP_Real tmpBound;
    4322 SCIP_BOUNDTYPE tmpBoundtype;
    4323 tmpVar = var;
    4324 SCIP_CALL( SCIPvarGetProbvarBound(&tmpVar, &tmpBound, &tmpBoundtype) );
    4326 goto RETURN_SCIP_OKAY;
    4327 }
    4328 }
    4329
    4330 if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS && !conshdlrdata->propcont )
    4331 return SCIP_OKAY;
    4332
    4333 valrange = consdata->valsreal[pos];
    4334 lhs = consdata->lhsreal;
    4335 rhs = consdata->rhsreal;
    4336 consdataGetActivityResiduals(scip, consdata, var, valrange, FALSE, &minresactivity, &maxresactivity,
    4337 &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
    4338 assert(var != NULL);
    4339 assert(!SCIPisInfinity(scip, lhs));
    4340 assert(!SCIPisInfinity(scip, -rhs));
    4341
    4342 lb = SCIPvarGetLbLocal(var);
    4343 ub = SCIPvarGetUbLocal(var);
    4344 assert(SCIPisLE(scip, lb, ub));
    4345
    4346 if( valrange.sup > 0.0 )
    4347 {
    4348 /* check, if we can tighten the variable's bounds */
    4349 if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
    4350 {
    4351 SCIP_Real newub;
    4352 SCIP_INTERVAL ubinterval;
    4353
    4355
    4356 /* newub = (rhs + SCIPintervalNegateReal(minresactivity))/valrange.inf; */
    4357 SCIPintervalSet(&ubinterval, rhs);
    4358 SCIPintervalSubScalar(SCIPinfinity(scip), &ubinterval, ubinterval, minresactivity);
    4359 SCIPintervalDiv(SCIPinfinity(scip), &ubinterval, ubinterval, valrange);
    4360 newub = ubinterval.sup;
    4361
    4362 if( !SCIPisInfinity(scip, newub) &&
    4363 ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
    4364 {
    4365 /* activity is never unreliable in exact solving */
    4366
    4367 /* tighten upper bound */
    4368 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
    4369 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, valrange.inf, minresactivity, maxresactivity, lhs, rhs, newub);
    4370
    4372 {
    4373 SCIP_Longint boundmaxdenom;
    4374
    4376 SCIPrationalSetReal(tmpbound, newub);
    4377
    4378 if( conshdlrdata->limitdenom )
    4379 {
    4380 boundmaxdenom = conshdlrdata->boundmaxdenom;
    4381 SCIPrationalComputeApproximation(tmpbound, tmpbound, boundmaxdenom, 1);
    4382 }
    4383
    4386 SCIP_BOUNDTYPE_UPPER, tmpbound, false, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
    4387
    4389 &infeasible, &tightened) );
    4391 }
    4392 else
    4393 {
    4396 SCIP_BOUNDTYPE_UPPER, newub, false, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
    4397
    4398 newub = SCIPadjustedVarUbExactFloat(scip, var, newub);
    4399 SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_RHS, pos), force,
    4400 &infeasible, &tightened) );
    4401 }
    4402
    4403 if( infeasible )
    4404 {
    4405 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    4406 SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
    4407
    4408 /* analyze conflict */
    4411 *cutoff = TRUE;
    4412 goto RETURN_SCIP_OKAY;
    4413 }
    4414 if( tightened )
    4415 {
    4416 ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
    4417 (*nchgbds)++;
    4418
    4419 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
    4420 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
    4421 }
    4422 }
    4423 }
    4424
    4425 if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
    4426 {
    4427 SCIP_Real newlb;
    4428 SCIP_INTERVAL lbinterval;
    4429
    4431 /* newlb = (lhs + SCIPintervalNegateReal(maxresactivity))/valrange.sup; */
    4432 SCIPintervalSet(&lbinterval, lhs);
    4433 SCIPintervalSubScalar(SCIPinfinity(scip), &lbinterval, lbinterval, maxresactivity);
    4434 SCIPintervalDiv(SCIPinfinity(scip), &lbinterval, lbinterval, valrange);
    4435 newlb = lbinterval.inf;
    4436
    4437 if( !SCIPisInfinity(scip, -newlb) &&
    4438 ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
    4439 {
    4440 /* tighten lower bound */
    4441 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
    4442 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, valrange.inf, minresactivity, maxresactivity, lhs, rhs, newlb);
    4443
    4445 {
    4446 SCIP_Longint boundmaxdenom;
    4447
    4449 SCIPrationalSetReal(tmpbound, newlb);
    4450
    4451 if( conshdlrdata->limitdenom )
    4452 {
    4453 boundmaxdenom = conshdlrdata->boundmaxdenom;
    4454 SCIPrationalComputeApproximation(tmpbound, tmpbound, boundmaxdenom, -1);
    4455 }
    4458 SCIP_BOUNDTYPE_LOWER, tmpbound, true, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
    4459
    4461 &infeasible, &tightened) );
    4463 }
    4464 else
    4465 {
    4468 SCIP_BOUNDTYPE_LOWER, newlb, true, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
    4469
    4470 newlb = SCIPadjustedVarLbExactFloat(scip, var, newlb);
    4471 SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_LHS, pos), force,
    4472 &infeasible, &tightened) );
    4473 }
    4474
    4475 if( infeasible )
    4476 {
    4477 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    4478 SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
    4479
    4482
    4483 *cutoff = TRUE;
    4484 goto RETURN_SCIP_OKAY;
    4485 }
    4486 if( tightened )
    4487 {
    4488 (*nchgbds)++;
    4489 SCIPdebug(lb = SCIPvarGetLbLocal(var)); /* get bound again: it may be additionally modified due to integrality */
    4490 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
    4491 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
    4492 }
    4493 }
    4494 }
    4495 }
    4496 else
    4497 {
    4498 /* check, if we can tighten the variable's bounds */
    4499 if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
    4500 {
    4501 SCIP_Real newlb;
    4502 SCIP_INTERVAL lbinterval;
    4503
    4505
    4506 SCIPintervalSet(&lbinterval, rhs);
    4507 SCIPintervalSubScalar(SCIPinfinity(scip), &lbinterval, lbinterval, minresactivity);
    4508 SCIPintervalDiv(SCIPinfinity(scip), &lbinterval, lbinterval, valrange);
    4509 newlb = lbinterval.inf;
    4510
    4511 assert(newlb <= lbinterval.inf);
    4512
    4513 if( !SCIPisInfinity(scip, -newlb) &&
    4514 ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
    4515 {
    4516 /* tighten lower bound */
    4517 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
    4518 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, valrange.sup, minresactivity, maxresactivity, lhs, rhs, newlb);
    4519
    4521 {
    4522 SCIP_Longint boundmaxdenom;
    4523
    4525 SCIPrationalSetReal(tmpbound, newlb);
    4526
    4527 if( conshdlrdata->limitdenom )
    4528 {
    4529 boundmaxdenom = conshdlrdata->boundmaxdenom;
    4530 SCIPrationalComputeApproximation(tmpbound, tmpbound, boundmaxdenom, -1);
    4531 }
    4534 SCIP_BOUNDTYPE_LOWER, tmpbound, false, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
    4535
    4537 &infeasible, &tightened) );
    4539 }
    4540 else
    4541 {
    4544 SCIP_BOUNDTYPE_LOWER, newlb, false, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
    4545
    4546 newlb = SCIPadjustedVarLbExactFloat(scip, var, newlb);
    4547 SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_RHS, pos), force,
    4548 &infeasible, &tightened) );
    4549 }
    4550
    4551 if( infeasible )
    4552 {
    4553 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    4554 SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
    4555
    4558
    4559 /**@todo analyze conflict detected in exactlinear constraint handler */
    4560 *cutoff = TRUE;
    4561 goto RETURN_SCIP_OKAY;
    4562 }
    4563 if( tightened )
    4564 {
    4565 lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
    4566 (*nchgbds)++;
    4567 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
    4568 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
    4569 }
    4570 }
    4571 }
    4572
    4573 if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
    4574 {
    4575 SCIP_Real newub;
    4576 SCIP_INTERVAL ubinterval;
    4577
    4579
    4580 /* newub = (maxresactivity + SCIPintervalNegateReal(lhs))/SCIPintervalNegateReal(valrange.inf); */
    4581 SCIPintervalSet(&ubinterval, lhs);
    4582 SCIPintervalSubScalar(SCIPinfinity(scip), &ubinterval, ubinterval, maxresactivity);
    4583 SCIPintervalDiv(SCIPinfinity(scip), &ubinterval, ubinterval, valrange);
    4584 newub = ubinterval.sup;
    4585
    4586 if( !SCIPisInfinity(scip, newub) &&
    4587 ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
    4588 {
    4589 /* tighten upper bound */
    4590 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g], newub=%.15g\n",
    4591 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, valrange.sup, minresactivity, maxresactivity, lhs, rhs, newub);
    4592
    4594 {
    4595 SCIP_Longint boundmaxdenom;
    4596
    4598 SCIPrationalSetReal(tmpbound, newub);
    4599
    4600 if( conshdlrdata->limitdenom )
    4601 {
    4602 boundmaxdenom = conshdlrdata->boundmaxdenom;
    4603 SCIPrationalComputeApproximation(tmpbound, tmpbound, boundmaxdenom, 1);
    4604 }
    4607 SCIP_BOUNDTYPE_UPPER, tmpbound, true, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
    4608
    4610 &infeasible, &tightened) );
    4612 }
    4613 else
    4614 {
    4617 SCIP_BOUNDTYPE_UPPER, newub, true, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
    4618
    4619 newub = SCIPadjustedVarUbExactFloat(scip, var, newub);
    4620 SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_LHS, pos), force,
    4621 &infeasible, &tightened) );
    4622 }
    4623
    4624 if( infeasible )
    4625 {
    4626 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    4627 SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
    4628
    4631
    4632 *cutoff = TRUE;
    4633 goto RETURN_SCIP_OKAY;
    4634 }
    4635 if( tightened )
    4636 {
    4637 (*nchgbds)++;
    4638 SCIPdebug(ub = SCIPvarGetUbLocal(var)); /* get bound again: it may be additionally modified due to integrality */
    4639 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
    4640 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
    4641 }
    4642 }
    4643 }
    4644 }
    4645 RETURN_SCIP_OKAY:
    4647 return SCIP_OKAY;
    4648}
    4649
    4650#define MAXTIGHTENROUNDS 10
    4651
    4652/** tightens bounds of variables in constraint due to activity bounds */
    4653static
    4655 SCIP* scip, /**< SCIP data structure */
    4656 SCIP_CONS* cons, /**< linear constraint */
    4657 SCIP_Bool sortvars, /**< should variables be used in sorted order? */
    4658 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    4659 int* nchgbds /**< pointer to count the total number of tightened bounds */
    4660 )
    4661{
    4662 SCIP_CONSDATA* consdata;
    4663 unsigned int tightenmode;
    4664 int nvars;
    4665 int nrounds;
    4666 int lastchange;
    4667 int v;
    4668 SCIP_Bool force;
    4669
    4670 assert(scip != NULL);
    4671 assert(cons != NULL);
    4672 assert(nchgbds != NULL);
    4673 assert(cutoff != NULL);
    4674
    4675 *cutoff = FALSE;
    4676
    4677 /* we cannot tighten variables' bounds, if the constraint may be not complete */
    4678 if( SCIPconsIsModifiable(cons) )
    4679 return SCIP_OKAY;
    4680
    4681 /* currently, we do not need to call applyFixings() as in cons_linear.c */
    4682
    4683 consdata = SCIPconsGetData(cons);
    4684 assert(consdata != NULL);
    4685
    4686 nvars = consdata->nvars;
    4687 force = (nvars == 1) && !SCIPconsIsModifiable(cons);
    4688
    4689 /* we are at the root node or during presolving */
    4690 if( SCIPgetDepth(scip) < 1 )
    4691 tightenmode = 2;
    4692 else
    4693 tightenmode = 1;
    4694
    4695 /* stop if we already tightened the constraint and the tightening is not forced */
    4696 if( !force && (consdata->boundstightened >= tightenmode) ) /*lint !e574*/
    4697 return SCIP_OKAY;
    4698
    4699 /* ensure that the variables are properly sorted */
    4700 if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
    4701 {
    4702 SCIP_CALL( consdataSort(scip, consdata) );
    4703 assert(consdata->coefsorted);
    4704 }
    4705
    4706 /* update maximal activity delta if necessary */
    4707 if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
    4709
    4710 assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
    4711 assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
    4712 checkMaxActivityDelta(scip, consdata);
    4713
    4714 /* this may happen if all variables are fixed */
    4715 if( SCIPisFeasZero(scip, consdata->maxactdelta) )
    4716 return SCIP_OKAY;
    4717
    4718 if( !SCIPisInfinity(scip, consdata->maxactdelta) )
    4719 {
    4720 SCIP_Real slack;
    4721 SCIP_Real surplus;
    4722 SCIP_Real minactivity;
    4723 SCIP_Real maxactivity;
    4724 SCIP_Bool minisrelax;
    4725 SCIP_Bool maxisrelax;
    4726 SCIP_Bool isminsettoinfinity;
    4727 SCIP_Bool ismaxsettoinfinity;
    4728
    4729 /* use maximal activity delta to skip propagation (cannot deduce anything) */
    4730 consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minisrelax, &maxisrelax,
    4731 &isminsettoinfinity, &ismaxsettoinfinity);
    4732
    4733 assert(!SCIPisInfinity(scip, minactivity));
    4734 assert(!SCIPisInfinity(scip, -maxactivity));
    4735
    4736 slack = (SCIPisInfinity(scip, consdata->rhsreal) || isminsettoinfinity) ? SCIPinfinity(scip) : (consdata->rhsreal - minactivity);
    4737 surplus = (SCIPisInfinity(scip, -consdata->lhsreal) || ismaxsettoinfinity) ? SCIPinfinity(scip) : (maxactivity - consdata->lhsreal);
    4738
    4739 /* check if the constraint will propagate */
    4740 if( consdata->maxactdelta <= MIN(slack, surplus) )
    4741 return SCIP_OKAY;
    4742 }
    4743
    4744 /* as long as the bounds might be tightened again, try to tighten them; abort after a maximal number of rounds */
    4745 lastchange = -1;
    4746
    4747 for( nrounds = 0; (force || consdata->boundstightened < tightenmode) && nrounds < MAXTIGHTENROUNDS; ++nrounds ) /*lint !e574*/
    4748 {
    4749#ifdef SCIP_DEBUG
    4750 int oldnchgbdstotal = *nchgbds;
    4751#endif
    4752
    4753 /* ensure that the variables are properly sorted
    4754 *
    4755 * note: it might happen that integer variables become binary during bound tightening at the root node
    4756 */
    4757 if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
    4758 {
    4759 SCIP_CALL( consdataSort(scip, consdata) );
    4760 assert(consdata->coefsorted);
    4761 }
    4762
    4763 /* mark the constraint to have the variables' bounds tightened */
    4764 consdata->boundstightened = (unsigned int)tightenmode;
    4765 /* try to tighten the bounds of each variable in the constraint. During solving process, the binary variable
    4766 * sorting enables skipping variables
    4767 */
    4768 v = 0;
    4769 while( v < nvars && v != lastchange && !(*cutoff) )
    4770 {
    4771 int oldnchgbds = *nchgbds;
    4772
    4773 SCIP_CALL( tightenVarBounds(scip, cons, v, cutoff, nchgbds, force) );
    4774
    4775 /* if there was no progress, skip the rest of the binary variables */
    4776 if( *cutoff )
    4777 {
    4778 break;
    4779 }
    4780 else if( *nchgbds > oldnchgbds )
    4781 {
    4782 lastchange = v;
    4783 ++v;
    4784 }
    4785 else if( consdata->coefsorted && v < consdata->nbinvars - 1
    4786 && !SCIPisFeasEQ(scip, SCIPvarGetUbLocal(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v])) )
    4787 v = consdata->nbinvars;
    4788 else
    4789 ++v;
    4790 }
    4791
    4792#ifdef SCIP_DEBUG
    4793 SCIPdebugMsg(scip, "linear constraint <%s> found %d bound changes in round %d\n", SCIPconsGetName(cons),
    4794 *nchgbds - oldnchgbdstotal, nrounds);
    4795#endif
    4796 }
    4797
    4798 return SCIP_OKAY;
    4799}
    4800
    4801/** checks linear constraint for feasibility of given solution or current solution */
    4802static
    4804 SCIP* scip, /**< SCIP data structure */
    4805 SCIP_CONS* cons, /**< linear constraint */
    4806 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    4807 SCIP_SOL* sol, /**< solution to be checked, or NULL for current solution */
    4808 SCIP_Bool useexactsol, /**< should the sol or solex be checked? */
    4809 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
    4810 SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
    4811 )
    4812{
    4813 SCIP_CONSDATA* consdata;
    4814 SCIP_RATIONAL* activity;
    4815 SCIP_Bool success;
    4816
    4817 assert(scip != NULL);
    4818 assert(cons != NULL);
    4819 assert(violated != NULL);
    4820
    4821 SCIPdebugMsg(scip, "checking linear constraint <%s>\n", SCIPconsGetName(cons));
    4822 SCIPdebug(consPrintConsSol(scip, cons, sol, useexactsol, NULL));
    4823
    4824 consdata = SCIPconsGetData(cons);
    4825 assert(consdata != NULL);
    4826
    4827 *violated = FALSE;
    4828 activity = consdata->activity;
    4829
    4830 /* only check exact constraint if fp cons is feasible enough */
    4831 if( (consdata->rowexact == NULL || checklprows) && !SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    4832 {
    4833 SCIP_Real activityfp;
    4834 SCIP_Real mu;
    4835
    4836 success = consdataComputeSolActivityWithErrorbound(scip, consdata, sol, &activityfp, &mu);
    4837
    4838 conshdlrdata->ncheckserrorbound++;
    4839
    4840 if( !success )
    4841 conshdlrdata->nabotserrorbound++;
    4842
    4843 if( success )
    4844 {
    4845 if( activityfp - mu > consdata->rhsreal || activityfp + mu < consdata->lhsreal )
    4846 {
    4847 SCIPdebugMsg(scip, "discarding solution due to fp check: activityfp=%g, lhsreal=%g, rhsreal=%g, mu=%g\n",
    4848 activityfp, consdata->lhsreal, consdata->rhsreal, mu);
    4849 *violated = TRUE;
    4850 conshdlrdata->nsuccesserrorbound++;
    4851 return SCIP_OKAY;
    4852 }
    4853 else if( activityfp + mu < consdata->rhsreal && activityfp - mu >= consdata->lhsreal )
    4854 {
    4855 SCIPdebugMsg(scip, "skipping exact check due to fp check: activityfp=%g, lhsreal=%g, rhsreal=%g, mu=%g\n",
    4856 activityfp, consdata->lhsreal, consdata->rhsreal, mu);
    4857 *violated = FALSE;
    4858 conshdlrdata->nsuccesserrorbound++;
    4859 return SCIP_OKAY;
    4860 }
    4861 else
    4862 {
    4863 SCIPdebugMsg(scip, "no decision due to fp check: activityfp=%g, lhsreal=%g, rhsreal=%g, mu=%g\n",
    4864 activityfp, consdata->lhsreal, consdata->rhsreal, mu);
    4865 }
    4866 }
    4867 }
    4868
    4869 if( consdata->rowexact != NULL )
    4870 {
    4871 if( !checklprows && SCIProwExactIsInLP(consdata->rowexact) && SCIPlpExactIsSolved(scip) )
    4872 return SCIP_OKAY;
    4873 else if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
    4874 consdataComputePseudoActivity(consdata, activity);
    4875 else
    4876 {
    4877 SCIP_CALL( SCIPgetRowSolActivityExact(scip, consdata->rowexact, sol, useexactsol, activity) );
    4878 }
    4879 }
    4880 else
    4881 consdataGetActivity(scip, consdata, sol, useexactsol, activity);
    4882
    4883 SCIPrationalDebugMessage("consdata activity=%q (lhs=%q, rhs=%q, row=%p, checklprows=%u, rowinlp=%u, sol=%p, hascurrentnodelp=%u)\n",
    4884 activity, consdata->lhs, consdata->rhs, (void*)consdata->rowexact, checklprows,
    4885 consdata->rowexact == NULL ? 0 : SCIProwExactIsInLP(consdata->rowexact), (void*)sol,
    4886 consdata->rowexact == NULL ? FALSE : SCIPhasCurrentNodeLP(scip));
    4887
    4888 /* the activity of pseudo solutions may be invalid if it comprises positive and negative infinity contributions; we
    4889 * return infeasible for safety
    4890 */
    4891 if( ((!SCIPrationalIsNegInfinity(consdata->lhs) && SCIPrationalIsLT(activity, consdata->lhs)) ||
    4892 (!SCIPrationalIsInfinity(consdata->rhs) && SCIPrationalIsGT(activity, consdata->rhs))) )
    4893 {
    4894 *violated = TRUE;
    4895
    4896 /* only reset constraint age if we are in enforcement */
    4897 if( sol == NULL )
    4898 {
    4900 }
    4901 }
    4902 else
    4903 {
    4904 /* only increase constraint age if we are in enforcement */
    4905 if( sol == NULL )
    4906 {
    4907 SCIP_CALL( SCIPincConsAge(scip, cons) );
    4908 }
    4909 }
    4910
    4911 return SCIP_OKAY;
    4912}
    4913
    4914/** creates an LP row in a linear constraint data */
    4915static
    4917 SCIP* scip, /**< SCIP data structure */
    4918 SCIP_CONS* cons /**< linear constraint */
    4919 )
    4920{
    4921 SCIP_CONSDATA* consdata;
    4922 SCIP_Bool onerowrelax;
    4923 SCIP_Bool hasfprelax;
    4924
    4925 assert(scip != NULL);
    4926 assert(cons != NULL);
    4927
    4928 consdata = SCIPconsGetData(cons);
    4929
    4930 assert(consdata != NULL);
    4931 assert(consdata->rowexact == NULL);
    4932
    4933 /* create empty fp-rows */
    4936
    4939
    4940 /* create exact row */
    4941 SCIP_CALL( SCIPcreateEmptyRowConsExact(scip, &consdata->rowexact, consdata->rowlhs, consdata->rowrhs,
    4942 consdata->lhs, consdata->rhs, consdata->hasfprelax) );
    4943
    4944 SCIP_CALL( SCIPcaptureRowExact(scip, consdata->rowexact) );
    4945
    4946 SCIP_CALL( SCIPaddVarsToRowExact(scip, consdata->rowexact, consdata->nvars, consdata->vars, consdata->vals) );
    4947
    4948 onerowrelax = TRUE;
    4949 hasfprelax = TRUE;
    4950
    4951 SCIP_CALL( SCIPgenerateFpRowsFromRowExact(scip, consdata->rowexact, consdata->rowlhs,
    4952 consdata->rowrhs, &onerowrelax, &hasfprelax) );
    4953
    4954 consdata->onerowrelax = onerowrelax;
    4955 consdata->hasfprelax = hasfprelax;
    4957 if( !(consdata->hasfprelax) || consdata->onerowrelax )
    4958 consdata->rowrhs = NULL;
    4959
    4960 return SCIP_OKAY;
    4961}
    4962
    4963/** adds linear constraint as cut to the LP */
    4964static
    4966 SCIP* scip, /**< SCIP data structure */
    4967 SCIP_CONS* cons, /**< linear constraint */
    4968 SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
    4969 )
    4970{
    4971 SCIP_CONSDATA* consdata;
    4972
    4973 assert(scip != NULL);
    4974 assert(cons != NULL);
    4975
    4976 consdata = SCIPconsGetData(cons);
    4977 assert(consdata != NULL);
    4978
    4979 if( consdata->rowexact == NULL )
    4980 {
    4981 /* convert consdata object into LP row and exact lp row */
    4982 SCIP_CALL( createRows(scip, cons) );
    4983 }
    4984 assert(consdata->rowlhs != NULL);
    4985 assert(consdata->rowexact != NULL);
    4986
    4987 if( consdata->nvars == 0 )
    4988 {
    4989 SCIPdebugMsg(scip, "Empty linear constraint enters LP: <%s>\n", SCIPconsGetName(cons));
    4990 }
    4991
    4992 /* insert LP row as cut */
    4993 if( !SCIProwIsInLP(consdata->rowlhs) )
    4994 {
    4995 SCIPdebugMsg(scip, "adding relaxation of linear constraint <%s>: ", SCIPconsGetName(cons));
    4996 SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->rowlhs, NULL)) );
    4997 SCIPdebug( SCIP_CALL( SCIPprintRowExact(scip, consdata->rowexact, NULL)) );
    4998
    4999 /* if presolving is turned off, the row might be trivial */
    5000 if( !SCIPrationalIsNegInfinity(consdata->lhs) || !SCIPrationalIsInfinity(consdata->rhs) )
    5001 {
    5002 SCIP_CALL( SCIPaddRow(scip, consdata->rowlhs, FALSE, cutoff) );
    5003 SCIP_CALL( SCIPaddRowExact(scip, consdata->rowexact) );
    5004 }
    5005#ifndef NDEBUG
    5006 else
    5007 {
    5008 int pr;
    5009 int cr;
    5010 SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrounds", &pr) );
    5011 SCIP_CALL( SCIPgetIntParam(scip, "constraints/linear/maxprerounds", &cr) );
    5012 assert( pr == 0 || cr == 0 );
    5013 }
    5014#endif
    5015 }
    5016
    5017 return SCIP_OKAY;
    5018}
    5019
    5020/** separates linear constraint: adds linear constraint as cut, if violated by given solution */
    5021static
    5023 SCIP* scip, /**< SCIP data structure */
    5024 SCIP_CONS* cons, /**< linear constraint */
    5025 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    5026 SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
    5027 int* ncuts, /**< pointer to add up the number of found cuts */
    5028 SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
    5029 )
    5030{ /*lint --e{715}*/
    5031 SCIP_Bool violated;
    5032 int oldncuts;
    5033
    5034 assert(scip != NULL);
    5035 assert(conshdlrdata != NULL);
    5036 assert(cons != NULL);
    5037 assert(cutoff != NULL);
    5038
    5039 assert(ncuts != NULL);
    5040
    5041 oldncuts = *ncuts;
    5042 *cutoff = FALSE;
    5043
    5044 SCIP_CALL( checkCons(scip, cons, conshdlrdata, sol, FALSE, (sol != NULL), &violated) );
    5045
    5046 if( violated )
    5047 {
    5048 /* insert LP row as cut */
    5049 SCIP_CALL( addRelaxation(scip, cons, cutoff) );
    5050 (*ncuts)++;
    5051 }
    5052
    5053 if( *ncuts > oldncuts )
    5054 {
    5056 }
    5057
    5058 return SCIP_OKAY;
    5059}
    5060
    5061/** propagation method for linear constraints */
    5062static
    5064 SCIP* scip, /**< SCIP data structure */
    5065 SCIP_CONS* cons, /**< linear constraint */
    5066 SCIP_Bool tightenbounds, /**< should the variable's bounds be tightened? */
    5067 SCIP_Bool sortvars, /**< should variable sorting for faster propagation be used? */
    5068 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    5069 int* nchgbds /**< pointer to count the total number of tightened bounds */
    5070 )
    5071{
    5072 SCIP_CONSDATA* consdata;
    5073 SCIP_Real minactivity;
    5074 SCIP_Real maxactivity;
    5075 SCIP_Bool minactisrelax;
    5076 SCIP_Bool maxactisrelax;
    5077 SCIP_Bool isminsettoinfinity;
    5078 SCIP_Bool ismaxsettoinfinity;
    5079
    5080 assert(scip != NULL);
    5081 assert(cons != NULL);
    5082 assert(cutoff != NULL);
    5083 assert(nchgbds != NULL);
    5084
    5085 /*SCIPdebugMsg(scip, "propagating linear constraint <%s>\n", SCIPconsGetName(cons));*/
    5086
    5087 consdata = SCIPconsGetData(cons);
    5088 assert(consdata != NULL);
    5089
    5090 if( consdata->eventdata == NULL )
    5091 {
    5092 SCIP_CONSHDLR* conshdlr;
    5093 SCIP_CONSHDLRDATA* conshdlrdata;
    5094
    5095 conshdlr = SCIPconsGetHdlr(cons);
    5096 assert(conshdlr != NULL);
    5097
    5098 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5099 assert(conshdlrdata != NULL);
    5100
    5101 /* catch bound change events of variables */
    5102 SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    5103 assert(consdata->eventdata != NULL);
    5104 }
    5105
    5106 *cutoff = FALSE;
    5107
    5108 /* we can only infer activity bounds of the linear constraint, if it is not modifiable */
    5109 if( !SCIPconsIsModifiable(cons) )
    5110 {
    5111 SCIP_CONSHDLR* conshdlr;
    5112 SCIP_CONSHDLRDATA* conshdlrdata;
    5113
    5114 conshdlr = SCIPconsGetHdlr(cons);
    5115 assert(conshdlr != NULL);
    5116
    5117 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5118 assert(conshdlrdata != NULL);
    5119
    5120 if( !SCIPconsIsInitial(cons) )
    5121 {
    5122 conshdlrdata->nconspropnoninit++;
    5123 conshdlrdata->propnonzerosnoninit += consdata->nvars;
    5124 }
    5125 else
    5126 {
    5127 conshdlrdata->nconsprop++;
    5128 conshdlrdata->propnonzeros += consdata->nvars;
    5129 }
    5130
    5131 /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
    5133 {
    5134 SCIP_CALL( SCIPincConsAge(scip, cons) );
    5135 }
    5136
    5137 /* tighten the variable's bounds */
    5138 if( tightenbounds )
    5139 {
    5140 int oldnchgbds;
    5141
    5142 oldnchgbds = *nchgbds;
    5143
    5144 SCIP_CALL( tightenBounds(scip, cons, sortvars, cutoff, nchgbds) );
    5145
    5146 if( *nchgbds > oldnchgbds )
    5147 {
    5149 }
    5150 }
    5151
    5152 /* check constraint for infeasibility and redundancy */
    5153 if( !(*cutoff) )
    5154 {
    5155 consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
    5156 &isminsettoinfinity, &ismaxsettoinfinity);
    5157
    5158 if( SCIPrationalIsGTReal(consdata->lhs, maxactivity) )
    5159 {
    5160 SCIPrationalDebugMessage("linear constraint <%s> is infeasible (lhs): activitybounds=[%.15g,%.15g], sides=[%q,%q]\n",
    5161 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
    5162
    5164
    5165 /**@todo analyze conflict detected in exactlinear constraint handler */
    5167 *cutoff = TRUE;
    5168 }
    5169 else if( SCIPrationalIsLTReal(consdata->rhs, minactivity) )
    5170 {
    5171 SCIPrationalDebugMessage("linear constraint <%s> is infeasible (rhs): activitybounds=[%.15g,%.15g], sides=[%q,%q]\n",
    5172 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
    5173
    5175
    5176 /**@todo analyze conflict detected in exactlinear constraint handler */
    5178 *cutoff = TRUE;
    5179 }
    5180 else if( SCIPrationalIsLEReal(consdata->lhs, minactivity) && SCIPrationalIsGEReal(consdata->rhs, maxactivity) )
    5181 {
    5182 SCIPrationalDebugMessage("linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%q,%q]\n",
    5183 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
    5184
    5185 /* remove the constraint locally unless it has become empty, in which case it is removed globally */
    5186 if( consdata->nvars > 0 )
    5188 else
    5189 SCIP_CALL( SCIPdelCons(scip, cons) );
    5190 }
    5191 }
    5192 }
    5193
    5194 return SCIP_OKAY;
    5195}
    5196
    5197
    5198/*
    5199 * Presolving methods
    5200 */
    5201
    5202/** helper function to enforce constraints */
    5203static
    5205 SCIP* scip, /**< SCIP data structure */
    5206 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    5207 SCIP_CONS** conss, /**< constraints to process */
    5208 int nconss, /**< number of constraints */
    5209 int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
    5210 SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
    5211 SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
    5212 )
    5213{
    5214 SCIP_CONSHDLRDATA* conshdlrdata;
    5215 SCIP_Bool violated;
    5216 SCIP_Bool checkexact;
    5217 SCIP_Bool cutoff = FALSE;
    5218 int c;
    5219
    5220 assert(scip != NULL);
    5221 assert(conshdlr != NULL);
    5222 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5223 assert(result != NULL);
    5224
    5225 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5226 assert(conshdlrdata != NULL);
    5227
    5228 if( sol == NULL )
    5229 checkexact = SCIPlpExactIsSolved(scip);
    5230 else
    5231 checkexact = SCIPsolIsExact(sol);
    5232
    5233 SCIPdebugMsg(scip, "Enforcement method of linear constraints for %s solution\n", sol == NULL ? "LP" : "relaxation");
    5235
    5236 /* check for violated constraints
    5237 * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
    5238 */
    5239 *result = SCIP_FEASIBLE;
    5240
    5241 /* check all useful linear constraints for feasibility */
    5242 for( c = 0; c < nusefulconss; ++c )
    5243 {
    5244 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, sol, checkexact, FALSE, &violated) );
    5245
    5246 if( violated )
    5247 {
    5248 /* insert LP row as cut */
    5249 SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
    5250 if( cutoff )
    5251 *result = SCIP_CUTOFF;
    5252 else
    5253 *result = SCIP_SEPARATED;
    5254 }
    5255 }
    5256
    5257 /* check all obsolete linear constraints for feasibility */
    5258 for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
    5259 {
    5260 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, sol, checkexact, FALSE, &violated) );
    5261
    5262 if( violated )
    5263 {
    5264 /* insert LP row as cut */
    5265 SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
    5266 if( cutoff )
    5267 *result = SCIP_CUTOFF;
    5268 else
    5269 *result = SCIP_SEPARATED;
    5270 }
    5271 }
    5272
    5273 SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
    5274
    5275 return SCIP_OKAY;
    5276}
    5277
    5278/*
    5279 * Callback methods of constraint handler
    5280 */
    5281
    5282/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    5283static
    5284SCIP_DECL_CONSHDLRCOPY(conshdlrCopyExactLinear)
    5285{ /*lint --e{715}*/
    5286 assert(scip != NULL);
    5287 assert(conshdlr != NULL);
    5288 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5289
    5290 /* call inclusion method of constraint handler */
    5292
    5293 *valid = TRUE;
    5294
    5295 return SCIP_OKAY;
    5296}
    5297
    5298/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
    5299static
    5300SCIP_DECL_CONSFREE(consFreeExactLinear)
    5301{ /*lint --e{715}*/
    5302 SCIP_CONSHDLRDATA* conshdlrdata;
    5303
    5304 assert(scip != NULL);
    5305 assert(conshdlr != NULL);
    5306 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5307
    5308 /* free constraint handler data */
    5309 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5310 assert(conshdlrdata != NULL);
    5311
    5312 conshdlrdataFree(scip, &conshdlrdata);
    5313
    5314 SCIPconshdlrSetData(conshdlr, NULL);
    5315
    5316 return SCIP_OKAY;
    5317}
    5318
    5319
    5320/** initialization method of constraint handler (called after problem was transformed) */
    5321static
    5322SCIP_DECL_CONSINIT(consInitExactLinear)
    5323{
    5324 SCIP_CONSHDLRDATA* conshdlrdata;
    5325 int c;
    5326
    5327 assert(scip != NULL);
    5328 assert(SCIPisExact(scip) || nconss == 0);
    5329
    5330 /* check for event handler */
    5331 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5332 assert(conshdlrdata != NULL);
    5333 assert(conshdlrdata->eventhdlr != NULL);
    5334 assert(nconss == 0 || conss != NULL);
    5335
    5336 /* catch events for the constraints */
    5337 for( c = 0; c < nconss; ++c )
    5338 {
    5339 /* catch all events */
    5340 SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
    5341 }
    5342
    5343 return SCIP_OKAY;
    5344}
    5345
    5346
    5347/** deinitialization method of constraint handler (called before transformed problem is freed) */
    5348static
    5349SCIP_DECL_CONSEXIT(consExitExactLinear)
    5350{
    5351 SCIP_CONSHDLRDATA* conshdlrdata;
    5352 int c;
    5353
    5354 assert(scip != NULL);
    5355 assert(SCIPisExact(scip) || nconss == 0);
    5356
    5357 /* check for event handler */
    5358 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5359 assert(conshdlrdata != NULL);
    5360 assert(conshdlrdata->eventhdlr != NULL);
    5361
    5362 /* drop events for the constraints */
    5363 for( c = nconss - 1; c >= 0; --c )
    5364 {
    5365 SCIP_CONSDATA* consdata;
    5366
    5367 consdata = SCIPconsGetData(conss[c]);
    5368 assert(consdata != NULL);
    5369
    5370 if( consdata->eventdata != NULL )
    5371 {
    5372 /* drop all events */
    5373 SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
    5374 assert(consdata->eventdata == NULL);
    5375 }
    5376 }
    5377
    5378 return SCIP_OKAY;
    5379}
    5380
    5381/** presolving deinitialization method of constraint handler (called after presolving has been finished) */
    5382static
    5383SCIP_DECL_CONSEXITPRE(consExitpreExactLinear)
    5384{ /*lint --e{715}*/
    5385 int c;
    5386
    5387 assert(scip != NULL);
    5388 assert(SCIPisExact(scip) || nconss == 0);
    5389
    5390 /* make sure, only active variables remain in the remaining constraints */
    5391 for( c = 0; c < nconss; ++c )
    5392 {
    5393 if( SCIPconsIsDeleted(conss[c]) )
    5394 continue;
    5395
    5396 /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
    5397 SCIP_CALL( applyFixings(scip, conss[c], NULL) );
    5398 }
    5399
    5400 return SCIP_OKAY;
    5401}
    5402
    5403
    5404/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
    5405static
    5406SCIP_DECL_CONSEXITSOL(consExitsolExactLinear)
    5407{ /*lint --e{715}*/
    5408 int c;
    5409
    5410 assert(scip != NULL);
    5411 assert(SCIPisExact(scip) || nconss == 0);
    5412
    5413 if( !SCIPisExact(scip) )
    5414 return SCIP_OKAY;
    5415
    5416 /* release the rows of all constraints */
    5417 for( c = 0; c < nconss; ++c )
    5418 {
    5419 SCIP_CONSDATA* consdata;
    5420
    5421 consdata = SCIPconsGetData(conss[c]);
    5422 assert(consdata != NULL);
    5423
    5424 if( consdata->rowlhs != NULL )
    5425 {
    5426 SCIP_CALL( SCIPreleaseRowExact(scip, &consdata->rowexact) );
    5427 SCIP_CALL( SCIPreleaseRow(scip, &consdata->rowlhs) );
    5428
    5429 if( consdata->rowrhs != NULL )
    5430 {
    5431 assert(!consdata->onerowrelax);
    5432 SCIP_CALL( SCIPreleaseRow(scip, &consdata->rowrhs) );
    5433 }
    5434 }
    5435 }
    5436
    5437 /**@todo when enabling restarts, extend SCIPconvertCutsToConss() in order to convert exact cuts to exactlinear
    5438 * constraints and call here
    5439 */
    5440
    5441 return SCIP_OKAY;
    5442}
    5443
    5444
    5445/** constraint deactivation notification method of constraint handler */
    5446static
    5447SCIP_DECL_CONSDEACTIVE(consDeactiveExactLinear)
    5448{ /*lint --e{715}*/
    5449 assert(scip != NULL);
    5450 assert(SCIPisExact(scip));
    5451 assert(cons != NULL);
    5452
    5453 if( SCIPconsIsDeleted(cons) )
    5454 {
    5455 SCIP_CONSHDLRDATA* conshdlrdata;
    5456 SCIP_CONSDATA* consdata;
    5457
    5458 assert(conshdlr != NULL);
    5459 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5460
    5461 /* get constraint data */
    5462 consdata = SCIPconsGetData(cons);
    5463 assert(consdata != NULL);
    5464
    5465 /* check for event handler */
    5466 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5467 assert(conshdlrdata != NULL);
    5468 assert(conshdlrdata->eventhdlr != NULL);
    5469
    5470 /* free event data */
    5471 if( consdata->eventdata != NULL )
    5472 {
    5473 /* drop bound change events of variables */
    5474 SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    5475 }
    5476 assert(consdata->eventdata == NULL);
    5477 }
    5478
    5479 return SCIP_OKAY;
    5480}
    5481
    5482
    5483/** frees specific constraint data */
    5484static
    5485SCIP_DECL_CONSDELETE(consDeleteExactLinear)
    5486{ /*lint --e{715}*/
    5487 assert(scip != NULL);
    5488 assert(SCIPisExact(scip));
    5489 assert(conshdlr != NULL);
    5490 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5491
    5492 if( (*consdata)->eventdata != NULL )
    5493 {
    5494 SCIP_CONSHDLRDATA* conshdlrdata;
    5495
    5496 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5497 assert(conshdlrdata != NULL);
    5498
    5499 /* drop all events */
    5500 SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    5501 assert((*consdata)->eventdata == NULL);
    5502 }
    5503 /* free linear constraint */
    5504 SCIP_CALL( consdataFree(scip, consdata) );
    5505
    5506 return SCIP_OKAY;
    5507}
    5508
    5509
    5510/** transforms constraint data into data belonging to the transformed problem */
    5511static
    5512SCIP_DECL_CONSTRANS(consTransExactLinear)
    5513{ /*lint --e{715}*/
    5514 SCIP_CONSDATA* sourcedata;
    5515 SCIP_CONSDATA* targetdata;
    5516
    5517 assert(scip != NULL);
    5518 assert(SCIPisExact(scip));
    5519 assert(conshdlr != NULL);
    5520 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5522 assert(sourcecons != NULL);
    5523 assert(targetcons != NULL);
    5524
    5525 sourcedata = SCIPconsGetData(sourcecons);
    5526 assert(sourcedata != NULL);
    5527 assert(sourcedata->rowlhs == NULL && sourcedata->rowexact == NULL); /* in original problem, there cannot be LP rows */
    5528
    5529 /* create linear constraint data for target constraint */
    5530 SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs,
    5531 sourcedata->rhs) );
    5532
    5533 if( sourcedata->nvars > 0 )
    5534 consdataScaleMinValue(scip, targetdata, 2 * SCIPepsilon(scip));
    5535
    5536 /* create target constraint */
    5537 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
    5538 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    5539 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
    5540 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
    5541 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
    5542
    5543 return SCIP_OKAY;
    5544}
    5545
    5546/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
    5547static
    5548SCIP_DECL_CONSINITLP(consInitlpExactLinear)
    5549{ /*lint --e{715}*/
    5550 int c;
    5551
    5552 assert(scip != NULL);
    5553 assert(SCIPisExact(scip) || nconss == 0);
    5554 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5555
    5556 *infeasible = FALSE;
    5557
    5558 for( c = 0; c < nconss && !(*infeasible); ++c )
    5559 {
    5560 assert(SCIPconsIsInitial(conss[c]));
    5561 /* add both the relaxation to the fp-lp as well as the correct constraint to the exact lp */
    5562 SCIP_CALL( addRelaxation(scip, conss[c], infeasible) );
    5563 }
    5564
    5565 return SCIP_OKAY;
    5566}
    5567
    5568/** separation method of constraint handler for LP solutions */
    5569static
    5570SCIP_DECL_CONSSEPALP(consSepalpExactLinear)
    5571{ /*lint --e{715}*/
    5572 SCIP_CONSHDLRDATA* conshdlrdata;
    5573 SCIP_Bool cutoff;
    5574 int c;
    5575 int depth;
    5576 int nrounds;
    5577 int maxsepacuts;
    5578 int ncuts;
    5579
    5580 assert(scip != NULL);
    5581 assert(SCIPisExact(scip) || nconss == 0);
    5582 assert(conshdlr != NULL);
    5583 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5584 assert(result != NULL);
    5585
    5586 if( !SCIPisExact(scip) )
    5587 return SCIP_OKAY;
    5588
    5589 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5590 assert(conshdlrdata != NULL);
    5591 depth = SCIPgetDepth(scip);
    5592 nrounds = SCIPgetNSepaRounds(scip);
    5593
    5594 *result = SCIP_DIDNOTRUN;
    5595
    5596 /* only call the separator a given number of times at each node */
    5597 if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
    5598 || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
    5599 return SCIP_OKAY;
    5600
    5601 /* get the maximal number of cuts allowed in a separation round */
    5602 maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
    5603
    5604 *result = SCIP_DIDNOTFIND;
    5605 ncuts = 0;
    5606 cutoff = FALSE;
    5607
    5608 /* check all useful linear constraints for feasibility */
    5609 for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
    5610 {
    5611 SCIPdebugMsg(scip, "separating exact linear constraint <%s>\n", SCIPconsGetName(conss[c]));
    5612 SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, &ncuts, &cutoff) );
    5613 }
    5614
    5615 /* adjust return value */
    5616 if( cutoff )
    5617 *result = SCIP_CUTOFF;
    5618 else if( ncuts > 0 )
    5619 *result = SCIP_SEPARATED;
    5620
    5621 return SCIP_OKAY;
    5622}
    5623
    5624
    5625/** separation method of constraint handler for arbitrary primal solutions */
    5626static
    5627SCIP_DECL_CONSSEPASOL(consSepasolExactLinear)
    5628{ /*lint --e{715}*/
    5629 SCIP_CONSHDLRDATA* conshdlrdata;
    5630 int c;
    5631 int depth;
    5632 int nrounds;
    5633 int maxsepacuts;
    5634 int ncuts;
    5635 SCIP_Bool cutoff;
    5636
    5637 assert(scip != NULL);
    5638 assert(SCIPisExact(scip) || nconss == 0);
    5639 assert(conshdlr != NULL);
    5640 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5641 assert(result != NULL);
    5642
    5643 if( !SCIPisExact(scip) )
    5644 return SCIP_OKAY;
    5645
    5646 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5647 assert(conshdlrdata != NULL);
    5648 depth = SCIPgetDepth(scip);
    5649 nrounds = SCIPgetNSepaRounds(scip);
    5650
    5651 *result = SCIP_DIDNOTRUN;
    5652
    5653 /* only call the separator a given number of times at each node */
    5654 if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
    5655 || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
    5656 return SCIP_OKAY;
    5657
    5658 /* get the maximal number of cuts allowed in a separation round */
    5659 maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
    5660
    5661 *result = SCIP_DIDNOTFIND;
    5662 ncuts = 0;
    5663 cutoff = FALSE;
    5664
    5665 /* check all useful linear constraints for feasibility */
    5666 for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
    5667 {
    5668 SCIPdebugMsg(scip, "separating exact linear constraint <%s>\n", SCIPconsGetName(conss[c]));
    5669 SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, &ncuts, &cutoff) );
    5670 }
    5671
    5672 /* adjust return value */
    5673 if( cutoff )
    5674 *result = SCIP_CUTOFF;
    5675 else if( ncuts > 0 )
    5676 *result = SCIP_SEPARATED;
    5677
    5678 return SCIP_OKAY;
    5679}
    5680
    5681
    5682/** constraint enforcing method of constraint handler for LP solutions */
    5683static
    5684SCIP_DECL_CONSENFOLP(consEnfolpExactLinear)
    5685{ /*lint --e{715}*/
    5686 assert(scip != NULL);
    5687 assert(SCIPisExact(scip) || nconss == 0);
    5688
    5689 if( !SCIPisExact(scip) )
    5690 return SCIP_OKAY;
    5691
    5692 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
    5693
    5694 return SCIP_OKAY;
    5695}
    5696
    5697/** constraint enforcing method of constraint handler for relaxation solutions */
    5698static
    5699SCIP_DECL_CONSENFORELAX(consEnforelaxExactLinear)
    5700{ /*lint --e{715}*/
    5701 assert(scip != NULL);
    5702 assert(SCIPisExact(scip) || nconss == 0);
    5703
    5704 if( !SCIPisExact(scip) )
    5705 return SCIP_OKAY;
    5706
    5707 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
    5708
    5709 return SCIP_OKAY;
    5710}
    5711
    5712/** constraint enforcing method of constraint handler for pseudo solutions */
    5713static
    5714SCIP_DECL_CONSENFOPS(consEnfopsExactLinear)
    5715{ /*lint --e{715}*/
    5716 SCIP_CONSHDLRDATA* conshdlrdata;
    5717 SCIP_Bool violated;
    5718 int c;
    5719
    5720 assert(scip != NULL);
    5721 assert(SCIPisExact(scip) || nconss == 0);
    5722 assert(conshdlr != NULL);
    5723 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5724 assert(result != NULL);
    5725
    5726 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5727 assert(conshdlrdata != NULL);
    5728
    5729 SCIPdebugMsg(scip, "Enfops method of linear constraints\n");
    5730
    5731 if( !SCIPisExact(scip) )
    5732 {
    5733 *result = SCIP_DIDNOTRUN;
    5734 return SCIP_OKAY;
    5735 }
    5736
    5737 /* if the solution is infeasible anyway due to objective value, skip the enforcement */
    5738 if( objinfeasible )
    5739 {
    5740 SCIPdebugMsg(scip, "-> pseudo solution is objective infeasible, return.\n");
    5741
    5742 *result = SCIP_DIDNOTRUN;
    5743 return SCIP_OKAY;
    5744 }
    5745
    5746 /* check all linear constraints for feasibility */
    5747 violated = FALSE;
    5748 for( c = 0; c < nconss && !violated; ++c )
    5749 {
    5750 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, NULL, FALSE, TRUE, &violated) );
    5751 }
    5752
    5753 if( violated )
    5754 *result = SCIP_INFEASIBLE;
    5755 else
    5756 *result = SCIP_FEASIBLE;
    5757
    5758 SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
    5759
    5760 return SCIP_OKAY;
    5761}
    5762
    5763
    5764/** feasibility check method of constraint handler for integral solutions */
    5765static
    5766SCIP_DECL_CONSCHECK(consCheckExactLinear)
    5767{ /*lint --e{715}*/
    5768 SCIP_CONSHDLRDATA* conshdlrdata;
    5769 SCIP_Bool checkexact;
    5770 int c;
    5771
    5772 assert(scip != NULL);
    5773 assert(SCIPisExact(scip) || nconss == 0);
    5774 assert(conshdlr != NULL);
    5775 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5776 assert(result != NULL);
    5777
    5778 *result = SCIP_FEASIBLE;
    5779
    5780 if( !SCIPisExact(scip) )
    5781 return SCIP_OKAY;
    5782
    5783 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5784 assert(conshdlrdata != NULL);
    5785
    5786 /* if the fp-solution has a stand-in exact solution we check that instead */
    5787 checkexact = SCIPsolIsExact(sol);
    5788
    5789 /* check all linear constraints for feasibility */
    5790 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
    5791 {
    5792 SCIP_Bool violated = FALSE;
    5793 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, sol, checkexact, checklprows, &violated) );
    5794
    5795 if( violated )
    5796 {
    5797 *result = SCIP_INFEASIBLE;
    5798
    5799 if( printreason )
    5800 {
    5801 SCIP_CONSDATA* consdata;
    5802 SCIP_RATIONAL* activity;
    5803
    5805
    5806 consdata = SCIPconsGetData(conss[c]);
    5807 assert( consdata != NULL);
    5808
    5809 consdataGetActivity(scip, consdata, sol, checkexact, activity);
    5810
    5811 SCIP_CALL( consPrintConsSol(scip, conss[c], sol, checkexact, NULL ) );
    5812 SCIPinfoMessage(scip, NULL, ";\n");
    5813
    5814 if( SCIPrationalIsAbsInfinity(activity) )
    5815 SCIPinfoMessage(scip, NULL, "activity invalid due to infinity contributions\n");
    5816 else if( SCIPrationalIsLT(activity, consdata->lhs) )
    5817 {
    5818 SCIPrationalDiff(activity, consdata->lhs, activity);
    5819 SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by ");
    5821 SCIPinfoMessage(scip, NULL, "\n");
    5822 }
    5823 else if( SCIPrationalIsGT(activity, consdata->rhs) )
    5824 {
    5825 SCIPrationalDiff(activity, activity, consdata->rhs);
    5826 SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by ");
    5828 SCIPinfoMessage(scip, NULL, "\n");
    5829 }
    5830
    5832 }
    5833 }
    5834 }
    5835
    5836 return SCIP_OKAY;
    5837}
    5838
    5839/** domain propagation method of constraint handler */
    5840static
    5841SCIP_DECL_CONSPROP(consPropExactLinear)
    5842{ /*lint --e{715}*/
    5843 SCIP_CONSHDLRDATA* conshdlrdata;
    5844 SCIP_Bool tightenbounds;
    5845 SCIP_Bool cutoff;
    5846
    5847 int nchgbds;
    5848 int i;
    5849
    5850 assert(scip != NULL);
    5851 assert(SCIPisExact(scip) || nconss == 0);
    5852 assert(conshdlr != NULL);
    5853 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    5854 assert(result != NULL);
    5855
    5856 if( !SCIPisExact(scip) )
    5857 return SCIP_OKAY;
    5858
    5859 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5860 assert(conshdlrdata != NULL);
    5861
    5862 /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
    5863 if( SCIPinProbing(scip) )
    5864 tightenbounds = TRUE;
    5865 else
    5866 {
    5867 int depth;
    5868 int propfreq;
    5869 int tightenboundsfreq;
    5870
    5871 depth = SCIPgetDepth(scip);
    5872 propfreq = SCIPconshdlrGetPropFreq(conshdlr);
    5873 tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
    5874 tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
    5875 && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
    5876 }
    5877
    5878 cutoff = FALSE;
    5879 nchgbds = 0;
    5880
    5881 /* process constraints marked for propagation */
    5882 for( i = 0; i < nmarkedconss && !cutoff; i++ )
    5883 {
    5885 SCIP_CALL( propagateCons(scip, conss[i], tightenbounds,
    5886 conshdlrdata->sortvars, &cutoff, &nchgbds) );
    5887 }
    5888
    5889 /* adjust result code */
    5890 if( cutoff )
    5891 *result = SCIP_CUTOFF;
    5892 else if( nchgbds > 0 )
    5893 *result = SCIP_REDUCEDDOM;
    5894 else
    5895 *result = SCIP_DIDNOTFIND;
    5896
    5897 return SCIP_OKAY;
    5898}
    5899
    5900
    5901/** variable rounding lock method of constraint handler */
    5902static
    5903SCIP_DECL_CONSLOCK(consLockExactLinear)
    5904{ /*lint --e{715}*/
    5905 SCIP_CONSDATA* consdata;
    5906 SCIP_Bool haslhs;
    5907 SCIP_Bool hasrhs;
    5908 int i;
    5909
    5910 assert(scip != NULL);
    5911 assert(SCIPisExact(scip));
    5912 assert(cons != NULL);
    5913 consdata = SCIPconsGetData(cons);
    5914 assert(consdata != NULL);
    5915
    5916 haslhs = !SCIPrationalIsNegInfinity(consdata->lhs);
    5917 hasrhs = !SCIPrationalIsInfinity(consdata->rhs);
    5918
    5919 /* update rounding locks of every single variable */
    5920 for( i = 0; i < consdata->nvars; ++i )
    5921 {
    5922 if( SCIPrationalIsPositive(consdata->vals[i]) )
    5923 {
    5924 if( haslhs )
    5925 {
    5926 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
    5927 }
    5928 if( hasrhs )
    5929 {
    5930 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
    5931 }
    5932 }
    5933 else
    5934 {
    5935 if( haslhs )
    5936 {
    5937 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
    5938 }
    5939 if( hasrhs )
    5940 {
    5941 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
    5942 }
    5943 }
    5944 }
    5945
    5946 return SCIP_OKAY;
    5947}
    5948
    5949
    5950/** variable deletion method of constraint handler */
    5951static
    5952SCIP_DECL_CONSDELVARS(consDelvarsExactLinear)
    5953{
    5954 assert(scip != NULL);
    5955 assert(SCIPisExact(scip) || nconss == 0);
    5956 assert(conshdlr != NULL);
    5957 assert(conss != NULL || nconss == 0);
    5958
    5959 if( nconss > 0 )
    5960 {
    5961 SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
    5962 }
    5963
    5964 return SCIP_OKAY;
    5965}
    5966
    5967/** constraint display method of constraint handler */
    5968static
    5969SCIP_DECL_CONSPRINT(consPrintExactLinear)
    5970{ /*lint --e{715}*/
    5971 assert(scip != NULL);
    5972 assert(conshdlr != NULL);
    5973 assert(cons != NULL);
    5974
    5976
    5977 return SCIP_OKAY;
    5978}
    5979
    5980/** constraint copying method of constraint handler */
    5981static
    5982SCIP_DECL_CONSCOPY(consCopyExactLinear)
    5983{ /*lint --e{715}*/
    5984 SCIP_VAR** sourcevars;
    5985 SCIP_INTERVAL* sourcecoefs;
    5986 const char* consname;
    5987 int nvars;
    5988
    5989 assert(scip != NULL);
    5990 assert(sourcescip != NULL);
    5991 assert(sourcecons != NULL);
    5992
    5993 /* get variables and coefficients of the source constraint */
    5994 sourcevars = SCIPgetVarsExactLinear(sourcescip, sourcecons);
    5995 sourcecoefs = SCIPgetValsRealExactLinear(sourcescip, sourcecons);
    5996 nvars = SCIPgetNVarsExactLinear(sourcescip, sourcecons);
    5997
    5998 if( name != NULL )
    5999 consname = name;
    6000 else
    6001 consname = SCIPconsGetName(sourcecons);
    6002
    6003 SCIP_CALL( SCIPcopyConsExactLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
    6004 SCIPrationalGetReal(SCIPgetLhsExactLinear(sourcescip, sourcecons)), SCIPrationalGetReal(SCIPgetRhsExactLinear(sourcescip, sourcecons)), varmap, consmap,
    6005 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
    6006 assert(cons != NULL || *valid == FALSE);
    6007
    6008 return SCIP_OKAY;
    6009}
    6010
    6011/* find operators '<=', '==', '>=', [free] in input string and return those places. There should only be one operator,
    6012 * except for ranged rows for which exactly two operators '<=' must be present
    6013 */
    6014static
    6016 const char* str, /**< null terminated input string */
    6017 char** firstoperator, /**< pointer to store the string starting at the first operator */
    6018 char** secondoperator, /**< pointer to store the string starting at the second operator */
    6019 SCIP_Bool* success /**< pointer to store if the line contains a valid operator order */
    6020 )
    6021{
    6022 char* curr;
    6023
    6024 assert(str != NULL);
    6025 assert(firstoperator != NULL);
    6026 assert(secondoperator != NULL);
    6027
    6028 *firstoperator = NULL;
    6029 *secondoperator = NULL;
    6030
    6031 curr = (char*)str;
    6032 *success = TRUE;
    6033
    6034 /* loop over the input string to find all operators */
    6035 while( *curr && *success )
    6036 {
    6037 SCIP_Bool found = FALSE;
    6038 int increment = 1;
    6039
    6040 /* try if we found a possible operator */
    6041 switch( *curr )
    6042 {
    6043 case '<':
    6044 case '=':
    6045 case '>':
    6046
    6047 /* check if the two characters curr[0,1] form an operator together */
    6048 if( curr[1] == '=' )
    6049 {
    6050 found = TRUE;
    6051
    6052 /* update increment to continue after this operator */
    6053 increment = 2;
    6054 }
    6055 break;
    6056 case '[':
    6057 if( strncmp(curr, "[free]", 6) == 0 )
    6058 {
    6059 found = TRUE;
    6060
    6061 /* update increment to continue after this operator */
    6062 increment = 6;
    6063 }
    6064 break;
    6065 default:
    6066 break;
    6067 }
    6068
    6069 /* assign the found operator to the first or second pointer and check for violations of the linear constraint grammar */
    6070 if( found )
    6071 {
    6072 if( *firstoperator == NULL )
    6073 {
    6074 *firstoperator = curr;
    6075 }
    6076 else
    6077 {
    6078 if( *secondoperator != NULL )
    6079 {
    6080 SCIPerrorMessage("Found more than two operators in line %s\n", str);
    6081 *success = FALSE;
    6082 }
    6083 else if( strncmp(*firstoperator, "<=", 2) != 0 )
    6084 {
    6085 SCIPerrorMessage("Two operators in line that is not a ranged row: %s", str);
    6086 *success = FALSE;
    6087 }
    6088 else if( strncmp(curr, "<=", 2) != 0 )
    6089 {
    6090 SCIPerrorMessage("Bad second operator, expected ranged row specification: %s", str);
    6091 *success = FALSE;
    6092 }
    6093
    6094 *secondoperator = curr;
    6095 }
    6096 }
    6097
    6098 curr += increment;
    6099 }
    6100
    6101 /* check if we did find at least one operator */
    6102 if( *success )
    6103 {
    6104 if( *firstoperator == NULL )
    6105 {
    6106 SCIPerrorMessage("Could not find any operator in line %s\n", str);
    6107 *success = FALSE;
    6108 }
    6109 }
    6110
    6111 return SCIP_OKAY;
    6112}
    6113
    6114/** constraint parsing method of constraint handler */
    6115static
    6116SCIP_DECL_CONSPARSE(consParseExactLinear)
    6117{ /*lint --e{715}*/
    6118 SCIP_RETCODE retcode = SCIP_OKAY;
    6119 SCIP_VAR** vars = NULL;
    6120 SCIP_RATIONAL** coefs = NULL;
    6121 int nvars;
    6122 int coefssize = 100;
    6123 int requsize;
    6124 SCIP_RATIONAL* lhs;
    6125 SCIP_RATIONAL* rhs;
    6126 char* endptr;
    6127 char* firstop;
    6128 char* secondop;
    6129 SCIP_Bool operatorsuccess;
    6130 char* lhsstrptr = NULL;
    6131 char* rhsstrptr = NULL;
    6132 char* varstrptr = (char*)str;
    6133
    6134 assert(scip != NULL);
    6135 assert(success != NULL);
    6136 assert(str != NULL);
    6137 assert(name != NULL);
    6138 assert(cons != NULL);
    6139
    6140 *success = FALSE;
    6141
    6142 /* return of string empty */
    6143 if( !(*str) )
    6144 return SCIP_OKAY;
    6145
    6146 /* set left and right hand side to their default values */
    6149
    6152
    6153 /* ignore whitespace */
    6154 SCIP_CALL_TERMINATE( retcode, SCIPskipSpace((char**)&str), TERMINATE );
    6155
    6156 /* find operators in the line first, all other remaining parsing depends on occurence of the operators '<=', '>=', '==',
    6157 * and the special word [free]
    6158 */
    6159 SCIP_CALL_TERMINATE( retcode, findOperators(str, &firstop, &secondop, &operatorsuccess), TERMINATE );
    6160
    6161 /* if the grammar is not valid for parsing a linear constraint, return */
    6162 if( ! operatorsuccess )
    6163 {
    6164 retcode = SCIP_OKAY;
    6165 goto TERMINATE;
    6166 }
    6167 assert(firstop != NULL);
    6168
    6169 /* assign the strings for parsing the left hand side, right hand side, and the linear variable sum */
    6170 switch( *firstop )
    6171 {
    6172 case '<':
    6173 assert(firstop[1] == '=');
    6174 /* we have ranged row lhs <= a_1 x_1 + ... + a_n x_n <= rhs */
    6175 if( secondop != NULL )
    6176 {
    6177 assert(secondop[0] == '<' && secondop[1] == '=');
    6178 lhsstrptr = (char *)str;
    6179 varstrptr = firstop + 2;
    6180 rhsstrptr = secondop + 2;
    6181 }
    6182 else
    6183 {
    6184 /* we have an inequality with infinite left hand side a_1 x_1 + ... + a_n x_n <= rhs */
    6185 lhsstrptr = NULL;
    6186 varstrptr = (char *)str;
    6187 rhsstrptr = firstop + 2;
    6188 }
    6189 break;
    6190 case '>':
    6191 assert(firstop[1] == '=');
    6192 assert(secondop == NULL);
    6193 /* we have a_1 x_1 + ... + a_n x_n >= lhs */
    6194 lhsstrptr = firstop + 2;
    6195 break;
    6196 case '=':
    6197 assert(firstop[1] == '=');
    6198 assert(secondop == NULL);
    6199 /* we have a_1 x_1 + ... + a_n x_n == lhs (rhs) */
    6200 rhsstrptr = firstop + 2;
    6201 lhsstrptr = firstop + 2;
    6202 break;
    6203 case '[':
    6204 assert(strncmp(firstop, "[free]", 6) == 0);
    6205 assert(secondop == NULL);
    6206 /* nothing to assign in case of a free a_1 x_1 + ... + a_n x_n [free] */
    6207 break;
    6208 default:
    6209 /* it should not be possible that a different character appears in that position */
    6210 SCIPerrorMessage("Parsing has wrong operator character '%c', should be one of <=>[", *firstop);
    6211 retcode = SCIP_READERROR;
    6212 goto TERMINATE;
    6213 }
    6214
    6215 /* parse left hand side, if necessary */
    6216 if( lhsstrptr != NULL )
    6217 {
    6218 if( ! SCIPparseRational(scip, lhsstrptr, lhs, &endptr) )
    6219 {
    6220 SCIPerrorMessage("error parsing left hand side number from <%s>\n", lhsstrptr);
    6221 retcode = SCIP_OKAY;
    6222 goto TERMINATE;
    6223 }
    6224
    6225 /* in case of an equation, assign the left also to the right hand side */
    6226 if( rhsstrptr == lhsstrptr )
    6227 SCIPrationalSetRational(rhs, lhs);
    6228 }
    6229
    6230 /* parse right hand side, if different from left hand side */
    6231 if( rhsstrptr != NULL && rhsstrptr != lhsstrptr )
    6232 {
    6233 if( ! SCIPparseRational(scip, rhsstrptr, rhs, &endptr) )
    6234 {
    6235 SCIPerrorMessage("error parsing right hand side number from <%s>\n", lhsstrptr);
    6236 retcode = SCIP_OKAY;
    6237 goto TERMINATE;
    6238 }
    6239 }
    6240
    6241 /* initialize buffers for storing the variables and coefficients */
    6242 SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
    6244
    6245 assert(varstrptr != NULL);
    6246
    6247 /* parse linear sum to get variables and coefficients */
    6248 SCIP_CALL_TERMINATE( retcode, SCIPparseVarsLinearsumExact(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success), TERMINATE );
    6249
    6250 if( *success && requsize > coefssize )
    6251 {
    6252 /* realloc buffers and try again */
    6253 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requsize) );
    6254 SCIP_CALL( SCIPrationalReallocBufferArray(SCIPbuffer(scip), &coefs, coefssize, requsize) );
    6255
    6256 coefssize = requsize;
    6257
    6258 SCIP_CALL_TERMINATE( retcode, SCIPparseVarsLinearsumExact(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success), TERMINATE );
    6259 assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
    6260 }
    6261
    6262 if( *success )
    6263 {
    6264 SCIP_CALL_TERMINATE( retcode, SCIPcreateConsExactLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
    6265 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode),
    6266 TERMINATE );
    6267 }
    6268
    6269 TERMINATE:
    6270 if( !*success )
    6271 {
    6272 SCIPerrorMessage("no luck in parsing exact linear sum '%s'\n", varstrptr);
    6273 }
    6274 if( coefs != NULL )
    6275 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &coefs, coefssize);
    6277
    6280
    6281 return retcode;
    6282}
    6283
    6284
    6285/** constraint method of constraint handler which returns the variables (if possible) */
    6286static
    6287SCIP_DECL_CONSGETVARS(consGetVarsExactLinear)
    6288{ /*lint --e{715}*/
    6289 SCIP_CONSDATA* consdata;
    6290
    6291 consdata = SCIPconsGetData(cons);
    6292 assert(consdata != NULL);
    6293
    6294 if( varssize < consdata->nvars )
    6295 (*success) = FALSE;
    6296 else
    6297 {
    6298 assert(vars != NULL);
    6299
    6300 BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
    6301 (*success) = TRUE;
    6302 }
    6303
    6304 return SCIP_OKAY;
    6305}
    6306
    6307/**! [Callback for the number of variables]*/
    6308/** constraint method of constraint handler which returns the number of variables (if possible) */
    6309static
    6310SCIP_DECL_CONSGETNVARS(consGetNVarsExactLinear)
    6311{ /*lint --e{715}*/
    6312 SCIP_CONSDATA* consdata;
    6313
    6314 consdata = SCIPconsGetData(cons);
    6315 assert(consdata != NULL);
    6316
    6317 (*nvars) = consdata->nvars;
    6318 (*success) = TRUE;
    6319
    6320 return SCIP_OKAY;
    6321}
    6322/**! [Callback for the number of variables]*/
    6323
    6324/*
    6325 * Callback methods of event handler
    6326 */
    6327
    6328static
    6329SCIP_DECL_EVENTEXEC(eventExecExactLinear)
    6330{ /*lint --e{715}*/
    6331 SCIP_CONS* cons;
    6332 SCIP_CONSDATA* consdata;
    6333 SCIP_VAR* var;
    6334 SCIP_EVENTTYPE eventtype;
    6336 assert(scip != NULL);
    6337 assert(SCIPisExact(scip));
    6338 assert(eventhdlr != NULL);
    6339 assert(eventdata != NULL);
    6340 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    6341 assert(event != NULL);
    6342
    6343 cons = eventdata->cons;
    6344 assert(cons != NULL);
    6345 consdata = SCIPconsGetData(cons);
    6346 if( consdata == NULL )
    6347 return SCIP_OKAY;
    6348 /* we can skip events dropped for deleted constraints */
    6349 if( SCIPconsIsDeleted(cons) )
    6350 return SCIP_OKAY;
    6351
    6352 eventtype = SCIPeventGetType(event);
    6353 var = SCIPeventGetVar(event);
    6354 updateActivities = ((consdata->rowexact != NULL) == eventdata->rowvar) && consdata->validactivities;
    6355 assert(!consdata->validactivities || (consdata->validminact && consdata->validmaxact && consdata->validglbminact && consdata->validglbmaxact));
    6356
    6357 if( ((eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) != 0) )
    6358 {
    6359 SCIP_Real oldbound;
    6360 SCIP_Real newbound;
    6361 SCIP_INTERVAL valrange;
    6362 int varpos;
    6363 varpos = eventdata->varpos;
    6364
    6365 oldbound = SCIPeventGetOldbound(event);
    6366 newbound = SCIPeventGetNewbound(event);
    6367 assert(var != NULL);
    6368 valrange = consdata->valsreal[varpos];
    6369
    6370 /* we only need to update the activities if the constraint is active,
    6371 * otherwise we mark them to be invalid
    6372 */
    6373 if( SCIPconsIsActive(cons) )
    6374 {
    6375 /* update the activity values */
    6376 if( (eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
    6377 consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, valrange);
    6378 else
    6379 {
    6380 assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0);
    6381 consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, valrange);
    6382 }
    6383 }
    6384 else
    6386
    6387 consdata->presolved = FALSE;
    6388 consdata->rangedrowpropagated = 0;
    6389
    6390 /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
    6391 if( (eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0 )
    6392 {
    6394
    6395 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
    6396 if( consdata->maxactdeltavar == var )
    6397 {
    6398 consdata->maxactdelta = SCIP_INVALID;
    6399 consdata->maxactdeltavar = NULL;
    6400 }
    6401
    6402 /* check whether bound tightening might now be successful */
    6403 if( consdata->boundstightened > 0)
    6404 {
    6405 switch( eventtype )
    6406 {
    6408 if( (valrange.sup > 0.0 ? !SCIPisInfinity(scip, consdata->rhsreal) : !SCIPisInfinity(scip, -consdata->lhsreal)) )
    6409 consdata->boundstightened = 0;
    6410 break;
    6412 if( (valrange.sup > 0.0 ? !SCIPisInfinity(scip, -consdata->lhsreal) : !SCIPisInfinity(scip, consdata->rhsreal)) )
    6413 consdata->boundstightened = 0;
    6414 break;
    6415 default:
    6416 SCIPerrorMessage("invalid event type %" SCIP_EVENTTYPE_FORMAT "\n", eventtype);
    6417 return SCIP_INVALIDDATA;
    6418 }
    6419 }
    6420 }
    6421 /* update maximal activity delta if a bound was relaxed */
    6422 else if( !SCIPisInfinity(scip, consdata->maxactdelta) )
    6423 {
    6424 SCIP_Real lb;
    6425 SCIP_Real ub;
    6426 SCIP_Real domain;
    6427 SCIP_Real delta;
    6428
    6429 assert((eventtype & SCIP_EVENTTYPE_BOUNDRELAXED) != 0);
    6430
    6431 lb = SCIPvarGetLbLocal(var);
    6432 ub = SCIPvarGetUbLocal(var);
    6433
    6434 domain = ub - lb;
    6435 delta = SCIPintervalAbsMax(valrange) * domain;
    6436
    6437 if( delta > consdata->maxactdelta )
    6438 {
    6439 consdata->maxactdelta = delta;
    6440 consdata->maxactdeltavar = var;
    6441 }
    6442 }
    6443 }
    6444 else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != 0 )
    6445 {
    6446 /* we want to remove the fixed variable */
    6447 consdata->presolved = FALSE;
    6448 consdata->removedfixings = FALSE;
    6449 consdata->rangedrowpropagated = 0;
    6450
    6451 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
    6452 if( consdata->maxactdeltavar == var )
    6453 {
    6454 consdata->maxactdelta = SCIP_INVALID;
    6455 consdata->maxactdeltavar = NULL;
    6456 }
    6457 }
    6458 else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != 0 )
    6459 {
    6460 /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
    6463 consdata->presolved = FALSE;
    6464 }
    6465 else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != 0 )
    6466 {
    6467 SCIP_Real oldbound;
    6468 SCIP_Real newbound;
    6469 SCIP_INTERVAL valrange;
    6470 int varpos;
    6471
    6472 varpos = eventdata->varpos;
    6473
    6474 if( updateActivities )
    6475 {
    6476 oldbound = SCIPeventGetOldbound(event);
    6477 newbound = SCIPeventGetNewbound(event);
    6478 assert(var != NULL);
    6479 assert(consdata->vars[varpos] == var);
    6480 valrange = consdata->valsreal[varpos];
    6481
    6482 consdata->rangedrowpropagated = 0;
    6483
    6484 /* update the activity values */
    6485 if( (eventtype & SCIP_EVENTTYPE_GLBCHANGED) != 0 )
    6486 consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, valrange);
    6487 else
    6488 {
    6489 assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != 0);
    6490 consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, valrange);
    6491 }
    6492 }
    6493
    6494 /* if the variable is binary but not fixed it had to become binary due to this global change */
    6496 {
    6498 consdata->indexsorted = FALSE;
    6499 else
    6500 consdata->coefsorted = FALSE;
    6501 }
    6502 }
    6503 else if( ((eventtype & SCIP_EVENTTYPE_TYPECHANGED) != 0) )
    6504 {
    6506
    6507 /* for presolving it only matters if a variable type changed from continuous to some kind of integer */
    6508 consdata->presolved = (consdata->presolved && SCIPeventGetOldtype(event) < SCIP_VARTYPE_CONTINUOUS);
    6509
    6510 /* the ordering is preserved if the type changes from something different to binary to binary but SCIPvarIsBinary() is true */
    6511 consdata->indexsorted = (consdata->indexsorted && SCIPeventGetNewtype(event) == SCIP_VARTYPE_BINARY && SCIPvarIsBinary(var));
    6512 }
    6513 else if( (eventtype & SCIP_EVENTTYPE_VARDELETED) )
    6514 {
    6515 consdata->varsdeleted = TRUE;
    6516 }
    6517 return SCIP_OKAY;
    6518}
    6519
    6520
    6521/*
    6522 * Callback methods of conflict handler
    6523 */
    6524
    6525/*
    6526 * constraint specific interface methods
    6527 */
    6528
    6529/** creates the handler for linear constraints and includes it in SCIP */
    6531 SCIP* scip /**< SCIP data structure */
    6532 )
    6533{
    6534 SCIP_CONSHDLRDATA* conshdlrdata;
    6535 SCIP_CONSHDLR* conshdlr;
    6536 SCIP_EVENTHDLR* eventhdlr;
    6537
    6538 assert(scip != NULL);
    6539
    6540 /* create event handler for bound change events */
    6542 eventExecExactLinear, NULL) );
    6543
    6544 /* create constraint handler data */
    6545 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
    6546
    6547 /* include constraint handler */
    6550 consEnfolpExactLinear, consEnfopsExactLinear, consCheckExactLinear, consLockExactLinear,
    6551 conshdlrdata) );
    6552
    6553 assert(conshdlr != NULL);
    6554
    6555 /* mark constraint handler as exact */
    6556 SCIPconshdlrMarkExact(conshdlr);
    6557
    6558 /* set non-fundamental callbacks via specific setter functions */
    6559 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyExactLinear, consCopyExactLinear) );
    6560 SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveExactLinear) );
    6561 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteExactLinear) );
    6562 SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsExactLinear) );
    6563 SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitExactLinear) );
    6564 SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreExactLinear) );
    6565 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolExactLinear) );
    6566 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeExactLinear) );
    6567 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsExactLinear) );
    6568 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsExactLinear) );
    6569 SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitExactLinear) );
    6570 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpExactLinear) );
    6571 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseExactLinear) );
    6572 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintExactLinear) );
    6573 SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropExactLinear, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
    6575 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpExactLinear, consSepasolExactLinear, CONSHDLR_SEPAFREQ,
    6577 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransExactLinear) );
    6578 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxExactLinear) );
    6579
    6580 /* add constraint handler parameters */
    6582 "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
    6583 "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
    6584 &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
    6586 "constraints/" CONSHDLR_NAME "/maxrounds",
    6587 "maximal number of separation rounds per node (-1: unlimited)",
    6588 &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
    6590 "constraints/" CONSHDLR_NAME "/maxroundsroot",
    6591 "maximal number of separation rounds per node in the root node (-1: unlimited)",
    6592 &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
    6594 "constraints/" CONSHDLR_NAME "/maxsepacuts",
    6595 "maximal number of cuts separated per separation round",
    6596 &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
    6598 "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
    6599 "maximal number of cuts separated per separation round in the root node",
    6600 &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
    6602 "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
    6603 &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
    6605 "constraints/" CONSHDLR_NAME "/propcont",
    6606 "should bounds on continuous variables be tightened by propagation?",
    6607 &conshdlrdata->propcont, TRUE, TRUE, NULL, NULL) );
    6609 "constraints/" CONSHDLR_NAME "/limitdenom",
    6610 "should denominators of rational bounds on continuous variables be controlled?",
    6611 &conshdlrdata->limitdenom, TRUE, DEFAULT_LIMITDENOM, NULL, NULL) );
    6613 "constraints/" CONSHDLR_NAME "/boundmaxdenom",
    6614 "maximal denominator for rational bounds on continuous variables after propagation",
    6615 &conshdlrdata->boundmaxdenom, TRUE, DEFAULT_BOUNDMAXDENOM, 1L, SCIP_LONGINT_MAX, NULL, NULL) );
    6616
    6617 return SCIP_OKAY;
    6618}
    6619
    6620/** creates and captures a linear constraint
    6621 *
    6622 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    6623 */
    6625 SCIP* scip, /**< SCIP data structure */
    6626 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    6627 const char* name, /**< name of constraint */
    6628 int nvars, /**< number of nonzeros in the constraint */
    6629 SCIP_VAR** vars, /**< array with variables of constraint entries */
    6630 SCIP_RATIONAL** vals, /**< array with coefficients of constraint entries */
    6631 SCIP_RATIONAL* lhs, /**< left hand side of constraint */
    6632 SCIP_RATIONAL* rhs, /**< right hand side of constraint */
    6633 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    6634 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    6635 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    6636 * Usually set to TRUE. */
    6637 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    6638 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    6639 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    6640 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    6641 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    6642 * Usually set to TRUE. */
    6643 SCIP_Bool local, /**< is constraint only valid locally?
    6644 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    6645 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    6646 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    6647 * adds coefficients to this constraint. */
    6648 SCIP_Bool dynamic, /**< is constraint subject to aging?
    6649 * Usually set to FALSE. Set to TRUE for own cuts which
    6650 * are separated as constraints. */
    6651 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    6652 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    6653 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    6654 * if it may be moved to a more global node?
    6655 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    6656 )
    6657{
    6658 SCIP_CONSHDLR* conshdlr;
    6659 SCIP_CONSDATA* consdata;
    6660 int i;
    6661
    6662 assert(scip != NULL);
    6663 assert(cons != NULL);
    6664
    6665 /* find the linear constraint handler */
    6666 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    6667 if( conshdlr == NULL )
    6668 {
    6669 SCIPerrorMessage("linear constraint handler not found\n");
    6670 return SCIP_PLUGINNOTFOUND;
    6671 }
    6672
    6673 /* terminate if a coefficient is infinite */
    6674 for( i = 0; i < nvars; ++i )
    6675 {
    6676 if( SCIPrationalIsAbsInfinity(vals[i]) )
    6677 {
    6678 SCIPerrorMessage("coefficient of variable <%s> in constraint <%s> is infinite,"
    6679 " consider adjusting the infinity threshold\n", SCIPvarGetName(vars[i]), name);
    6680 SCIPABORT();
    6681 return SCIP_INVALIDDATA;
    6682 }
    6683 }
    6684
    6685 /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
    6686 * constraint after presolving we have to ensure that it holds active variables
    6687 */
    6688 if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE && nvars > 0 )
    6689 {
    6690 SCIP_VAR** consvars;
    6691 SCIP_RATIONAL** consvals;
    6692 SCIP_RATIONAL* constant;
    6693 int nconsvars;
    6694 int requiredsize;
    6695
    6697
    6698 nconsvars = nvars;
    6699 SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
    6700 SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
    6701
    6702 /* get active variables for new constraint */
    6703 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, nconsvars, constant, &requiredsize, TRUE) );
    6704
    6705 /* if space was not enough we need to resize the buffers */
    6706 if( requiredsize > nconsvars )
    6707 {
    6708 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
    6709 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
    6710
    6711 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, requiredsize, constant, &requiredsize, TRUE) );
    6712 assert(requiredsize <= nconsvars);
    6713 }
    6714
    6715 /* adjust sides and check that we do not subtract infinity values */
    6716 if( SCIPrationalIsAbsInfinity(constant) )
    6717 {
    6718 SCIPfreeBufferArray(scip, &consvals);
    6719 SCIPfreeBufferArray(scip, &consvars);
    6721 SCIPerrorMessage("while creating constraint <%s> inactive variables lead to an infinite constant\n", name);
    6722 SCIPABORT();
    6723 return SCIP_INVALIDDATA;
    6724 }
    6725 else
    6726 {
    6727 if( !SCIPrationalIsAbsInfinity(lhs) )
    6728 SCIPrationalDiff(lhs, lhs, constant);
    6729 if( !SCIPrationalIsAbsInfinity(rhs) )
    6730 SCIPrationalDiff(rhs, rhs, constant);
    6731 }
    6732
    6733 /* create constraint data */
    6734 SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
    6735
    6736 SCIPfreeBufferArray(scip, &consvals);
    6737 SCIPfreeBufferArray(scip, &consvars);
    6739 }
    6740 else
    6741 {
    6742 /* create constraint data */
    6743 SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
    6744 }
    6745 assert(consdata != NULL);
    6746
    6747 /* create constraint */
    6748 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
    6749 local, modifiable, dynamic, removable, stickingatnode) );
    6750
    6751 return SCIP_OKAY;
    6752}
    6753
    6754/** creates and captures a linear constraint
    6755 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
    6756 * method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
    6757 *
    6758 * @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
    6759 *
    6760 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    6761 */
    6763 SCIP* scip, /**< SCIP data structure */
    6764 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    6765 const char* name, /**< name of constraint */
    6766 int nvars, /**< number of nonzeros in the constraint */
    6767 SCIP_VAR** vars, /**< array with variables of constraint entries */
    6768 SCIP_RATIONAL** vals, /**< array with coefficients of constraint entries */
    6769 SCIP_RATIONAL* lhs, /**< left hand side of constraint */
    6770 SCIP_RATIONAL* rhs /**< right hand side of constraint */
    6771 )
    6772{
    6773 assert(scip != NULL);
    6774
    6775 SCIP_CALL( SCIPcreateConsExactLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
    6777
    6778 return SCIP_OKAY;
    6779}
    6780
    6781/** creates a linear constraint from an exact linear constraint by rounding values to floating-point and captures it */
    6783 SCIP* scip, /**< target SCIP data structure */
    6784 SCIP_CONS** cons, /**< pointer to store the created target constraint */
    6785 SCIP* sourcescip, /**< source SCIP data structure */
    6786 const char* name, /**< name of constraint */
    6787 int nvars, /**< number of variables in source variable array */
    6788 SCIP_VAR** sourcevars, /**< source variables of the linear constraints */
    6789 SCIP_INTERVAL* sourcecoefs, /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
    6790 SCIP_Real lhs, /**< left hand side of the linear constraint */
    6791 SCIP_Real rhs, /**< right hand side of the linear constraint */
    6792 SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
    6793 * variables of the target SCIP */
    6794 SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
    6795 * target constraints */
    6796 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
    6797 SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
    6798 SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
    6799 SCIP_Bool check, /**< should the constraint be checked for feasibility? */
    6800 SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
    6801 SCIP_Bool local, /**< is constraint only valid locally? */
    6802 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
    6803 SCIP_Bool dynamic, /**< is constraint subject to aging? */
    6804 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
    6805 SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
    6806 * if it may be moved to a more global node? */
    6807 SCIP_Bool global, /**< create a global or a local copy? */
    6808 SCIP_Bool* valid /**< pointer to store if the copying was valid */
    6809 )
    6810{
    6811 SCIP_VAR** vars;
    6812 SCIP_Real* coefs;
    6813
    6814 SCIP_Real constant;
    6815 int requiredsize;
    6816 int v;
    6817 SCIP_Bool success;
    6818
    6819 /**@todo This method is currently only used for subSCIPs in floating-point heuristics, but should be extended to be
    6820 * able to perform an exact copy in the future. This would allow application of the cons_components presolver,
    6821 * for example. In this case, whether an exact or an fp copy is created, could probably be decided by checking
    6822 * SCIPisExact() for the target SCIP.
    6823 */
    6824 assert(!SCIPisExact(scip));
    6825 (*valid) = FALSE;
    6826
    6827 if( SCIPisGT(scip, lhs, rhs) )
    6828 {
    6829 return SCIP_OKAY;
    6830 }
    6831
    6832 if( nvars == 0 )
    6833 {
    6834 SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
    6835 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    6836 return SCIP_OKAY;
    6837 }
    6838
    6839 /* duplicate variable array */
    6840 SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, sourcevars, nvars) );
    6841
    6842 /* duplicate coefficient array */
    6843 if( sourcecoefs != NULL )
    6844 {
    6845 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
    6846 for( int i = 0; i < nvars; i++ )
    6847 {
    6848 coefs[i] = SCIPintervalGetSup(sourcecoefs[i]);
    6849 assert(!SCIPisInfinity(scip, coefs[i]) && !SCIPisInfinity(scip, -coefs[i]));
    6850 }
    6851 }
    6852 else
    6853 {
    6854 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
    6855 for( v = 0; v < nvars; ++v )
    6856 coefs[v] = 1.0;
    6857 }
    6858
    6859 constant = 0.0;
    6860
    6861 /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
    6862 * the target SCIP
    6863 */
    6864 if( !SCIPvarIsOriginal(vars[0]) )
    6865 {
    6866 SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize) );
    6867
    6868 if( requiredsize > nvars )
    6869 {
    6870 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
    6871 SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
    6872
    6873 SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize) );
    6874 assert(requiredsize <= nvars);
    6875 }
    6876 }
    6877 else
    6878 {
    6879 for( v = 0; v < nvars; ++v )
    6880 {
    6881 assert(SCIPvarIsOriginal(vars[v]));
    6882 SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
    6883 assert(vars[v] != NULL);
    6884 }
    6885 }
    6886
    6887 success = TRUE;
    6888 /* map variables of the source constraint to variables of the target SCIP */
    6889 for( v = 0; v < nvars && success; ++v )
    6890 {
    6891 SCIP_VAR* var;
    6892 var = vars[v];
    6893
    6894 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, &success) );
    6895 assert(!(success) || vars[v] != NULL);
    6896 }
    6897
    6898 /* only create the target constraint, if all variables could be copied */
    6899 if( success )
    6900 {
    6901 if( !SCIPisInfinity(scip, -lhs) )
    6902 lhs -= constant;
    6903
    6904 if( !SCIPisInfinity(scip, rhs) )
    6905 rhs -= constant;
    6906
    6907 SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
    6908 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    6909 }
    6910
    6911 /* free buffer array */
    6912 SCIPfreeBufferArray(scip, &coefs);
    6913 SCIPfreeBufferArray(scip, &vars);
    6914
    6915 return SCIP_OKAY;
    6916}
    6917
    6918/** adds coefficient to linear constraint (if it is not zero) */
    6920 SCIP* scip, /**< SCIP data structure */
    6921 SCIP_CONS* cons, /**< constraint data */
    6922 SCIP_VAR* var, /**< variable of constraint entry */
    6923 SCIP_RATIONAL* val /**< coefficient of constraint entry */
    6924 )
    6925{
    6926 assert(scip != NULL);
    6927 assert(cons != NULL);
    6928 assert(var != NULL);
    6929
    6930 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    6931 {
    6932 SCIPerrorMessage("constraint is not of type exactlinear\n");
    6933 return SCIP_INVALIDDATA;
    6934 }
    6935
    6936 /* terminate if coefficient is infinite */
    6937 if( SCIPrationalIsAbsInfinity(val) )
    6938 {
    6939 SCIPerrorMessage("coefficient of variable <%s> in constraint <%s> is infinite,"
    6940 " consider adjusting the infinity threshold\n", SCIPvarGetName(var), SCIPconsGetName(cons));
    6941 SCIPABORT();
    6942 return SCIP_INVALIDDATA;
    6943 }
    6944
    6945 /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
    6946 * constraint after presolving we have to ensure that it holds active variables
    6947 */
    6949 {
    6950 SCIP_CONSDATA* consdata;
    6951 SCIP_VAR** consvars;
    6952 SCIP_RATIONAL** consvals;
    6953 SCIP_RATIONAL* constant;
    6954 SCIP_RATIONAL* rhs;
    6955 SCIP_RATIONAL* lhs;
    6956 int nconsvars;
    6957 int requiredsize;
    6958 int v;
    6959
    6960 SCIPerrorMessage("adding coefficients after presolving not supported yet in exact solving mode \n");
    6961 SCIPABORT();
    6962
    6963 nconsvars = 1;
    6964 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
    6965 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
    6966 consvars[0] = var;
    6967 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &consvals[0], val) );
    6969
    6970 /* get active variables for new constraint */
    6971 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, nconsvars, constant, &requiredsize, TRUE) );
    6972
    6973 /* if space was not enough we need to resize the buffers */
    6974 if( requiredsize > nconsvars )
    6975 {
    6976 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
    6977 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
    6978
    6979 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, requiredsize, constant, &requiredsize, TRUE) );
    6980 assert(requiredsize <= nconsvars);
    6981 }
    6982
    6983 consdata = SCIPconsGetData(cons);
    6984 assert(consdata != NULL);
    6985
    6986 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &lhs, consdata->lhs) );
    6987 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &rhs, consdata->rhs) );
    6988
    6989 /* adjust sides and check that we do not subtract infinity values */
    6990 if( SCIPrationalIsAbsInfinity(constant) )
    6991 {
    6992 SCIPfreeBufferArray(scip, &consvals);
    6993 SCIPfreeBufferArray(scip, &consvars);
    6994
    6995 SCIPerrorMessage("adding variable <%s> to constraint <%s> leads to infinite constant and cannot be handled safely\n",
    6996 SCIPvarGetName(var), SCIPconsGetName(cons));
    6997
    6998 SCIPABORT();
    6999 return SCIP_INVALIDDATA; /*lint !e527*/
    7000 }
    7001 /* constant is not infinite */
    7002 else
    7003 {
    7004 if( !SCIPrationalIsAbsInfinity(lhs) )
    7005 SCIPrationalDiff(lhs, lhs, constant);
    7006 if( !SCIPrationalIsAbsInfinity(rhs) )
    7007 SCIPrationalDiff(rhs, rhs, constant);
    7008 }
    7009
    7010 /* add all active variables to constraint */
    7011 for( v = nconsvars - 1; v >= 0; --v )
    7012 {
    7013 SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
    7014 }
    7015
    7016 /* update left and right hand sides */
    7017 SCIP_CALL( chgLhs(scip, cons, lhs) );
    7018 SCIP_CALL( chgRhs(scip, cons, rhs) );
    7019
    7021 SCIPfreeBufferArray(scip, &consvals);
    7022 SCIPfreeBufferArray(scip, &consvars);
    7023 }
    7024 else
    7025 {
    7026 SCIP_CALL( addCoef(scip, cons, var, val) );
    7027 }
    7028
    7029 return SCIP_OKAY;
    7030}
    7031
    7032/** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
    7033 * not yet contained in the constraint
    7034 *
    7035 * @note This method may only be called during problem creation stage for an original constraint and variable.
    7036 *
    7037 * @note This method requires linear time to search for occurences of the variable in the constraint data.
    7038 */
    7040 SCIP* scip, /**< SCIP data structure */
    7041 SCIP_CONS* cons, /**< constraint data */
    7042 SCIP_VAR* var, /**< variable of constraint entry */
    7043 SCIP_RATIONAL* val /**< new coefficient of constraint entry */
    7044 )
    7045{
    7046 SCIP_CONSDATA* consdata;
    7047 SCIP_VAR** vars;
    7048 SCIP_Bool found;
    7049 int i;
    7050
    7051 assert(scip != NULL);
    7052 assert(cons != NULL);
    7053 assert(var != NULL);
    7054
    7055 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7056 {
    7057 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7058 return SCIP_INVALIDDATA;
    7059 }
    7060
    7062 {
    7063 SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
    7064 return SCIP_INVALIDDATA;
    7065 }
    7066
    7067 consdata = SCIPconsGetData(cons);
    7068 assert(consdata != NULL);
    7069
    7070 vars = consdata->vars;
    7071 found = FALSE;
    7072 i = 0;
    7073 while( i < consdata->nvars )
    7074 {
    7075 if( vars[i] == var )
    7076 {
    7077 if( found || SCIPrationalIsZero(val) )
    7078 {
    7079 SCIP_CALL( delCoefPos(scip, cons, i) );
    7080
    7081 /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
    7082 i--;
    7083 }
    7084 else
    7085 {
    7086 SCIP_CALL( chgCoefPos(scip, cons, i, val) );
    7087 }
    7088 found = TRUE;
    7089 }
    7090 i++;
    7091 }
    7092
    7093 if( !found && !SCIPrationalIsZero(val) )
    7094 {
    7095 SCIP_CALL( SCIPaddCoefExactLinear(scip, cons, var, val) );
    7096 }
    7097
    7098 return SCIP_OKAY;
    7099}
    7100
    7101/** deletes variable from linear constraint
    7102 *
    7103 * @note This method may only be called during problem creation stage for an original constraint and variable.
    7104 *
    7105 * @note This method requires linear time to search for occurences of the variable in the constraint data.
    7106 */
    7108 SCIP* scip, /**< SCIP data structure */
    7109 SCIP_CONS* cons, /**< constraint data */
    7110 SCIP_VAR* var /**< variable of constraint entry */
    7111 )
    7112{
    7113 SCIP_RATIONAL* temp;
    7114
    7115 assert(scip != NULL);
    7116 assert(cons != NULL);
    7117 assert(var != NULL);
    7118
    7120
    7121 SCIP_CALL( SCIPchgCoefExactLinear(scip, cons, var, temp) );
    7122
    7124
    7125 return SCIP_OKAY;
    7126}
    7127
    7128/** gets left hand side of linear constraint */
    7130 SCIP* scip, /**< SCIP data structure */
    7131 SCIP_CONS* cons /**< constraint data */
    7132 )
    7133{
    7134 SCIP_CONSDATA* consdata;
    7135
    7136 assert(scip != NULL);
    7137 assert(cons != NULL);
    7138
    7139 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7140 {
    7141 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7142 SCIPABORT();
    7143 return NULL; /*lint !e527*/
    7144 }
    7145
    7146 consdata = SCIPconsGetData(cons);
    7147 assert(consdata != NULL);
    7148
    7149 return consdata->lhs;
    7150}
    7151
    7152/** gets right hand side of linear constraint */
    7154 SCIP* scip, /**< SCIP data structure */
    7155 SCIP_CONS* cons /**< constraint data */
    7156 )
    7157{
    7158 SCIP_CONSDATA* consdata;
    7159
    7160 assert(scip != NULL);
    7161 assert(cons != NULL);
    7162
    7163 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7164 {
    7165 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7166 SCIPABORT();
    7167 return NULL; /*lint !e527*/
    7168 }
    7169
    7170 consdata = SCIPconsGetData(cons);
    7171 assert(consdata != NULL);
    7172
    7173 return consdata->rhs;
    7174}
    7175
    7176/** changes left hand side of linear constraint */
    7178 SCIP* scip, /**< SCIP data structure */
    7179 SCIP_CONS* cons, /**< constraint data */
    7180 SCIP_RATIONAL* lhs /**< new left hand side */
    7181 )
    7182{
    7183 assert(scip != NULL);
    7184 assert(cons != NULL);
    7185
    7186 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7187 {
    7188 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7189 return SCIP_INVALIDDATA;
    7190 }
    7191
    7192 SCIP_CALL( chgLhs(scip, cons, lhs) );
    7193
    7194 return SCIP_OKAY;
    7195}
    7196
    7197/** changes right hand side of linear constraint */
    7199 SCIP* scip, /**< SCIP data structure */
    7200 SCIP_CONS* cons, /**< constraint data */
    7201 SCIP_RATIONAL* rhs /**< new right hand side */
    7202 )
    7203{
    7204 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7205 {
    7206 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7207 return SCIP_INVALIDDATA;
    7208 }
    7209
    7210 SCIP_CALL( chgRhs(scip, cons, rhs) );
    7211
    7212 return SCIP_OKAY;
    7213}
    7214
    7215/** gets the number of variables in the linear constraint */
    7217 SCIP* scip, /**< SCIP data structure */
    7218 SCIP_CONS* cons /**< constraint data */
    7219 )
    7220{
    7221 SCIP_CONSDATA* consdata;
    7222
    7223 assert(scip != NULL);
    7224 assert(cons != NULL);
    7225
    7226 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7227 {
    7228 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7229 SCIPABORT();
    7230 return -1; /*lint !e527*/
    7231 }
    7232
    7233 consdata = SCIPconsGetData(cons);
    7234 assert(consdata != NULL);
    7235
    7236 return consdata->nvars;
    7237}
    7238
    7239/** gets the array of variables in the linear constraint; the user must not modify this array! */
    7241 SCIP* scip, /**< SCIP data structure */
    7242 SCIP_CONS* cons /**< constraint data */
    7243 )
    7244{
    7245 SCIP_CONSDATA* consdata;
    7246
    7247 assert(scip != NULL);
    7248 assert(cons != NULL);
    7249
    7250 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7251 {
    7252 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7253 SCIPABORT();
    7254 return NULL; /*lint !e527*/
    7255 }
    7256
    7257 consdata = SCIPconsGetData(cons);
    7258 assert(consdata != NULL);
    7259
    7260 return consdata->vars;
    7261}
    7262
    7263/** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
    7265 SCIP* scip, /**< SCIP data structure */
    7266 SCIP_CONS* cons /**< constraint data */
    7267 )
    7268{
    7269 SCIP_CONSDATA* consdata;
    7270
    7271 assert(scip != NULL);
    7272 assert(cons != NULL);
    7273
    7274 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7275 {
    7276 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7277 SCIPABORT();
    7278 return NULL; /*lint !e527*/
    7279 }
    7280
    7281 consdata = SCIPconsGetData(cons);
    7282 assert(consdata != NULL);
    7283
    7284 return consdata->valsreal;
    7285}
    7286
    7287/** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
    7289 SCIP* scip, /**< SCIP data structure */
    7290 SCIP_CONS* cons /**< constraint data */
    7291 )
    7292{
    7293 SCIP_CONSDATA* consdata;
    7294
    7295 assert(scip != NULL);
    7296 assert(cons != NULL);
    7297
    7298 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7299 {
    7300 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7301 SCIPABORT();
    7302 return NULL; /*lint !e527*/
    7303 }
    7304
    7305 consdata = SCIPconsGetData(cons);
    7306 assert(consdata != NULL);
    7307
    7308 return consdata->vals;
    7309}
    7310
    7311/** gets the activity of the linear constraint in the given solution
    7312 *
    7313 * @note if the activity comprises positive and negative infinity contributions, the result is currently undefined
    7314 */
    7316 SCIP* scip, /**< SCIP data structure */
    7317 SCIP_CONS* cons, /**< constraint data */
    7318 SCIP_SOL* sol, /**< solution, or NULL to use current node's solution */
    7319 SCIP_RATIONAL* ret
    7320 )
    7321{
    7322 SCIP_CONSDATA* consdata;
    7323
    7324 assert(scip != NULL);
    7325 assert(cons != NULL);
    7326
    7327 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7328 {
    7329 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7330 SCIPABORT();
    7331 SCIPrationalSetInfinity(ret); /*lint !e527*/
    7332 }
    7333
    7334 consdata = SCIPconsGetData(cons);
    7335 assert(consdata != NULL);
    7336
    7337 if( consdata->rowexact != NULL )
    7338 {
    7339 SCIP_CALL( SCIPgetRowSolActivityExact(scip, consdata->rowexact, sol, FALSE, ret) );
    7340 }
    7341 else
    7342 consdataGetActivity(scip, consdata, sol, TRUE, ret);
    7343
    7344 return SCIP_OKAY;
    7345}
    7346
    7347/** gets the feasibility of the linear constraint in the given solution */
    7349 SCIP* scip, /**< SCIP data structure */
    7350 SCIP_CONS* cons, /**< constraint data */
    7351 SCIP_SOL* sol, /**< solution, or NULL to use current node's solution */
    7352 SCIP_RATIONAL* ret /**< pointer to store the result */
    7353 )
    7354{
    7355 SCIP_CONSDATA* consdata;
    7356
    7357 assert(scip != NULL);
    7358 assert(cons != NULL);
    7359
    7360 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7361 {
    7362 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7363 SCIPABORT();
    7364 }
    7365
    7366 consdata = SCIPconsGetData(cons);
    7367 assert(consdata != NULL);
    7368
    7369 if( consdata->rowexact != NULL )
    7370 SCIP_CALL( SCIPgetRowSolFeasibilityExact(scip, consdata->rowexact, sol, ret) );
    7371 else
    7372 consdataGetFeasibility(scip, consdata, sol, ret);
    7373
    7374 return SCIP_OKAY;
    7375}
    7376
    7377/** gets the dual solution of the linear constraint in the current LP
    7378 *
    7379 * @note this method currently returns the value from the floating-point LP
    7380 */
    7382 SCIP* scip, /**< SCIP data structure */
    7383 SCIP_CONS* cons, /**< constraint data */
    7384 SCIP_RATIONAL* ret /**< result pointer */
    7385 )
    7386{
    7387 SCIP_CONSDATA* consdata;
    7388
    7389 assert(scip != NULL);
    7390 assert(cons != NULL);
    7391 assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
    7392
    7393 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7394 {
    7395 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7396 SCIPABORT();
    7397 }
    7398
    7399 consdata = SCIPconsGetData(cons);
    7400 assert(consdata != NULL);
    7401
    7402 if( consdata->rowlhs != NULL )
    7403 SCIPrationalSetReal(ret, SCIProwGetDualsol(consdata->rowlhs));
    7404 else
    7405 SCIPrationalSetReal(ret, 0.0);
    7406}
    7407
    7408/** gets the dual Farkas value of the linear constraint in the current infeasible LP
    7409 *
    7410 * @note this method currently returns an approximate value from the floating-point LP
    7411 */
    7413 SCIP* scip, /**< SCIP data structure */
    7414 SCIP_CONS* cons, /**< constraint data */
    7415 SCIP_RATIONAL* ret /**< result pointer */
    7416 )
    7417{
    7418 SCIP_CONSDATA* consdata;
    7419
    7420 assert(scip != NULL);
    7421 assert(cons != NULL);
    7422 assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
    7423
    7424 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7425 {
    7426 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7427 SCIPABORT();
    7428 }
    7429
    7430 consdata = SCIPconsGetData(cons);
    7431 assert(consdata != NULL);
    7432
    7433 if( consdata->rowlhs != NULL )
    7434 SCIPrationalSetReal(ret, SCIProwGetDualfarkas(consdata->rowlhs));
    7435 else
    7436 SCIPrationalSetReal(ret, 0.0);
    7437}
    7438
    7439/** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
    7440 * the user must not modify the row!
    7441 */
    7443 SCIP* scip, /**< SCIP data structure */
    7444 SCIP_CONS* cons /**< constraint data */
    7445 )
    7446{
    7447 SCIP_CONSDATA* consdata;
    7448
    7449 assert(scip != NULL);
    7450 assert(cons != NULL);
    7451
    7452 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7453 {
    7454 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7455 SCIPABORT();
    7456 return NULL; /*lint !e527*/
    7457 }
    7458
    7459 consdata = SCIPconsGetData(cons);
    7460 assert(consdata != NULL);
    7461
    7462 return consdata->rowlhs;
    7463}
    7464
    7465/** returns the exact linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
    7466 * the user must not modify the row!
    7467 */
    7469 SCIP* scip, /**< SCIP data structure */
    7470 SCIP_CONS* cons /**< constraint data */
    7471 )
    7472{
    7473 SCIP_CONSDATA* consdata;
    7474
    7475 assert(scip != NULL);
    7476 assert(cons != NULL);
    7477
    7478 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    7479 {
    7480 SCIPerrorMessage("constraint is not of type exactlinear\n");
    7481 SCIPABORT();
    7482 return NULL; /*lint !e527*/
    7483 }
    7484
    7485 consdata = SCIPconsGetData(cons);
    7486 assert(consdata != NULL);
    7487
    7488 return consdata->rowexact;
    7489}
    static long bound
    internal methods for clocks and timing issues
    enum Proprule PROPRULE
    Definition: cons_and.c:173
    Proprule
    Definition: cons_and.c:166
    struct InferInfo INFERINFO
    enum Proprule PROPRULE
    static SCIP_DECL_CONSINITLP(consInitlpExactLinear)
    static SCIP_DECL_CONSINIT(consInitExactLinear)
    static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
    static void permSortConsdata(SCIP_CONSDATA *consdata, int *perm, int nvars)
    #define CONSHDLR_NEEDSCONS
    static void consdataRecomputeMaxActivityDelta(SCIP *scip, SCIP_CONSDATA *consdata)
    #define CONSHDLR_SEPAFREQ
    static SCIP_DECL_CONSTRANS(consTransExactLinear)
    static SCIP_RETCODE addRelaxation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff)
    static SCIP_DECL_CONSDELVARS(consDelvarsExactLinear)
    static SCIP_DECL_CONSEXITPRE(consExitpreExactLinear)
    static void consdataUpdateActivitiesLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb, SCIP_INTERVAL val)
    static void consdataUpdateAddCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_RATIONAL *valExact, SCIP_INTERVAL val)
    static void getMaxActivity(SCIP *scip, SCIP_CONSDATA *consdata, int posinf, int neginf, int poshuge, int neghuge, SCIP_Real delta, SCIP_Bool global, SCIP_Bool goodrelax, SCIP_Real *maxactivity, SCIP_Bool *isrelax, SCIP_Bool *issettoinfinity)
    #define CONSHDLR_CHECKPRIORITY
    #define CONSHDLR_DESC
    static SCIP_RATIONAL * consdataGetMinAbsvalEx(SCIP *scip, SCIP_CONSDATA *consdata)
    static SCIP_DECL_CONSDELETE(consDeleteExactLinear)
    static void consdataCalcMinAbsvalEx(SCIP_CONSDATA *consdata)
    static SCIP_DECL_SORTINDCOMP(consdataCompVar)
    static void consdataRecomputeMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
    static SCIP_RETCODE chgCoefPos(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_RATIONAL *newval)
    static SCIP_DECL_CONSCHECK(consCheckExactLinear)
    #define CONSHDLR_PROP_TIMING
    static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
    static SCIP_Bool consdataComputeSolActivityWithErrorbound(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol, SCIP_Real *activity, SCIP_Real *errorbound)
    static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
    static SCIP_DECL_CONSPARSE(consParseExactLinear)
    static void consdataRecomputeGlbMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
    static SCIP_RETCODE printActivityConflictToCertificate(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_Bool rhs)
    static void consdataUpdateDelCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_RATIONAL *valExact, SCIP_INTERVAL val)
    static void consdataRecomputeMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
    static SCIP_RETCODE chgRhs(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *rhs)
    static SCIP_RETCODE performVarDeletions(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss)
    #define checkMaxActivityDelta(scip, consdata)
    #define DEFAULT_LIMITDENOM
    #define CONSHDLR_SEPAPRIORITY
    #define DEFAULT_MAXROUNDSROOT
    static void consdataGetActivityResiduals(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_INTERVAL val, SCIP_Bool goodrelax, SCIP_Real *minresactivity, SCIP_Real *maxresactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
    static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_SOL *sol, int *ncuts, SCIP_Bool *cutoff)
    static SCIP_DECL_CONSENFORELAX(consEnforelaxExactLinear)
    static void consdataGetActivityBounds(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Bool goodrelax, SCIP_Real *minactivity, SCIP_Real *maxactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
    static SCIP_RETCODE propagateCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool tightenbounds, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
    static SCIP_RETCODE consPrintConsSol(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool useexactsol, FILE *file)
    static SCIP_RETCODE mergeMultiples(SCIP *scip, SCIP_CONS *cons)
    static void consdataCheckNonbinvar(SCIP_CONSDATA *consdata)
    #define DEFAULT_SORTVARS
    static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_CONS *cons, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
    #define DEFAULT_BOUNDMAXDENOM
    static SCIP_RETCODE consCatchEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
    static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
    static void consdataUpdateActivitiesGlbUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldub, SCIP_Real newub, SCIP_INTERVAL val)
    static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs)
    static SCIP_DECL_CONSDEACTIVE(consDeactiveExactLinear)
    #define DEFAULT_MAXSEPACUTSROOT
    @ PROPRULE_1_RANGEDROW
    @ PROPRULE_1_LHS
    @ PROPRULE_INVALID
    @ PROPRULE_1_RHS
    static SCIP_RETCODE consDropAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
    static void consdataUpdateActivitiesGlbLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldlb, SCIP_Real newlb, SCIP_INTERVAL val)
    static SCIP_RETCODE findOperators(const char *str, char **firstoperator, char **secondoperator, SCIP_Bool *success)
    static SCIP_RETCODE checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_SOL *sol, SCIP_Bool useexactsol, SCIP_Bool checklprows, SCIP_Bool *violated)
    static SCIP_RETCODE chgLhs(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *lhs)
    static SCIP_DECL_CONSGETVARS(consGetVarsExactLinear)
    static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, int pos)
    static SCIP_DECL_CONSPROP(consPropExactLinear)
    static void consdataUpdateActivitiesUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub, SCIP_INTERVAL val)
    #define CONSHDLR_PROPFREQ
    static void consdataComputePseudoActivity(SCIP_CONSDATA *consdata, SCIP_RATIONAL *pseudoactivity)
    static SCIP_RETCODE createRows(SCIP *scip, SCIP_CONS *cons)
    static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyExactLinear)
    static SCIP_DECL_CONSGETNVARS(consGetNVarsExactLinear)
    static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result)
    static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
    #define DEFAULT_MAXSEPACUTS
    static void consdataGetActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol, SCIP_Bool useexact, SCIP_RATIONAL *activity)
    static void consdataScaleMinValue(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real minval)
    #define CONSHDLR_EAGERFREQ
    #define DEFAULT_TIGHTENBOUNDSFREQ
    static SCIP_DECL_CONSCOPY(consCopyExactLinear)
    static SCIP_DECL_CONSEXITSOL(consExitsolExactLinear)
    #define EVENTHDLR_DESC
    static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
    static void consdataRecomputeGlbMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
    static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
    static void consdataCalcActivities(SCIP *scip, SCIP_CONSDATA *consdata)
    static SCIP_DECL_CONSFREE(consFreeExactLinear)
    #define DEFAULT_MAXROUNDS
    static SCIP_DECL_CONSLOCK(consLockExactLinear)
    static SCIP_DECL_EVENTEXEC(eventExecExactLinear)
    static SCIP_DECL_CONSENFOPS(consEnfopsExactLinear)
    #define CONSHDLR_ENFOPRIORITY
    static int getInferInt(PROPRULE proprule, int pos)
    static SCIP_DECL_CONSENFOLP(consEnfolpExactLinear)
    #define CONSHDLR_DELAYSEPA
    static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
    static void consdataInvalidateActivities(SCIP_CONSDATA *consdata)
    static SCIP_RETCODE consDropEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
    static SCIP_RETCODE tightenVarBounds(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
    static void consdataGetFeasibility(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol, SCIP_RATIONAL *ret)
    #define CONSHDLR_NAME
    static SCIP_DECL_CONSSEPALP(consSepalpExactLinear)
    static int inferInfoToInt(INFERINFO inferinfo)
    static SCIP_RETCODE consdataSort(SCIP *scip, SCIP_CONSDATA *consdata)
    #define EVENTHDLR_NAME
    static void consdataUpdateChgCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_INTERVAL oldval, SCIP_RATIONAL *oldvalExact, SCIP_INTERVAL newval, SCIP_RATIONAL *newvalExact)
    static SCIP_RETCODE consCatchAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
    static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
    static SCIP_DECL_CONSPRINT(consPrintExactLinear)
    #define CONSHDLR_DELAYPROP
    static void consdataUpdateActivities(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_INTERVAL valrange, SCIP_BOUNDTYPE boundtype, SCIP_Bool global)
    static SCIP_DECL_CONSSEPASOL(consSepasolExactLinear)
    static void getMinActivity(SCIP *scip, SCIP_CONSDATA *consdata, int posinf, int neginf, int poshuge, int neghuge, SCIP_Real delta, SCIP_Bool global, SCIP_Bool goodrelax, SCIP_Real *minactivity, SCIP_Bool *isrelax, SCIP_Bool *issettoinfinity)
    static SCIP_DECL_CONSEXIT(consExitExactLinear)
    static INFERINFO getInferInfo(PROPRULE proprule, int pos)
    #define MAXTIGHTENROUNDS
    Constraint handler for linear constraints in their most general form, .
    Constraint handler for knapsack constraints of the form , x binary and .
    Constraint handler for linear constraints in their most general form, .
    constraint handler for nonlinear constraints specified by algebraic expressions
    methods for debugging
    common defines and data types used in all packages of SCIP
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_MAXTREEDEPTH
    Definition: def.h:297
    #define SCIP_REAL_UNITROUNDOFF
    Definition: def.h:160
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define SCIP_UNKNOWN
    Definition: def.h:179
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_CALL_TERMINATE(retcode, x, TERM)
    Definition: def.h:376
    #define SCIPABORT()
    Definition: def.h:327
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_LONGINT_MAX
    Definition: def.h:142
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPchgLhsExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *lhs)
    SCIP_RATIONAL * SCIPgetLhsExactLinear(SCIP *scip, SCIP_CONS *cons)
    void SCIPgetFpDualsolExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *ret)
    SCIP_RATIONAL * SCIPgetRhsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPchgRhsExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *rhs)
    SCIP_RETCODE SCIPcreateConsExactLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *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_VAR ** SCIPgetVarsExactLinear(SCIP *scip, SCIP_CONS *cons)
    void SCIPgetFpDualfarkasExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *ret)
    SCIP_RETCODE SCIPcopyConsExactLinear(SCIP *scip, SCIP_CONS **cons, SCIP *sourcescip, const char *name, int nvars, SCIP_VAR **sourcevars, SCIP_INTERVAL *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)
    int SCIPgetNVarsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPaddCoefExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
    SCIP_RETCODE SCIPcertifyConsOrigExactLinear(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS *cons)
    SCIP_RETCODE SCIPgetActivityExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_RATIONAL *ret)
    SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_RETCODE SCIPcreateConsBasicExactLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs)
    SCIP_ROWEXACT * SCIPgetRowExactExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_INTERVAL * SCIPgetValsRealExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RATIONAL ** SCIPgetValsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPdelCoefExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
    SCIP_ROW * SCIPgetRowExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPgetFeasibilityExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_RATIONAL *ret)
    SCIP_RETCODE SCIPchgCoefExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
    SCIP_RETCODE SCIPincludeConshdlrExactLinear(SCIP *scip)
    SCIP_Bool SCIPisConsCompressionEnabled(SCIP *scip)
    Definition: scip_copy.c:662
    SCIP_RETCODE SCIPgetVarCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR *sourcevar, SCIP_VAR **targetvar, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *success)
    Definition: scip_copy.c:713
    SCIP_Bool SCIPisTransformed(SCIP *scip)
    Definition: scip_general.c:647
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3420
    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
    SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
    Definition: scip_message.c:88
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:111
    SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    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 SCIPgetIntParam(SCIP *scip, const char *name, int *value)
    Definition: scip_param.c:269
    SCIP_RETCODE SCIPcertifyCons(SCIP *scip, SCIP_Bool isorigfile, const char *consname, const char sense, SCIP_RATIONAL *side, int len, int *ind, SCIP_RATIONAL **val)
    SCIP_RETCODE SCIPcertifyActivityVarBound(SCIP *scip, const char *linename, SCIP_BOUNDTYPE boundtype, SCIP_Real newbound, SCIP_Bool ismaxactivity, SCIP_CONS *constraint, SCIP_VAR *variable, SCIP_ROWEXACT *row, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_VAR **vars, int nvars)
    SCIP_RETCODE SCIPcertifyActivityConflict(SCIP *scip, SCIP_CONS *cons, SCIP_ROWEXACT *row, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, int nvals, SCIP_RATIONAL **vals, SCIP_VAR **vars, SCIP_RATIONAL *diff, SCIP_Bool userhs)
    SCIP_Bool SCIPisCertified(SCIP *scip)
    SCIP_RETCODE SCIPcertifyActivityVarBoundExact(SCIP *scip, const char *linename, SCIP_BOUNDTYPE boundtype, SCIP_RATIONAL *newbound, SCIP_Bool ismaxactivity, SCIP_CONS *constraint, SCIP_VAR *variable, SCIP_ROWEXACT *row, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_VAR **vars, int nvars)
    SCIP_Bool SCIPshouldCertificateTrackBounds(SCIP *scip)
    SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
    Definition: scip_cons.c:808
    void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: cons.c:4346
    SCIP_RETCODE SCIPsetConshdlrInit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINIT((*consinit)))
    Definition: scip_cons.c:396
    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
    void SCIPconshdlrMarkExact(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4370
    SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
    Definition: scip_cons.c:693
    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
    int SCIPconshdlrGetPropFreq(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:5282
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXIT((*consexit)))
    Definition: scip_cons.c:420
    SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
    Definition: scip_cons.c:516
    SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
    Definition: scip_cons.c:347
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
    Definition: scip_cons.c:468
    SCIP_RETCODE SCIPsetConshdlrDelvars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELVARS((*consdelvars)))
    Definition: scip_cons.c:762
    SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
    Definition: scip_cons.c:624
    SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4336
    SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
    Definition: scip_cons.c:601
    SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
    Definition: scip_cons.c:854
    SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
    Definition: scip_cons.c:785
    SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
    Definition: cons.c:8419
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8648
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8558
    SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
    Definition: cons.c:8688
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8588
    SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
    Definition: cons.c:8518
    SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
    Definition: cons.c:8698
    SCIP_Bool SCIPconsIsLockedType(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
    Definition: cons.c:8782
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8578
    SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:2042
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8450
    SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: scip_cons.c:997
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8608
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8628
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1812
    SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:2014
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8638
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8668
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8568
    SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1784
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8658
    SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
    Definition: scip_cut.c:225
    SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: scip_event.c:111
    const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:396
    SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
    Definition: event.c:1194
    SCIP_VARTYPE SCIPeventGetNewtype(SCIP_EVENT *event)
    Definition: event.c:1479
    SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: scip_event.c:367
    SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: scip_event.c:413
    SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
    Definition: event.c:1391
    SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
    Definition: event.c:1217
    SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
    Definition: event.c:1415
    SCIP_VARTYPE SCIPeventGetOldtype(SCIP_EVENT *event)
    Definition: event.c:1462
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    SCIP_RETCODE SCIPaddRowExact(SCIP *scip, SCIP_ROWEXACT *rowexact)
    Definition: scip_exact.c:257
    void SCIPintervalSetRoundingModeUpwards(void)
    void SCIPintervalSetRoundingModeDownwards(void)
    SCIP_ROUNDMODE SCIPintervalGetRoundingMode(void)
    void SCIPintervalSetRoundingMode(SCIP_ROUNDMODE roundmode)
    SCIP_Real SCIPintervalAbsMax(SCIP_INTERVAL interval)
    void SCIPintervalSubScalar(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_Real operand2)
    int SCIP_ROUNDMODE
    Definition: intervalarith.h:65
    void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
    void SCIPintervalDiv(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
    SCIP_Real SCIPintervalGetSup(SCIP_INTERVAL interval)
    SCIP_Real SCIPintervalNegateReal(SCIP_Real x)
    void SCIPintervalSetRational(SCIP_INTERVAL *resultant, SCIP_RATIONAL *value)
    SCIP_RETCODE SCIPreleaseRowExact(SCIP *scip, SCIP_ROWEXACT **row)
    Definition: scip_lpexact.c:110
    SCIP_Bool SCIPgetRowSolActivityWithErrorboundExact(SCIP *scip, SCIP_ROWEXACT *row, SCIP_SOL *sol, SCIP_Real *activity, SCIP_Real *errorbound)
    Definition: scip_lpexact.c:396
    SCIP_RETCODE SCIPprintRowExact(SCIP *scip, SCIP_ROWEXACT *row, FILE *file)
    Definition: scip_lpexact.c:419
    SCIP_RETCODE SCIPgenerateFpRowsFromRowExact(SCIP *scip, SCIP_ROWEXACT *row, SCIP_ROW *rowlhs, SCIP_ROW *rowrhs, SCIP_Bool *onerowrelax, SCIP_Bool *hasfprelax)
    Definition: scip_lpexact.c:309
    SCIP_RETCODE SCIPgetRowSolActivityExact(SCIP *scip, SCIP_ROWEXACT *row, SCIP_SOL *sol, SCIP_Bool useexact, SCIP_RATIONAL *result)
    Definition: scip_lpexact.c:367
    SCIP_RETCODE SCIPgetRowSolFeasibilityExact(SCIP *scip, SCIP_ROWEXACT *row, SCIP_SOL *sol, SCIP_RATIONAL *result)
    Definition: scip_lpexact.c:335
    SCIP_RETCODE SCIPchgRowExactLhs(SCIP *scip, SCIP_ROWEXACT *row, SCIP_RATIONAL *lhs)
    Definition: scip_lpexact.c:131
    SCIP_RETCODE SCIPcreateEmptyRowConsExact(SCIP *scip, SCIP_ROWEXACT **rowexact, SCIP_ROW *fprow, SCIP_ROW *fprowrhs, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_Bool isfprelaxable)
    Definition: scip_lpexact.c:228
    SCIP_RETCODE SCIPchgRowExactRhs(SCIP *scip, SCIP_ROWEXACT *row, SCIP_RATIONAL *rhs)
    Definition: scip_lpexact.c:155
    SCIP_RETCODE SCIPaddVarsToRowExact(SCIP *scip, SCIP_ROWEXACT *row, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals)
    Definition: scip_lpexact.c:182
    SCIP_Bool SCIPlpExactIsSolved(SCIP *scip)
    Definition: scip_lpexact.c:456
    SCIP_RETCODE SCIPcaptureRowExact(SCIP *scip, SCIP_ROWEXACT *row)
    Definition: scip_lpexact.c:88
    SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
    Definition: scip_lp.c:87
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    BMS_BUFMEM * SCIPbuffer(SCIP *scip)
    Definition: scip_mem.c:72
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPfreeBufferArrayNull(scip, ptr)
    Definition: scip_mem.h:137
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    SCIP_Bool SCIPinProbing(SCIP *scip)
    Definition: scip_probing.c:98
    SCIP_Bool SCIPrationalIsLTReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1576
    void SCIPrationalMin(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1342
    SCIP_RETCODE SCIPrationalCreateBlock(BMS_BLKMEM *blkmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:108
    SCIP_RETCODE SCIPrationalCreate(SCIP_RATIONAL **rational)
    Definition: rational.cpp:94
    void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1066
    SCIP_Bool SCIPrationalIsAbsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1421
    void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:618
    void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:935
    SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
    Definition: rational.cpp:2085
    SCIP_RETCODE SCIPrationalCreateString(BMS_BLKMEM *mem, SCIP_RATIONAL **rational, const char *desc)
    Definition: rational.cpp:796
    void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:461
    #define SCIPrationalDebugMessage
    Definition: rational.h:641
    void SCIPrationalAbs(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
    Definition: rational.cpp:1310
    void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1132
    SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1680
    SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1503
    void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
    Definition: rational.cpp:603
    SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1474
    SCIP_RETCODE SCIPrationalCopyBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **result, SCIP_RATIONAL *src)
    Definition: rational.cpp:151
    void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:473
    SCIP_RETCODE SCIPrationalCopyBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***target, SCIP_RATIONAL **src, int len)
    Definition: rational.cpp:249
    void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:983
    SCIP_Bool SCIPrationalIsLEReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1615
    SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1640
    int SCIPrationalGetSign(const SCIP_RATIONAL *rational)
    Definition: rational.cpp:2048
    SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:123
    void SCIPrationalAddProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1173
    SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1624
    void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
    Definition: rational.cpp:569
    SCIP_Bool SCIPrationalIsGEReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1606
    void SCIPrationalMessage(SCIP_MESSAGEHDLR *msg, FILE *file, SCIP_RATIONAL *rational)
    Definition: rational.cpp:1790
    void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:630
    void SCIPrationalSetFraction(SCIP_RATIONAL *res, SCIP_Longint nom, SCIP_Longint denom)
    Definition: rational.cpp:582
    void SCIPrationalNegate(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
    Definition: rational.cpp:1297
    SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1650
    void SCIPrationalDiffReal(SCIP_RATIONAL *res, SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1009
    SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1660
    void SCIPrationalFreeBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***ratblockarray, int size)
    Definition: rational.cpp:501
    SCIP_Real SCIPrationalRoundReal(SCIP_RATIONAL *rational, SCIP_ROUNDMODE_RAT roundmode)
    Definition: rational.cpp:2110
    SCIP_Bool SCIPrationalIsEQReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1437
    SCIP_RETCODE SCIPrationalCreateBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***rational, int size)
    Definition: rational.cpp:214
    SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1670
    void SCIPrationalFree(SCIP_RATIONAL **rational)
    Definition: rational.cpp:450
    SCIP_Bool SCIPrationalIsGTReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1546
    SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1404
    SCIP_RETCODE SCIPrationalReallocBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***result, int oldlen, int newlen)
    Definition: rational.cpp:314
    void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1097
    void SCIPrationalComputeApproximation(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_Longint maxdenom, int forcegreater)
    Definition: rational.cpp:2464
    void SCIPrationalFreeBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***ratbufarray, int size)
    Definition: rational.cpp:518
    SCIP_Bool SCIPrationalIsAbsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1530
    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 SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
    Definition: scip_lp.c:2176
    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_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2349
    void SCIPgetSolValExact(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_RATIONAL *res)
    Definition: scip_sol.c:1803
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    SCIP_Bool SCIPsolIsExact(SCIP_SOL *sol)
    Definition: sol.c:4150
    int SCIPgetNSepaRounds(SCIP *scip)
    SCIP_Bool SCIPisUbBetter(SCIP *scip, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPparseRational(SCIP *scip, const char *str, SCIP_RATIONAL *value, char **endptr)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLbBetter(SCIP *scip, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(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_Real SCIPgetHugeValue(SCIP *scip)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPepsilon(SCIP *scip)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPinRepropagation(SCIP *scip)
    Definition: scip_tree.c:146
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18320
    SCIP_RETCODE SCIPvarGetProbvarBound(SCIP_VAR **var, SCIP_Real *bound, SCIP_BOUNDTYPE *boundtype)
    Definition: var.c:17801
    SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
    Definition: var.c:23534
    SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
    Definition: var.c:23889
    SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5210
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_RATIONAL * SCIPvarGetAggrScalarExact(SCIP_VAR *var)
    Definition: var.c:23760
    SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
    Definition: scip_var.c:2119
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4386
    SCIP_Real SCIPadjustedVarLbExactFloat(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
    Definition: scip_var.c:5602
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_RATIONAL * SCIPvarGetAggrConstantExact(SCIP_VAR *var)
    Definition: var.c:23783
    SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
    Definition: var.c:23430
    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
    int SCIPvarGetCertificateIndex(SCIP_VAR *var)
    Definition: var.c:25098
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5296
    SCIP_RETCODE SCIPinferVarLbConsExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:7296
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23662
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_RATIONAL * SCIPvarGetMultaggrConstantExact(SCIP_VAR *var)
    Definition: var.c:23855
    SCIP_RETCODE SCIPgetProbvarLinearSumExact(SCIP *scip, SCIP_VAR **vars, SCIP_RATIONAL **scalars, int *nvars, int varssize, SCIP_RATIONAL *constant, int *requiredsize, SCIP_Bool mergemultiples)
    Definition: scip_var.c:2443
    SCIP_RATIONAL * SCIPvarGetUbLocalExact(SCIP_VAR *var)
    Definition: var.c:24278
    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_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_RETCODE SCIPparseVarsLinearsumExact(SCIP *scip, char *str, SCIP_VAR **vars, SCIP_RATIONAL **vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
    Definition: scip_var.c:1007
    SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:2332
    SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
    Definition: var.c:23806
    SCIP_RETCODE SCIPinferVarUbConsExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:7174
    int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
    Definition: var.c:23794
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_RATIONAL * SCIPvarGetBestBoundLocalExact(SCIP_VAR *var)
    Definition: var.c:24325
    SCIP_RATIONAL * SCIPvarGetLbGlobalExact(SCIP_VAR *var)
    Definition: var.c:24130
    SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
    Definition: var.c:23878
    SCIP_RATIONAL ** SCIPvarGetMultaggrScalarsExact(SCIP_VAR *var)
    Definition: var.c:23830
    SCIP_Real SCIPadjustedVarUbExactFloat(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
    Definition: scip_var.c:5666
    SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
    Definition: var.c:23417
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    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_RATIONAL * SCIPvarGetLbLocalExact(SCIP_VAR *var)
    Definition: var.c:24244
    int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
    Definition: var.c:17274
    SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
    Definition: scip_var.c:361
    SCIP_RETCODE SCIPgetProbvarSumExact(SCIP *scip, SCIP_VAR **var, SCIP_RATIONAL *scalar, SCIP_RATIONAL *constant)
    Definition: scip_var.c:2538
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4328
    SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
    Definition: scip_var.c:2078
    SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    SCIP_RETCODE SCIPwriteVarsLinearsumExact(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_RATIONAL **vals, int nvars, SCIP_Bool type)
    Definition: scip_var.c:533
    SCIP_RATIONAL * SCIPvarGetUbGlobalExact(SCIP_VAR *var)
    Definition: var.c:24152
    SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
    Definition: var.c:23736
    void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
    Definition: misc.c:5581
    SCIP_RETCODE SCIPskipSpace(char **s)
    Definition: misc.c:10816
    static SCIP_RETCODE updateActivities(SCIP *scip, SCIP_Real *minactivities, SCIP_Real *maxactivities, SCIP_ROW **violrows, int *violrowpos, int *nviolrows, int *nviolfracrows, int *nfracsinrow, int nlprows, SCIP_VAR *var, SCIP_Real oldsolval, SCIP_Real newsolval)
    interval arithmetics for provable bounds
    SCIP_Bool SCIProwExactIsInLP(SCIP_ROWEXACT *row)
    Definition: lpexact.c:5036
    SCIP_RATIONAL ** SCIProwExactGetVals(SCIP_ROWEXACT *row)
    Definition: lpexact.c:5016
    int SCIProwExactGetNNonz(SCIP_ROWEXACT *row)
    Definition: lpexact.c:5006
    memory allocation routines
    #define BMScopyMemoryArray(ptr, source, num)
    Definition: memory.h:134
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
    Definition: message.c:618
    public methods for conflict analysis handlers
    public methods for managing constraints
    public methods for managing events
    public methods for LP management
    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
    methods for sorting joint arrays of various types
    public methods for problem variables
    wrapper for rational number arithmetic
    public methods for branching rule plugins and branching
    public methods for certified solving
    public methods for conflict handler plugins and conflict analysis
    public methods for constraint handler plugins and constraints
    public methods for problem copies
    public methods for cuts and aggregation rows
    public methods for event handler plugins and event handlers
    public methods for exact solving
    general public methods
    public methods for the LP relaxation, rows and columns
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for message handling
    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 querying solving statistics
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1221
    internal methods for storing separated exact cuts
    SCIP_Real sup
    Definition: intervalarith.h:57
    SCIP_Real inf
    Definition: intervalarith.h:56
    datastructures for problem statistics
    struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
    Definition: type_cons.h:64
    struct SCIP_ConsData SCIP_CONSDATA
    Definition: type_cons.h:65
    #define SCIP_EVENTTYPE_BOUNDCHANGED
    Definition: type_event.h:127
    #define SCIP_EVENTTYPE_VARUNLOCKED
    Definition: type_event.h:73
    #define SCIP_EVENTTYPE_TYPECHANGED
    Definition: type_event.h:86
    #define SCIP_EVENTTYPE_GUBCHANGED
    Definition: type_event.h:76
    #define SCIP_EVENTTYPE_GBDCHANGED
    Definition: type_event.h:122
    struct SCIP_EventData SCIP_EVENTDATA
    Definition: type_event.h:179
    #define SCIP_EVENTTYPE_UBTIGHTENED
    Definition: type_event.h:79
    #define SCIP_EVENTTYPE_VARFIXED
    Definition: type_event.h:72
    #define SCIP_EVENTTYPE_VARDELETED
    Definition: type_event.h:71
    #define SCIP_EVENTTYPE_FORMAT
    Definition: type_event.h:157
    #define SCIP_EVENTTYPE_GLBCHANGED
    Definition: type_event.h:75
    #define SCIP_EVENTTYPE_BOUNDRELAXED
    Definition: type_event.h:126
    #define SCIP_EVENTTYPE_LBCHANGED
    Definition: type_event.h:123
    #define SCIP_EVENTTYPE_UBCHANGED
    Definition: type_event.h:124
    uint64_t SCIP_EVENTTYPE
    Definition: type_event.h:156
    #define SCIP_EVENTTYPE_BOUNDTIGHTENED
    Definition: type_event.h:125
    #define SCIP_EVENTTYPE_LBTIGHTENED
    Definition: type_event.h:77
    @ 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_R_ROUND_UPWARDS
    Definition: type_rational.h:58
    @ SCIP_R_ROUND_DOWNWARDS
    Definition: type_rational.h:57
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_FEASIBLE
    Definition: type_result.h:45
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_INFEASIBLE
    Definition: type_result.h:46
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    type definitions for return codes for SCIP methods
    @ SCIP_READERROR
    Definition: type_retcode.h:45
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_PROBLEM
    Definition: type_set.h:45
    @ SCIP_STAGE_INITSOLVE
    Definition: type_set.h:52
    @ SCIP_STAGE_EXITPRESOLVE
    Definition: type_set.h:50
    @ SCIP_STAGE_TRANSFORMING
    Definition: type_set.h:46
    @ SCIP_STAGE_PRESOLVED
    Definition: type_set.h:51
    #define NLOCKTYPES
    Definition: type_var.h:138
    @ SCIP_VARTYPE_CONTINUOUS
    Definition: type_var.h:71
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    @ SCIP_VARSTATUS_ORIGINAL
    Definition: type_var.h:51
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    @ SCIP_VARSTATUS_NEGATED
    Definition: type_var.h:57
    @ SCIP_VARSTATUS_AGGREGATED
    Definition: type_var.h:55
    @ SCIP_VARSTATUS_LOOSE
    Definition: type_var.h:52
    enum SCIP_LockType SCIP_LOCKTYPE
    Definition: type_var.h:144
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141
    enum SCIP_Vartype SCIP_VARTYPE
    Definition: type_var.h:73
    internal methods for problem variables