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-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file cons_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#ifndef _WIN32
    79#include <strings.h> /*lint --e{766}*/
    80#endif
    81
    82
    83#define CONSHDLR_NAME "exactlinear"
    84#define CONSHDLR_DESC "exact linear constraints of the form lhs <= a^T x <= rhs"
    85#define CONSHDLR_SEPAPRIORITY +100000 /**< priority of the constraint handler for separation */
    86#define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
    87#define CONSHDLR_CHECKPRIORITY -1000000 /**< priority of the constraint handler for checking feasibility */
    88#define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
    89#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
    90#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
    91 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
    92#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
    93#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    94#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
    95
    96#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
    97
    98#define EVENTHDLR_NAME "exactlinear"
    99#define EVENTHDLR_DESC "bound change event handler for exact linear constraints"
    100
    101#define DEFAULT_TIGHTENBOUNDSFREQ 1 /**< multiplier on propagation frequency, how often the bounds are tightened */
    102#define DEFAULT_MAXROUNDS 5 /**< maximal number of separation rounds per node (-1: unlimited) */
    103#define DEFAULT_MAXROUNDSROOT -1 /**< maximal number of separation rounds in the root node (-1: unlimited) */
    104#define DEFAULT_MAXSEPACUTS 50 /**< maximal number of cuts separated per separation round */
    105#define DEFAULT_MAXSEPACUTSROOT 200 /**< maximal number of cuts separated per separation round in root node */
    106#define DEFAULT_SORTVARS TRUE /**< should variables be sorted after presolve w.r.t their coefficient absolute for faster
    107 * propagation? */
    108#define DEFAULT_LIMITDENOM FALSE /**< should denominator sizes for continuous variables be controlled?*/
    109#define DEFAULT_BOUNDMAXDENOM 256L /**< maximal denominator for rational bounds on continuous variables after propagation */
    110
    111
    112/** constraint data for linear constraints */
    113struct SCIP_ConsData
    114{
    115 SCIP_RATIONAL* lhs; /**< left hand side of row (for ranged rows) */
    116 SCIP_RATIONAL* rhs; /**< right hand side of row */
    117 SCIP_Real lhsreal; /**< real relaxation of lhs */
    118 SCIP_Real rhsreal; /**< real relaxation of rhs */
    119 SCIP_RATIONAL* violation; /**< used to store violation */
    120 SCIP_RATIONAL* activity; /**< used to store activity */
    121 SCIP_Real maxabsval; /**< maximum absolute value of all coefficients */
    122 SCIP_Real minabsval; /**< minimal absolute value of all coefficients */
    123 SCIP_Real minactivity; /**< minimal value w.r.t. the variable's local bounds for the constraint's
    124 * activity, ignoring the coefficients contributing with infinite value */
    125 SCIP_Real maxactivity; /**< maximal value w.r.t. the variable's local bounds for the constraint's
    126 * activity, ignoring the coefficients contributing with infinite value */
    127 SCIP_Real lastminactivity; /**< last minimal activity which was computed by complete summation
    128 * over all contributing values */
    129 SCIP_Real lastmaxactivity; /**< last maximal activity which was computed by complete summation
    130 * over all contributing values */
    131 SCIP_Real glbminactivity; /**< minimal value w.r.t. the variable's global bounds for the constraint's
    132 * activity, ignoring the coefficients contributing with infinite value */
    133 SCIP_Real glbmaxactivity; /**< maximal value w.r.t. the variable's global bounds for the constraint's
    134 * activity, ignoring the coefficients contributing with infinite value */
    135 SCIP_Real lastglbminactivity; /**< last global minimal activity which was computed by complete summation
    136 * over all contributing values */
    137 SCIP_Real lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
    138 * over all contributing values */
    139 SCIP_Real maxactdelta; /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
    140 SCIP_VAR* maxactdeltavar; /**< variable with maximal activity contribution, or NULL if invalid */
    141 SCIP_RATIONAL* maxabsvalexact; /**< exact maximum absolute value of all coefficients */
    142 SCIP_RATIONAL* minabsvalexact; /**< exact minimal absolute value of all coefficients */
    143 SCIP_ROW* rowlhs; /**< LP row, if constraint is already stored in LP row format; represents fp-relaxation of lhs-part of rowexact;
    144 only this row will be added to the exact LP, rowrhs is used for safe aggregation of rows */
    145 SCIP_ROW* rowrhs; /**< LP row, if constraint is already stored in LP row format; represents fp-relaxation of rhs-part of rowexact */
    146 SCIP_ROWEXACT* rowexact; /**< Exact rational lp row */
    147 SCIP_VAR** vars; /**< variables of constraint entries */
    148 SCIP_RATIONAL** vals; /**< coefficients of constraint entries */
    149 SCIP_INTERVAL* valsreal; /**< values of val rounded up/down to closest fp-representable numbers */
    150 SCIP_EVENTDATA** eventdata; /**< event data for bound change events of the variables */
    151 int minactivityneginf; /**< number of coefficients contributing with neg. infinite value to minactivity */
    152 int minactivityposinf; /**< number of coefficients contributing with pos. infinite value to minactivity */
    153 int maxactivityneginf; /**< number of coefficients contributing with neg. infinite value to maxactivity */
    154 int maxactivityposinf; /**< number of coefficients contributing with pos. infinite value to maxactivity */
    155 int minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
    156 int minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
    157 int maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
    158 int maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
    159 int glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
    160 int glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
    161 int glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
    162 int glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
    163 int glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
    164 int glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
    165 int glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
    166 int glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
    167 int varssize; /**< size of the vars- and vals-arrays */
    168 int nvars; /**< number of nonzeros in constraint */
    169 int nbinvars; /**< the number of binary variables in the constraint, only valid after
    170 * sorting in stage >= SCIP_STAGE_INITSOLVE
    171 */
    172 unsigned int boundstightened:2; /**< is constraint already propagated with bound tightening? */
    173 unsigned int rangedrowpropagated:2; /**< did we perform ranged row propagation on this constraint?
    174 * (0: no, 1: yes, 2: with potentially adding artificial constraint */
    175 unsigned int validmaxabsval:1; /**< is the maximum absolute value valid? */
    176 unsigned int validminabsval:1; /**< is the minimum absolute value valid? */
    177 unsigned int validactivities:1; /**< are the activity bounds (local and global) valid? */
    178 unsigned int validminact:1; /**< is the local minactivity valid? */
    179 unsigned int validmaxact:1; /**< is the local maxactivity valid? */
    180 unsigned int validglbminact:1; /**< is the global minactivity valid? */
    181 unsigned int validglbmaxact:1; /**< is the global maxactivity valid? */
    182 unsigned int presolved:1; /**< is constraint already presolved? */
    183 unsigned int removedfixings:1; /**< are all fixed variables removed from the constraint? */
    184 unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
    185 unsigned int normalized:1; /**< is the constraint in normalized form? */
    186 unsigned int coefsorted :1; /**< are the constraint's variables sorted? */
    187 unsigned int merged:1; /**< are the constraint's equal variables already merged? */
    188 unsigned int cliquesadded:1; /**< were the cliques of the constraint already extracted? */
    189 unsigned int implsadded:1; /**< were the implications of the constraint already extracted? */
    190 unsigned int indexsorted:1; /**< are binary variables sorted w.r.t. the absolute value of their coefficient? */
    191 unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
    192 unsigned int hascontvar:1; /**< does the constraint contain at least one continuous variable? */
    193 unsigned int hasnonbinvar:1; /**< does the constraint contain at least one non-binary variable? */
    194 unsigned int hasnonbinvalid:1; /**< is the information stored in hasnonbinvar and hascontvar valid? */
    195 unsigned int onerowrelax:1; /**< is one floating-point row enough for the fp-relaxation? if so only rowlhs is used */
    196 unsigned int hasfprelax:1; /**< is the constraint possible to be represented as a fp relaxation (only false if var without bound is present) */
    197};
    198
    199/** event data for bound change event */
    200struct SCIP_EventData
    201{
    202 SCIP_CONS* cons; /**< linear constraint to process the bound change for */
    203 int varpos; /**< position of variable in vars array */
    204 bool rowvar; /**< is the event a row event? */
    205 int filterpos; /**< position of event in variable's event filter */
    206};
    207
    208/** constraint handler data */
    209struct SCIP_ConshdlrData
    210{
    211 SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
    212 SCIP_RATIONAL* maxaggrnormscale; /**< maximal allowed relative gain in maximum norm for constraint aggregation
    213 * (0.0: disable constraint aggregation) */
    214 SCIP_RATIONAL* maxcardbounddist; /**< maximal relative distance from current node's dual bound to primal bound compared
    215 * to best node's dual bound for separating knapsack cardinality cuts */
    216 SCIP_RATIONAL* mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
    217 SCIP_RATIONAL* maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
    218 * (faster, but numerically less stable) */
    219 int tightenboundsfreq; /**< multiplier on propagation frequency, how often the bounds are tightened */
    220 int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
    221 int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
    222 int maxsepacuts; /**< maximal number of cuts separated per separation round */
    223 int maxsepacutsroot; /**< maximal number of cuts separated per separation round in root node */
    224 int naddconss; /**< number of added constraints */
    225 SCIP_Longint ncheckserrorbound; /**< number of times running error analyis activity computation was called */
    226 SCIP_Longint nsuccesserrorbound; /**< number of times running error analyis activity computation could determine feasibility */
    227 SCIP_Longint nabotserrorbound; /**< number of times running error analysis activity computation not appliccable (e.g. row->len != fprow->len) */
    228 SCIP_Longint nconsprop; /**< number of times a constraint was propagated */
    229 SCIP_Longint nconspropnoninit; /**< number of times a non-initial (conflict) constraint was propagated */
    230 SCIP_Longint propnonzeros; /**< number of nonzeros in propagated rows */
    231 SCIP_Longint propnonzerosnoninit;/**< number of nonzeros in propagated rows in non-initial (conflict) propagations */
    232 SCIP_Bool sortvars; /**< should binary variables be sorted for faster propagation? */
    233 SCIP_Bool propcont; /**< should bounds on continuous variables be tightened by propagation?*/
    234 SCIP_Bool limitdenom; /**< should denominator sizes for continuous variables be controlled?*/
    235 SCIP_Longint boundmaxdenom; /**< maximal denominator for rational bounds on continuous variables after propagation */
    236};
    237
    238
    239/*
    240 * Propagation rules
    241 */
    242
    243/*lint --e{749} */
    245{
    246 PROPRULE_1_RHS = 1, /**< activity residuals of all other variables tighten bounds of single
    247 * variable due to the right hand side of the inequality */
    248 PROPRULE_1_LHS = 2, /**< activity residuals of all other variables tighten bounds of single
    249 * variable due to the left hand side of the inequality */
    250 PROPRULE_1_RANGEDROW = 3, /**< fixed variables and gcd of all left variables tighten bounds of a
    251 * single variable in this reanged row */
    252 PROPRULE_INVALID = 0 /**< propagation was applied without a specific propagation rule */
    254typedef enum Proprule PROPRULE;
    255
    256/** inference information */
    257struct InferInfo
    258{
    259 union
    260 {
    261 struct
    262 {
    263 unsigned int proprule:8; /**< propagation rule that was applied */
    264 unsigned int pos:24; /**< variable position, the propagation rule was applied at */
    265 } asbits;
    266 int asint; /**< inference information as a single int value */
    267 } val;
    268};
    269
    270typedef struct InferInfo INFERINFO;
    271
    272
    273/** converts an inference information into an int */
    274static
    276 INFERINFO inferinfo /**< inference information to convert */
    277 )
    278{
    279 return inferinfo.val.asint;
    280}
    281
    282
    283/** constructs an inference information out of a propagation rule and a position number */
    284static
    286 PROPRULE proprule, /**< propagation rule that deduced the value */
    287 int pos /**< variable position, the propagation rule was applied at */
    288 )
    289{
    290 INFERINFO inferinfo;
    291
    292 assert(pos >= 0);
    293 /* in the inferinfo struct only 24 bits for 'pos' are reserved */
    294 assert(pos < (1<<24));
    295
    296 inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
    297 inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
    298
    299 return inferinfo;
    300}
    301
    302/** constructs an inference information out of a propagation rule and a position number, returns info as int */
    303static
    305 PROPRULE proprule, /**< propagation rule that deduced the value */
    306 int pos /**< variable position, the propagation rule was applied at */
    307 )
    308{
    309 return inferInfoToInt(getInferInfo(proprule, pos));
    310}
    311
    312/** ensures, that vars and vals arrays can store at least num entries */
    313static
    315 SCIP* scip, /**< SCIP data structure */
    316 SCIP_CONSDATA* consdata, /**< linear constraint data */
    317 int num /**< minimum number of entries to store */
    318 )
    319{
    320 int k;
    321 assert(scip != NULL);
    322 assert(consdata != NULL);
    323 assert(consdata->nvars <= consdata->varssize);
    324
    325 if( num > consdata->varssize )
    326 {
    327 int newsize;
    328
    329 newsize = SCIPcalcMemGrowSize(scip, num);
    330 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
    331 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
    332 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->valsreal, consdata->varssize, newsize) );
    333 for( k = consdata->varssize; k < newsize; ++k )
    334 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &consdata->vals[k]) );
    335
    336 if( consdata->eventdata != NULL )
    337 {
    338 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
    339 }
    340 consdata->varssize = newsize;
    341 }
    342 assert(num <= consdata->varssize);
    343
    344 return SCIP_OKAY;
    345}
    346
    347
    348/*
    349 * local methods for managing linear constraint update methods
    350 */
    351
    352
    353/** creates constraint handler data for linear constraint handler */
    354static
    356 SCIP* scip, /**< SCIP data structure */
    357 SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
    358 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    359 )
    360{
    361 assert(scip != NULL);
    362 assert(conshdlrdata != NULL);
    363 assert(eventhdlr != NULL);
    364
    365 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
    366 (*conshdlrdata)->naddconss = 0;
    367 (*conshdlrdata)->ncheckserrorbound = 0;
    368 (*conshdlrdata)->nabotserrorbound = 0;
    369 (*conshdlrdata)->nsuccesserrorbound = 0;
    370 (*conshdlrdata)->nconsprop = 0;
    371 (*conshdlrdata)->nconspropnoninit = 0;
    372 (*conshdlrdata)->propnonzeros = 0;
    373 (*conshdlrdata)->propnonzerosnoninit = 0;
    374 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxaggrnormscale) );
    375 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxcardbounddist) );
    376 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxeasyactivitydelta) );
    377 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->mingainpernmincomp) );
    378
    379 /* set event handler for updating linear constraint activity bounds */
    380 (*conshdlrdata)->eventhdlr = eventhdlr;
    381
    382 return SCIP_OKAY;
    383}
    384
    385/** frees constraint handler data for linear constraint handler */
    386static
    388 SCIP* scip, /**< SCIP data structure */
    389 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
    390 )
    391{
    392 assert(scip != NULL);
    393 assert(conshdlrdata != NULL);
    394 assert(*conshdlrdata != NULL);
    395
    396 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxaggrnormscale);
    397 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxcardbounddist);
    398 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxeasyactivitydelta);
    399 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->mingainpernmincomp);
    400
    401 SCIPfreeBlockMemory(scip, conshdlrdata);
    402}
    403
    404/*
    405 * local methods
    406 */
    407
    408/** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
    409static
    411 SCIP* scip, /**< SCIP data structure */
    412 SCIP_CONS* cons, /**< linear constraint */
    413 SCIP_VAR* var, /**< variable of constraint entry */
    414 SCIP_RATIONAL* val /**< coefficient of constraint entry */
    415 )
    416{
    417 SCIP_CONSDATA* consdata;
    418
    419 assert(scip != NULL);
    420 assert(cons != NULL);
    421 assert(var != NULL);
    422
    423 consdata = SCIPconsGetData(cons);
    424 assert(consdata != NULL);
    425 assert(!SCIPrationalIsZero(val));
    426
    427 if( SCIPrationalIsPositive(val) )
    428 {
    429 SCIP_CALL( SCIPlockVarCons(scip, var, cons,
    430 !SCIPrationalIsNegInfinity(consdata->lhs), !SCIPrationalIsInfinity(consdata->rhs)) );
    431 }
    432 else
    433 {
    434 SCIP_CALL( SCIPlockVarCons(scip, var, cons,
    435 !SCIPrationalIsInfinity(consdata->rhs), !SCIPrationalIsNegInfinity(consdata->lhs)) );
    436 }
    437
    438 return SCIP_OKAY;
    439}
    440
    441/** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
    442static
    444 SCIP* scip, /**< SCIP data structure */
    445 SCIP_CONS* cons, /**< linear constraint */
    446 SCIP_VAR* var, /**< variable of constraint entry */
    447 SCIP_RATIONAL* val /**< coefficient of constraint entry */
    448 )
    449{
    450 SCIP_CONSDATA* consdata;
    451
    452 assert(scip != NULL);
    453 assert(cons != NULL);
    454 assert(var != NULL);
    455
    456 consdata = SCIPconsGetData(cons);
    457 assert(consdata != NULL);
    458 assert(!SCIPrationalIsZero(val));
    459
    460 if( SCIPrationalIsPositive(val) )
    461 {
    462 SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPrationalIsNegInfinity(consdata->lhs),
    463 !SCIPrationalIsInfinity(consdata->rhs)) );
    464 }
    465 else
    466 {
    467 SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPrationalIsInfinity(consdata->rhs),
    468 !SCIPrationalIsNegInfinity(consdata->lhs)) );
    469 }
    470
    471 return SCIP_OKAY;
    472}
    473
    474/** creates event data for variable at given position, and catches events */
    475/**! [SnippetDebugAssertions] */
    476static
    478 SCIP* scip, /**< SCIP data structure */
    479 SCIP_CONS* cons, /**< linear constraint */
    480 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    481 int pos /**< array position of variable to catch bound change events for */
    482 )
    483{
    484 SCIP_CONSDATA* consdata;
    485 assert(scip != NULL);
    486 assert(cons != NULL);
    487 assert(eventhdlr != NULL);
    488
    489 consdata = SCIPconsGetData(cons);
    490 assert(consdata != NULL);
    491
    492 assert(0 <= pos && pos < consdata->nvars);
    493 assert(consdata->vars != NULL);
    494 assert(consdata->vars[pos] != NULL);
    495 assert(SCIPvarIsTransformed(consdata->vars[pos]));
    496 assert(consdata->eventdata != NULL);
    497 assert(consdata->eventdata[pos] == NULL);
    498
    499 SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
    500 consdata->eventdata[pos]->cons = cons;
    501 consdata->eventdata[pos]->varpos = pos;
    502 consdata->eventdata[pos]->rowvar = false;
    503
    504 SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
    507 eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
    508
    509 consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(consdata->vars[pos]);
    510
    511 return SCIP_OKAY;
    512}
    513
    514/**! [SnippetDebugAssertions] */
    515
    516/** deletes event data for variable at given position, and drops events */
    517static
    519 SCIP* scip, /**< SCIP data structure */
    520 SCIP_CONS* cons, /**< linear constraint */
    521 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    522 int pos /**< array position of variable to catch bound change events for */
    523 )
    524{
    525 SCIP_CONSDATA* consdata;
    526 assert(scip != NULL);
    527 assert(cons != NULL);
    528 assert(eventhdlr != NULL);
    529
    530 consdata = SCIPconsGetData(cons);
    531 assert(consdata != NULL);
    532
    533 assert(0 <= pos && pos < consdata->nvars);
    534 assert(consdata->vars[pos] != NULL);
    535 assert(consdata->eventdata != NULL);
    536 assert(consdata->eventdata[pos] != NULL);
    537 assert(consdata->eventdata[pos]->cons == cons);
    538 assert(consdata->eventdata[pos]->varpos == pos);
    539
    540 SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
    543 eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
    544
    545 SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
    546
    547 return SCIP_OKAY;
    548}
    549
    550/** catches bound change events for all variables in transformed linear constraint */
    551static
    553 SCIP* scip, /**< SCIP data structure */
    554 SCIP_CONS* cons, /**< linear constraint */
    555 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
    556 )
    557{
    558 SCIP_CONSDATA* consdata;
    559 int i;
    560
    561 assert(scip != NULL);
    562 assert(cons != NULL);
    563
    564 consdata = SCIPconsGetData(cons);
    565 assert(consdata != NULL);
    566 assert(consdata->eventdata == NULL);
    567
    568 /* allocate eventdata array */
    569 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
    570 assert(consdata->eventdata != NULL);
    571 BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
    572
    573 /* catch event for every single variable */
    574 for( i = 0; i < consdata->nvars; ++i )
    575 {
    576 SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
    577 }
    578
    579 return SCIP_OKAY;
    580}
    581
    582/** drops bound change events for all variables in transformed linear constraint */
    583static
    585 SCIP* scip, /**< SCIP data structure */
    586 SCIP_CONS* cons, /**< linear constraint */
    587 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
    588 )
    589{
    590 SCIP_CONSDATA* consdata;
    591 int i;
    592
    593 assert(scip != NULL);
    594 assert(cons != NULL);
    595
    596 consdata = SCIPconsGetData(cons);
    597 assert(consdata != NULL);
    598 assert(consdata->eventdata != NULL);
    599
    600 /* drop event of every single variable */
    601 for( i = consdata->nvars - 1; i >= 0; --i )
    602 {
    603 SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
    604 }
    605
    606 /* free eventdata array */
    607 SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
    608 assert(consdata->eventdata == NULL);
    609
    610 return SCIP_OKAY;
    611}
    612
    613/** creates a linear constraint data */
    614static
    616 SCIP* scip, /**< SCIP data structure */
    617 SCIP_CONSDATA** consdata, /**< pointer to linear constraint data */
    618 int nvars, /**< number of nonzeros in the constraint */
    619 SCIP_VAR** vars, /**< array with variables of constraint entries */
    620 SCIP_RATIONAL** vals, /**< array with coefficients of constraint entries */
    621 SCIP_RATIONAL* lhs, /**< left hand side of row */
    622 SCIP_RATIONAL* rhs /**< right hand side of row */
    623 )
    624{
    625 int v;
    626 SCIP_RATIONAL* constant;
    627 SCIP_Real lhsrel;
    628 SCIP_Real rhsrel;
    629
    630 assert(scip != NULL);
    631 assert(consdata != NULL);
    632 assert(nvars == 0 || vars != NULL);
    633 assert(nvars == 0 || vals != NULL);
    634
    635 if( SCIPrationalIsGT(lhs, rhs) )
    636 {
    637 SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
    638 SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", SCIPrationalGetReal(lhs), SCIPrationalGetReal(rhs));
    639 }
    640
    641 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
    642
    643 (*consdata)->varssize = 0;
    644 (*consdata)->nvars = nvars;
    645 (*consdata)->hascontvar = FALSE;
    646 (*consdata)->hasnonbinvar = FALSE;
    647 (*consdata)->hasnonbinvalid = TRUE;
    648 (*consdata)->vars = NULL;
    649 (*consdata)->vals = NULL;
    650 (*consdata)->valsreal = NULL;
    651
    653 if( nvars > 0 )
    654 {
    655 int k;
    656
    657 SCIP_VAR** varsbuffer;
    658 SCIP_RATIONAL** valsbuffer;
    659 SCIP_INTERVAL* valsrealbuffer;
    660
    661 /* copy variables into temporary buffer */
    662 SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
    664 SCIP_CALL( SCIPallocBufferArray(scip, &valsrealbuffer, nvars) );
    665 k = 0;
    666
    667 /* loop over variables and sort out fixed ones */
    668 for( v = 0; v < nvars; ++v )
    669 {
    670 SCIP_VAR* var;
    671
    672 var = vars[v];
    673 assert(var != NULL);
    674 assert(!SCIPrationalIsAbsInfinity(vals[v]));
    675
    676 if( !SCIPrationalIsZero(vals[v]) )
    677 {
    678 /* treat fixed variable as a constant if problem compression is enabled */
    680 {
    681 SCIPrationalAddProd(constant, vals[v], SCIPvarGetLbGlobalExact(var));
    682 }
    683 else
    684 {
    685 varsbuffer[k] = var;
    686 SCIPrationalSetRational(valsbuffer[k], vals[v]);
    687 SCIPintervalSetRational(&(valsrealbuffer[k]), vals[v]);
    688 k++;
    689
    690 /* update hascontvar and hasnonbinvar flags */
    691 if( !(*consdata)->hascontvar )
    692 {
    693 SCIP_VARTYPE vartype = SCIPvarGetType(var);
    694
    695 if( vartype != SCIP_VARTYPE_BINARY )
    696 {
    697 (*consdata)->hasnonbinvar = TRUE;
    698
    699 if( vartype == SCIP_VARTYPE_CONTINUOUS )
    700 (*consdata)->hascontvar = TRUE;
    701 }
    702 }
    703 }
    704 }
    705 }
    706 (*consdata)->nvars = k;
    707
    708 if( k > 0 )
    709 {
    710 /* copy the possibly reduced buffer arrays into block */
    711 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
    712 SCIP_CALL( SCIPrationalCopyBlockArray(SCIPblkmem(scip), &(*consdata)->vals, valsbuffer, k) );
    713 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->valsreal, valsrealbuffer, k) );
    714 (*consdata)->varssize = k;
    715 }
    716
    717 SCIPfreeBufferArray(scip, &valsrealbuffer);
    718 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &valsbuffer, nvars);
    719 SCIPfreeBufferArray(scip, &varsbuffer);
    720 }
    721
    722 (*consdata)->eventdata = NULL;
    723
    726
    727 /* due to compressed copying, we may have fixed variables contributing to the left and right hand side */
    728 if( !SCIPrationalIsZero(constant) )
    729 {
    730 if( !SCIPrationalIsAbsInfinity(lhs) )
    731 SCIPrationalDiff(lhs, lhs, constant);
    732
    733 if( !SCIPrationalIsAbsInfinity(rhs) )
    734 SCIPrationalDiff(rhs, rhs, constant);
    735 }
    736
    737 (*consdata)->rowlhs = NULL;
    738 (*consdata)->rowrhs = NULL;
    739 (*consdata)->rowexact = NULL;
    740 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &(*consdata)->lhs, lhs) );
    741 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &(*consdata)->rhs, rhs) );
    742 (*consdata)->lhsreal = lhsrel;
    743 (*consdata)->rhsreal = rhsrel;
    744 SCIP_CALL( SCIPrationalCreateString(SCIPblkmem(scip), &(*consdata)->maxabsvalexact, "inf") );
    745 SCIP_CALL( SCIPrationalCreateString(SCIPblkmem(scip), &(*consdata)->minabsvalexact, "inf") );
    746 (*consdata)->maxabsval = SCIP_INVALID;
    747 (*consdata)->minabsval = SCIP_INVALID;
    748 (*consdata)->minactivity = SCIP_INVALID;
    749 (*consdata)->maxactivity = SCIP_INVALID;
    750 (*consdata)->lastminactivity = SCIP_INVALID;
    751 (*consdata)->lastmaxactivity = SCIP_INVALID;
    752 (*consdata)->maxactdelta = SCIP_INVALID;
    753 (*consdata)->maxactdeltavar = NULL;
    754 (*consdata)->minactivityneginf = -1;
    755 (*consdata)->minactivityposinf = -1;
    756 (*consdata)->maxactivityneginf = -1;
    757 (*consdata)->maxactivityposinf = -1;
    758 (*consdata)->minactivityneghuge = -1;
    759 (*consdata)->minactivityposhuge = -1;
    760 (*consdata)->maxactivityneghuge = -1;
    761 (*consdata)->maxactivityposhuge = -1;
    762 (*consdata)->glbminactivity = SCIP_INVALID;
    763 (*consdata)->glbmaxactivity = SCIP_INVALID;
    764 (*consdata)->lastglbminactivity = SCIP_INVALID;
    765 (*consdata)->lastglbmaxactivity = SCIP_INVALID;
    766 (*consdata)->glbminactivityneginf = -1;
    767 (*consdata)->glbminactivityposinf = -1;
    768 (*consdata)->glbmaxactivityneginf = -1;
    769 (*consdata)->glbmaxactivityposinf = -1;
    770 (*consdata)->glbminactivityneghuge = -1;
    771 (*consdata)->glbminactivityposhuge = -1;
    772 (*consdata)->glbmaxactivityneghuge = -1;
    773 (*consdata)->glbmaxactivityposhuge = -1;
    774 (*consdata)->validmaxabsval = FALSE;
    775 (*consdata)->validminabsval = FALSE;
    776 (*consdata)->validactivities = FALSE;
    777 (*consdata)->validminact = FALSE;
    778 (*consdata)->validmaxact = FALSE;
    779 (*consdata)->validglbminact = FALSE;
    780 (*consdata)->validglbmaxact = FALSE;
    781 (*consdata)->boundstightened = 0;
    782 (*consdata)->presolved = FALSE;
    783 (*consdata)->removedfixings = FALSE;
    784 (*consdata)->changed = TRUE;
    785 (*consdata)->normalized = FALSE;
    786 (*consdata)->indexsorted = (nvars <= 1);
    787 (*consdata)->merged = (nvars <= 1);
    788 (*consdata)->cliquesadded = FALSE;
    789 (*consdata)->implsadded = FALSE;
    790 (*consdata)->coefsorted = FALSE;
    791 (*consdata)->nbinvars = -1;
    792 (*consdata)->varsdeleted = FALSE;
    793 (*consdata)->rangedrowpropagated = 0;
    794 (*consdata)->onerowrelax = FALSE;
    795 (*consdata)->hasfprelax = FALSE;
    796
    797 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*consdata)->activity) );
    798 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*consdata)->violation) );
    799
    801 {
    802 /* get transformed variables */
    803 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
    804 }
    805
    806 /* capture variables */
    807 for( v = 0; v < (*consdata)->nvars; v++ )
    808 {
    809 assert((*consdata)->vars[v] != NULL);
    810 assert(!SCIPrationalIsZero((*consdata)->vals[v]));
    811 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
    812 }
    813
    815
    816 return SCIP_OKAY;
    817}
    818
    819/** frees a linear constraint data */
    820static
    822 SCIP* scip, /**< SCIP data structure */
    823 SCIP_CONSDATA** consdata /**< pointer to linear constraint data */
    824 )
    825{
    826 int v;
    827
    828 assert(scip != NULL);
    829 assert(consdata != NULL);
    830 assert(*consdata != NULL);
    831 assert((*consdata)->varssize >= 0);
    832
    833 /* release the row */
    834 if( (*consdata)->rowlhs != NULL )
    835 {
    836 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->rowlhs) );
    837 }
    838 if( (*consdata)->rowrhs != NULL && !(*consdata)->onerowrelax )
    839 {
    840 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->rowrhs) );
    841 }
    842
    843 /* release variables */
    844 for( v = 0; v < (*consdata)->nvars; v++ )
    845 {
    846 assert((*consdata)->vars[v] != NULL);
    847 assert(!SCIPrationalIsZero((*consdata)->vals[v]));
    848 SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
    849 }
    850
    851 SCIPrationalFreeBlockArray(SCIPblkmem(scip), &(*consdata)->vals, (*consdata)->varssize);
    852
    853 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
    854 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
    855 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->valsreal, (*consdata)->varssize);
    856
    857 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->lhs);
    858 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->rhs);
    859 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->maxabsvalexact);
    860 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->minabsvalexact);
    861 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->violation);
    862 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->activity);
    863
    864 SCIPfreeBlockMemory(scip, consdata);
    865 return SCIP_OKAY;
    866}
    867/** prints linear constraint in CIP format to file stream */
    868static
    870 SCIP* scip, /**< SCIP data structure */
    871 SCIP_CONSDATA* consdata, /**< linear constraint data */
    872 FILE* file /**< output file (or NULL for standard output) */
    873 )
    874{
    875 assert(scip != NULL);
    876 assert(consdata != NULL);
    877
    878 /* print left hand side for ranged rows */
    879 if( !SCIPrationalIsNegInfinity(consdata->lhs)
    880 && !SCIPrationalIsInfinity(consdata->rhs)
    881 && !SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    882 {
    883 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    884 SCIPinfoMessage(scip, file, " <= ");
    885 }
    886
    887 /* print coefficients and variables */
    888 if( consdata->nvars == 0 )
    889 SCIPinfoMessage(scip, file, "0");
    890 else
    891 {
    892 /* post linear sum of the linear constraint */
    893 SCIP_CALL( SCIPwriteVarsLinearsumExact(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
    894 }
    895
    896 /* print right hand side */
    897 if( SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    898 {
    899 SCIPinfoMessage(scip, file, " == ");
    900 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    901 }
    902 else if( !SCIPrationalIsInfinity(consdata->rhs) )
    903 {
    904 SCIPinfoMessage(scip, file, " <= ");
    905 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->rhs);
    906 }
    907 else if( !SCIPrationalIsNegInfinity(consdata->lhs) )
    908 {
    909 SCIPinfoMessage(scip, file, " >= ");
    910 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    911 }
    912 else
    913 SCIPinfoMessage(scip, file, " [free]");
    914
    915 return SCIP_OKAY;
    916}
    917
    918/** prints linear constraint and contained solution values of variables to file stream */
    919static
    921 SCIP* scip, /**< SCIP data structure */
    922 SCIP_CONS* cons, /**< linear constraint */
    923 SCIP_SOL* sol, /**< solution to print */
    924 SCIP_Bool useexactsol, /**< should the exact sol be used */
    925 FILE* file /**< output file (or NULL for standard output) */
    926 )
    927{
    928 SCIP_CONSDATA* consdata;
    929
    930 assert(scip != NULL);
    931 assert(cons != NULL);
    932
    933 consdata = SCIPconsGetData(cons);
    934 assert(consdata != NULL);
    935
    937
    938 /* print left hand side for ranged rows */
    939 /* print left hand side for ranged rows */
    940 if( !SCIPrationalIsNegInfinity(consdata->lhs)
    941 && !SCIPrationalIsInfinity(consdata->rhs)
    942 && !SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    943 {
    944 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    945 SCIPinfoMessage(scip, file, " <= ");
    946 }
    947
    948 /* print coefficients and variables */
    949 if( consdata->nvars == 0 )
    950 SCIPinfoMessage(scip, file, "0");
    951 else
    952 {
    953 int v;
    954
    955 /* post linear sum of the linear constraint */
    956 for( v = 0; v < consdata->nvars; ++v )
    957 {
    958 if( consdata->vals != NULL )
    959 {
    960 if( SCIPrationalIsEQReal(consdata->vals[v], 1.0) )
    961 {
    962 if( v > 0 )
    963 SCIPinfoMessage(scip, file, " +");
    964 }
    965 else if( SCIPrationalIsEQReal(consdata->vals[v], -1.0) )
    966 SCIPinfoMessage(scip, file, " -");
    967 else
    968 {
    969 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->vals[v]);
    970 }
    971 }
    972 else if( consdata->nvars > 0 )
    973 SCIPinfoMessage(scip, file, " +");
    974
    975 /* print variable name */
    976 SCIP_CALL( SCIPwriteVarName(scip, file, consdata->vars[v], TRUE) );
    977
    978 if( sol != NULL )
    979 {
    980 SCIPinfoMessage(scip, file, " (");
    981 if( useexactsol )
    982 {
    983 SCIP_RATIONAL* tmp;
    985 SCIPgetSolValExact(scip, sol, consdata->vars[v], tmp);
    988 }
    989 else
    990 SCIPinfoMessage(scip, file, "%+.9g", SCIPgetSolVal(scip, sol, consdata->vars[v]));
    991 SCIPinfoMessage(scip, file, ")");
    992 }
    993 }
    994 }
    995
    996 /* print right hand side */
    997 if( SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    998 {
    999 SCIPinfoMessage(scip, file, " == ");
    1000 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    1001 }
    1002 else if( !SCIPrationalIsInfinity(consdata->rhs) )
    1003 {
    1004 SCIPinfoMessage(scip, file, " <= ");
    1005 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->rhs);
    1006 }
    1007 else if( !SCIPrationalIsNegInfinity(consdata->lhs) )
    1008 {
    1009 SCIPinfoMessage(scip, file, " >= ");
    1010 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
    1011 }
    1012 else
    1013 SCIPinfoMessage(scip, file, " [free]");
    1014
    1015 SCIPinfoMessage(scip, file, ";\n");
    1016
    1017 return SCIP_OKAY;
    1018}
    1019
    1020/** invalidates activity bounds, such that they are recalculated in next get */
    1021static
    1023 SCIP_CONSDATA* consdata /**< linear constraint */
    1024 )
    1025{
    1026 assert(consdata != NULL);
    1027
    1028 consdata->validactivities = FALSE;
    1029 consdata->validminact = FALSE;
    1030 consdata->validmaxact = FALSE;
    1031 consdata->validglbminact = FALSE;
    1032 consdata->validglbmaxact = FALSE;
    1033 consdata->validmaxabsval = FALSE;
    1034 consdata->validminabsval = FALSE;
    1035 consdata->hasnonbinvalid = FALSE;
    1036 consdata->minactivity = SCIP_INVALID;
    1037 consdata->maxactivity = SCIP_INVALID;
    1038 consdata->lastminactivity = SCIP_INVALID;
    1039 consdata->lastmaxactivity = SCIP_INVALID;
    1040 consdata->maxabsval = SCIP_INVALID;
    1041 consdata->minabsval = SCIP_INVALID;
    1042 consdata->maxactdelta = SCIP_INVALID;
    1043 SCIPrationalSetInfinity(consdata->maxabsvalexact);
    1044 SCIPrationalSetInfinity(consdata->minabsvalexact);
    1045 consdata->maxactdeltavar = NULL;
    1046 consdata->minactivityneginf = -1;
    1047 consdata->minactivityposinf = -1;
    1048 consdata->maxactivityneginf = -1;
    1049 consdata->maxactivityposinf = -1;
    1050 consdata->minactivityneghuge = -1;
    1051 consdata->minactivityposhuge = -1;
    1052 consdata->maxactivityneghuge = -1;
    1053 consdata->maxactivityposhuge = -1;
    1054 consdata->glbminactivity = SCIP_INVALID;
    1055 consdata->glbmaxactivity = SCIP_INVALID;
    1056 consdata->lastglbminactivity = SCIP_INVALID;
    1057 consdata->lastglbmaxactivity = SCIP_INVALID;
    1058 consdata->glbminactivityneginf = -1;
    1059 consdata->glbminactivityposinf = -1;
    1060 consdata->glbmaxactivityneginf = -1;
    1061 consdata->glbmaxactivityposinf = -1;
    1062 consdata->glbminactivityneghuge = -1;
    1063 consdata->glbminactivityposhuge = -1;
    1064 consdata->glbmaxactivityneghuge = -1;
    1065 consdata->glbmaxactivityposhuge = -1;
    1066}
    1067
    1068/** computes the pseudo activity of a constraint */
    1069static
    1071 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1072 SCIP_RATIONAL* pseudoactivity /**< buffer to store pseudoactivity */
    1073 )
    1074{
    1075 int i;
    1076 int pseudoactivityposinf;
    1077 int pseudoactivityneginf;
    1079 SCIP_RATIONAL* val;
    1080
    1081 SCIPrationalSetFraction(pseudoactivity, 0LL, 1LL);
    1082
    1083 pseudoactivityposinf = 0;
    1084 pseudoactivityneginf = 0;
    1085
    1086 for( i = consdata->nvars - 1; i >= 0; --i )
    1087 {
    1088 bound = SCIPvarGetBestBoundLocalExact(consdata->vars[i]);
    1089 val = consdata->vals[i];
    1090 assert(!SCIPrationalIsZero(val));
    1091
    1093 {
    1094 if( SCIPrationalIsNegative(val) )
    1095 ++pseudoactivityposinf;
    1096 else
    1097 ++pseudoactivityneginf;
    1098 }
    1099 else if( SCIPrationalIsInfinity(bound) )
    1100 {
    1101 if( SCIPrationalIsNegative(val) )
    1102 ++pseudoactivityneginf;
    1103 else
    1104 ++pseudoactivityposinf;
    1105 }
    1106 else
    1107 SCIPrationalAddProd(pseudoactivity, val, bound);
    1108 }
    1109
    1110 /* set pseudo activity to infeasible infinity for contradicting contributions */
    1111 if( pseudoactivityneginf > 0 && ( pseudoactivityposinf == 0 || !SCIPrationalIsNegInfinity(consdata->lhs) ) )
    1112 SCIPrationalSetNegInfinity(pseudoactivity);
    1113 else if( pseudoactivityposinf > 0 && ( pseudoactivityneginf == 0 || !SCIPrationalIsInfinity(consdata->rhs) ) )
    1114 SCIPrationalSetInfinity(pseudoactivity);
    1115}
    1116
    1117/** recompute the minactivity of a constraint */
    1118static
    1120 SCIP* scip, /**< SCIP data structure */
    1121 SCIP_CONSDATA* consdata /**< linear constraint data */
    1122 )
    1123{
    1124 SCIP_ROUNDMODE prevmode;
    1125 SCIP_Real contribution;
    1126 int i;
    1127
    1128 consdata->minactivity = 0.0;
    1129 prevmode = SCIPintervalGetRoundingMode();
    1131
    1132 for( i = consdata->nvars - 1; i >= 0; --i )
    1133 {
    1134 if( consdata->valsreal[i].sup < 0.0 )
    1135 {
    1136 assert(consdata->valsreal[i].inf <= 0.0);
    1137
    1138 contribution = SCIPvarGetUbLocal(consdata->vars[i]);
    1139
    1140 if( SCIPisInfinity(scip, contribution) )
    1141 continue;
    1142 }
    1143 else
    1144 {
    1145 assert(consdata->valsreal[i].inf >= 0.0);
    1146
    1147 contribution = SCIPvarGetLbLocal(consdata->vars[i]);
    1148
    1149 if( SCIPisInfinity(scip, -contribution) )
    1150 continue;
    1151 }
    1152
    1153 contribution *= contribution < 0.0 ? consdata->valsreal[i].sup : consdata->valsreal[i].inf;
    1154
    1155 if( SCIPisHugeValue(scip, REALABS(contribution)) )
    1156 continue;
    1157
    1158 consdata->minactivity += contribution;
    1159 }
    1160
    1161 /* the activity was just computed from scratch and is valid now */
    1162 consdata->validminact = TRUE;
    1163
    1164 /* the activity was just computed from scratch, mark it to be reliable */
    1165 consdata->lastminactivity = consdata->minactivity;
    1167}
    1168
    1169/** recompute the maxactivity of a constraint */
    1170static
    1172 SCIP* scip, /**< SCIP data structure */
    1173 SCIP_CONSDATA* consdata /**< linear constraint data */
    1174 )
    1175{
    1176 SCIP_ROUNDMODE prevmode;
    1177 SCIP_Real contribution;
    1178 int i;
    1179
    1180 consdata->maxactivity = 0.0;
    1181 prevmode = SCIPintervalGetRoundingMode();
    1183
    1184 for( i = consdata->nvars - 1; i >= 0; --i )
    1185 {
    1186 if( consdata->valsreal[i].sup < 0.0 )
    1187 {
    1188 assert(consdata->valsreal[i].inf <= 0.0);
    1189
    1190 contribution = SCIPvarGetLbLocal(consdata->vars[i]);
    1191
    1192 if( SCIPisInfinity(scip, -contribution) )
    1193 continue;
    1194 }
    1195 else
    1196 {
    1197 assert(consdata->valsreal[i].inf >= 0.0);
    1198
    1199 contribution = SCIPvarGetUbLocal(consdata->vars[i]);
    1200
    1201 if( SCIPisInfinity(scip, contribution) )
    1202 continue;
    1203 }
    1204
    1205 contribution *= contribution < 0.0 ? consdata->valsreal[i].inf : consdata->valsreal[i].sup;
    1206
    1207 if( SCIPisHugeValue(scip, REALABS(contribution)) )
    1208 continue;
    1209
    1210 consdata->maxactivity += contribution;
    1211 }
    1212
    1213 /* the activity was just computed from scratch and is valid now */
    1214 consdata->validmaxact = TRUE;
    1215
    1216 /* the activity was just computed from scratch, mark it to be reliable */
    1217 consdata->lastmaxactivity = consdata->maxactivity;
    1218
    1220}
    1221
    1222/** recompute the global minactivity of a constraint */
    1223static
    1225 SCIP* scip, /**< SCIP data structure */
    1226 SCIP_CONSDATA* consdata /**< linear constraint data */
    1227 )
    1228{
    1229 SCIP_ROUNDMODE prevmode;
    1230 SCIP_Real contribution;
    1231 int i;
    1232
    1233 consdata->glbminactivity = 0.0;
    1234 prevmode = SCIPintervalGetRoundingMode();
    1236
    1237 for( i = consdata->nvars - 1; i >= 0; --i )
    1238 {
    1239 if( consdata->valsreal[i].sup < 0.0 )
    1240 {
    1241 assert(consdata->valsreal[i].inf <= 0.0);
    1242
    1243 contribution = SCIPvarGetUbGlobal(consdata->vars[i]);
    1244
    1245 if( SCIPisInfinity(scip, contribution) )
    1246 continue;
    1247 }
    1248 else
    1249 {
    1250 assert(consdata->valsreal[i].inf >= 0.0);
    1251
    1252 contribution = SCIPvarGetLbGlobal(consdata->vars[i]);
    1253
    1254 if( SCIPisInfinity(scip, -contribution) )
    1255 continue;
    1256 }
    1257
    1258 contribution *= contribution < 0.0 ? consdata->valsreal[i].sup : consdata->valsreal[i].inf;
    1259
    1260 if( SCIPisHugeValue(scip, REALABS(contribution)) )
    1261 continue;
    1262
    1263 consdata->glbminactivity += contribution;
    1264 }
    1265
    1266 /* the activity was just computed from scratch and is valid now */
    1267 consdata->validglbminact = TRUE;
    1268
    1269 /* the activity was just computed from scratch, mark it to be reliable */
    1270 consdata->lastglbminactivity = consdata->glbminactivity;
    1271
    1273}
    1274
    1275/** recompute the global maxactivity of a constraint */
    1276static
    1278 SCIP* scip, /**< SCIP data structure */
    1279 SCIP_CONSDATA* consdata /**< linear constraint data */
    1280 )
    1281{
    1282 SCIP_ROUNDMODE prevmode;
    1283 SCIP_Real contribution;
    1284 int i;
    1285
    1286 consdata->glbmaxactivity = 0.0;
    1287 prevmode = SCIPintervalGetRoundingMode();
    1289
    1290 for( i = consdata->nvars - 1; i >= 0; --i )
    1291 {
    1292 if( consdata->valsreal[i].sup < 0.0 )
    1293 {
    1294 assert(consdata->valsreal[i].inf <= 0.0);
    1295
    1296 contribution = SCIPvarGetLbGlobal(consdata->vars[i]);
    1297
    1298 if( SCIPisInfinity(scip, -contribution) )
    1299 continue;
    1300 }
    1301 else
    1302 {
    1303 assert(consdata->valsreal[i].inf >= 0.0);
    1304
    1305 contribution = SCIPvarGetUbGlobal(consdata->vars[i]);
    1306
    1307 if( SCIPisInfinity(scip, contribution) )
    1308 continue;
    1309 }
    1310
    1311 contribution *= contribution < 0.0 ? consdata->valsreal[i].inf : consdata->valsreal[i].sup;
    1312
    1313 if( SCIPisHugeValue(scip, REALABS(contribution)) )
    1314 continue;
    1315
    1316 consdata->glbmaxactivity += contribution;
    1317 }
    1318
    1319 /* the activity was just computed from scratch and is valid now */
    1320 consdata->validglbmaxact = TRUE;
    1321
    1322 /* the activity was just computed from scratch, mark it to be reliable */
    1323 consdata->lastglbmaxactivity = consdata->glbmaxactivity;
    1325}
    1326
    1327/** calculates minimum absolute value of coefficients */
    1328static
    1330 SCIP_CONSDATA* consdata /**< linear constraint data */
    1331 )
    1332{
    1333 int i;
    1334 assert(consdata != NULL);
    1335 assert(!consdata->validminabsval);
    1336
    1337 consdata->validminabsval = TRUE;
    1338
    1339 if( consdata->nvars > 0 )
    1340 {
    1341 SCIPrationalAbs(consdata->minabsvalexact, consdata->vals[0]);
    1342 assert(!SCIPrationalIsZero(consdata->vals[0]));
    1343 }
    1344 else
    1345 SCIPrationalSetReal(consdata->minabsvalexact, 0.0);
    1346
    1347 for( i = 1; i < consdata->nvars; ++i )
    1348 {
    1349 assert(!SCIPrationalIsZero(consdata->vals[i]));
    1350
    1351 if( SCIPrationalIsAbsGT(consdata->minabsvalexact, consdata->vals[i]) )
    1352 SCIPrationalAbs(consdata->minabsvalexact, consdata->vals[i]);
    1353 }
    1354}
    1355
    1356/** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
    1357static
    1359 SCIP_CONSDATA* consdata /**< linear constraint data */
    1360 )
    1361{
    1362 int v;
    1363
    1364 assert(!consdata->hasnonbinvalid);
    1365 consdata->hasnonbinvar = FALSE;
    1366 consdata->hascontvar = FALSE;
    1367
    1368 for( v = consdata->nvars - 1; v >= 0; --v )
    1369 {
    1370 SCIP_VARTYPE vartype = SCIPvarGetType(consdata->vars[v]);
    1371
    1372 if( vartype != SCIP_VARTYPE_BINARY )
    1373 {
    1374 consdata->hasnonbinvar = TRUE;
    1375
    1376 if( vartype == SCIP_VARTYPE_CONTINUOUS )
    1377 {
    1378 consdata->hascontvar = TRUE;
    1379 break;
    1380 }
    1381 }
    1382 }
    1383 assert(consdata->hascontvar || v < 0);
    1384
    1385 consdata->hasnonbinvalid = TRUE;
    1386}
    1387
    1388#ifdef SCIP_MORE_DEBUG
    1389/* checks that the stored maximal activity delta (if not invalid) is correct */
    1390static
    1392 SCIP* scip, /**< SCIP data structure */
    1393 SCIP_CONSDATA* consdata /**< linear constraint data */
    1394 )
    1395{
    1396 if( consdata->maxactdelta != SCIP_INVALID )
    1397 {
    1398 SCIP_Rational* maxactdelta;
    1399 SCIP_Rational* domain;
    1400 SCIP_Rational* delta;
    1401 SCIP_RATIONAL* lb;
    1402 SCIP_RATIONAL* ub;
    1403 int v;
    1404
    1408
    1409 for( v = consdata->nvars - 1; v >= 0; --v )
    1410 {
    1411 lb = SCIPvarGetLbLocalExact(consdata->vars[v]);
    1412 ub = SCIPvarGetUbLocalExact(consdata->vars[v]);
    1413
    1415 {
    1416 SCIPrationalSetInfinity(maxactdelta);
    1417 break;
    1418 }
    1419
    1420 SCIPrationalDiff(domain, ub, lb);
    1421 SCIPrationalAbs(delta, consdata->vals[v]);
    1422 SCIPrationalMult(delta, delta, domain);
    1423
    1424 if( SCIPrationalisGT(delta,maxactdelta) )
    1425 {
    1426 SCIPrationalSetRational(maxactdelta, delta);
    1427 }
    1428 }
    1429 assert(SCIPrationalIsEQ(maxactdelta, consdata->maxactdelta));
    1430
    1433 SCIPrationalFreeBuffer(SCIPbuffer(scip), maxactdelta);
    1434 }
    1435}
    1436#else
    1437#define checkMaxActivityDelta(scip, consdata) /**/
    1438#endif
    1439
    1440/** recompute maximal activity contribution for a single variable */
    1441static
    1443 SCIP* scip, /**< SCIP data structure */
    1444 SCIP_CONSDATA* consdata /**< linear constraint data */
    1445 )
    1446{
    1447 SCIP_Real delta;
    1448 int v;
    1449 consdata->maxactdelta = 0.0;
    1450
    1451 if( !consdata->hasnonbinvalid )
    1452 consdataCheckNonbinvar(consdata);
    1453
    1454 /* easy case, the problem consists only of binary variables */
    1455 if( !consdata->hasnonbinvar )
    1456 {
    1457 for( v = consdata->nvars - 1; v >= 0; --v )
    1458 {
    1459 if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
    1460 {
    1461 delta = SCIPintervalAbsMax(consdata->valsreal[v]);
    1462
    1463 if( delta > consdata->maxactdelta )
    1464 {
    1465 consdata->maxactdelta = delta;
    1466 consdata->maxactdeltavar = consdata->vars[v];
    1467 }
    1468 }
    1469 }
    1470 return;
    1471 }
    1472
    1473 for( v = consdata->nvars - 1; v >= 0; --v )
    1474 {
    1475 SCIP_Real domain;
    1476 SCIP_Real lb;
    1477 SCIP_Real ub;
    1478
    1479 lb = SCIPvarGetLbLocal(consdata->vars[v]);
    1480 ub = SCIPvarGetUbLocal(consdata->vars[v]);
    1481
    1482 if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
    1483 {
    1484 consdata->maxactdelta = SCIPinfinity(scip);
    1485 consdata->maxactdeltavar = consdata->vars[v];
    1486 break;
    1487 }
    1488
    1489 domain = ub - lb;
    1490 delta = SCIPintervalAbsMax(consdata->valsreal[v]) * domain;
    1491
    1492 if( delta > consdata->maxactdelta )
    1493 {
    1494 consdata->maxactdelta = delta;
    1495 consdata->maxactdeltavar = consdata->vars[v];
    1496 }
    1497 }
    1498}
    1499
    1500/** updates activities for a change in a bound */
    1501static
    1503 SCIP* scip, /**< SCIP data structure */
    1504 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1505 SCIP_VAR* var, /**< variable that has been changed; can be NULL for global bound changes */
    1506 SCIP_Real oldbound, /**< old bound of variable */
    1507 SCIP_Real newbound, /**< new bound of variable */
    1508 SCIP_INTERVAL valrange, /**< coefficient of constraint entry */
    1509 SCIP_BOUNDTYPE boundtype, /**< type of the bound change */
    1510 SCIP_Bool global /**< is it a global or a local bound change? */
    1511 )
    1512{
    1513 SCIP_Real* activity;
    1514 SCIP_Real* lastactivity;
    1515 int* activityposinf;
    1516 int* activityneginf;
    1517 int* activityposhuge;
    1518 int* activityneghuge;
    1519 SCIP_Real oldcontribution;
    1520 SCIP_Real newcontribution;
    1521 SCIP_Real delta;
    1522 SCIP_Bool validact;
    1523 SCIP_Bool finitenewbound;
    1524 SCIP_Bool hugevalnewcont;
    1525 SCIP_Real oldval;
    1526 SCIP_Real newval;
    1527 SCIP_ROUNDMODE prevmode;
    1528
    1529 prevmode = SCIPintervalGetRoundingMode();
    1530
    1531 assert(scip != NULL);
    1532 assert(consdata != NULL);
    1533 assert(global || (var != NULL));
    1534 assert(consdata->validactivities);
    1535 assert(consdata->minactivity < SCIP_INVALID);
    1536 assert(consdata->maxactivity < SCIP_INVALID);
    1537 assert(consdata->lastminactivity < SCIP_INVALID);
    1538 assert(consdata->lastmaxactivity < SCIP_INVALID);
    1539 assert(consdata->minactivityneginf >= 0);
    1540 assert(consdata->minactivityposinf >= 0);
    1541 assert(consdata->maxactivityneginf >= 0);
    1542 assert(consdata->maxactivityposinf >= 0);
    1543 assert(consdata->minactivityneghuge >= 0);
    1544 assert(consdata->minactivityposhuge >= 0);
    1545 assert(consdata->maxactivityneghuge >= 0);
    1546 assert(consdata->maxactivityposhuge >= 0);
    1547 assert(consdata->glbminactivity < SCIP_INVALID);
    1548 assert(consdata->glbmaxactivity < SCIP_INVALID);
    1549 assert(consdata->lastglbminactivity < SCIP_INVALID);
    1550 assert(consdata->lastglbmaxactivity < SCIP_INVALID);
    1551 assert(consdata->glbminactivityneginf >= 0);
    1552 assert(consdata->glbminactivityposinf >= 0);
    1553 assert(consdata->glbmaxactivityneginf >= 0);
    1554 assert(consdata->glbmaxactivityposinf >= 0);
    1555 assert(consdata->glbminactivityneghuge >= 0);
    1556 assert(consdata->glbminactivityposhuge >= 0);
    1557 assert(consdata->glbmaxactivityneghuge >= 0);
    1558 assert(consdata->glbmaxactivityposhuge >= 0);
    1559
    1560 delta = 0.0;
    1561
    1562 /* we are updating global activities */
    1563 if( global )
    1564 {
    1565 /* depending on the boundtype and the coefficient, we choose the activity to be updated:
    1566 * lower bound + pos. coef: update minactivity
    1567 * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
    1568 * upper bound + pos. coef: update maxactivity
    1569 * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
    1570 */
    1571 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    1572 {
    1573 if( valrange.sup < 0.0 )
    1574 {
    1575 assert(valrange.inf <= 0.0);
    1576
    1577 activity = &(consdata->glbmaxactivity);
    1578 lastactivity = &(consdata->lastglbmaxactivity);
    1579 activityposinf = &(consdata->glbmaxactivityneginf);
    1580 activityneginf = &(consdata->glbmaxactivityposinf);
    1581 activityposhuge = &(consdata->glbmaxactivityposhuge);
    1582 activityneghuge = &(consdata->glbmaxactivityneghuge);
    1583 validact = consdata->validglbmaxact;
    1585 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
    1586 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
    1587 }
    1588 else
    1589 {
    1590 assert(valrange.inf >= 0.0);
    1591
    1592 activity = &(consdata->glbminactivity);
    1593 lastactivity = &(consdata->lastglbminactivity);
    1594 activityposinf = &(consdata->glbminactivityposinf);
    1595 activityneginf = &(consdata->glbminactivityneginf);
    1596 activityposhuge = &(consdata->glbminactivityposhuge);
    1597 activityneghuge = &(consdata->glbminactivityneghuge);
    1598 validact = consdata->validglbminact;
    1600 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
    1601 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
    1602 }
    1603 }
    1604 else
    1605 {
    1606 if( valrange.sup < 0.0 )
    1607 {
    1608 assert(valrange.inf <= 0.0);
    1609
    1610 activity = &(consdata->glbminactivity);
    1611 lastactivity = &(consdata->lastglbminactivity);
    1612 activityposinf = &(consdata->glbminactivityneginf);
    1613 activityneginf = &(consdata->glbminactivityposinf);
    1614 activityposhuge = &(consdata->glbminactivityposhuge);
    1615 activityneghuge = &(consdata->glbminactivityneghuge);
    1616 validact = consdata->validglbminact;
    1618 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
    1619 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
    1620 }
    1621 else
    1622 {
    1623 assert(valrange.inf >= 0.0);
    1624
    1625 activity = &(consdata->glbmaxactivity);
    1626 lastactivity = &(consdata->lastglbmaxactivity);
    1627 activityposinf = &(consdata->glbmaxactivityposinf);
    1628 activityneginf = &(consdata->glbmaxactivityneginf);
    1629 activityposhuge = &(consdata->glbmaxactivityposhuge);
    1630 activityneghuge = &(consdata->glbmaxactivityneghuge);
    1631 validact = consdata->validglbmaxact;
    1633 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
    1634 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
    1635 }
    1636 }
    1637 }
    1638 /* we are updating local activities */
    1639 else
    1640 {
    1641 /* depending on the boundtype and the coefficient, we choose the activity to be updated:
    1642 * lower bound + pos. coef: update minactivity
    1643 * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
    1644 * upper bound + pos. coef: update maxactivity
    1645 * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
    1646 */
    1647 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    1648 {
    1649 if( valrange.sup < 0.0 )
    1650 {
    1651 assert(valrange.inf <= 0.0);
    1652
    1653 activity = &(consdata->maxactivity);
    1654 lastactivity = &(consdata->lastmaxactivity);
    1655 activityposinf = &(consdata->maxactivityneginf);
    1656 activityneginf = &(consdata->maxactivityposinf);
    1657 activityposhuge = &(consdata->maxactivityposhuge);
    1658 activityneghuge = &(consdata->maxactivityneghuge);
    1659 validact = consdata->validmaxact;
    1661 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
    1662 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
    1663 }
    1664 else
    1665 {
    1666 assert(valrange.inf >= 0.0);
    1667
    1668 activity = &(consdata->minactivity);
    1669 lastactivity = &(consdata->lastminactivity);
    1670 activityposinf = &(consdata->minactivityposinf);
    1671 activityneginf = &(consdata->minactivityneginf);
    1672 activityposhuge = &(consdata->minactivityposhuge);
    1673 activityneghuge = &(consdata->minactivityneghuge);
    1674 validact = consdata->validminact;
    1676 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
    1677 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
    1678 }
    1679 }
    1680 else
    1681 {
    1682 if( valrange.sup < 0.0 )
    1683 {
    1684 assert(valrange.inf <= 0.0);
    1685
    1686 activity = &(consdata->minactivity);
    1687 lastactivity = &(consdata->lastminactivity);
    1688 activityposinf = &(consdata->minactivityneginf);
    1689 activityneginf = &(consdata->minactivityposinf);
    1690 activityposhuge = &(consdata->minactivityposhuge);
    1691 activityneghuge = &(consdata->minactivityneghuge);
    1692 validact = consdata->validminact;
    1694 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
    1695 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
    1696 }
    1697 else
    1698 {
    1699 assert(valrange.inf >= 0.0);
    1700
    1701 activity = &(consdata->maxactivity);
    1702 lastactivity = &(consdata->lastmaxactivity);
    1703 activityposinf = &(consdata->maxactivityposinf);
    1704 activityneginf = &(consdata->maxactivityneginf);
    1705 activityposhuge = &(consdata->maxactivityposhuge);
    1706 activityneghuge = &(consdata->maxactivityneghuge);
    1707 validact = consdata->validmaxact;
    1709 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
    1710 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
    1711 }
    1712 }
    1713 }
    1714
    1715 oldcontribution = SCIPintervalNegateReal(oldval) * oldbound;
    1716 newcontribution = newval * newbound;
    1717 hugevalnewcont = SCIPisHugeValue(scip, REALABS(newcontribution));
    1718 finitenewbound = !SCIPisInfinity(scip, REALABS(newbound));
    1719
    1720 if( SCIPisInfinity(scip, REALABS(oldbound)) )
    1721 {
    1722 /* old bound was +infinity */
    1723 if( oldbound > 0.0 )
    1724 {
    1725 assert((*activityposinf) >= 1);
    1726
    1727 /* we only have to do something if the new bound is not again +infinity */
    1728 if( finitenewbound || newbound < 0.0 )
    1729 {
    1730 /* decrease the counter for positive infinite contributions */
    1731 (*activityposinf)--;
    1732
    1733 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
    1734 if( !finitenewbound && newbound < 0.0 )
    1735 (*activityneginf)++;
    1736 else if( hugevalnewcont )
    1737 {
    1738 /* if the contribution of this variable is too large, increase the counter for huge values */
    1739 if( newcontribution > 0.0 )
    1740 (*activityposhuge)++;
    1741 else
    1742 (*activityneghuge)++;
    1743 }
    1744 /* "normal case": just add the contribution to the activity */
    1745 else
    1746 delta = newcontribution;
    1747 }
    1748 }
    1749 /* old bound was -infinity */
    1750 else
    1751 {
    1752 assert(oldbound < 0.0);
    1753 assert((*activityneginf) >= 1);
    1754
    1755 /* we only have to do something ig the new bound is not again -infinity */
    1756 if( finitenewbound || newbound > 0.0 )
    1757 {
    1758 /* decrease the counter for negative infinite contributions */
    1759 (*activityneginf)--;
    1760
    1761 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
    1762 if( !finitenewbound && newbound > 0.0 )
    1763 (*activityposinf)++;
    1764 else if( hugevalnewcont )
    1765 {
    1766 /* if the contribution of this variable is too large, increase the counter for huge values */
    1767 if( newcontribution > 0.0 )
    1768 (*activityposhuge)++;
    1769 else
    1770 (*activityneghuge)++;
    1771 }
    1772 /* "normal case": just add the contribution to the activity */
    1773 else
    1774 delta = newcontribution;
    1775 }
    1776 }
    1777 }
    1778 else if( SCIPisHugeValue(scip, REALABS(oldcontribution)) )
    1779 {
    1780 /* old contribution was too large and positive */
    1781 if( -oldcontribution > 0.0 )
    1782 {
    1783 assert((*activityposhuge) >= 1);
    1784
    1785 /* decrease the counter for huge positive contributions; it might be increased again later,
    1786 * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
    1787 */
    1788 (*activityposhuge)--;
    1789
    1790 if( !finitenewbound )
    1791 {
    1792 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
    1793 if( newbound > 0.0 )
    1794 (*activityposinf)++;
    1795 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
    1796 else
    1797 (*activityneginf)++;
    1798 }
    1799 else if( hugevalnewcont )
    1800 {
    1801 /* if the contribution of this variable is too large and positive, increase the corresponding counter */
    1802 if( newcontribution > 0.0 )
    1803 (*activityposhuge)++;
    1804 /* if the contribution of this variable is too large and negative, increase the corresponding counter */
    1805 else
    1806 (*activityneghuge)++;
    1807 }
    1808 /* "normal case": just add the contribution to the activity */
    1809 else
    1810 delta = newcontribution;
    1811 }
    1812 /* old contribution was too large and negative */
    1813 else
    1814 {
    1815 assert(-oldcontribution < 0.0);
    1816 assert((*activityneghuge) >= 1);
    1817
    1818 /* decrease the counter for huge negative contributions; it might be increased again later,
    1819 * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
    1820 */
    1821 (*activityneghuge)--;
    1822
    1823 if( !finitenewbound )
    1824 {
    1825 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
    1826 if( newbound > 0.0 )
    1827 (*activityposinf)++;
    1828 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
    1829 else
    1830 (*activityneginf)++;
    1831 }
    1832 else if( hugevalnewcont )
    1833 {
    1834 /* if the contribution of this variable is too large and positive, increase the corresponding counter */
    1835 if( newcontribution > 0.0 )
    1836 (*activityposhuge)++;
    1837 /* if the contribution of this variable is too large and negative, increase the corresponding counter */
    1838 else
    1839 (*activityneghuge)++;
    1840 }
    1841 /* "normal case": just add the contribution to the activity */
    1842 else
    1843 delta = newcontribution;
    1844 }
    1845 }
    1846 /* old bound was finite and not too large */
    1847 else
    1848 {
    1849 if( !finitenewbound )
    1850 {
    1851 /* if the new bound is +infinity, the old contribution has to be subtracted
    1852 * and the counter for positive infinite contributions has to be increased
    1853 */
    1854 if( newbound > 0.0 )
    1855 {
    1856 (*activityposinf)++;
    1857 delta = oldcontribution;
    1858 }
    1859 /* if the new bound is -infinity, the old contribution has to be subtracted
    1860 * and the counter for negative infinite contributions has to be increased
    1861 */
    1862 else
    1863 {
    1864 assert(newbound < 0.0 );
    1865
    1866 (*activityneginf)++;
    1867 delta = oldcontribution;
    1868 }
    1869 }
    1870 /* if the contribution of this variable is too large, increase the counter for huge values */
    1871 else if( hugevalnewcont )
    1872 {
    1873 if( newcontribution > 0.0 )
    1874 {
    1875 (*activityposhuge)++;
    1876 delta = oldcontribution;
    1877 }
    1878 else
    1879 {
    1880 (*activityneghuge)++;
    1881 delta = oldcontribution;
    1882 }
    1883 }
    1884 /* "normal case": just update the activity */
    1885 else
    1886 delta = newcontribution + oldcontribution;
    1887 }
    1888
    1889 /* update the activity, if the current value is valid and there was a change in the finite part */
    1890 if( validact && (delta != 0.0) )
    1891 {
    1892 /* if the absolute value of the activity is increased, this is regarded as reliable,
    1893 * otherwise, we check whether we can still trust the updated value
    1894 */
    1895 (*activity) = (*activity) + delta;
    1896 assert(!SCIPisInfinity(scip, -(*activity)) && !SCIPisInfinity(scip, *activity));
    1897
    1898 if( REALABS((*lastactivity)) < REALABS(*activity) )
    1899 {
    1900 (*lastactivity) = (*activity);
    1901 }
    1902 }
    1903
    1905}
    1906/** updates minimum and maximum activity for a change in lower bound */
    1907static
    1909 SCIP* scip, /**< SCIP data structure */
    1910 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1911 SCIP_VAR* var, /**< variable that has been changed */
    1912 SCIP_Real oldlb, /**< old lower bound of variable */
    1913 SCIP_Real newlb, /**< new lower bound of variable */
    1914 SCIP_INTERVAL val /**< coefficient of constraint entry */
    1915 )
    1916{
    1917 assert(scip != NULL);
    1918 assert(consdata != NULL);
    1919 assert(var != NULL);
    1920
    1921 if( consdata->validactivities )
    1922 {
    1923 consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE);
    1924
    1925 assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
    1926 assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
    1927 }
    1928}
    1929
    1930/** updates minimum and maximum activity for a change in upper bound */
    1931static
    1933 SCIP* scip, /**< SCIP data structure */
    1934 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1935 SCIP_VAR* var, /**< variable that has been changed */
    1936 SCIP_Real oldub, /**< old upper bound of variable */
    1937 SCIP_Real newub, /**< new upper bound of variable */
    1938 SCIP_INTERVAL val /**< coefficient of constraint entry */
    1939 )
    1940{
    1941 assert(scip != NULL);
    1942 assert(consdata != NULL);
    1943 assert(var != NULL);
    1944
    1945 if( consdata->validactivities )
    1946 {
    1947 consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE);
    1948
    1949 assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
    1950 assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
    1951 }
    1952}
    1953
    1954/** updates minimum and maximum global activity for a change in the global lower bound */
    1955static
    1957 SCIP* scip, /**< SCIP data structure */
    1958 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1959 SCIP_Real oldlb, /**< old lower bound of variable */
    1960 SCIP_Real newlb, /**< new lower bound of variable */
    1961 SCIP_INTERVAL val /**< coefficient of constraint entry */
    1962 )
    1963{
    1964 assert(scip != NULL);
    1965 assert(consdata != NULL);
    1966
    1967 if( consdata->validactivities )
    1968 {
    1969 consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE);
    1970
    1971 assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
    1972 assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
    1973 }
    1974}
    1975
    1976/** updates minimum and maximum global activity for a change in global upper bound */
    1977static
    1979 SCIP* scip, /**< SCIP data structure */
    1980 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1981 SCIP_Real oldub, /**< old upper bound of variable */
    1982 SCIP_Real newub, /**< new upper bound of variable */
    1983 SCIP_INTERVAL val /**< coefficient of constraint entry */
    1984 )
    1985{
    1986 assert(scip != NULL);
    1987 assert(consdata != NULL);
    1988
    1989 if( consdata->validactivities )
    1990 {
    1991 consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE);
    1992
    1993 assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
    1994 assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
    1995 }
    1996}
    1997
    1998/** updates minimum and maximum activity and maximum absolute value for coefficient addition */
    1999static
    2001 SCIP* scip, /**< SCIP data structure */
    2002 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2003 SCIP_VAR* var, /**< variable of constraint entry */
    2004 SCIP_RATIONAL* valExact, /**< coefficient of constraint entry */
    2005 SCIP_INTERVAL val /**< coefficient of constraint entry */
    2006 )
    2007{
    2008 assert(scip != NULL);
    2009 assert(consdata != NULL);
    2010 assert(var != NULL);
    2011
    2012 /* update maximum absolute value */
    2013 if( consdata->validmaxabsval )
    2014 {
    2015 SCIP_Real absval;
    2016
    2017 assert(consdata->maxabsval < SCIP_INVALID);
    2018
    2019 absval = MAX(REALABS(val.inf), REALABS(val.sup)); /*lint !e777 !e666*/
    2020 consdata->maxabsval = MAX(consdata->maxabsval, absval);
    2021 }
    2022
    2023 if( consdata->validminabsval )
    2024 {
    2025 SCIP_Real absval;
    2026
    2027 assert(consdata->minabsval < SCIP_INVALID);
    2028
    2029 absval = MAX(REALABS(val.inf), REALABS(val.sup)); /*lint !e777 !e666*/
    2030 consdata->minabsval = MIN(consdata->minabsval, absval);
    2031 }
    2032
    2033 /* invalidate maximum absolute value, if this coefficient was the maximum */
    2034 if( consdata->validmaxabsval )
    2035 {
    2036 if( SCIPrationalIsAbsEQ(valExact, consdata->maxabsvalexact) )
    2037 {
    2038 consdata->validmaxabsval = FALSE;
    2039 SCIPrationalSetInfinity(consdata->maxabsvalexact);
    2040 }
    2041 }
    2042
    2043 /* invalidate minimum absolute value, if this coefficient was the minimum */
    2044 if( consdata->validminabsval )
    2045 {
    2046 if( SCIPrationalIsAbsEQ(valExact, consdata->minabsvalexact) )
    2047 {
    2048 consdata->validminabsval = FALSE;
    2049 SCIPrationalSetInfinity(consdata->minabsvalexact);
    2050 }
    2051 }
    2052
    2053 /* update minimal and maximal activity */
    2054 if( consdata->validactivities )
    2055 {
    2056 assert(consdata->minactivity < SCIP_INVALID);
    2057 assert(consdata->maxactivity < SCIP_INVALID);
    2058 assert(consdata->glbminactivity < SCIP_INVALID);
    2059 assert(consdata->glbmaxactivity < SCIP_INVALID);
    2060
    2061 consdataUpdateActivitiesLb(scip, consdata, var, 0.0, SCIPvarGetLbLocal(var), val);
    2062 consdataUpdateActivitiesUb(scip, consdata, var, 0.0, SCIPvarGetUbLocal(var), val);
    2063 consdataUpdateActivitiesGlbLb(scip, consdata, 0.0, SCIPvarGetLbGlobal(var), val);
    2064 consdataUpdateActivitiesGlbUb(scip, consdata, 0.0, SCIPvarGetUbGlobal(var), val);
    2065 }
    2066}
    2067
    2068/** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
    2069static
    2071 SCIP* scip, /**< SCIP data structure */
    2072 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2073 SCIP_VAR* var, /**< variable of constraint entry */
    2074 SCIP_RATIONAL* valExact, /**< exact coefficient of constraint entry */
    2075 SCIP_INTERVAL val /**< coefficient of constraint entry */
    2076 )
    2077{
    2078 assert(scip != NULL);
    2079 assert(consdata != NULL);
    2080 assert(var != NULL);
    2081
    2082 /* invalidate maximum absolute value, if this coefficient was the maximum */
    2083 if( consdata->validmaxabsval )
    2084 {
    2085 SCIP_Real absval;
    2086
    2087 absval = SCIPintervalAbsMax(val);
    2088
    2089 if( SCIPisEQ(scip, absval, consdata->maxabsval) )
    2090 {
    2091 consdata->validmaxabsval = FALSE;
    2092 consdata->maxabsval = SCIP_INVALID;
    2093 }
    2094 }
    2095
    2096 /* invalidate minimum absolute value, if this coefficient was the minimum */
    2097 if( consdata->validminabsval )
    2098 {
    2099 SCIP_Real absval;
    2100
    2101 absval = SCIPintervalAbsMax(val);
    2102
    2103 if( SCIPisEQ(scip, absval, consdata->minabsval) )
    2104 {
    2105 consdata->validminabsval = FALSE;
    2106 consdata->minabsval = SCIP_INVALID;
    2107 }
    2108 }
    2109
    2110 /* invalidate maximum absolute value, if this coefficient was the maximum */
    2111 if( consdata->validmaxabsval )
    2112 {
    2113 if( SCIPrationalIsAbsEQ(valExact, consdata->maxabsvalexact) )
    2114 {
    2115 consdata->validmaxabsval = FALSE;
    2116 SCIPrationalSetInfinity(consdata->maxabsvalexact);
    2117 }
    2118 }
    2119
    2120 /* invalidate minimum absolute value, if this coefficient was the minimum */
    2121 if( consdata->validminabsval )
    2122 {
    2123 if( SCIPrationalIsAbsEQ(valExact, consdata->minabsvalexact) )
    2124 {
    2125 consdata->validminabsval = FALSE;
    2126 SCIPrationalSetInfinity(consdata->minabsvalexact);
    2127 }
    2128 }
    2129
    2130 /* update minimal and maximal activity */
    2131 if( consdata->validactivities )
    2132 {
    2133 assert(consdata->minactivity < SCIP_INVALID);
    2134 assert(consdata->maxactivity < SCIP_INVALID);
    2135 assert(consdata->glbminactivity < SCIP_INVALID);
    2136 assert(consdata->glbmaxactivity < SCIP_INVALID);
    2137
    2138 consdataUpdateActivitiesLb(scip, consdata, var, SCIPvarGetLbLocal(var), 0.0, val);
    2139 consdataUpdateActivitiesUb(scip, consdata, var, SCIPvarGetUbLocal(var), 0.0, val);
    2140 consdataUpdateActivitiesGlbLb(scip, consdata, SCIPvarGetLbGlobal(var), 0.0, val);
    2141 consdataUpdateActivitiesGlbUb(scip, consdata, SCIPvarGetUbGlobal(var), 0.0, val);
    2142 }
    2143}
    2144
    2145/** returns the minimum absolute value of all coefficients in the constraint */
    2146static
    2148 SCIP* scip, /**< SCIP data structure */
    2149 SCIP_CONSDATA* consdata /**< linear constraint data */
    2150 )
    2151{
    2152 assert(scip != NULL);
    2153 assert(consdata != NULL);
    2154
    2155 if( !consdata->validminabsval )
    2156 consdataCalcMinAbsvalEx(consdata);
    2157 assert(consdata->validminabsval);
    2158
    2159 return consdata->minabsvalexact;
    2160}
    2161
    2162
    2163/** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
    2164static
    2166 SCIP* scip, /**< SCIP data structure */
    2167 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2168 SCIP_VAR* var, /**< variable of constraint entry */
    2169 SCIP_INTERVAL oldval, /**< old coefficient of constraint entry */
    2170 SCIP_RATIONAL* oldvalExact, /**< old exact coefficient of constraint entry */
    2171 SCIP_INTERVAL newval, /**< new coefficient of constraint entry */
    2172 SCIP_RATIONAL* newvalExact /**< new coefficient of constraint entry */
    2173 )
    2174{
    2175 assert(scip != NULL);
    2176 assert(consdata != NULL);
    2177 assert(var != NULL);
    2178
    2179 /* update maximum absolute value */
    2180 if( consdata->validmaxabsval )
    2181 {
    2182 SCIP_Real absval;
    2183
    2184 absval = SCIPintervalAbsMax(newval);
    2185
    2186 if( absval >= consdata->maxabsval )
    2187 {
    2188 consdata->maxabsval = absval;
    2189 }
    2190 else
    2191 {
    2192 absval = SCIPintervalAbsMax(oldval);
    2193
    2194 /* invalidate maximum absolute value */
    2195 if( SCIPisEQ(scip, absval, consdata->maxabsval) )
    2196 {
    2197 consdata->validmaxabsval = FALSE;
    2198 consdata->maxabsval = SCIP_INVALID;
    2199 }
    2200 }
    2201 }
    2202
    2203 /* update minimum absolute value */
    2204 if( consdata->validminabsval )
    2205 {
    2206 SCIP_Real absval;
    2207
    2208 absval = SCIPintervalAbsMax(newval);
    2209
    2210 if( absval <= consdata->minabsval )
    2211 {
    2212 consdata->minabsval = absval;
    2213 }
    2214 else
    2215 {
    2216 absval = SCIPintervalAbsMax(oldval);
    2217
    2218 /* invalidate minimum absolute value */
    2219 if( SCIPisEQ(scip, absval, consdata->minabsval) )
    2220 {
    2221 consdata->validminabsval = FALSE;
    2222 consdata->minabsval = SCIP_INVALID;
    2223 }
    2224 }
    2225 }
    2226 /* update maximum absolute value */
    2227 if( consdata->validmaxabsval )
    2228 {
    2229 if( SCIPrationalIsAbsGT(newvalExact, consdata->maxabsvalexact) )
    2230 {
    2231 SCIPrationalAbs(consdata->maxabsvalexact, newvalExact);
    2232 }
    2233 else
    2234 {
    2235 /* invalidate maximum absolute value */
    2236 if( SCIPrationalIsAbsEQ(oldvalExact, consdata->maxabsvalexact) )
    2237 {
    2238 consdata->validmaxabsval = FALSE;
    2239 SCIPrationalSetInfinity(consdata->maxabsvalexact);
    2240 }
    2241 }
    2242 }
    2243 /* update minimum absolute value */
    2244 if( consdata->validminabsval )
    2245 {
    2246 if( SCIPrationalIsAbsGT(consdata->minabsvalexact, newvalExact) )
    2247 {
    2248 SCIPrationalAbs(consdata->minabsvalexact, newvalExact);
    2249 }
    2250 else
    2251 {
    2252 /* invalidate minimum absolute value */
    2253 if( SCIPrationalIsAbsEQ(oldvalExact, consdata->minabsvalexact) )
    2254 {
    2255 consdata->validminabsval = FALSE;
    2256 SCIPrationalSetInfinity(consdata->minabsvalexact);
    2257 }
    2258 }
    2259 }
    2260
    2261 /* update maximum activity delta */
    2262 if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
    2263 {
    2264 SCIP_Real domain;
    2265 SCIP_Real delta;
    2266
    2267 assert(!SCIPisInfinity(scip, SCIPvarGetLbLocal(var)));
    2268 assert(!SCIPisInfinity(scip, SCIPvarGetUbLocal(var)));
    2269
    2270 domain = SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var);
    2271 delta = SCIPintervalAbsMax(newval) * domain;
    2272
    2273 if( delta > consdata->maxactdelta )
    2274 {
    2275 consdata->maxactdelta = delta;
    2276 consdata->maxactdeltavar = var;
    2277 }
    2278 else
    2279 {
    2280 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
    2281 if( consdata->maxactdeltavar == var )
    2282 consdata->maxactdelta = SCIP_INVALID;
    2283 }
    2284 }
    2285
    2286 /* @todo as in cons_linear, do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
    2287 consdataUpdateDelCoef(scip, consdata, var, oldvalExact, oldval);
    2288 consdataUpdateAddCoef(scip, consdata, var, newvalExact, newval);
    2289}
    2290
    2291/** ensures that every nonzero is a least minval so that we don't get problem with SCIPs 0 in floating point representation */
    2292static
    2294 SCIP* scip, /**< SCIP data structure */
    2295 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2296 SCIP_Real minval /**< minmimal value for coefficients in constraint */
    2297 )
    2298{
    2299 int i;
    2300 SCIP_RATIONAL* scalingfactor;
    2301 SCIP_RATIONAL* minabsval;
    2302
    2303 assert(scip != NULL);
    2304 assert(consdata != NULL);
    2305
    2306 minabsval = consdataGetMinAbsvalEx(scip, consdata);
    2307
    2308 assert(!SCIPrationalIsZero(minabsval) || consdata->nvars == 0);
    2309
    2310 (void) SCIPrationalCreateBuffer(SCIPbuffer(scip), &scalingfactor);
    2311
    2312 if( SCIPrationalIsLTReal(minabsval, minval) )
    2313 {
    2314 SCIPrationalSetReal(scalingfactor, minval);
    2315 SCIPrationalDiv(scalingfactor, scalingfactor, minabsval);
    2316
    2317 for( i = 0; i < consdata->nvars; i++ )
    2318 {
    2319 SCIPrationalMult(consdata->vals[i], consdata->vals[i], scalingfactor);
    2320 SCIPintervalSetRational(&(consdata->valsreal[i]), consdata->vals[i]);
    2321 }
    2322
    2323 SCIPrationalMult(consdata->rhs, consdata->rhs, scalingfactor);
    2324 consdata->rhsreal = SCIPrationalRoundReal(consdata->rhs, SCIP_R_ROUND_UPWARDS);
    2325
    2326 SCIPrationalMult(consdata->lhs, consdata->lhs, scalingfactor);
    2327 consdata->lhsreal = SCIPrationalRoundReal(consdata->lhs, SCIP_R_ROUND_DOWNWARDS);
    2328 }
    2329
    2331
    2332 SCIPrationalFreeBuffer(SCIPbuffer(scip), &scalingfactor);
    2333}
    2334
    2335/** calculates minimum and maximum local and global activity for constraint from scratch;
    2336 * additionally recalculates maximum absolute value of coefficients
    2337 */
    2338static
    2340 SCIP* scip, /**< SCIP data structure */
    2341 SCIP_CONSDATA* consdata /**< linear constraint data */
    2342 )
    2343{
    2344 int i;
    2345 assert(scip != NULL);
    2346 assert(consdata != NULL);
    2347 assert(!consdata->validactivities);
    2348 assert(consdata->minactivity >= SCIP_INVALID || consdata->validminact);
    2349 assert(consdata->maxactivity >= SCIP_INVALID || consdata->validmaxact);
    2350 assert(consdata->glbminactivity >= SCIP_INVALID || consdata->validglbminact);
    2351 assert(consdata->glbmaxactivity >= SCIP_INVALID || consdata->validglbmaxact);
    2352
    2353 consdata->validmaxabsval = TRUE;
    2354 consdata->validminabsval = TRUE;
    2355 consdata->validactivities = TRUE;
    2356 consdata->validminact = TRUE;
    2357 consdata->validmaxact = TRUE;
    2358 consdata->validglbminact = TRUE;
    2359 consdata->validglbmaxact = TRUE;
    2360 consdata->maxabsval = 0.0;
    2361 consdata->minabsval = (consdata->nvars == 0 ? 0.0 : SCIPintervalAbsMax(consdata->valsreal[0]));
    2362 consdata->minactivity = 0.0;
    2363 consdata->maxactivity = 0.0;
    2364 consdata->lastminactivity = 0.0;
    2365 consdata->lastmaxactivity = 0.0;
    2366 consdata->minactivityneginf = 0;
    2367 consdata->minactivityposinf = 0;
    2368 consdata->maxactivityneginf = 0;
    2369 consdata->maxactivityposinf = 0;
    2370 consdata->minactivityneghuge = 0;
    2371 consdata->minactivityposhuge = 0;
    2372 consdata->maxactivityneghuge = 0;
    2373 consdata->maxactivityposhuge = 0;
    2374 consdata->glbminactivity = 0.0;
    2375 consdata->glbmaxactivity = 0.0;
    2376 consdata->lastglbminactivity = 0.0;
    2377 consdata->lastglbmaxactivity = 0.0;
    2378 consdata->glbminactivityneginf = 0;
    2379 consdata->glbminactivityposinf = 0;
    2380 consdata->glbmaxactivityneginf = 0;
    2381 consdata->glbmaxactivityposinf = 0;
    2382 consdata->glbminactivityneghuge = 0;
    2383 consdata->glbminactivityposhuge = 0;
    2384 consdata->glbmaxactivityneghuge = 0;
    2385 consdata->glbmaxactivityposhuge = 0;
    2386
    2387 for( i = 0; i < consdata->nvars; ++i )
    2388 consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], consdata->valsreal[i]);
    2389 consdata->lastminactivity = consdata->minactivity;
    2390 consdata->lastmaxactivity = consdata->maxactivity;
    2391 consdata->lastglbminactivity = consdata->glbminactivity;
    2392 consdata->lastglbmaxactivity = consdata->glbmaxactivity;
    2393}
    2394
    2395/** computes the activity of a row for a given solution plus a bound on the floating-point error using running error analysis */
    2396static
    2398 SCIP* scip, /**< SCIP data structure */
    2399 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2400 SCIP_SOL* sol, /**< primal CIP solution */
    2401 SCIP_Real* activity, /**< buffer to return floating-point activity */
    2402 SCIP_Real* errorbound /**< buffer to return bound on absolute floating-point error */
    2403 )
    2404{
    2405 SCIP_Real solval;
    2406 SCIP_Real sum;
    2407 SCIP_Real mu;
    2408 SCIP_Real inf;
    2409 SCIP_Bool success;
    2410 int v;
    2411
    2412 assert(activity != NULL);
    2413 assert(errorbound != NULL);
    2414
    2415 inf = SCIPinfinity(scip);
    2416 *activity = SCIP_UNKNOWN;
    2417 *errorbound = inf;
    2418
    2419 sum = 0.0;
    2420 mu = 0.0;
    2421 /* normally we want to use the row since all fixed/aggregated variables do not appear there */
    2422 if( consdata->rowlhs == NULL )
    2423 {
    2424 for( v = 0; v < consdata->nvars; ++v )
    2425 {
    2426 if( SCIPvarGetStatus(consdata->vars[v]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(consdata->vars[v]) == SCIP_VARSTATUS_LOOSE )
    2427 solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
    2428 else
    2429 return FALSE;
    2430
    2431 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
    2432 return FALSE;
    2433
    2434 sum += consdata->valsreal[v].inf * solval;
    2435 mu += REALABS(sum);
    2436 /* the factor 3 + eps is needed to account for rounding errors in valsreal[v]/solval */
    2437 mu += (3.0 + SCIP_REAL_UNITROUNDOFF) * REALABS(consdata->valsreal[v].inf * solval);
    2438 }
    2439 }
    2440 else
    2441 {
    2442 success = SCIPgetRowSolActivityWithErrorboundExact(scip, consdata->rowexact, sol, &sum, &mu);
    2443
    2444 if( !success )
    2445 return FALSE;
    2446 }
    2447
    2448 sum = MAX(sum, -inf);
    2449 sum = MIN(sum, +inf);
    2450 *activity = sum;
    2451
    2452 if( SCIPisInfinity(scip, sum) || SCIPisInfinity(scip, -sum) )
    2453 *errorbound = inf;
    2454 else
    2455 *errorbound = mu * 1.1 * SCIP_REAL_UNITROUNDOFF;
    2456
    2457 return TRUE;
    2458}
    2459
    2460/** gets minimal activity for constraint and given values of counters for infinite and huge contributions
    2461 * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
    2462 */
    2463static
    2465 SCIP* scip, /**< SCIP data structure */
    2466 SCIP_CONSDATA* consdata, /**< linear constraint */
    2467 int posinf, /**< number of coefficients contributing pos. infinite value */
    2468 int neginf, /**< number of coefficients contributing neg. infinite value */
    2469 int poshuge, /**< number of coefficients contributing huge pos. value */
    2470 int neghuge, /**< number of coefficients contributing huge neg. value */
    2471 SCIP_Real delta, /**< value to subtract from stored minactivity
    2472 * (contribution of the variable set to zero when getting residual activity) */
    2473 SCIP_Bool global, /**< should the global or local minimal activity be returned? */
    2474 SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
    2475 SCIP_Real* minactivity, /**< pointer to store the minimal activity */
    2476 SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
    2477 * i.e. is <= the exact minactivity (in case of huge contributing values) */
    2478 SCIP_Bool* issettoinfinity /**< pointer to store whether minactivity was set to infinity or calculated */
    2479 )
    2480{
    2481 assert(scip != NULL);
    2482 assert(consdata != NULL);
    2483 assert(posinf >= 0);
    2484 assert(neginf >= 0);
    2485 assert(poshuge >= 0);
    2486 assert(neghuge >= 0);
    2487 assert(minactivity != NULL);
    2488 assert(isrelax != NULL);
    2489 assert(issettoinfinity != NULL);
    2490
    2491 /* if we have pos. infinite contributions, the minactivity is +infty */
    2492 if( posinf > 0 )
    2493 {
    2494 *minactivity = SCIPinfinity(scip);
    2495 *issettoinfinity = TRUE;
    2496 *isrelax = FALSE;
    2497 }
    2498 /* if we have neg. (and no pos.) infinite contributions, the minactivity is -infty */
    2499 else if( neginf > 0 )
    2500 {
    2501 *minactivity = -SCIPinfinity(scip);
    2502 *issettoinfinity = TRUE;
    2503 *isrelax = FALSE;
    2504 }
    2505 /* if we have neg. huge contributions, we only know that -infty is a relaxation of the minactivity */
    2506 else if( neghuge > 0 )
    2507 {
    2508 *minactivity = -SCIPinfinity(scip);
    2509 *issettoinfinity = TRUE;
    2510 *isrelax = TRUE;
    2511 }
    2512 /* we do not need a good relaxation and we have positive huge contributions, so we just return -infty as activity */
    2513 else if( !goodrelax && poshuge > 0 )
    2514 {
    2515 *minactivity = -SCIPinfinity(scip);
    2516 *issettoinfinity = TRUE;
    2517 *isrelax = TRUE;
    2518 }
    2519 else
    2520 {
    2521 SCIP_Real tmpactivity;
    2522
    2523 /* recompute minactivity if it is not valid */
    2524 if( global )
    2525 {
    2526 if( !consdata->validglbminact )
    2528 assert(consdata->validglbminact);
    2529
    2530 tmpactivity = consdata->glbminactivity;
    2531 }
    2532 else
    2533 {
    2534 if( !consdata->validminact )
    2536 assert(consdata->validminact);
    2537
    2538 tmpactivity = consdata->minactivity;
    2539 }
    2540
    2541 /* we have no infinite and no neg. huge contributions, but pos. huge contributions;
    2542 * a feasible relaxation of the minactivity is the number of positive huge contributions
    2543 * times the minimum value counting as "huge" plus finite (and non-huge) part of minactivity - delta
    2544 */
    2545 if( poshuge > 0 )
    2546 {
    2547 *minactivity = 1.0 * poshuge * SCIPgetHugeValue(scip) + (tmpactivity - delta);
    2548 *issettoinfinity = FALSE;
    2549 *isrelax = TRUE;
    2550 }
    2551 /* all counters are zero, so the minactivity is just stored and we subtract the delta */
    2552 else
    2553 {
    2554 *minactivity = tmpactivity - delta;
    2555 *issettoinfinity = FALSE;
    2556 *isrelax = FALSE;
    2557 }
    2558 }
    2559}
    2560
    2561/** gets maximal activity for constraint and given values of counters for infinite and huge contributions
    2562 * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
    2563 */
    2564static
    2566 SCIP* scip, /**< SCIP data structure */
    2567 SCIP_CONSDATA* consdata, /**< linear constraint */
    2568 int posinf, /**< number of coefficients contributing pos. infinite value */
    2569 int neginf, /**< number of coefficients contributing neg. infinite value */
    2570 int poshuge, /**< number of coefficients contributing huge pos. value */
    2571 int neghuge, /**< number of coefficients contributing huge neg. value */
    2572 SCIP_Real delta, /**< value to subtract from stored maxactivity
    2573 * (contribution of the variable set to zero when getting residual activity) */
    2574 SCIP_Bool global, /**< should the global or local maximal activity be returned? */
    2575 SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
    2576 SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
    2577 SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
    2578 * i.e. is >= the exact maxactivity (in case of huge contributing values) */
    2579 SCIP_Bool* issettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
    2580 )
    2581{
    2582 assert(scip != NULL);
    2583 assert(consdata != NULL);
    2584 assert(posinf >= 0);
    2585 assert(neginf >= 0);
    2586 assert(poshuge >= 0);
    2587 assert(neghuge >= 0);
    2588 assert(maxactivity != NULL);
    2589 assert(isrelax != NULL);
    2590 assert(issettoinfinity != NULL);
    2591
    2592 /* if we have neg. infinite contributions, the maxactivity is -infty */
    2593 if( neginf > 0 )
    2594 {
    2595 *maxactivity = -SCIPinfinity(scip);
    2596 *issettoinfinity = TRUE;
    2597 *isrelax = FALSE;
    2598 }
    2599 /* if we have pos. (and no neg.) infinite contributions, the maxactivity is +infty */
    2600 else if( posinf > 0 )
    2601 {
    2602 *maxactivity = SCIPinfinity(scip);
    2603 *issettoinfinity = TRUE;
    2604 *isrelax = FALSE;
    2605 }
    2606 /* if we have pos. huge contributions, we only know that +infty is a relaxation of the maxactivity */
    2607 else if( poshuge > 0 )
    2608 {
    2609 *maxactivity = SCIPinfinity(scip);
    2610 *issettoinfinity = TRUE;
    2611 *isrelax = TRUE;
    2612 }
    2613 /* we do not need a good relaxation and we have positve huge contributions, so we just return +infty as activity */
    2614 else if( !goodrelax && neghuge > 0 )
    2615 {
    2616 *maxactivity = SCIPinfinity(scip);
    2617 *issettoinfinity = TRUE;
    2618 *isrelax = TRUE;
    2619 }
    2620 else
    2621 {
    2622 SCIP_Real tmpactivity;
    2623
    2624 /* recompute maxactivity if it is not valid */
    2625 if( global )
    2626 {
    2627 if( !consdata->validglbmaxact )
    2629 assert(consdata->validglbmaxact);
    2630
    2631 tmpactivity = consdata->glbmaxactivity;
    2632 }
    2633 else
    2634 {
    2635 if( !consdata->validmaxact )
    2637 assert(consdata->validmaxact);
    2638
    2639 tmpactivity = consdata->maxactivity;
    2640 }
    2641
    2642 /* we have no infinite, and no pos. huge contributions, but neg. huge contributions;
    2643 * a feasible relaxation of the maxactivity is minus the number of negative huge contributions
    2644 * times the minimum value counting as "huge" plus the finite (and non-huge) part of maxactivity minus delta
    2645 */
    2646 if( neghuge > 0 )
    2647 {
    2648 *maxactivity = -1.0 * neghuge * SCIPgetHugeValue(scip) + tmpactivity - delta;
    2649 *issettoinfinity = FALSE;
    2650 *isrelax = TRUE;
    2651 }
    2652 /* all counters are zero, so the maxactivity is just stored and we subtract the delta */
    2653 else
    2654 {
    2655 *maxactivity = tmpactivity - delta;
    2656 *issettoinfinity = FALSE;
    2657 *isrelax = FALSE;
    2658 }
    2659 }
    2660}
    2661
    2662/** gets activity bounds for constraint */
    2663static
    2665 SCIP* scip, /**< SCIP data structure */
    2666 SCIP_CONSDATA* consdata, /**< linear constraint */
    2667 SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
    2668 * relaxed activities ignored, anyway? */
    2669 SCIP_Real* minactivity, /**< pointer to store the minimal activity */
    2670 SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
    2671 SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
    2672 * i.e. <= the exact minactivity (in case of huge contributions),
    2673 * or equal to the exact minimal activity */
    2674 SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
    2675 * i.e. >= the exact maxactivity (in case of huge contributions),
    2676 * or equal to the exact maximal activity */
    2677 SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minactivity was set to infinity or calculated */
    2678 SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
    2679
    2680 )
    2681{
    2682 assert(scip != NULL);
    2683 assert(consdata != NULL);
    2684 assert(minactivity != NULL);
    2685 assert(maxactivity != NULL);
    2686 assert(isminsettoinfinity != NULL);
    2687 assert(ismaxsettoinfinity != NULL);
    2688
    2689 if( !consdata->validactivities )
    2690 {
    2691 consdataCalcActivities(scip, consdata);
    2692 assert(consdata->validminact);
    2693 assert(consdata->validmaxact);
    2694 }
    2695 assert(consdata->minactivity < SCIP_INVALID);
    2696 assert(consdata->maxactivity < SCIP_INVALID);
    2697 assert(consdata->minactivityneginf >= 0);
    2698 assert(consdata->minactivityposinf >= 0);
    2699 assert(consdata->maxactivityneginf >= 0);
    2700 assert(consdata->maxactivityposinf >= 0);
    2701
    2702 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2703 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2704 minactivity, minisrelax, isminsettoinfinity);
    2705
    2706 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2707 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2708 maxactivity, maxisrelax, ismaxsettoinfinity);
    2709}
    2710
    2711/** gets activity bounds for constraint after setting variable to zero */
    2712static
    2714 SCIP* scip, /**< SCIP data structure */
    2715 SCIP_CONSDATA* consdata, /**< linear constraint */
    2716 SCIP_VAR* var, /**< variable to calculate activity residual for */
    2717 SCIP_INTERVAL val, /**< coefficient value of variable in linear constraint */
    2718 SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
    2719 * relaxed acticities ignored, anyway? */
    2720 SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity */
    2721 SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity */
    2722 SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
    2723 * relaxation, i.e. <= the exact residual minactivity (in case of huge
    2724 * contributions), or equal to the exact residual minactivity */
    2725 SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
    2726 * relaxation, i.e. <= the exact residual maxactivity (in case of huge
    2727 * contributions), or equal to the exact residual minactivity */
    2728 SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
    2729 SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
    2730 )
    2731{
    2732 SCIP_Real minactbound;
    2733 SCIP_Real maxactbound;
    2734 SCIP_Real absval;
    2735 SCIP_ROUNDMODE prevmode;
    2736 prevmode = SCIPintervalGetRoundingMode();
    2737
    2738 assert(scip != NULL);
    2739 assert(consdata != NULL);
    2740 assert(var != NULL);
    2741 assert(minresactivity != NULL);
    2742 assert(maxresactivity != NULL);
    2743 assert(minisrelax != NULL);
    2744 assert(maxisrelax != NULL);
    2745 assert(isminsettoinfinity != NULL);
    2746 assert(ismaxsettoinfinity != NULL);
    2747
    2748 /* get activity bounds of linear constraint */
    2749 if( !consdata->validactivities )
    2750 {
    2751 consdataCalcActivities(scip, consdata);
    2752 assert(consdata->validminact);
    2753 assert(consdata->validmaxact);
    2754 }
    2755 assert(consdata->minactivity < SCIP_INVALID);
    2756 assert(consdata->maxactivity < SCIP_INVALID);
    2757 assert(consdata->minactivityneginf >= 0);
    2758 assert(consdata->minactivityposinf >= 0);
    2759 assert(consdata->maxactivityneginf >= 0);
    2760 assert(consdata->maxactivityposinf >= 0);
    2761 assert(consdata->minactivityneghuge >= 0);
    2762 assert(consdata->minactivityposhuge >= 0);
    2763 assert(consdata->maxactivityneghuge >= 0);
    2764 assert(consdata->maxactivityposhuge >= 0);
    2765
    2766 if( val.sup < 0.0 )
    2767 {
    2768 assert(val.inf <= 0.0);
    2769
    2770 minactbound = -SCIPvarGetUbLocal(var);
    2771 maxactbound = -SCIPvarGetLbLocal(var);
    2772 absval = -val.inf;
    2773 }
    2774 else
    2775 {
    2776 assert(val.inf >= 0.0);
    2777
    2778 minactbound = SCIPvarGetLbLocal(var);
    2779 maxactbound = SCIPvarGetUbLocal(var);
    2780 absval = val.sup;
    2781 }
    2782
    2783 /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
    2784 * and contribution of variable set to zero that has to be subtracted from finite part of activity
    2785 */
    2786 if( SCIPisInfinity(scip, minactbound) )
    2787 {
    2788 assert(consdata->minactivityposinf >= 1);
    2789
    2790 getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
    2791 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2792 minresactivity, minisrelax, isminsettoinfinity);
    2793 }
    2794 else if( SCIPisInfinity(scip, -minactbound) )
    2795 {
    2796 assert(consdata->minactivityneginf >= 1);
    2797
    2798 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
    2799 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2800 minresactivity, minisrelax, isminsettoinfinity);
    2801 }
    2802 else if( SCIPisHugeValue(scip, minactbound * absval) )
    2803 {
    2804 assert(consdata->minactivityposhuge >= 1);
    2805
    2806 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2807 consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2808 minresactivity, minisrelax, isminsettoinfinity);
    2809 }
    2810 else if( SCIPisHugeValue(scip, -minactbound * absval) )
    2811 {
    2812 assert(consdata->minactivityneghuge >= 1);
    2813
    2814 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2815 consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
    2816 minresactivity, minisrelax, isminsettoinfinity);
    2817 }
    2818 else
    2819 {
    2820 SCIP_Real delta;
    2821 delta = absval * minactbound;
    2824 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2825 consdata->minactivityposhuge, consdata->minactivityneghuge, delta, FALSE, goodrelax,
    2826 minresactivity, minisrelax, isminsettoinfinity);
    2827 }
    2828
    2829 /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
    2830 * and contribution of variable set to zero that has to be subtracted from finite part of activity
    2831 */
    2832 if( SCIPisInfinity(scip, -maxactbound) )
    2833 {
    2834 assert(consdata->maxactivityneginf >= 1);
    2835
    2836 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
    2837 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2838 maxresactivity, maxisrelax, ismaxsettoinfinity);
    2839 }
    2840 else if( SCIPisInfinity(scip, maxactbound) )
    2841 {
    2842 assert(consdata->maxactivityposinf >= 1);
    2843
    2844 getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
    2845 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2846 maxresactivity, maxisrelax, ismaxsettoinfinity);
    2847 }
    2848 else if( SCIPisHugeValue(scip, absval * maxactbound) )
    2849 {
    2850 assert(consdata->maxactivityposhuge >= 1);
    2851
    2852 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2853 consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2854 maxresactivity, maxisrelax, ismaxsettoinfinity);
    2855 }
    2856 else if( SCIPisHugeValue(scip, -absval * maxactbound) )
    2857 {
    2858 assert(consdata->maxactivityneghuge >= 1);
    2859
    2860 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2861 consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
    2862 maxresactivity, maxisrelax, ismaxsettoinfinity);
    2863 }
    2864 else
    2865 {
    2866 SCIP_Real delta;
    2867 delta = absval * maxactbound;
    2870 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2871 consdata->maxactivityposhuge, consdata->maxactivityneghuge, delta, FALSE, goodrelax,
    2872 maxresactivity, maxisrelax, ismaxsettoinfinity);
    2873 }
    2875}
    2876
    2877/** calculates the activity of the linear constraint for given solution */
    2878static
    2880 SCIP* scip, /**< SCIP data structure */
    2881 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2882 SCIP_SOL* sol, /**< solution to get activity for, NULL to current solution */
    2883 SCIP_Bool useexact, /**< should the exact solution be used */
    2884 SCIP_RATIONAL* activity /**< pointer to store the activity */
    2885 )
    2886{
    2887 assert(scip != NULL);
    2888 assert(consdata != NULL);
    2889
    2890 if( (sol == NULL) && !SCIPhasCurrentNodeLP(scip) )
    2891 consdataComputePseudoActivity(consdata, activity);
    2892 else
    2893 {
    2894 SCIP_RATIONAL* solval;
    2895 int nposinf;
    2896 int nneginf;
    2897 SCIP_Bool negsign;
    2898 int v;
    2899
    2900 (void) SCIPrationalCreateBuffer(SCIPbuffer(scip), &solval);
    2901
    2902 SCIPrationalSetFraction(activity, 0LL, 1LL);
    2903 nposinf = 0;
    2904 nneginf = 0;
    2905
    2906 for( v = 0; v < consdata->nvars; ++v )
    2907 {
    2908 if( useexact )
    2909 SCIPgetSolValExact(scip, sol, consdata->vars[v], solval);
    2910 else
    2911 SCIPrationalSetReal(solval, SCIPgetSolVal(scip, sol, consdata->vars[v]));
    2912
    2913 assert(!SCIPrationalIsZero(consdata->vals[v]));
    2914 negsign = SCIPrationalIsNegative(consdata->vals[v]);
    2915
    2916 if( (SCIPrationalIsInfinity(solval) && !negsign) || (SCIPrationalIsNegInfinity(solval) && negsign) )
    2917 ++nposinf;
    2918 else if( (SCIPrationalIsInfinity(solval) && negsign) || (SCIPrationalIsNegInfinity(solval) && !negsign) )
    2919 ++nneginf;
    2920 else
    2921 {
    2922 SCIPrationalAddProd(activity, solval, consdata->vals[v]);
    2923 }
    2924 }
    2925 assert(nneginf >= 0 && nposinf >= 0);
    2926
    2927 SCIPdebugMsg(scip, "activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", SCIPrationalGetReal(activity), nposinf, nneginf);
    2928
    2929 /* set activity to infeasible infinity for contradicting contributions */
    2930 if( nneginf > 0 && ( nposinf == 0 || !SCIPrationalIsNegInfinity(consdata->lhs) ) )
    2932 else if( nposinf > 0 && ( nneginf == 0 || !SCIPrationalIsInfinity(consdata->rhs) ) )
    2933 SCIPrationalSetInfinity(activity);
    2934
    2935 SCIPrationalDebugMessage("corrected activity of linear constraint: %q\n", activity);
    2936
    2938 }
    2939}
    2940
    2941/** calculates the feasibility of the linear constraint for given solution */
    2942static
    2944 SCIP* scip, /**< SCIP data structure */
    2945 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2946 SCIP_SOL* sol, /**< solution to get feasibility for, NULL to current solution */
    2947 SCIP_RATIONAL* ret /**< pointer to store the result */
    2948 )
    2949{
    2950 SCIP_RATIONAL* activity;
    2951 SCIP_RATIONAL* op1;
    2952 SCIP_RATIONAL* op2;
    2953
    2954 assert(scip != NULL);
    2955 assert(consdata != NULL);
    2956
    2957 (void) SCIPrationalCreateBuffer(SCIPbuffer(scip), &activity);
    2960
    2961 consdataGetActivity(scip, consdata, sol, FALSE, activity);
    2962 SCIPrationalDiff(op1, consdata->rhs, activity);
    2963 SCIPrationalDiff(op2, activity, consdata->lhs);
    2964
    2965 SCIPrationalMin(ret, op1, op2);
    2966
    2970}
    2971
    2972/** creates an LP row in a linear constraint data */
    2973static
    2975 SCIP* scip, /**< SCIP data structure */
    2976 SCIP_CONS* cons /**< linear constraint */
    2977 );
    2978
    2979/** prints the certificate for a given original exact linear constraint */
    2981 SCIP* scip, /**< SCIP data structure */
    2982 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    2983 SCIP_CONS* cons /**< constraint */
    2984 )
    2985{
    2986 SCIP_CONSDATA* consdata;
    2987 int* varsindex;
    2988 int i;
    2989
    2990 /*lint --e{715}*/
    2991 assert(scip != NULL);
    2992 assert(conshdlr != NULL);
    2993 assert(cons != NULL);
    2994
    2995 /* print constraint into certificate output */
    2996 if( SCIPisCertified(scip) )
    2997 {
    2998 consdata = SCIPconsGetData(cons);
    2999
    3000 SCIP_CALL( SCIPallocBufferArray(scip, &varsindex, consdata->nvars) );
    3001 for( i = 0; i < consdata->nvars; ++i )
    3002 varsindex[i] = SCIPvarGetCertificateIndex(consdata->vars[i]);
    3003
    3004 /* print constraint */
    3005 if( SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
    3006 {
    3007 assert(!SCIPrationalIsAbsInfinity(consdata->lhs));
    3008 SCIP_CALL( SCIPcertifyCons(scip, TRUE, NULL, 'E', consdata->lhs, consdata->nvars, varsindex, consdata->vals) );
    3009 }
    3010 else
    3011 {
    3012 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
    3013 {
    3014 SCIP_CALL( SCIPcertifyCons(scip, TRUE, NULL, 'G', consdata->lhs, consdata->nvars, varsindex, consdata->vals) );
    3015 }
    3016 if( !SCIPrationalIsInfinity(consdata->rhs) )
    3017 {
    3018 SCIP_CALL( SCIPcertifyCons(scip, TRUE, NULL, 'L', consdata->rhs, consdata->nvars, varsindex, consdata->vals) );
    3019 }
    3020 }
    3021
    3022 SCIPfreeBufferArray(scip, &varsindex);
    3023 }
    3024
    3025 return SCIP_OKAY;
    3026}
    3027
    3028/** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
    3029static
    3031{ /*lint --e{715}*/
    3032 SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
    3033
    3034 assert(consdata != NULL);
    3035 assert(0 <= ind1 && ind1 < consdata->nvars);
    3036 assert(0 <= ind2 && ind2 < consdata->nvars);
    3037
    3038 return SCIPvarCompare(consdata->vars[ind1], consdata->vars[ind2]);
    3039}
    3040
    3041/** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
    3042static
    3043SCIP_DECL_SORTINDCOMP(consdataCompVarProp)
    3044{ /*lint --e{715}*/
    3045 SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
    3046 SCIP_VAR* var1;
    3047 SCIP_VAR* var2;
    3048
    3049 assert(consdata != NULL);
    3050 assert(0 <= ind1 && ind1 < consdata->nvars);
    3051 assert(0 <= ind2 && ind2 < consdata->nvars);
    3052
    3053 var1 = consdata->vars[ind1];
    3054 var2 = consdata->vars[ind2];
    3055
    3056 /* exactly one variable is binary */
    3057 if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
    3058 {
    3059 return (SCIPvarIsBinary(var1) ? -1 : +1);
    3060 }
    3061 /* both variables are binary */
    3062 else if( SCIPvarIsBinary(var1) )
    3063 {
    3064 if( SCIPrationalIsAbsEQ(consdata->vals[ind1], consdata->vals[ind2]) ) {
    3065 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
    3066 }
    3067 if( SCIPrationalIsAbsGT(consdata->vals[ind1], consdata->vals[ind2]) )
    3068 return -1;
    3069 else
    3070 return +1;
    3071 }
    3072 else
    3073 {
    3074 SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
    3075 SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
    3076
    3077 if( vartype1 < vartype2 )
    3078 {
    3079 return -1;
    3080 }
    3081 else if( vartype1 > vartype2 )
    3082 {
    3083 return +1;
    3084 }
    3085 else
    3086 {
    3087 /* both variables are continuous */
    3088 if( !SCIPvarIsIntegral(var1) )
    3089 {
    3090 assert(!SCIPvarIsIntegral(var2));
    3091 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
    3092 }
    3093 else
    3094 {
    3095 SCIP_RATIONAL* abscont1;
    3096 SCIP_RATIONAL* abscont2;
    3097
    3098 (void) SCIPrationalCreate(&abscont1);
    3099 (void) SCIPrationalCreate(&abscont2);
    3100
    3102 SCIPrationalMult(abscont1, consdata->vals[ind1], abscont1);
    3103
    3105 SCIPrationalMult(abscont2, consdata->vals[ind2], abscont2);
    3106
    3107 if( SCIPrationalIsAbsEQ(abscont1, abscont2) ) {
    3108 SCIPrationalFree(&abscont1);
    3109 SCIPrationalFree(&abscont2);
    3110 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
    3111 }
    3112 if( SCIPrationalIsAbsGT(abscont2, abscont1) )
    3113 {
    3114 SCIPrationalFree(&abscont1);
    3115 SCIPrationalFree(&abscont2);
    3116 return 1;
    3117 }
    3118 else
    3119 {
    3120 SCIPrationalFree(&abscont1);
    3121 SCIPrationalFree(&abscont2);
    3122 return -1;
    3123 }
    3124 }
    3125 }
    3126 }
    3127}
    3128
    3129/** permutes the constraint's variables according to a given permutation. */
    3130static
    3132 SCIP_CONSDATA* consdata, /**< the constraint data */
    3133 int* perm, /**< the target permutation */
    3134 int nvars /**< the number of variables */
    3135 )
    3136{ /*lint --e{715}*/
    3137 SCIP_VAR* varv;
    3138 SCIP_EVENTDATA* eventdatav;
    3139 SCIP_INTERVAL valrealv;
    3140 SCIP_RATIONAL* valv;
    3141 int v;
    3142 int i;
    3143 int nexti;
    3144
    3145 assert(perm != NULL);
    3146 assert(consdata != NULL);
    3147
    3148 /* permute the variables in the linear constraint according to the target permutation */
    3149 eventdatav = NULL;
    3150 for( v = 0; v < nvars; ++v )
    3151 {
    3152 if( perm[v] != v )
    3153 {
    3154 varv = consdata->vars[v];
    3155 valv = consdata->vals[v];
    3156 valrealv = consdata->valsreal[v];
    3157 if( consdata->eventdata != NULL )
    3158 eventdatav = consdata->eventdata[v];
    3159 i = v;
    3160 do
    3161 {
    3162 assert(0 <= perm[i] && perm[i] < nvars);
    3163 assert(perm[i] != i);
    3164 consdata->vars[i] = consdata->vars[perm[i]];
    3165 consdata->vals[i] = consdata->vals[perm[i]];
    3166 consdata->valsreal[i] = consdata->valsreal[perm[i]];
    3167 if( consdata->eventdata != NULL )
    3168 {
    3169 consdata->eventdata[i] = consdata->eventdata[perm[i]];
    3170 consdata->eventdata[i]->varpos = i;
    3171 }
    3172 nexti = perm[i];
    3173 perm[i] = i;
    3174 i = nexti;
    3175 }
    3176 while( perm[i] != v );
    3177 consdata->vars[i] = varv;
    3178 consdata->vals[i] = valv;
    3179 consdata->valsreal[i] = valrealv;
    3180 if( consdata->eventdata != NULL )
    3181 {
    3182 consdata->eventdata[i] = eventdatav;
    3183 consdata->eventdata[i]->varpos = i;
    3184 }
    3185 perm[i] = i;
    3186 }
    3187 }
    3188#ifdef SCIP_DEBUG
    3189 /* check sorting */
    3190 for( v = 0; v < nvars; ++v )
    3191 {
    3192 assert(perm[v] == v);
    3193 assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
    3194 }
    3195#endif
    3196}
    3197
    3198/** sorts linear constraint's variables depending on the stage of the solving process:
    3199 * - during PRESOLVING
    3200 * sorts variables by binary, integer, implied integral, and continuous variables,
    3201 * and the variables of the same type by non-decreasing variable index
    3202 *
    3203 * - during SOLVING
    3204 * sorts variables of the remaining problem by binary, integer, implied integral, and continuous variables,
    3205 * and binary and integer variables by their global max activity delta (within each group),
    3206 * ties within a group are broken by problem index of the variable.
    3207 *
    3208 * This fastens the propagation time of the constraint handler.
    3209 */
    3210static
    3212 SCIP* scip, /**< SCIP data structure */
    3213 SCIP_CONSDATA* consdata /**< linear constraint data */
    3214 )
    3215{
    3216 assert(scip != NULL);
    3217 assert(consdata != NULL);
    3218
    3219 /* check if there are variables for sorting */
    3220 if( consdata->nvars <= 1 )
    3221 {
    3222 consdata->indexsorted = TRUE;
    3223 consdata->coefsorted = TRUE;
    3224 consdata->nbinvars = (consdata->nvars == 1 ? (int)SCIPvarIsBinary(consdata->vars[0]) : 0);
    3225 }
    3226 else if( (!consdata->indexsorted && SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE)
    3227 || (!consdata->coefsorted && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE) )
    3228 {
    3229 int* perm;
    3230 int v;
    3231
    3232 /* get temporary memory to store the sorted permutation */
    3233 SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
    3234
    3235 /* call sorting method */
    3237 SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
    3238 else
    3239 SCIPsort(perm, consdataCompVarProp, (void*)consdata, consdata->nvars);
    3240
    3241 permSortConsdata(consdata, perm, consdata->nvars);
    3242
    3243 /* free temporary memory */
    3244 SCIPfreeBufferArray(scip, &perm);
    3245
    3247 {
    3248 consdata->indexsorted = FALSE;
    3249 consdata->coefsorted = TRUE;
    3250
    3251 /* count binary variables in the sorted vars array */
    3252 consdata->nbinvars = 0;
    3253 for( v = 0; v < consdata->nvars; ++v )
    3254 {
    3255 if( SCIPvarIsBinary(consdata->vars[v]) )
    3256 ++consdata->nbinvars;
    3257 else
    3258 break;
    3259 }
    3260 }
    3261 else
    3262 {
    3263 consdata->indexsorted = TRUE;
    3264 consdata->coefsorted = FALSE;
    3265 }
    3266 }
    3267
    3268 return SCIP_OKAY;
    3269}
    3270
    3271
    3272/*
    3273 * local linear constraint handler methods
    3274 */
    3275
    3276/** sets left hand side of linear constraint */
    3277static
    3279 SCIP* scip, /**< SCIP data structure */
    3280 SCIP_CONS* cons, /**< linear constraint */
    3281 SCIP_RATIONAL* lhs /**< new left hand side */
    3282 )
    3283{
    3284 SCIP_CONSDATA* consdata;
    3285 SCIP_Bool locked;
    3286 int i;
    3287
    3288 assert(scip != NULL);
    3289 assert(cons != NULL);
    3290 assert(!SCIPrationalIsInfinity(lhs));
    3291
    3292 consdata = SCIPconsGetData(cons);
    3293 assert(consdata != NULL);
    3294 assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
    3295 assert(!SCIPrationalIsInfinity(consdata->lhs));
    3296
    3297 /* check whether the side is not changed */
    3298 if( SCIPrationalIsEQ(consdata->lhs, lhs) )
    3299 return SCIP_OKAY;
    3300
    3301 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
    3302 if( SCIPrationalIsEQ(lhs, consdata->rhs) )
    3303 {
    3304 SCIPrationalSetRational(consdata->rhs, lhs);
    3305 assert(consdata->rowlhs == NULL);
    3306 }
    3307
    3308 locked = FALSE;
    3309 for( i = 0; i < NLOCKTYPES && !locked; i++ )
    3310 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
    3311
    3312 /* if necessary, update the rounding locks of variables */
    3313 if( locked )
    3314 {
    3315 if( SCIPrationalIsNegInfinity(consdata->lhs) && !SCIPrationalIsNegInfinity(lhs) )
    3316 {
    3317 SCIP_VAR** vars;
    3318 SCIP_RATIONAL** vals;
    3319 int v;
    3320
    3321 /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
    3322 vars = consdata->vars;
    3323 vals = consdata->vals;
    3324
    3325 for( v = 0; v < consdata->nvars; ++v )
    3326 {
    3327 assert(vars[v] != NULL);
    3328 assert(!SCIPrationalIsZero(vals[v]));
    3329
    3330 if( SCIPrationalIsPositive(vals[v]) )
    3331 {
    3332 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3333 }
    3334 else
    3335 {
    3336 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3337 }
    3338 }
    3339 }
    3340 else if( !SCIPrationalIsNegInfinity(consdata->lhs) && SCIPrationalIsNegInfinity(lhs) )
    3341 {
    3342 SCIP_VAR** vars;
    3343 SCIP_RATIONAL** vals;
    3344 int v;
    3345
    3346 /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
    3347 vars = consdata->vars;
    3348 vals = consdata->vals;
    3349
    3350 for( v = 0; v < consdata->nvars; ++v )
    3351 {
    3352 assert(vars[v] != NULL);
    3353 assert(!SCIPrationalIsZero(vals[v]));
    3354
    3355 if( SCIPrationalIsPositive(vals[v]) )
    3356 {
    3357 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3358 }
    3359 else
    3360 {
    3361 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3362 }
    3363 }
    3364 }
    3365 }
    3366
    3367 /* 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 */
    3368 if( !SCIPrationalIsNegInfinity(lhs) && SCIPrationalIsGT(lhs, consdata->lhs) )
    3369 {
    3370 consdata->boundstightened = 0;
    3371 consdata->presolved = FALSE;
    3372 consdata->cliquesadded = FALSE;
    3373 consdata->implsadded = FALSE;
    3374
    3375 /* mark the constraint for propagation */
    3376 if( SCIPconsIsTransformed(cons) )
    3377 {
    3379 }
    3380 }
    3381
    3382 /* set new left hand side and update constraint data */
    3383 SCIPrationalSetRational(consdata->lhs, lhs);
    3384 consdata->lhsreal = SCIPrationalRoundReal(lhs, SCIP_R_ROUND_DOWNWARDS);
    3385 consdata->changed = TRUE;
    3386 consdata->normalized = FALSE;
    3387 consdata->rangedrowpropagated = 0;
    3388
    3389 /* update the lhs of the LP row */
    3390 if( consdata->rowexact != NULL )
    3391 {
    3392 SCIP_CALL( SCIPchgRowExactLhs(scip, consdata->rowexact, lhs) );
    3393 }
    3394
    3395 return SCIP_OKAY;
    3396}
    3397
    3398/** sets right hand side of linear constraint */
    3399static
    3401 SCIP* scip, /**< SCIP data structure */
    3402 SCIP_CONS* cons, /**< linear constraint */
    3403 SCIP_RATIONAL* rhs /**< new right hand side */
    3404 )
    3405{
    3406 SCIP_CONSDATA* consdata;
    3407 SCIP_Bool locked;
    3408 int i;
    3409
    3410 assert(scip != NULL);
    3411 assert(cons != NULL);
    3412 assert(!SCIPrationalIsNegInfinity(rhs));
    3413
    3414 consdata = SCIPconsGetData(cons);
    3415 assert(consdata != NULL);
    3416 assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
    3417 assert(!SCIPrationalIsNegInfinity(consdata->rhs));
    3418
    3419 /* check whether the side is not changed */
    3420 if( SCIPrationalIsEQ(consdata->rhs, rhs) )
    3421 return SCIP_OKAY;
    3422
    3423 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
    3424 if( SCIPrationalIsEQ(rhs, consdata->lhs) )
    3425 {
    3426 SCIPrationalSetRational(consdata->rhs, rhs);
    3427 assert(consdata->rowlhs == NULL);
    3428 }
    3429
    3430 locked = FALSE;
    3431 for( i = 0; i < NLOCKTYPES && !locked; i++ )
    3432 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
    3433
    3434 /* if necessary, update the rounding locks of variables */
    3435 if( locked )
    3436 {
    3437 assert(SCIPconsIsTransformed(cons));
    3438
    3439 if( SCIPrationalIsInfinity(consdata->rhs) && !SCIPrationalIsInfinity(rhs) )
    3440 {
    3441 SCIP_VAR** vars;
    3442 SCIP_RATIONAL** vals;
    3443 int v;
    3444
    3445 /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
    3446 vars = consdata->vars;
    3447 vals = consdata->vals;
    3448
    3449 for( v = 0; v < consdata->nvars; ++v )
    3450 {
    3451 assert(vars[v] != NULL);
    3452 assert(!SCIPrationalIsZero(vals[v]));
    3453
    3454 if( SCIPrationalIsPositive(vals[v]) )
    3455 {
    3456 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3457 }
    3458 else
    3459 {
    3460 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3461 }
    3462 }
    3463 }
    3464 else if( !SCIPrationalIsInfinity(consdata->rhs) && SCIPrationalIsInfinity(rhs) )
    3465 {
    3466 SCIP_VAR** vars;
    3467 SCIP_RATIONAL** vals;
    3468 int v;
    3469
    3470 /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
    3471 vars = consdata->vars;
    3472 vals = consdata->vals;
    3473
    3474 for( v = 0; v < consdata->nvars; ++v )
    3475 {
    3476 assert(vars[v] != NULL);
    3477 assert(!SCIPrationalIsZero(vals[v]));
    3478
    3479 if( SCIPrationalIsPositive(vals[v]) )
    3480 {
    3481 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3482 }
    3483 else
    3484 {
    3485 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3486 }
    3487 }
    3488 }
    3489 }
    3490
    3491 /* 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 */
    3492 if( !SCIPrationalIsInfinity(rhs) && SCIPrationalIsLT(rhs, consdata->rhs) )
    3493 {
    3494 consdata->boundstightened = 0;
    3495 consdata->presolved = FALSE;
    3496 consdata->cliquesadded = FALSE;
    3497 consdata->implsadded = FALSE;
    3498
    3499 /* mark the constraint for propagation */
    3500 if( SCIPconsIsTransformed(cons) )
    3501 {
    3503 }
    3504 }
    3505
    3506 /* set new right hand side and update constraint data */
    3507 SCIPrationalSetRational(consdata->rhs, rhs);
    3508 consdata->rhsreal = SCIPrationalRoundReal(rhs, SCIP_R_ROUND_UPWARDS);
    3509 consdata->changed = TRUE;
    3510 consdata->normalized = FALSE;
    3511 consdata->rangedrowpropagated = 0;
    3512
    3513 /* update the rhs of the LP row */
    3514 if( consdata->rowexact != NULL )
    3515 {
    3516 SCIP_CALL( SCIPchgRowExactRhs(scip, consdata->rowexact, rhs) );
    3517 }
    3518
    3519 return SCIP_OKAY;
    3520}
    3521
    3522/** adds coefficient in linear constraint */
    3523static
    3525 SCIP* scip, /**< SCIP data structure */
    3526 SCIP_CONS* cons, /**< linear constraint */
    3527 SCIP_VAR* var, /**< variable of constraint entry */
    3528 SCIP_RATIONAL* val /**< coefficient of constraint entry */
    3529 )
    3530{
    3531 SCIP_CONSDATA* consdata;
    3532 SCIP_Bool transformed;
    3533
    3534 assert(scip != NULL);
    3535 assert(cons != NULL);
    3536 assert(var != NULL);
    3537
    3538 /* ignore coefficient if it is nearly zero */
    3539 if( SCIPrationalIsZero(val) )
    3540 return SCIP_OKAY;
    3541
    3542 consdata = SCIPconsGetData(cons);
    3543 assert(consdata != NULL);
    3544
    3545 /* are we in the transformed problem? */
    3546 transformed = SCIPconsIsTransformed(cons);
    3547
    3548 /* always use transformed variables in transformed constraints */
    3549 if( transformed )
    3550 {
    3551 SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
    3552 }
    3553 assert(var != NULL);
    3554 assert(transformed == SCIPvarIsTransformed(var));
    3555
    3556 SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
    3557 consdata->vars[consdata->nvars] = var;
    3558 SCIPrationalSetRational(consdata->vals[consdata->nvars], val);
    3559 SCIPintervalSetRational(&(consdata->valsreal[consdata->nvars]), val);
    3560 consdata->nvars++;
    3561
    3562 /* capture variable */
    3563 SCIP_CALL( SCIPcaptureVar(scip, var) );
    3564
    3565 /* if we are in transformed problem, the variable needs an additional event data */
    3566 if( transformed )
    3567 {
    3568 if( consdata->eventdata != NULL )
    3569 {
    3570 SCIP_CONSHDLR* conshdlr;
    3571 SCIP_CONSHDLRDATA* conshdlrdata;
    3572
    3573 /* check for event handler */
    3574 conshdlr = SCIPconsGetHdlr(cons);
    3575 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3576 assert(conshdlrdata != NULL);
    3577 assert(conshdlrdata->eventhdlr != NULL);
    3578
    3579 /* initialize eventdata array */
    3580 consdata->eventdata[consdata->nvars-1] = NULL;
    3581
    3582 /* catch bound change events of variable */
    3583 SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
    3584 }
    3585
    3586 /* update minimum and maximum activities */
    3587 consdataUpdateAddCoef(scip, consdata, var, consdata->vals[consdata->nvars - 1], consdata->valsreal[consdata->nvars - 1]);
    3588 }
    3589
    3590 /* install rounding locks for new variable */
    3591 SCIP_CALL( lockRounding(scip, cons, var, val) );
    3592
    3593 /* mark the constraint for propagation */
    3594 if( transformed )
    3595 {
    3597 }
    3598
    3599 consdata->boundstightened = 0;
    3600 consdata->presolved = FALSE;
    3601 consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
    3602
    3603 consdata->changed = TRUE;
    3604 consdata->normalized = FALSE;
    3605 consdata->cliquesadded = FALSE;
    3606 consdata->implsadded = FALSE;
    3607 consdata->rangedrowpropagated = 0;
    3608
    3609 if( consdata->nvars == 1 )
    3610 {
    3611 consdata->indexsorted = TRUE;
    3612 consdata->coefsorted = TRUE;
    3613 consdata->merged = TRUE;
    3614 }
    3615 else
    3616 {
    3617 consdata->merged = FALSE;
    3618
    3620 {
    3621 consdata->indexsorted = consdata->indexsorted && (consdataCompVar((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
    3622 consdata->coefsorted = FALSE;
    3623 }
    3624 else
    3625 {
    3626 consdata->indexsorted = FALSE;
    3627 consdata->coefsorted = consdata->coefsorted && (consdataCompVarProp((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
    3628 }
    3629 }
    3630
    3631 /* update hascontvar and hasnonbinvar flags */
    3632 if( consdata->hasnonbinvalid && !consdata->hascontvar )
    3633 {
    3634 SCIP_VARTYPE vartype = SCIPvarGetType(var);
    3635
    3636 if( vartype != SCIP_VARTYPE_BINARY )
    3637 {
    3638 consdata->hasnonbinvar = TRUE;
    3639
    3640 if( vartype == SCIP_VARTYPE_CONTINUOUS )
    3641 consdata->hascontvar = TRUE;
    3642 }
    3643 }
    3644
    3645 /* add the new coefficient to the LP row */
    3646 if( consdata->rowexact != NULL )
    3647 {
    3648 SCIP_CALL( SCIPaddVarsToRowExact(scip, consdata->rowexact, 1, &var, &val) );
    3649 }
    3650
    3651 return SCIP_OKAY;
    3652}
    3653
    3654/** deletes coefficient at given position from linear constraint data */
    3655static
    3657 SCIP* scip, /**< SCIP data structure */
    3658 SCIP_CONS* cons, /**< linear constraint */
    3659 int pos /**< position of coefficient to delete */
    3660 )
    3661{
    3662 SCIP_CONSDATA* consdata;
    3663 SCIP_VAR* var;
    3664 SCIP_RATIONAL* val;
    3665
    3666 assert(scip != NULL);
    3667 assert(cons != NULL);
    3668
    3669 consdata = SCIPconsGetData(cons);
    3670 assert(consdata != NULL);
    3671 assert(0 <= pos && pos < consdata->nvars);
    3672
    3673 var = consdata->vars[pos];
    3674 val = consdata->vals[pos];
    3675 assert(var != NULL);
    3676
    3677 /* remove rounding locks for deleted variable */
    3678 SCIP_CALL( unlockRounding(scip, cons, var, val) );
    3679
    3680 /* if we are in transformed problem, delete the event data of the variable */
    3681 if( SCIPconsIsTransformed(cons) )
    3682 {
    3683 SCIP_CONSHDLR* conshdlr;
    3684 SCIP_CONSHDLRDATA* conshdlrdata;
    3685
    3686 /* check for event handler */
    3687 conshdlr = SCIPconsGetHdlr(cons);
    3688 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3689 assert(conshdlrdata != NULL);
    3690 assert(conshdlrdata->eventhdlr != NULL);
    3691
    3692 /* drop bound change events of variable */
    3693 if( consdata->eventdata != NULL )
    3694 {
    3695 SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
    3696 assert(consdata->eventdata[pos] == NULL);
    3697 }
    3698 }
    3699
    3700 /* move the last variable to the free slot */
    3701 if( pos != consdata->nvars - 1 )
    3702 {
    3703 consdata->vars[pos] = consdata->vars[consdata->nvars-1];
    3704 SCIPrationalSetRational(consdata->vals[pos], consdata->vals[consdata->nvars - 1]);
    3705 consdata->valsreal[pos] = consdata->valsreal[consdata->nvars -1];
    3706
    3707 if( consdata->eventdata != NULL )
    3708 {
    3709 consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
    3710 assert(consdata->eventdata[pos] != NULL);
    3711 consdata->eventdata[pos]->varpos = pos;
    3712 }
    3713
    3714 consdata->indexsorted = consdata->indexsorted && (pos + 2 >= consdata->nvars);
    3715 consdata->coefsorted = consdata->coefsorted && (pos + 2 >= consdata->nvars);
    3716 }
    3717 consdata->nvars--;
    3718
    3719 /* mark the constraint for propagation */
    3720 if( SCIPconsIsTransformed(cons) )
    3721 {
    3723 }
    3724
    3725 consdata->boundstightened = 0;
    3726 consdata->presolved = FALSE;
    3727 consdata->changed = TRUE;
    3728 consdata->normalized = FALSE;
    3729 consdata->cliquesadded = FALSE;
    3730 consdata->implsadded = FALSE;
    3731 consdata->rangedrowpropagated = 0;
    3732
    3733 /* check if hasnonbinvar flag might be incorrect now */
    3734 if( consdata->hasnonbinvar && SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
    3735 {
    3736 consdata->hasnonbinvalid = FALSE;
    3737 }
    3738
    3739 /* release variable */
    3740 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    3741
    3742 return SCIP_OKAY;
    3743}
    3744
    3745/** changes coefficient value at given position of linear constraint data */
    3746static
    3748 SCIP* scip, /**< SCIP data structure */
    3749 SCIP_CONS* cons, /**< linear constraint */
    3750 int pos, /**< position of coefficient to delete */
    3751 SCIP_RATIONAL* newval /**< new value of coefficient */
    3752 )
    3753{
    3754 SCIP_CONSDATA* consdata;
    3755 SCIP_VAR* var;
    3756 SCIP_RATIONAL* val;
    3757 SCIP_Bool locked;
    3758 SCIP_INTERVAL newvalfp;
    3759 int i;
    3760
    3761 assert(scip != NULL);
    3762 assert(cons != NULL);
    3763 assert(!SCIPrationalIsZero(newval));
    3764
    3765 consdata = SCIPconsGetData(cons);
    3766 assert(consdata != NULL);
    3767 assert(0 <= pos && pos < consdata->nvars);
    3768
    3769 var = consdata->vars[pos];
    3770 val = consdata->vals[pos];
    3771 assert(var != NULL);
    3772 assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
    3773
    3774 locked = FALSE;
    3775 for( i = 0; i < NLOCKTYPES && !locked; i++ )
    3776 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
    3777
    3778 /* if necessary, update the rounding locks of the variable */
    3779 if( locked && ((SCIPrationalIsNegative(newval) && SCIPrationalIsPositive(val)) || (SCIPrationalIsNegative(val) && SCIPrationalIsPositive(newval))) )
    3780 {
    3781 assert(SCIPconsIsTransformed(cons));
    3782
    3783 /* remove rounding locks for variable with old coefficient */
    3784 SCIP_CALL( unlockRounding(scip, cons, var, val) );
    3785
    3786 /* install rounding locks for variable with new coefficient */
    3787 SCIP_CALL( lockRounding(scip, cons, var, newval) );
    3788 }
    3789 SCIPintervalSetRational(&newvalfp, newval);
    3790 /* update minimum and maximum activities */
    3791 if( SCIPconsIsTransformed(cons) )
    3792 consdataUpdateChgCoef(scip, consdata, var, consdata->valsreal[pos], val, newvalfp, newval);
    3793
    3794 /* change the value */
    3795 SCIPrationalSetRational(consdata->vals[pos], newval);
    3796 consdata->valsreal[pos] = newvalfp;
    3797 if( consdata->coefsorted )
    3798 {
    3799 if( pos > 0 )
    3800 consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos - 1, pos) <= 0);
    3801 if( consdata->coefsorted && pos < consdata->nvars - 1 )
    3802 consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos, pos + 1) <= 0);
    3803 }
    3804 /* mark the constraint for propagation */
    3805 if( SCIPconsIsTransformed(cons) )
    3806 {
    3808 }
    3809
    3810 consdata->boundstightened = 0;
    3811 consdata->presolved = FALSE;
    3812 consdata->changed = TRUE;
    3813 consdata->normalized = FALSE;
    3814 consdata->cliquesadded = FALSE;
    3815 consdata->implsadded = FALSE;
    3816 consdata->rangedrowpropagated = 0;
    3817
    3818 return SCIP_OKAY;
    3819}
    3820
    3821/* perform deletion of variables in all constraints of the constraint handler */
    3822static
    3824 SCIP* scip, /**< SCIP data structure */
    3825 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    3826 SCIP_CONS** conss, /**< array of constraints */
    3827 int nconss /**< number of constraints */
    3828 )
    3829{
    3830 SCIP_CONSDATA* consdata;
    3831 int i;
    3832 int v;
    3833
    3834 assert(scip != NULL);
    3835 assert(conshdlr != NULL);
    3836 assert(conss != NULL);
    3837 assert(nconss >= 0);
    3838
    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(result != NULL);
    5223
    5225
    5226 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5227 assert(conshdlrdata != NULL);
    5228
    5229 if( sol == NULL )
    5230 checkexact = SCIPlpExactIsSolved(scip);
    5231 else
    5232 checkexact = SCIPsolIsExact(sol);
    5233
    5234 SCIPdebugMsg(scip, "Enforcement method of linear constraints for %s solution\n", sol == NULL ? "LP" : "relaxation");
    5236
    5237 /* check for violated constraints
    5238 * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
    5239 */
    5240 *result = SCIP_FEASIBLE;
    5241
    5242 /* check all useful linear constraints for feasibility */
    5243 for( c = 0; c < nusefulconss; ++c )
    5244 {
    5245 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, sol, checkexact, FALSE, &violated) );
    5246
    5247 if( violated )
    5248 {
    5249 /* insert LP row as cut */
    5250 SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
    5251 if( cutoff )
    5252 *result = SCIP_CUTOFF;
    5253 else
    5254 *result = SCIP_SEPARATED;
    5255 }
    5256 }
    5257
    5258 /* check all obsolete linear constraints for feasibility */
    5259 for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
    5260 {
    5261 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, sol, checkexact, FALSE, &violated) );
    5262
    5263 if( violated )
    5264 {
    5265 /* insert LP row as cut */
    5266 SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
    5267 if( cutoff )
    5268 *result = SCIP_CUTOFF;
    5269 else
    5270 *result = SCIP_SEPARATED;
    5271 }
    5272 }
    5273
    5274 SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
    5275
    5276 return SCIP_OKAY;
    5277}
    5278
    5279/*
    5280 * Callback methods of constraint handler
    5281 */
    5282
    5283/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    5284static
    5285SCIP_DECL_CONSHDLRCOPY(conshdlrCopyExactLinear)
    5286{ /*lint --e{715}*/
    5287 assert(scip != NULL);
    5288 assert(conshdlr != NULL);
    5289
    5291
    5292 /* call inclusion method of constraint handler */
    5294
    5295 *valid = TRUE;
    5296
    5297 return SCIP_OKAY;
    5298}
    5299
    5300/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
    5301static
    5302SCIP_DECL_CONSFREE(consFreeExactLinear)
    5303{ /*lint --e{715}*/
    5304 SCIP_CONSHDLRDATA* conshdlrdata;
    5305
    5306 assert(scip != NULL);
    5307 assert(conshdlr != NULL);
    5308
    5310
    5311 /* free constraint handler data */
    5312 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5313 assert(conshdlrdata != NULL);
    5314
    5315 conshdlrdataFree(scip, &conshdlrdata);
    5316
    5317 SCIPconshdlrSetData(conshdlr, NULL);
    5318
    5319 return SCIP_OKAY;
    5320}
    5321
    5322
    5323/** initialization method of constraint handler (called after problem was transformed) */
    5324static
    5325SCIP_DECL_CONSINIT(consInitExactLinear)
    5326{
    5327 SCIP_CONSHDLRDATA* conshdlrdata;
    5328 int c;
    5329
    5330 assert(scip != NULL);
    5331 assert(SCIPisExact(scip) || nconss == 0);
    5332
    5333 /* check for event handler */
    5334 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5335 assert(conshdlrdata != NULL);
    5336 assert(conshdlrdata->eventhdlr != NULL);
    5337 assert(nconss == 0 || conss != NULL);
    5338
    5339 /* catch events for the constraints */
    5340 for( c = 0; c < nconss; ++c )
    5341 {
    5342 /* catch all events */
    5343 SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
    5344 }
    5345
    5346 return SCIP_OKAY;
    5347}
    5348
    5349
    5350/** deinitialization method of constraint handler (called before transformed problem is freed) */
    5351static
    5352SCIP_DECL_CONSEXIT(consExitExactLinear)
    5353{
    5354 SCIP_CONSHDLRDATA* conshdlrdata;
    5355 int c;
    5356
    5357 assert(scip != NULL);
    5358 assert(SCIPisExact(scip) || nconss == 0);
    5359
    5360 /* check for event handler */
    5361 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5362 assert(conshdlrdata != NULL);
    5363 assert(conshdlrdata->eventhdlr != NULL);
    5364
    5365 /* drop events for the constraints */
    5366 for( c = nconss - 1; c >= 0; --c )
    5367 {
    5368 SCIP_CONSDATA* consdata;
    5369
    5370 consdata = SCIPconsGetData(conss[c]);
    5371 assert(consdata != NULL);
    5372
    5373 if( consdata->eventdata != NULL )
    5374 {
    5375 /* drop all events */
    5376 SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
    5377 assert(consdata->eventdata == NULL);
    5378 }
    5379 }
    5380
    5381 return SCIP_OKAY;
    5382}
    5383
    5384/** presolving deinitialization method of constraint handler (called after presolving has been finished) */
    5385static
    5386SCIP_DECL_CONSEXITPRE(consExitpreExactLinear)
    5387{ /*lint --e{715}*/
    5388 int c;
    5389
    5390 assert(scip != NULL);
    5391 assert(SCIPisExact(scip) || nconss == 0);
    5392
    5393 /* make sure, only active variables remain in the remaining constraints */
    5394 for( c = 0; c < nconss; ++c )
    5395 {
    5396 if( SCIPconsIsDeleted(conss[c]) )
    5397 continue;
    5398
    5399 /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
    5400 SCIP_CALL( applyFixings(scip, conss[c], NULL) );
    5401 }
    5402
    5403 return SCIP_OKAY;
    5404}
    5405
    5406
    5407/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
    5408static
    5409SCIP_DECL_CONSEXITSOL(consExitsolExactLinear)
    5410{ /*lint --e{715}*/
    5411 int c;
    5412
    5413 assert(scip != NULL);
    5414 assert(SCIPisExact(scip) || nconss == 0);
    5415
    5416 if( !SCIPisExact(scip) )
    5417 return SCIP_OKAY;
    5418
    5419 /* release the rows of all constraints */
    5420 for( c = 0; c < nconss; ++c )
    5421 {
    5422 SCIP_CONSDATA* consdata;
    5423
    5424 consdata = SCIPconsGetData(conss[c]);
    5425 assert(consdata != NULL);
    5426
    5427 if( consdata->rowlhs != NULL )
    5428 {
    5429 SCIP_CALL( SCIPreleaseRowExact(scip, &consdata->rowexact) );
    5430 SCIP_CALL( SCIPreleaseRow(scip, &consdata->rowlhs) );
    5431
    5432 if( consdata->rowrhs != NULL )
    5433 {
    5434 assert(!consdata->onerowrelax);
    5435 SCIP_CALL( SCIPreleaseRow(scip, &consdata->rowrhs) );
    5436 }
    5437 }
    5438 }
    5439
    5440 /**@todo when enabling restarts, extend SCIPconvertCutsToConss() in order to convert exact cuts to exactlinear
    5441 * constraints and call here
    5442 */
    5443
    5444 return SCIP_OKAY;
    5445}
    5446
    5447
    5448/** constraint deactivation notification method of constraint handler */
    5449static
    5450SCIP_DECL_CONSDEACTIVE(consDeactiveExactLinear)
    5451{ /*lint --e{715}*/
    5452 assert(scip != NULL);
    5453 assert(SCIPisExact(scip));
    5454 assert(cons != NULL);
    5455
    5456 if( SCIPconsIsDeleted(cons) )
    5457 {
    5458 SCIP_CONSHDLRDATA* conshdlrdata;
    5459 SCIP_CONSDATA* consdata;
    5460
    5461 assert(conshdlr != NULL);
    5462
    5464
    5465 /* get constraint data */
    5466 consdata = SCIPconsGetData(cons);
    5467 assert(consdata != NULL);
    5468
    5469 /* check for event handler */
    5470 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5471 assert(conshdlrdata != NULL);
    5472 assert(conshdlrdata->eventhdlr != NULL);
    5473
    5474 /* free event data */
    5475 if( consdata->eventdata != NULL )
    5476 {
    5477 /* drop bound change events of variables */
    5478 SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    5479 }
    5480 assert(consdata->eventdata == NULL);
    5481 }
    5482
    5483 return SCIP_OKAY;
    5484}
    5485
    5486
    5487/** frees specific constraint data */
    5488static
    5489SCIP_DECL_CONSDELETE(consDeleteExactLinear)
    5490{ /*lint --e{715}*/
    5491 assert(scip != NULL);
    5492 assert(SCIPisExact(scip));
    5493 assert(conshdlr != NULL);
    5494
    5496
    5497 if( (*consdata)->eventdata != NULL )
    5498 {
    5499 SCIP_CONSHDLRDATA* conshdlrdata;
    5500
    5501 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5502 assert(conshdlrdata != NULL);
    5503
    5504 /* drop all events */
    5505 SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    5506 assert((*consdata)->eventdata == NULL);
    5507 }
    5508 /* free linear constraint */
    5509 SCIP_CALL( consdataFree(scip, consdata) );
    5510
    5511 return SCIP_OKAY;
    5512}
    5513
    5514
    5515/** transforms constraint data into data belonging to the transformed problem */
    5516static
    5517SCIP_DECL_CONSTRANS(consTransExactLinear)
    5518{ /*lint --e{715}*/
    5519 SCIP_CONSDATA* sourcedata;
    5520 SCIP_CONSDATA* targetdata;
    5521
    5522 assert(scip != NULL);
    5523 assert(SCIPisExact(scip));
    5524 assert(conshdlr != NULL);
    5526 assert(sourcecons != NULL);
    5527 assert(targetcons != NULL);
    5528
    5530
    5531 sourcedata = SCIPconsGetData(sourcecons);
    5532 assert(sourcedata != NULL);
    5533 assert(sourcedata->rowlhs == NULL && sourcedata->rowexact == NULL); /* in original problem, there cannot be LP rows */
    5534
    5535 /* create linear constraint data for target constraint */
    5536 SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs,
    5537 sourcedata->rhs) );
    5538
    5539 if( sourcedata->nvars > 0 )
    5540 consdataScaleMinValue(scip, targetdata, 2 * SCIPepsilon(scip));
    5541
    5542 /* create target constraint */
    5543 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
    5544 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    5545 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
    5546 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
    5547 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
    5548
    5549 return SCIP_OKAY;
    5550}
    5551
    5552/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
    5553static
    5554SCIP_DECL_CONSINITLP(consInitlpExactLinear)
    5555{ /*lint --e{715}*/
    5556 int c;
    5557
    5558 assert(scip != NULL);
    5559 assert(SCIPisExact(scip) || nconss == 0);
    5560
    5562
    5563 *infeasible = FALSE;
    5564
    5565 for( c = 0; c < nconss && !(*infeasible); ++c )
    5566 {
    5567 assert(SCIPconsIsInitial(conss[c]));
    5568 /* add both the relaxation to the fp-lp as well as the correct constraint to the exact lp */
    5569 SCIP_CALL( addRelaxation(scip, conss[c], infeasible) );
    5570 }
    5571
    5572 return SCIP_OKAY;
    5573}
    5574
    5575/** separation method of constraint handler for LP solutions */
    5576static
    5577SCIP_DECL_CONSSEPALP(consSepalpExactLinear)
    5578{ /*lint --e{715}*/
    5579 SCIP_CONSHDLRDATA* conshdlrdata;
    5580 SCIP_Bool cutoff;
    5581 int c;
    5582 int depth;
    5583 int nrounds;
    5584 int maxsepacuts;
    5585 int ncuts;
    5586
    5587 assert(scip != NULL);
    5588 assert(SCIPisExact(scip) || nconss == 0);
    5589 assert(conshdlr != NULL);
    5590 assert(result != NULL);
    5591
    5593
    5594 if( !SCIPisExact(scip) )
    5595 return SCIP_OKAY;
    5596
    5597 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5598 assert(conshdlrdata != NULL);
    5599 depth = SCIPgetDepth(scip);
    5600 nrounds = SCIPgetNSepaRounds(scip);
    5601
    5602 *result = SCIP_DIDNOTRUN;
    5603
    5604 /* only call the separator a given number of times at each node */
    5605 if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
    5606 || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
    5607 return SCIP_OKAY;
    5608
    5609 /* get the maximal number of cuts allowed in a separation round */
    5610 maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
    5611
    5612 *result = SCIP_DIDNOTFIND;
    5613 ncuts = 0;
    5614 cutoff = FALSE;
    5615
    5616 /* check all useful linear constraints for feasibility */
    5617 for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
    5618 {
    5619 SCIPdebugMsg(scip, "separating exact linear constraint <%s>\n", SCIPconsGetName(conss[c]));
    5620 SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, &ncuts, &cutoff) );
    5621 }
    5622
    5623 /* adjust return value */
    5624 if( cutoff )
    5625 *result = SCIP_CUTOFF;
    5626 else if( ncuts > 0 )
    5627 *result = SCIP_SEPARATED;
    5628
    5629 return SCIP_OKAY;
    5630}
    5631
    5632
    5633/** separation method of constraint handler for arbitrary primal solutions */
    5634static
    5635SCIP_DECL_CONSSEPASOL(consSepasolExactLinear)
    5636{ /*lint --e{715}*/
    5637 SCIP_CONSHDLRDATA* conshdlrdata;
    5638 int c;
    5639 int depth;
    5640 int nrounds;
    5641 int maxsepacuts;
    5642 int ncuts;
    5643 SCIP_Bool cutoff;
    5644
    5645 assert(scip != NULL);
    5646 assert(SCIPisExact(scip) || nconss == 0);
    5647 assert(conshdlr != NULL);
    5648 assert(result != NULL);
    5649
    5651
    5652 if( !SCIPisExact(scip) )
    5653 return SCIP_OKAY;
    5654
    5655 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5656 assert(conshdlrdata != NULL);
    5657 depth = SCIPgetDepth(scip);
    5658 nrounds = SCIPgetNSepaRounds(scip);
    5659
    5660 *result = SCIP_DIDNOTRUN;
    5661
    5662 /* only call the separator a given number of times at each node */
    5663 if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
    5664 || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
    5665 return SCIP_OKAY;
    5666
    5667 /* get the maximal number of cuts allowed in a separation round */
    5668 maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
    5669
    5670 *result = SCIP_DIDNOTFIND;
    5671 ncuts = 0;
    5672 cutoff = FALSE;
    5673
    5674 /* check all useful linear constraints for feasibility */
    5675 for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
    5676 {
    5677 SCIPdebugMsg(scip, "separating exact linear constraint <%s>\n", SCIPconsGetName(conss[c]));
    5678 SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, &ncuts, &cutoff) );
    5679 }
    5680
    5681 /* adjust return value */
    5682 if( cutoff )
    5683 *result = SCIP_CUTOFF;
    5684 else if( ncuts > 0 )
    5685 *result = SCIP_SEPARATED;
    5686
    5687 return SCIP_OKAY;
    5688}
    5689
    5690
    5691/** constraint enforcing method of constraint handler for LP solutions */
    5692static
    5693SCIP_DECL_CONSENFOLP(consEnfolpExactLinear)
    5694{ /*lint --e{715}*/
    5695 assert(scip != NULL);
    5696 assert(SCIPisExact(scip) || nconss == 0);
    5697
    5698 if( !SCIPisExact(scip) )
    5699 return SCIP_OKAY;
    5700
    5701 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
    5702
    5703 return SCIP_OKAY;
    5704}
    5705
    5706/** constraint enforcing method of constraint handler for relaxation solutions */
    5707static
    5708SCIP_DECL_CONSENFORELAX(consEnforelaxExactLinear)
    5709{ /*lint --e{715}*/
    5710 assert(scip != NULL);
    5711 assert(SCIPisExact(scip) || nconss == 0);
    5712
    5713 if( !SCIPisExact(scip) )
    5714 return SCIP_OKAY;
    5715
    5716 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
    5717
    5718 return SCIP_OKAY;
    5719}
    5720
    5721/** constraint enforcing method of constraint handler for pseudo solutions */
    5722static
    5723SCIP_DECL_CONSENFOPS(consEnfopsExactLinear)
    5724{ /*lint --e{715}*/
    5725 SCIP_CONSHDLRDATA* conshdlrdata;
    5726 SCIP_Bool violated;
    5727 int c;
    5728
    5729 assert(scip != NULL);
    5730 assert(SCIPisExact(scip) || nconss == 0);
    5731 assert(conshdlr != NULL);
    5732 assert(result != NULL);
    5733
    5735
    5736 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5737 assert(conshdlrdata != NULL);
    5738
    5739 SCIPdebugMsg(scip, "Enfops method of linear constraints\n");
    5740
    5741 if( !SCIPisExact(scip) )
    5742 {
    5743 *result = SCIP_DIDNOTRUN;
    5744 return SCIP_OKAY;
    5745 }
    5746
    5747 /* if the solution is infeasible anyway due to objective value, skip the enforcement */
    5748 if( objinfeasible )
    5749 {
    5750 SCIPdebugMsg(scip, "-> pseudo solution is objective infeasible, return.\n");
    5751
    5752 *result = SCIP_DIDNOTRUN;
    5753 return SCIP_OKAY;
    5754 }
    5755
    5756 /* check all linear constraints for feasibility */
    5757 violated = FALSE;
    5758 for( c = 0; c < nconss && !violated; ++c )
    5759 {
    5760 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, NULL, FALSE, TRUE, &violated) );
    5761 }
    5762
    5763 if( violated )
    5764 *result = SCIP_INFEASIBLE;
    5765 else
    5766 *result = SCIP_FEASIBLE;
    5767
    5768 SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
    5769
    5770 return SCIP_OKAY;
    5771}
    5772
    5773
    5774/** feasibility check method of constraint handler for integral solutions */
    5775static
    5776SCIP_DECL_CONSCHECK(consCheckExactLinear)
    5777{ /*lint --e{715}*/
    5778 SCIP_CONSHDLRDATA* conshdlrdata;
    5779 SCIP_Bool checkexact;
    5780 int c;
    5781
    5782 assert(scip != NULL);
    5783 assert(SCIPisExact(scip) || nconss == 0);
    5784 assert(conshdlr != NULL);
    5785 assert(result != NULL);
    5786
    5788
    5789 *result = SCIP_FEASIBLE;
    5790
    5791 if( !SCIPisExact(scip) )
    5792 return SCIP_OKAY;
    5793
    5794 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5795 assert(conshdlrdata != NULL);
    5796
    5797 /* if the fp-solution has a stand-in exact solution we check that instead */
    5798 checkexact = SCIPsolIsExact(sol);
    5799
    5800 /* check all linear constraints for feasibility */
    5801 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
    5802 {
    5803 SCIP_Bool violated = FALSE;
    5804 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, sol, checkexact, checklprows, &violated) );
    5805
    5806 if( violated )
    5807 {
    5808 *result = SCIP_INFEASIBLE;
    5809
    5810 if( printreason )
    5811 {
    5812 SCIP_CONSDATA* consdata;
    5813 SCIP_RATIONAL* activity;
    5814
    5816
    5817 consdata = SCIPconsGetData(conss[c]);
    5818 assert( consdata != NULL);
    5819
    5820 consdataGetActivity(scip, consdata, sol, checkexact, activity);
    5821
    5822 SCIP_CALL( consPrintConsSol(scip, conss[c], sol, checkexact, NULL ) );
    5823 SCIPinfoMessage(scip, NULL, ";\n");
    5824
    5825 if( SCIPrationalIsAbsInfinity(activity) )
    5826 SCIPinfoMessage(scip, NULL, "activity invalid due to infinity contributions\n");
    5827 else if( SCIPrationalIsLT(activity, consdata->lhs) )
    5828 {
    5829 SCIPrationalDiff(activity, consdata->lhs, activity);
    5830 SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by ");
    5832 SCIPinfoMessage(scip, NULL, "\n");
    5833 }
    5834 else if( SCIPrationalIsGT(activity, consdata->rhs) )
    5835 {
    5836 SCIPrationalDiff(activity, activity, consdata->rhs);
    5837 SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by ");
    5839 SCIPinfoMessage(scip, NULL, "\n");
    5840 }
    5841
    5843 }
    5844 }
    5845 }
    5846
    5847 return SCIP_OKAY;
    5848}
    5849
    5850/** domain propagation method of constraint handler */
    5851static
    5852SCIP_DECL_CONSPROP(consPropExactLinear)
    5853{ /*lint --e{715}*/
    5854 SCIP_CONSHDLRDATA* conshdlrdata;
    5855 SCIP_Bool tightenbounds;
    5856 SCIP_Bool cutoff;
    5857
    5858 int nchgbds;
    5859 int i;
    5860
    5861 assert(scip != NULL);
    5862 assert(SCIPisExact(scip) || nconss == 0);
    5863 assert(conshdlr != NULL);
    5864 assert(result != NULL);
    5865
    5867
    5868 if( !SCIPisExact(scip) )
    5869 return SCIP_OKAY;
    5870
    5871 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5872 assert(conshdlrdata != NULL);
    5873
    5874 /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
    5875 if( SCIPinProbing(scip) )
    5876 tightenbounds = TRUE;
    5877 else
    5878 {
    5879 int depth;
    5880 int propfreq;
    5881 int tightenboundsfreq;
    5882
    5883 depth = SCIPgetDepth(scip);
    5884 propfreq = SCIPconshdlrGetPropFreq(conshdlr);
    5885 tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
    5886 tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
    5887 && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
    5888 }
    5889
    5890 cutoff = FALSE;
    5891 nchgbds = 0;
    5892
    5893 /* process constraints marked for propagation */
    5894 for( i = 0; i < nmarkedconss && !cutoff; i++ )
    5895 {
    5897 SCIP_CALL( propagateCons(scip, conss[i], tightenbounds,
    5898 conshdlrdata->sortvars, &cutoff, &nchgbds) );
    5899 }
    5900
    5901 /* adjust result code */
    5902 if( cutoff )
    5903 *result = SCIP_CUTOFF;
    5904 else if( nchgbds > 0 )
    5905 *result = SCIP_REDUCEDDOM;
    5906 else
    5907 *result = SCIP_DIDNOTFIND;
    5908
    5909 return SCIP_OKAY;
    5910}
    5911
    5912
    5913/** variable rounding lock method of constraint handler */
    5914static
    5915SCIP_DECL_CONSLOCK(consLockExactLinear)
    5916{ /*lint --e{715}*/
    5917 SCIP_CONSDATA* consdata;
    5918 SCIP_Bool haslhs;
    5919 SCIP_Bool hasrhs;
    5920 int i;
    5921
    5922 assert(scip != NULL);
    5923 assert(SCIPisExact(scip));
    5924 assert(cons != NULL);
    5925 consdata = SCIPconsGetData(cons);
    5926 assert(consdata != NULL);
    5927
    5928 haslhs = !SCIPrationalIsNegInfinity(consdata->lhs);
    5929 hasrhs = !SCIPrationalIsInfinity(consdata->rhs);
    5930
    5931 /* update rounding locks of every single variable */
    5932 for( i = 0; i < consdata->nvars; ++i )
    5933 {
    5934 if( SCIPrationalIsPositive(consdata->vals[i]) )
    5935 {
    5936 if( haslhs )
    5937 {
    5938 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
    5939 }
    5940 if( hasrhs )
    5941 {
    5942 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
    5943 }
    5944 }
    5945 else
    5946 {
    5947 if( haslhs )
    5948 {
    5949 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
    5950 }
    5951 if( hasrhs )
    5952 {
    5953 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
    5954 }
    5955 }
    5956 }
    5957
    5958 return SCIP_OKAY;
    5959}
    5960
    5961
    5962/** variable deletion method of constraint handler */
    5963static
    5964SCIP_DECL_CONSDELVARS(consDelvarsExactLinear)
    5965{
    5966 assert(scip != NULL);
    5967 assert(SCIPisExact(scip) || nconss == 0);
    5968 assert(conshdlr != NULL);
    5969 assert(conss != NULL || nconss == 0);
    5970
    5971 if( nconss > 0 )
    5972 {
    5973 SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
    5974 }
    5975
    5976 return SCIP_OKAY;
    5977}
    5978
    5979/** constraint display method of constraint handler */
    5980static
    5981SCIP_DECL_CONSPRINT(consPrintExactLinear)
    5982{ /*lint --e{715}*/
    5983 assert(scip != NULL);
    5984 assert(conshdlr != NULL);
    5985 assert(cons != NULL);
    5986
    5988
    5989 return SCIP_OKAY;
    5990}
    5991
    5992/** constraint copying method of constraint handler */
    5993static
    5994SCIP_DECL_CONSCOPY(consCopyExactLinear)
    5995{ /*lint --e{715}*/
    5996 SCIP_VAR** sourcevars;
    5997 SCIP_INTERVAL* sourcecoefs;
    5998 const char* consname;
    5999 int nvars;
    6000
    6001 assert(scip != NULL);
    6002 assert(sourcescip != NULL);
    6003 assert(sourcecons != NULL);
    6004
    6005 /* get variables and coefficients of the source constraint */
    6006 sourcevars = SCIPgetVarsExactLinear(sourcescip, sourcecons);
    6007 sourcecoefs = SCIPgetValsRealExactLinear(sourcescip, sourcecons);
    6008 nvars = SCIPgetNVarsExactLinear(sourcescip, sourcecons);
    6009
    6010 if( name != NULL )
    6011 consname = name;
    6012 else
    6013 consname = SCIPconsGetName(sourcecons);
    6014
    6015 SCIP_CALL( SCIPcopyConsExactLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
    6016 SCIPrationalGetReal(SCIPgetLhsExactLinear(sourcescip, sourcecons)), SCIPrationalGetReal(SCIPgetRhsExactLinear(sourcescip, sourcecons)), varmap, consmap,
    6017 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
    6018 assert(cons != NULL || *valid == FALSE);
    6019
    6020 return SCIP_OKAY;
    6021}
    6022
    6023/* find operators '<=', '==', '>=', [free] in input string and return those places. There should only be one operator,
    6024 * except for ranged rows for which exactly two operators '<=' must be present
    6025 */
    6026static
    6028 const char* str, /**< null terminated input string */
    6029 char** firstoperator, /**< pointer to store the string starting at the first operator */
    6030 char** secondoperator, /**< pointer to store the string starting at the second operator */
    6031 SCIP_Bool* success /**< pointer to store if the line contains a valid operator order */
    6032 )
    6033{
    6034 char* curr;
    6035
    6036 assert(str != NULL);
    6037 assert(firstoperator != NULL);
    6038 assert(secondoperator != NULL);
    6039
    6040 *firstoperator = NULL;
    6041 *secondoperator = NULL;
    6042
    6043 curr = (char*)str;
    6044 *success = TRUE;
    6045
    6046 /* loop over the input string to find all operators */
    6047 while( *curr && *success )
    6048 {
    6049 SCIP_Bool found = FALSE;
    6050 int increment = 1;
    6051
    6052 /* try if we found a possible operator */
    6053 switch( *curr )
    6054 {
    6055 case '<':
    6056 case '=':
    6057 case '>':
    6058
    6059 /* check if the two characters curr[0,1] form an operator together */
    6060 if( curr[1] == '=' )
    6061 {
    6062 found = TRUE;
    6063
    6064 /* update increment to continue after this operator */
    6065 increment = 2;
    6066 }
    6067 break;
    6068 case '[':
    6069 if( strncmp(curr, "[free]", 6) == 0 )
    6070 {
    6071 found = TRUE;
    6072
    6073 /* update increment to continue after this operator */
    6074 increment = 6;
    6075 }
    6076 break;
    6077 default:
    6078 break;
    6079 }
    6080
    6081 /* assign the found operator to the first or second pointer and check for violations of the linear constraint grammar */
    6082 if( found )
    6083 {
    6084 if( *firstoperator == NULL )
    6085 {
    6086 *firstoperator = curr;
    6087 }
    6088 else
    6089 {
    6090 if( *secondoperator != NULL )
    6091 {
    6092 SCIPerrorMessage("Found more than two operators in line %s\n", str);
    6093 *success = FALSE;
    6094 }
    6095 else if( strncmp(*firstoperator, "<=", 2) != 0 )
    6096 {
    6097 SCIPerrorMessage("Two operators in line that is not a ranged row: %s", str);
    6098 *success = FALSE;
    6099 }
    6100 else if( strncmp(curr, "<=", 2) != 0 )
    6101 {
    6102 SCIPerrorMessage("Bad second operator, expected ranged row specification: %s", str);
    6103 *success = FALSE;
    6104 }
    6105
    6106 *secondoperator = curr;
    6107 }
    6108 }
    6109
    6110 curr += increment;
    6111 }
    6112
    6113 /* check if we did find at least one operator */
    6114 if( *success )
    6115 {
    6116 if( *firstoperator == NULL )
    6117 {
    6118 SCIPerrorMessage("Could not find any operator in line %s\n", str);
    6119 *success = FALSE;
    6120 }
    6121 }
    6122
    6123 return SCIP_OKAY;
    6124}
    6125
    6126/** constraint parsing method of constraint handler */
    6127static
    6128SCIP_DECL_CONSPARSE(consParseExactLinear)
    6129{ /*lint --e{715}*/
    6130 SCIP_RETCODE retcode = SCIP_OKAY;
    6131 SCIP_VAR** vars = NULL;
    6132 SCIP_RATIONAL** coefs = NULL;
    6133 int nvars;
    6134 int coefssize = 100;
    6135 int requsize;
    6136 SCIP_RATIONAL* lhs;
    6137 SCIP_RATIONAL* rhs;
    6138 char* endptr;
    6139 char* firstop;
    6140 char* secondop;
    6141 SCIP_Bool operatorsuccess;
    6142 char* lhsstrptr = NULL;
    6143 char* rhsstrptr = NULL;
    6144 char* varstrptr = (char*)str;
    6145
    6146 assert(scip != NULL);
    6147 assert(success != NULL);
    6148 assert(str != NULL);
    6149 assert(name != NULL);
    6150 assert(cons != NULL);
    6151
    6152 *success = FALSE;
    6153
    6154 /* return of string empty */
    6155 if( !(*str) )
    6156 return SCIP_OKAY;
    6157
    6158 /* set left and right hand side to their default values */
    6161
    6164
    6165 /* ignore whitespace */
    6166 SCIP_CALL_TERMINATE( retcode, SCIPskipSpace((char**)&str), TERMINATE );
    6167
    6168 /* find operators in the line first, all other remaining parsing depends on occurence of the operators '<=', '>=', '==',
    6169 * and the special word [free]
    6170 */
    6171 SCIP_CALL_TERMINATE( retcode, findOperators(str, &firstop, &secondop, &operatorsuccess), TERMINATE );
    6172
    6173 /* if the grammar is not valid for parsing a linear constraint, return */
    6174 if( ! operatorsuccess )
    6175 {
    6176 retcode = SCIP_OKAY;
    6177 goto TERMINATE;
    6178 }
    6179 assert(firstop != NULL);
    6180
    6181 /* assign the strings for parsing the left hand side, right hand side, and the linear variable sum */
    6182 switch( *firstop )
    6183 {
    6184 case '<':
    6185 assert(firstop[1] == '=');
    6186 /* we have ranged row lhs <= a_1 x_1 + ... + a_n x_n <= rhs */
    6187 if( secondop != NULL )
    6188 {
    6189 assert(secondop[0] == '<' && secondop[1] == '=');
    6190 lhsstrptr = (char *)str;
    6191 varstrptr = firstop + 2;
    6192 rhsstrptr = secondop + 2;
    6193 }
    6194 else
    6195 {
    6196 /* we have an inequality with infinite left hand side a_1 x_1 + ... + a_n x_n <= rhs */
    6197 lhsstrptr = NULL;
    6198 varstrptr = (char *)str;
    6199 rhsstrptr = firstop + 2;
    6200 }
    6201 break;
    6202 case '>':
    6203 assert(firstop[1] == '=');
    6204 assert(secondop == NULL);
    6205 /* we have a_1 x_1 + ... + a_n x_n >= lhs */
    6206 lhsstrptr = firstop + 2;
    6207 break;
    6208 case '=':
    6209 assert(firstop[1] == '=');
    6210 assert(secondop == NULL);
    6211 /* we have a_1 x_1 + ... + a_n x_n == lhs (rhs) */
    6212 rhsstrptr = firstop + 2;
    6213 lhsstrptr = firstop + 2;
    6214 break;
    6215 case '[':
    6216 assert(strncmp(firstop, "[free]", 6) == 0);
    6217 assert(secondop == NULL);
    6218 /* nothing to assign in case of a free a_1 x_1 + ... + a_n x_n [free] */
    6219 break;
    6220 default:
    6221 /* it should not be possible that a different character appears in that position */
    6222 SCIPerrorMessage("Parsing has wrong operator character '%c', should be one of <=>[", *firstop);
    6223 retcode = SCIP_READERROR;
    6224 goto TERMINATE;
    6225 }
    6226
    6227 /* parse left hand side, if necessary */
    6228 if( lhsstrptr != NULL )
    6229 {
    6230 if( ! SCIPparseRational(scip, lhsstrptr, lhs, &endptr) )
    6231 {
    6232 SCIPerrorMessage("error parsing left hand side number from <%s>\n", lhsstrptr);
    6233 retcode = SCIP_OKAY;
    6234 goto TERMINATE;
    6235 }
    6236
    6237 /* in case of an equation, assign the left also to the right hand side */
    6238 if( rhsstrptr == lhsstrptr )
    6239 SCIPrationalSetRational(rhs, lhs);
    6240 }
    6241
    6242 /* parse right hand side, if different from left hand side */
    6243 if( rhsstrptr != NULL && rhsstrptr != lhsstrptr )
    6244 {
    6245 if( ! SCIPparseRational(scip, rhsstrptr, rhs, &endptr) )
    6246 {
    6247 SCIPerrorMessage("error parsing right hand side number from <%s>\n", lhsstrptr);
    6248 retcode = SCIP_OKAY;
    6249 goto TERMINATE;
    6250 }
    6251 }
    6252
    6253 /* initialize buffers for storing the variables and coefficients */
    6254 SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
    6256
    6257 assert(varstrptr != NULL);
    6258
    6259 /* parse linear sum to get variables and coefficients */
    6260 SCIP_CALL_TERMINATE( retcode, SCIPparseVarsLinearsumExact(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success), TERMINATE );
    6261
    6262 if( *success && requsize > coefssize )
    6263 {
    6264 /* realloc buffers and try again */
    6265 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requsize) );
    6266 SCIP_CALL( SCIPrationalReallocBufferArray(SCIPbuffer(scip), &coefs, coefssize, requsize) );
    6267
    6268 coefssize = requsize;
    6269
    6270 SCIP_CALL_TERMINATE( retcode, SCIPparseVarsLinearsumExact(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success), TERMINATE );
    6271 assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
    6272 }
    6273
    6274 if( *success )
    6275 {
    6276 SCIP_CALL_TERMINATE( retcode, SCIPcreateConsExactLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
    6277 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode),
    6278 TERMINATE );
    6279 }
    6280
    6281 TERMINATE:
    6282 if( !*success )
    6283 {
    6284 SCIPerrorMessage("no luck in parsing exact linear sum '%s'\n", varstrptr);
    6285 }
    6286 if( coefs != NULL )
    6287 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &coefs, coefssize);
    6289
    6292
    6293 return retcode;
    6294}
    6295
    6296
    6297/** constraint method of constraint handler which returns the variables (if possible) */
    6298static
    6299SCIP_DECL_CONSGETVARS(consGetVarsExactLinear)
    6300{ /*lint --e{715}*/
    6301 SCIP_CONSDATA* consdata;
    6302
    6303 consdata = SCIPconsGetData(cons);
    6304 assert(consdata != NULL);
    6305
    6306 if( varssize < consdata->nvars )
    6307 (*success) = FALSE;
    6308 else
    6309 {
    6310 assert(vars != NULL);
    6311
    6312 BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
    6313 (*success) = TRUE;
    6314 }
    6315
    6316 return SCIP_OKAY;
    6317}
    6318
    6319/**! [Callback for the number of variables]*/
    6320/** constraint method of constraint handler which returns the number of variables (if possible) */
    6321static
    6322SCIP_DECL_CONSGETNVARS(consGetNVarsExactLinear)
    6323{ /*lint --e{715}*/
    6324 SCIP_CONSDATA* consdata;
    6325
    6326 consdata = SCIPconsGetData(cons);
    6327 assert(consdata != NULL);
    6328
    6329 (*nvars) = consdata->nvars;
    6330 (*success) = TRUE;
    6331
    6332 return SCIP_OKAY;
    6333}
    6334/**! [Callback for the number of variables]*/
    6335
    6336/*
    6337 * Callback methods of event handler
    6338 */
    6339
    6340static
    6341SCIP_DECL_EVENTEXEC(eventExecExactLinear)
    6342{ /*lint --e{715}*/
    6343 SCIP_CONS* cons;
    6344 SCIP_CONSDATA* consdata;
    6345 SCIP_VAR* var;
    6346 SCIP_EVENTTYPE eventtype;
    6348 assert(scip != NULL);
    6349 assert(SCIPisExact(scip));
    6350 assert(eventhdlr != NULL);
    6351 assert(eventdata != NULL);
    6352 assert(event != NULL);
    6353
    6355
    6356 cons = eventdata->cons;
    6357 assert(cons != NULL);
    6358 consdata = SCIPconsGetData(cons);
    6359 if( consdata == NULL )
    6360 return SCIP_OKAY;
    6361 /* we can skip events dropped for deleted constraints */
    6362 if( SCIPconsIsDeleted(cons) )
    6363 return SCIP_OKAY;
    6364
    6365 eventtype = SCIPeventGetType(event);
    6366 var = SCIPeventGetVar(event);
    6367 updateActivities = ((consdata->rowexact != NULL) == eventdata->rowvar) && consdata->validactivities;
    6368 assert(!consdata->validactivities || (consdata->validminact && consdata->validmaxact && consdata->validglbminact && consdata->validglbmaxact));
    6369
    6370 if( ((eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) != 0) )
    6371 {
    6372 SCIP_Real oldbound;
    6373 SCIP_Real newbound;
    6374 SCIP_INTERVAL valrange;
    6375 int varpos;
    6376 varpos = eventdata->varpos;
    6377
    6378 oldbound = SCIPeventGetOldbound(event);
    6379 newbound = SCIPeventGetNewbound(event);
    6380 assert(var != NULL);
    6381 valrange = consdata->valsreal[varpos];
    6382
    6383 /* we only need to update the activities if the constraint is active,
    6384 * otherwise we mark them to be invalid
    6385 */
    6386 if( SCIPconsIsActive(cons) )
    6387 {
    6388 /* update the activity values */
    6389 if( (eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
    6390 consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, valrange);
    6391 else
    6392 {
    6393 assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0);
    6394 consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, valrange);
    6395 }
    6396 }
    6397 else
    6399
    6400 consdata->presolved = FALSE;
    6401
    6402 /* in probing do not reset disabled ranged row propagation */
    6403 if( !SCIPinProbing(scip) )
    6404 consdata->rangedrowpropagated = 0;
    6405
    6406 /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
    6407 if( (eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0 )
    6408 {
    6410
    6411 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
    6412 if( consdata->maxactdeltavar == var )
    6413 {
    6414 consdata->maxactdelta = SCIP_INVALID;
    6415 consdata->maxactdeltavar = NULL;
    6416 }
    6417
    6418 /* check whether bound tightening might now be successful */
    6419 if( consdata->boundstightened > 0)
    6420 {
    6421 switch( eventtype )
    6422 {
    6424 if( (valrange.sup > 0.0 ? !SCIPisInfinity(scip, consdata->rhsreal) : !SCIPisInfinity(scip, -consdata->lhsreal)) )
    6425 consdata->boundstightened = 0;
    6426 break;
    6428 if( (valrange.sup > 0.0 ? !SCIPisInfinity(scip, -consdata->lhsreal) : !SCIPisInfinity(scip, consdata->rhsreal)) )
    6429 consdata->boundstightened = 0;
    6430 break;
    6431 default:
    6432 SCIPerrorMessage("invalid event type %" SCIP_EVENTTYPE_FORMAT "\n", eventtype);
    6433 return SCIP_INVALIDDATA;
    6434 }
    6435 }
    6436 }
    6437 /* update maximal activity delta if a bound was relaxed */
    6438 else if( !SCIPisInfinity(scip, consdata->maxactdelta) )
    6439 {
    6440 SCIP_Real lb;
    6441 SCIP_Real ub;
    6442 SCIP_Real domain;
    6443 SCIP_Real delta;
    6444
    6445 assert((eventtype & SCIP_EVENTTYPE_BOUNDRELAXED) != 0);
    6446
    6447 lb = SCIPvarGetLbLocal(var);
    6448 ub = SCIPvarGetUbLocal(var);
    6449
    6450 domain = ub - lb;
    6451 delta = SCIPintervalAbsMax(valrange) * domain;
    6452
    6453 if( delta > consdata->maxactdelta )
    6454 {
    6455 consdata->maxactdelta = delta;
    6456 consdata->maxactdeltavar = var;
    6457 }
    6458 }
    6459 }
    6460 else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != 0 )
    6461 {
    6462 /* we want to remove the fixed variable */
    6463 consdata->presolved = FALSE;
    6464 consdata->removedfixings = FALSE;
    6465 consdata->rangedrowpropagated = 0;
    6466
    6467 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
    6468 if( consdata->maxactdeltavar == var )
    6469 {
    6470 consdata->maxactdelta = SCIP_INVALID;
    6471 consdata->maxactdeltavar = NULL;
    6472 }
    6473 }
    6474 else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != 0 )
    6475 {
    6476 /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
    6479 consdata->presolved = FALSE;
    6480 }
    6481 else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != 0 )
    6482 {
    6483 SCIP_Real oldbound;
    6484 SCIP_Real newbound;
    6485 SCIP_INTERVAL valrange;
    6486 int varpos;
    6487
    6488 varpos = eventdata->varpos;
    6489
    6490 if( updateActivities )
    6491 {
    6492 oldbound = SCIPeventGetOldbound(event);
    6493 newbound = SCIPeventGetNewbound(event);
    6494 assert(var != NULL);
    6495 assert(consdata->vars[varpos] == var);
    6496 valrange = consdata->valsreal[varpos];
    6497
    6498 consdata->rangedrowpropagated = 0;
    6499
    6500 /* update the activity values */
    6501 if( (eventtype & SCIP_EVENTTYPE_GLBCHANGED) != 0 )
    6502 consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, valrange);
    6503 else
    6504 {
    6505 assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != 0);
    6506 consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, valrange);
    6507 }
    6508 }
    6509
    6510 /* if the variable is binary but not fixed it had to become binary due to this global change */
    6512 {
    6514 consdata->indexsorted = FALSE;
    6515 else
    6516 consdata->coefsorted = FALSE;
    6517 }
    6518 }
    6519 else if( ((eventtype & SCIP_EVENTTYPE_TYPECHANGED) != 0) )
    6520 {
    6522
    6523 /* for presolving it only matters if a variable type changed from continuous to some kind of integer */
    6524 consdata->presolved = (consdata->presolved && SCIPeventGetOldtype(event) < SCIP_VARTYPE_CONTINUOUS);
    6525
    6526 /* the ordering is preserved if the type changes from something different to binary to binary but SCIPvarIsBinary() is true */
    6527 consdata->indexsorted = (consdata->indexsorted && SCIPeventGetNewtype(event) == SCIP_VARTYPE_BINARY && SCIPvarIsBinary(var));
    6528 }
    6529 else if( (eventtype & SCIP_EVENTTYPE_VARDELETED) )
    6530 {
    6531 consdata->varsdeleted = TRUE;
    6532 }
    6533 return SCIP_OKAY;
    6534}
    6535
    6536
    6537/*
    6538 * Callback methods of conflict handler
    6539 */
    6540
    6541/*
    6542 * constraint specific interface methods
    6543 */
    6544
    6545/** creates the handler for linear constraints and includes it in SCIP */
    6547 SCIP* scip /**< SCIP data structure */
    6548 )
    6549{
    6550 SCIP_CONSHDLRDATA* conshdlrdata;
    6551 SCIP_CONSHDLR* conshdlr;
    6552 SCIP_EVENTHDLR* eventhdlr;
    6553
    6554 assert(scip != NULL);
    6555
    6556 /* create event handler for bound change events */
    6558 eventExecExactLinear, NULL) );
    6559
    6560 /* create constraint handler data */
    6561 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
    6562
    6563 /* include constraint handler */
    6566 consEnfolpExactLinear, consEnfopsExactLinear, consCheckExactLinear, consLockExactLinear,
    6567 conshdlrdata) );
    6568
    6569 assert(conshdlr != NULL);
    6570
    6571 /* mark constraint handler as exact */
    6572 SCIPconshdlrMarkExact(conshdlr);
    6573
    6574 /* set non-fundamental callbacks via specific setter functions */
    6575 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyExactLinear, consCopyExactLinear) );
    6576 SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveExactLinear) );
    6577 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteExactLinear) );
    6578 SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsExactLinear) );
    6579 SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitExactLinear) );
    6580 SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreExactLinear) );
    6581 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolExactLinear) );
    6582 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeExactLinear) );
    6583 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsExactLinear) );
    6584 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsExactLinear) );
    6585 SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitExactLinear) );
    6586 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpExactLinear) );
    6587 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseExactLinear) );
    6588 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintExactLinear) );
    6589 SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropExactLinear, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
    6591 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpExactLinear, consSepasolExactLinear, CONSHDLR_SEPAFREQ,
    6593 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransExactLinear) );
    6594 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxExactLinear) );
    6595
    6596 /* add constraint handler parameters */
    6598 "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
    6599 "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
    6600 &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
    6602 "constraints/" CONSHDLR_NAME "/maxrounds",
    6603 "maximal number of separation rounds per node (-1: unlimited)",
    6604 &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
    6606 "constraints/" CONSHDLR_NAME "/maxroundsroot",
    6607 "maximal number of separation rounds per node in the root node (-1: unlimited)",
    6608 &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
    6610 "constraints/" CONSHDLR_NAME "/maxsepacuts",
    6611 "maximal number of cuts separated per separation round",
    6612 &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
    6614 "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
    6615 "maximal number of cuts separated per separation round in the root node",
    6616 &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
    6618 "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
    6619 &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
    6621 "constraints/" CONSHDLR_NAME "/propcont",
    6622 "should bounds on continuous variables be tightened by propagation?",
    6623 &conshdlrdata->propcont, TRUE, TRUE, NULL, NULL) );
    6625 "constraints/" CONSHDLR_NAME "/limitdenom",
    6626 "should denominators of rational bounds on continuous variables be controlled?",
    6627 &conshdlrdata->limitdenom, TRUE, DEFAULT_LIMITDENOM, NULL, NULL) );
    6629 "constraints/" CONSHDLR_NAME "/boundmaxdenom",
    6630 "maximal denominator for rational bounds on continuous variables after propagation",
    6631 &conshdlrdata->boundmaxdenom, TRUE, DEFAULT_BOUNDMAXDENOM, 1L, SCIP_LONGINT_MAX, NULL, NULL) );
    6632
    6633 return SCIP_OKAY;
    6634}
    6635
    6636/** creates and captures a linear constraint
    6637 *
    6638 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    6639 */
    6641 SCIP* scip, /**< SCIP data structure */
    6642 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    6643 const char* name, /**< name of constraint */
    6644 int nvars, /**< number of nonzeros in the constraint */
    6645 SCIP_VAR** vars, /**< array with variables of constraint entries */
    6646 SCIP_RATIONAL** vals, /**< array with coefficients of constraint entries */
    6647 SCIP_RATIONAL* lhs, /**< left hand side of constraint */
    6648 SCIP_RATIONAL* rhs, /**< right hand side of constraint */
    6649 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    6650 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    6651 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    6652 * Usually set to TRUE. */
    6653 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    6654 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    6655 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    6656 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    6657 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    6658 * Usually set to TRUE. */
    6659 SCIP_Bool local, /**< is constraint only valid locally?
    6660 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    6661 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    6662 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    6663 * adds coefficients to this constraint. */
    6664 SCIP_Bool dynamic, /**< is constraint subject to aging?
    6665 * Usually set to FALSE. Set to TRUE for own cuts which
    6666 * are separated as constraints. */
    6667 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    6668 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    6669 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    6670 * if it may be moved to a more global node?
    6671 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    6672 )
    6673{
    6674 SCIP_CONSHDLR* conshdlr;
    6675 SCIP_CONSDATA* consdata;
    6676 int i;
    6677
    6678 assert(scip != NULL);
    6679 assert(cons != NULL);
    6680
    6681 /* find the linear constraint handler */
    6682 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    6683 if( conshdlr == NULL )
    6684 {
    6685 SCIPerrorMessage("linear constraint handler not found\n");
    6686 return SCIP_PLUGINNOTFOUND;
    6687 }
    6688
    6689 /* terminate if a coefficient is infinite */
    6690 for( i = 0; i < nvars; ++i )
    6691 {
    6692 if( SCIPrationalIsAbsInfinity(vals[i]) )
    6693 {
    6694 SCIPerrorMessage("coefficient of variable <%s> in constraint <%s> is infinite,"
    6695 " consider adjusting the infinity threshold\n", SCIPvarGetName(vars[i]), name);
    6696 SCIPABORT();
    6697 return SCIP_INVALIDDATA;
    6698 }
    6699 }
    6700
    6701 /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
    6702 * constraint after presolving we have to ensure that it holds active variables
    6703 */
    6704 if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE && nvars > 0 )
    6705 {
    6706 SCIP_VAR** consvars;
    6707 SCIP_RATIONAL** consvals;
    6708 SCIP_RATIONAL* constant;
    6709 int nconsvars;
    6710 int requiredsize;
    6711
    6713
    6714 nconsvars = nvars;
    6715 SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
    6716 SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
    6717
    6718 /* get active variables for new constraint */
    6719 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, nconsvars, constant, &requiredsize, TRUE) );
    6720
    6721 /* if space was not enough we need to resize the buffers */
    6722 if( requiredsize > nconsvars )
    6723 {
    6724 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
    6725 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
    6726
    6727 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, requiredsize, constant, &requiredsize, TRUE) );
    6728 assert(requiredsize <= nconsvars);
    6729 }
    6730
    6731 /* adjust sides and check that we do not subtract infinity values */
    6732 if( SCIPrationalIsAbsInfinity(constant) )
    6733 {
    6734 SCIPfreeBufferArray(scip, &consvals);
    6735 SCIPfreeBufferArray(scip, &consvars);
    6737 SCIPerrorMessage("while creating constraint <%s> inactive variables lead to an infinite constant\n", name);
    6738 SCIPABORT();
    6739 return SCIP_INVALIDDATA;
    6740 }
    6741 else
    6742 {
    6743 if( !SCIPrationalIsAbsInfinity(lhs) )
    6744 SCIPrationalDiff(lhs, lhs, constant);
    6745 if( !SCIPrationalIsAbsInfinity(rhs) )
    6746 SCIPrationalDiff(rhs, rhs, constant);
    6747 }
    6748
    6749 /* create constraint data */
    6750 SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
    6751
    6752 SCIPfreeBufferArray(scip, &consvals);
    6753 SCIPfreeBufferArray(scip, &consvars);
    6755 }
    6756 else
    6757 {
    6758 /* create constraint data */
    6759 SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
    6760 }
    6761 assert(consdata != NULL);
    6762
    6763 /* create constraint */
    6764 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
    6765 local, modifiable, dynamic, removable, stickingatnode) );
    6766
    6767 return SCIP_OKAY;
    6768}
    6769
    6770/** creates and captures a linear constraint
    6771 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
    6772 * method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
    6773 *
    6774 * @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
    6775 *
    6776 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    6777 */
    6779 SCIP* scip, /**< SCIP data structure */
    6780 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    6781 const char* name, /**< name of constraint */
    6782 int nvars, /**< number of nonzeros in the constraint */
    6783 SCIP_VAR** vars, /**< array with variables of constraint entries */
    6784 SCIP_RATIONAL** vals, /**< array with coefficients of constraint entries */
    6785 SCIP_RATIONAL* lhs, /**< left hand side of constraint */
    6786 SCIP_RATIONAL* rhs /**< right hand side of constraint */
    6787 )
    6788{
    6789 assert(scip != NULL);
    6790
    6791 SCIP_CALL( SCIPcreateConsExactLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
    6793
    6794 return SCIP_OKAY;
    6795}
    6796
    6797/** creates a linear constraint from an exact linear constraint by rounding values to floating-point and captures it */
    6799 SCIP* scip, /**< target SCIP data structure */
    6800 SCIP_CONS** cons, /**< pointer to store the created target constraint */
    6801 SCIP* sourcescip, /**< source SCIP data structure */
    6802 const char* name, /**< name of constraint */
    6803 int nvars, /**< number of variables in source variable array */
    6804 SCIP_VAR** sourcevars, /**< source variables of the linear constraints */
    6805 SCIP_INTERVAL* sourcecoefs, /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
    6806 SCIP_Real lhs, /**< left hand side of the linear constraint */
    6807 SCIP_Real rhs, /**< right hand side of the linear constraint */
    6808 SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
    6809 * variables of the target SCIP */
    6810 SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
    6811 * target constraints */
    6812 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
    6813 SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
    6814 SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
    6815 SCIP_Bool check, /**< should the constraint be checked for feasibility? */
    6816 SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
    6817 SCIP_Bool local, /**< is constraint only valid locally? */
    6818 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
    6819 SCIP_Bool dynamic, /**< is constraint subject to aging? */
    6820 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
    6821 SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
    6822 * if it may be moved to a more global node? */
    6823 SCIP_Bool global, /**< create a global or a local copy? */
    6824 SCIP_Bool* valid /**< pointer to store if the copying was valid */
    6825 )
    6826{
    6827 SCIP_VAR** vars;
    6828 SCIP_Real* coefs;
    6829
    6830 SCIP_Real constant;
    6831 int requiredsize;
    6832 int v;
    6833 SCIP_Bool success;
    6834
    6835 /**@todo This method is currently only used for subSCIPs in floating-point heuristics, but should be extended to be
    6836 * able to perform an exact copy in the future. This would allow application of the cons_components presolver,
    6837 * for example. In this case, whether an exact or an fp copy is created, could probably be decided by checking
    6838 * SCIPisExact() for the target SCIP.
    6839 */
    6840 assert(!SCIPisExact(scip));
    6841 (*valid) = FALSE;
    6842
    6843 if( SCIPisGT(scip, lhs, rhs) )
    6844 {
    6845 return SCIP_OKAY;
    6846 }
    6847
    6848 if( nvars == 0 )
    6849 {
    6850 SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
    6851 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    6852 return SCIP_OKAY;
    6853 }
    6854
    6855 /* duplicate variable array */
    6856 SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, sourcevars, nvars) );
    6857
    6858 /* duplicate coefficient array */
    6859 if( sourcecoefs != NULL )
    6860 {
    6861 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
    6862 for( int i = 0; i < nvars; i++ )
    6863 {
    6864 coefs[i] = SCIPintervalGetSup(sourcecoefs[i]);
    6865 assert(!SCIPisInfinity(scip, coefs[i]) && !SCIPisInfinity(scip, -coefs[i]));
    6866 }
    6867 }
    6868 else
    6869 {
    6870 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
    6871 for( v = 0; v < nvars; ++v )
    6872 coefs[v] = 1.0;
    6873 }
    6874
    6875 constant = 0.0;
    6876
    6877 /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
    6878 * the target SCIP
    6879 */
    6880 if( !SCIPvarIsOriginal(vars[0]) )
    6881 {
    6882 SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize) );
    6883
    6884 if( requiredsize > nvars )
    6885 {
    6886 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
    6887 SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
    6888
    6889 SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize) );
    6890 assert(requiredsize <= nvars);
    6891 }
    6892 }
    6893 else
    6894 {
    6895 for( v = 0; v < nvars; ++v )
    6896 {
    6897 assert(SCIPvarIsOriginal(vars[v]));
    6898 SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
    6899 assert(vars[v] != NULL);
    6900 }
    6901 }
    6902
    6903 success = TRUE;
    6904 /* map variables of the source constraint to variables of the target SCIP */
    6905 for( v = 0; v < nvars && success; ++v )
    6906 {
    6907 SCIP_VAR* var;
    6908 var = vars[v];
    6909
    6910 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, &success) );
    6911 assert(!(success) || vars[v] != NULL);
    6912 }
    6913
    6914 /* only create the target constraint, if all variables could be copied */
    6915 if( success )
    6916 {
    6917 if( !SCIPisInfinity(scip, -lhs) )
    6918 lhs -= constant;
    6919
    6920 if( !SCIPisInfinity(scip, rhs) )
    6921 rhs -= constant;
    6922
    6923 SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
    6924 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    6925 }
    6926
    6927 /* free buffer array */
    6928 SCIPfreeBufferArray(scip, &coefs);
    6929 SCIPfreeBufferArray(scip, &vars);
    6930
    6931 return SCIP_OKAY;
    6932}
    6933
    6934/** adds coefficient to linear constraint (if it is not zero) */
    6936 SCIP* scip, /**< SCIP data structure */
    6937 SCIP_CONS* cons, /**< constraint data */
    6938 SCIP_VAR* var, /**< variable of constraint entry */
    6939 SCIP_RATIONAL* val /**< coefficient of constraint entry */
    6940 )
    6941{
    6942 assert(scip != NULL);
    6943 assert(cons != NULL);
    6944 assert(var != NULL);
    6945
    6947
    6948 /* terminate if coefficient is infinite */
    6949 if( SCIPrationalIsAbsInfinity(val) )
    6950 {
    6951 SCIPerrorMessage("coefficient of variable <%s> in constraint <%s> is infinite,"
    6952 " consider adjusting the infinity threshold\n", SCIPvarGetName(var), SCIPconsGetName(cons));
    6953 SCIPABORT();
    6954 return SCIP_INVALIDDATA;
    6955 }
    6956
    6957 /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
    6958 * constraint after presolving we have to ensure that it holds active variables
    6959 */
    6961 {
    6962 SCIP_CONSDATA* consdata;
    6963 SCIP_VAR** consvars;
    6964 SCIP_RATIONAL** consvals;
    6965 SCIP_RATIONAL* constant;
    6966 SCIP_RATIONAL* rhs;
    6967 SCIP_RATIONAL* lhs;
    6968 int nconsvars;
    6969 int requiredsize;
    6970 int v;
    6971
    6972 SCIPerrorMessage("adding coefficients after presolving not supported yet in exact solving mode \n");
    6973 SCIPABORT();
    6974
    6975 nconsvars = 1;
    6976 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
    6977 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
    6978 consvars[0] = var;
    6979 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &consvals[0], val) );
    6981
    6982 /* get active variables for new constraint */
    6983 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, nconsvars, constant, &requiredsize, TRUE) );
    6984
    6985 /* if space was not enough we need to resize the buffers */
    6986 if( requiredsize > nconsvars )
    6987 {
    6988 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
    6989 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
    6990
    6991 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, requiredsize, constant, &requiredsize, TRUE) );
    6992 assert(requiredsize <= nconsvars);
    6993 }
    6994
    6995 consdata = SCIPconsGetData(cons);
    6996 assert(consdata != NULL);
    6997
    6998 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &lhs, consdata->lhs) );
    6999 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &rhs, consdata->rhs) );
    7000
    7001 /* adjust sides and check that we do not subtract infinity values */
    7002 if( SCIPrationalIsAbsInfinity(constant) )
    7003 {
    7004 SCIPfreeBufferArray(scip, &consvals);
    7005 SCIPfreeBufferArray(scip, &consvars);
    7006
    7007 SCIPerrorMessage("adding variable <%s> to constraint <%s> leads to infinite constant and cannot be handled safely\n",
    7008 SCIPvarGetName(var), SCIPconsGetName(cons));
    7009
    7010 SCIPABORT();
    7011 return SCIP_INVALIDDATA; /*lint !e527*/
    7012 }
    7013 /* constant is not infinite */
    7014 else
    7015 {
    7016 if( !SCIPrationalIsAbsInfinity(lhs) )
    7017 SCIPrationalDiff(lhs, lhs, constant);
    7018 if( !SCIPrationalIsAbsInfinity(rhs) )
    7019 SCIPrationalDiff(rhs, rhs, constant);
    7020 }
    7021
    7022 /* add all active variables to constraint */
    7023 for( v = nconsvars - 1; v >= 0; --v )
    7024 {
    7025 SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
    7026 }
    7027
    7028 /* update left and right hand sides */
    7029 SCIP_CALL( chgLhs(scip, cons, lhs) );
    7030 SCIP_CALL( chgRhs(scip, cons, rhs) );
    7031
    7033 SCIPfreeBufferArray(scip, &consvals);
    7034 SCIPfreeBufferArray(scip, &consvars);
    7035 }
    7036 else
    7037 {
    7038 SCIP_CALL( addCoef(scip, cons, var, val) );
    7039 }
    7040
    7041 return SCIP_OKAY;
    7042}
    7043
    7044/** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
    7045 * not yet contained in the constraint
    7046 *
    7047 * @note This method may only be called during problem creation stage for an original constraint and variable.
    7048 *
    7049 * @note This method requires linear time to search for occurences of the variable in the constraint data.
    7050 */
    7052 SCIP* scip, /**< SCIP data structure */
    7053 SCIP_CONS* cons, /**< constraint data */
    7054 SCIP_VAR* var, /**< variable of constraint entry */
    7055 SCIP_RATIONAL* val /**< new coefficient of constraint entry */
    7056 )
    7057{
    7058 SCIP_CONSDATA* consdata;
    7059 SCIP_VAR** vars;
    7060 SCIP_Bool found;
    7061 int i;
    7062
    7063 assert(scip != NULL);
    7064 assert(cons != NULL);
    7065 assert(var != NULL);
    7066
    7068
    7070 {
    7071 SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
    7072 return SCIP_INVALIDDATA;
    7073 }
    7074
    7075 consdata = SCIPconsGetData(cons);
    7076 assert(consdata != NULL);
    7077
    7078 vars = consdata->vars;
    7079 found = FALSE;
    7080 i = 0;
    7081 while( i < consdata->nvars )
    7082 {
    7083 if( vars[i] == var )
    7084 {
    7085 if( found || SCIPrationalIsZero(val) )
    7086 {
    7087 SCIP_CALL( delCoefPos(scip, cons, i) );
    7088
    7089 /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
    7090 i--;
    7091 }
    7092 else
    7093 {
    7094 SCIP_CALL( chgCoefPos(scip, cons, i, val) );
    7095 }
    7096 found = TRUE;
    7097 }
    7098 i++;
    7099 }
    7100
    7101 if( !found && !SCIPrationalIsZero(val) )
    7102 {
    7103 SCIP_CALL( SCIPaddCoefExactLinear(scip, cons, var, val) );
    7104 }
    7105
    7106 return SCIP_OKAY;
    7107}
    7108
    7109/** deletes variable from linear constraint
    7110 *
    7111 * @note This method may only be called during problem creation stage for an original constraint and variable.
    7112 *
    7113 * @note This method requires linear time to search for occurences of the variable in the constraint data.
    7114 */
    7116 SCIP* scip, /**< SCIP data structure */
    7117 SCIP_CONS* cons, /**< constraint data */
    7118 SCIP_VAR* var /**< variable of constraint entry */
    7119 )
    7120{
    7121 SCIP_RATIONAL* temp;
    7122
    7123 assert(scip != NULL);
    7124 assert(cons != NULL);
    7125 assert(var != NULL);
    7126
    7128
    7129 SCIP_CALL( SCIPchgCoefExactLinear(scip, cons, var, temp) );
    7130
    7132
    7133 return SCIP_OKAY;
    7134}
    7135
    7136/** gets left hand side of linear constraint */
    7138 SCIP* scip, /**< SCIP data structure */
    7139 SCIP_CONS* cons /**< constraint data */
    7140 )
    7141{
    7142 SCIP_CONSDATA* consdata;
    7143
    7144 assert(scip != NULL);
    7145 assert(cons != NULL);
    7146
    7148
    7149 consdata = SCIPconsGetData(cons);
    7150 assert(consdata != NULL);
    7151
    7152 return consdata->lhs;
    7153}
    7154
    7155/** gets right hand side of linear constraint */
    7157 SCIP* scip, /**< SCIP data structure */
    7158 SCIP_CONS* cons /**< constraint data */
    7159 )
    7160{
    7161 SCIP_CONSDATA* consdata;
    7162
    7163 assert(scip != NULL);
    7164 assert(cons != NULL);
    7165
    7167
    7168 consdata = SCIPconsGetData(cons);
    7169 assert(consdata != NULL);
    7170
    7171 return consdata->rhs;
    7172}
    7173
    7174/** changes left hand side of linear constraint */
    7176 SCIP* scip, /**< SCIP data structure */
    7177 SCIP_CONS* cons, /**< constraint data */
    7178 SCIP_RATIONAL* lhs /**< new left hand side */
    7179 )
    7180{
    7181 assert(scip != NULL);
    7182 assert(cons != NULL);
    7183 assert(lhs != NULL);
    7184
    7186
    7187 SCIP_CALL( chgLhs(scip, cons, lhs) );
    7188
    7189 return SCIP_OKAY;
    7190}
    7191
    7192/** changes right hand side of linear constraint */
    7194 SCIP* scip, /**< SCIP data structure */
    7195 SCIP_CONS* cons, /**< constraint data */
    7196 SCIP_RATIONAL* rhs /**< new right hand side */
    7197 )
    7198{
    7199 assert(scip != NULL);
    7200 assert(cons != NULL);
    7201 assert(rhs != NULL);
    7202
    7204
    7205 SCIP_CALL( chgRhs(scip, cons, rhs) );
    7206
    7207 return SCIP_OKAY;
    7208}
    7209
    7210/** gets the number of variables in the linear constraint */
    7212 SCIP* scip, /**< SCIP data structure */
    7213 SCIP_CONS* cons /**< constraint data */
    7214 )
    7215{
    7216 SCIP_CONSDATA* consdata;
    7217
    7218 assert(scip != NULL);
    7219 assert(cons != NULL);
    7220
    7222
    7223 consdata = SCIPconsGetData(cons);
    7224 assert(consdata != NULL);
    7225
    7226 return consdata->nvars;
    7227}
    7228
    7229/** gets the array of variables in the linear constraint; the user must not modify this array! */
    7231 SCIP* scip, /**< SCIP data structure */
    7232 SCIP_CONS* cons /**< constraint data */
    7233 )
    7234{
    7235 SCIP_CONSDATA* consdata;
    7236
    7237 assert(scip != NULL);
    7238 assert(cons != NULL);
    7239
    7241
    7242 consdata = SCIPconsGetData(cons);
    7243 assert(consdata != NULL);
    7244
    7245 return consdata->vars;
    7246}
    7247
    7248/** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
    7250 SCIP* scip, /**< SCIP data structure */
    7251 SCIP_CONS* cons /**< constraint data */
    7252 )
    7253{
    7254 SCIP_CONSDATA* consdata;
    7255
    7256 assert(scip != NULL);
    7257 assert(cons != NULL);
    7258
    7260
    7261 consdata = SCIPconsGetData(cons);
    7262 assert(consdata != NULL);
    7263
    7264 return consdata->valsreal;
    7265}
    7266
    7267/** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
    7269 SCIP* scip, /**< SCIP data structure */
    7270 SCIP_CONS* cons /**< constraint data */
    7271 )
    7272{
    7273 SCIP_CONSDATA* consdata;
    7274
    7275 assert(scip != NULL);
    7276 assert(cons != NULL);
    7277
    7279
    7280 consdata = SCIPconsGetData(cons);
    7281 assert(consdata != NULL);
    7282
    7283 return consdata->vals;
    7284}
    7285
    7286/** gets the activity of the linear constraint in the given solution
    7287 *
    7288 * @note if the activity comprises positive and negative infinity contributions, the result is currently undefined
    7289 */
    7291 SCIP* scip, /**< SCIP data structure */
    7292 SCIP_CONS* cons, /**< constraint data */
    7293 SCIP_SOL* sol, /**< solution, or NULL to use current node's solution */
    7294 SCIP_RATIONAL* ret
    7295 )
    7296{
    7297 SCIP_CONSDATA* consdata;
    7298
    7299 assert(scip != NULL);
    7300 assert(cons != NULL);
    7301
    7303
    7304 consdata = SCIPconsGetData(cons);
    7305 assert(consdata != NULL);
    7306
    7307 if( consdata->rowexact != NULL )
    7308 {
    7309 SCIP_CALL( SCIPgetRowSolActivityExact(scip, consdata->rowexact, sol, FALSE, ret) );
    7310 }
    7311 else
    7312 consdataGetActivity(scip, consdata, sol, TRUE, ret);
    7313
    7314 return SCIP_OKAY;
    7315}
    7316
    7317/** gets the feasibility of the linear constraint in the given solution */
    7319 SCIP* scip, /**< SCIP data structure */
    7320 SCIP_CONS* cons, /**< constraint data */
    7321 SCIP_SOL* sol, /**< solution, or NULL to use current node's solution */
    7322 SCIP_RATIONAL* ret /**< pointer to store the result */
    7323 )
    7324{
    7325 SCIP_CONSDATA* consdata;
    7326
    7327 assert(scip != NULL);
    7328 assert(cons != NULL);
    7329
    7331
    7332 consdata = SCIPconsGetData(cons);
    7333 assert(consdata != NULL);
    7334
    7335 if( consdata->rowexact != NULL )
    7336 SCIP_CALL( SCIPgetRowSolFeasibilityExact(scip, consdata->rowexact, sol, ret) );
    7337 else
    7338 consdataGetFeasibility(scip, consdata, sol, ret);
    7339
    7340 return SCIP_OKAY;
    7341}
    7342
    7343/** gets the dual solution of the linear constraint in the current LP
    7344 *
    7345 * @note this method currently returns the value from the floating-point LP
    7346 */
    7348 SCIP* scip, /**< SCIP data structure */
    7349 SCIP_CONS* cons, /**< constraint data */
    7350 SCIP_RATIONAL* ret /**< result pointer */
    7351 )
    7352{
    7353 SCIP_CONSDATA* consdata;
    7354
    7355 assert(scip != NULL);
    7356 assert(cons != NULL);
    7357 assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
    7358
    7359 SCIP_STRINGEQ( SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME, /**@todo return SCIP_INVALIDCALL type */ );
    7360
    7361 consdata = SCIPconsGetData(cons);
    7362 assert(consdata != NULL);
    7363
    7364 if( consdata->rowlhs != NULL )
    7365 SCIPrationalSetReal(ret, SCIProwGetDualsol(consdata->rowlhs));
    7366 else
    7367 SCIPrationalSetReal(ret, 0.0);
    7368}
    7369
    7370/** gets the dual Farkas value of the linear constraint in the current infeasible LP
    7371 *
    7372 * @note this method currently returns an approximate value from the floating-point LP
    7373 */
    7375 SCIP* scip, /**< SCIP data structure */
    7376 SCIP_CONS* cons, /**< constraint data */
    7377 SCIP_RATIONAL* ret /**< result pointer */
    7378 )
    7379{
    7380 SCIP_CONSDATA* consdata;
    7381
    7382 assert(scip != NULL);
    7383 assert(cons != NULL);
    7384 assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
    7385
    7386 SCIP_STRINGEQ( SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME, /**@todo return SCIP_INVALIDCALL type */ );
    7387
    7388 consdata = SCIPconsGetData(cons);
    7389 assert(consdata != NULL);
    7390
    7391 if( consdata->rowlhs != NULL )
    7392 SCIPrationalSetReal(ret, SCIProwGetDualfarkas(consdata->rowlhs));
    7393 else
    7394 SCIPrationalSetReal(ret, 0.0);
    7395}
    7396
    7397/** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
    7398 * the user must not modify the row!
    7399 */
    7401 SCIP* scip, /**< SCIP data structure */
    7402 SCIP_CONS* cons /**< constraint data */
    7403 )
    7404{
    7405 SCIP_CONSDATA* consdata;
    7406
    7407 assert(scip != NULL);
    7408 assert(cons != NULL);
    7409
    7411
    7412 consdata = SCIPconsGetData(cons);
    7413 assert(consdata != NULL);
    7414
    7415 return consdata->rowlhs;
    7416}
    7417
    7418/** returns the exact linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
    7419 * the user must not modify the row!
    7420 */
    7422 SCIP* scip, /**< SCIP data structure */
    7423 SCIP_CONS* cons /**< constraint data */
    7424 )
    7425{
    7426 SCIP_CONSDATA* consdata;
    7427
    7428 assert(scip != NULL);
    7429 assert(cons != NULL);
    7430
    7432
    7433 consdata = SCIPconsGetData(cons);
    7434 assert(consdata != NULL);
    7435
    7436 return consdata->rowexact;
    7437}
    static long bound
    internal methods for clocks and timing issues
    enum Proprule PROPRULE
    Definition: cons_and.c:172
    Proprule
    Definition: cons_and.c:165
    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:257
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_MAXTREEDEPTH
    Definition: def.h:306
    #define SCIP_REAL_UNITROUNDOFF
    Definition: def.h:169
    #define SCIP_INVALID
    Definition: def.h:187
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define SCIP_UNKNOWN
    Definition: def.h:188
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define SCIP_CALL_TERMINATE(retcode, x, TERM)
    Definition: def.h:385
    #define SCIPABORT()
    Definition: def.h:336
    #define REALABS(x)
    Definition: def.h:191
    #define SCIP_LONGINT_MAX
    Definition: def.h:151
    #define SCIP_CALL(x)
    Definition: def.h:364
    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:655
    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:4350
    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:4374
    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:5286
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4320
    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:4340
    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:8423
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8652
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8413
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8562
    SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
    Definition: cons.c:8692
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8592
    SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
    Definition: cons.c:8522
    SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
    Definition: cons.c:8702
    SCIP_Bool SCIPconsIsLockedType(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
    Definition: cons.c:8786
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8582
    SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:2042
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8454
    SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: scip_cons.c:997
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8612
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8632
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8393
    SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1812
    SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:2014
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8642
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8672
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8572
    SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1784
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8662
    SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
    Definition: scip_cut.c:225
    SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: scip_event.c:111
    const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:396
    SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
    Definition: event.c:1194
    SCIP_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:1577
    void SCIPrationalMin(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1343
    SCIP_RETCODE SCIPrationalCreateBlock(BMS_BLKMEM *blkmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:109
    SCIP_RETCODE SCIPrationalCreate(SCIP_RATIONAL **rational)
    Definition: rational.cpp:95
    void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1067
    SCIP_Bool SCIPrationalIsAbsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1422
    void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:619
    void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:936
    SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
    Definition: rational.cpp:2084
    SCIP_RETCODE SCIPrationalCreateString(BMS_BLKMEM *mem, SCIP_RATIONAL **rational, const char *desc)
    Definition: rational.cpp:797
    void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:462
    #define SCIPrationalDebugMessage
    Definition: rational.h:641
    void SCIPrationalAbs(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
    Definition: rational.cpp:1311
    void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1133
    SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1681
    SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1504
    void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
    Definition: rational.cpp:604
    SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1475
    SCIP_RETCODE SCIPrationalCopyBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **result, SCIP_RATIONAL *src)
    Definition: rational.cpp:152
    void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:474
    SCIP_RETCODE SCIPrationalCopyBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***target, SCIP_RATIONAL **src, int len)
    Definition: rational.cpp:250
    void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:984
    SCIP_Bool SCIPrationalIsLEReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1616
    SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1641
    int SCIPrationalGetSign(const SCIP_RATIONAL *rational)
    Definition: rational.cpp:2047
    SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:124
    void SCIPrationalAddProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1174
    SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1625
    void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
    Definition: rational.cpp:570
    SCIP_Bool SCIPrationalIsGEReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1607
    void SCIPrationalMessage(SCIP_MESSAGEHDLR *msg, FILE *file, SCIP_RATIONAL *rational)
    Definition: rational.cpp:1791
    void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:631
    void SCIPrationalSetFraction(SCIP_RATIONAL *res, SCIP_Longint nom, SCIP_Longint denom)
    Definition: rational.cpp:583
    void SCIPrationalNegate(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
    Definition: rational.cpp:1298
    SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1651
    void SCIPrationalDiffReal(SCIP_RATIONAL *res, SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1010
    SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1661
    void SCIPrationalFreeBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***ratblockarray, int size)
    Definition: rational.cpp:502
    SCIP_Real SCIPrationalRoundReal(SCIP_RATIONAL *rational, SCIP_ROUNDMODE_RAT roundmode)
    Definition: rational.cpp:2109
    SCIP_Bool SCIPrationalIsEQReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1438
    SCIP_RETCODE SCIPrationalCreateBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***rational, int size)
    Definition: rational.cpp:215
    SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1671
    void SCIPrationalFree(SCIP_RATIONAL **rational)
    Definition: rational.cpp:451
    SCIP_Bool SCIPrationalIsGTReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1547
    SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1405
    SCIP_RETCODE SCIPrationalReallocBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***result, int oldlen, int newlen)
    Definition: rational.cpp:315
    void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1098
    void SCIPrationalComputeApproximation(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_Longint maxdenom, int forcegreater)
    Definition: rational.cpp:2463
    void SCIPrationalFreeBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***ratbufarray, int size)
    Definition: rational.cpp:519
    SCIP_Bool SCIPrationalIsAbsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1531
    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:2351
    void SCIPgetSolValExact(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_RATIONAL *res)
    Definition: scip_sol.c:1801
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_Bool SCIPsolIsExact(SCIP_SOL *sol)
    Definition: sol.c:4165
    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:18365
    SCIP_RETCODE SCIPvarGetProbvarBound(SCIP_VAR **var, SCIP_Real *bound, SCIP_BOUNDTYPE *boundtype)
    Definition: var.c:17846
    SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
    Definition: var.c:23566
    SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
    Definition: var.c:23921
    SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5210
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23674
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23510
    SCIP_RATIONAL * SCIPvarGetAggrScalarExact(SCIP_VAR *var)
    Definition: var.c:23792
    SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
    Definition: scip_var.c:2119
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4380
    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:24300
    SCIP_RATIONAL * SCIPvarGetAggrConstantExact(SCIP_VAR *var)
    Definition: var.c:23815
    SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
    Definition: var.c:23462
    SCIP_RETCODE SCIPinferVarUbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:7069
    int SCIPvarGetCertificateIndex(SCIP_VAR *var)
    Definition: var.c:25130
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5296
    SCIP_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:23694
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_RATIONAL * SCIPvarGetMultaggrConstantExact(SCIP_VAR *var)
    Definition: var.c:23887
    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:24310
    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:23522
    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:23838
    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:23826
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    SCIP_RATIONAL * SCIPvarGetBestBoundLocalExact(SCIP_VAR *var)
    Definition: var.c:24357
    SCIP_RATIONAL * SCIPvarGetLbGlobalExact(SCIP_VAR *var)
    Definition: var.c:24162
    SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
    Definition: var.c:23910
    SCIP_RATIONAL ** SCIPvarGetMultaggrScalarsExact(SCIP_VAR *var)
    Definition: var.c:23862
    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:23449
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6964
    SCIP_RATIONAL * SCIPvarGetLbLocalExact(SCIP_VAR *var)
    Definition: var.c:24276
    int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
    Definition: var.c:17319
    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:4322
    SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
    Definition: scip_var.c:2078
    SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    SCIP_RETCODE 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:24184
    SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
    Definition: var.c:23768
    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:1219
    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
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    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