Scippy

    SCIP

    Solving Constraint Integer Programs

    cons_linear.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file cons_linear.c
    26 * @ingroup DEFPLUGINS_CONS
    27 * @brief Constraint handler for linear constraints in their most general form, \f$lhs <= a^T x <= rhs\f$.
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Marc Pfetsch
    31 * @author Kati Wolter
    32 * @author Michael Winkler
    33 * @author Gerald Gamrath
    34 * @author Domenico Salvagnin
    35 *
    36 * Linear constraints are separated with a high priority, because they are easy
    37 * to separate. Instead of using the global cut pool, the same effect can be
    38 * implemented by adding linear constraints to the root node, such that they are
    39 * separated each time, the linear constraints are separated. A constraint
    40 * handler, which generates linear constraints in this way should have a lower
    41 * separation priority than the linear constraint handler, and it should have a
    42 * separation frequency that is a multiple of the frequency of the linear
    43 * constraint handler. In this way, it can be avoided to separate the same cut
    44 * twice, because if a separation run of the handler is always preceded by a
    45 * separation of the linear constraints, the priorily added constraints are
    46 * always satisfied.
    47 *
    48 * Linear constraints are enforced and checked with a very low priority. Checking
    49 * of (many) linear constraints is much more involved than checking the solution
    50 * values for integrality. Because we are separating the linear constraints quite
    51 * often, it is only necessary to enforce them for integral solutions. A constraint
    52 * handler which generates pool cuts in its enforcing method should have an
    53 * enforcing priority smaller than that of the linear constraint handler to avoid
    54 * regenerating constraints which already exist.
    55 */
    56
    57/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    58
    60#include "scip/cons_nonlinear.h"
    61#include "scip/cons_knapsack.h"
    62#include "scip/cons_linear.h"
    63#include "scip/debug.h"
    64#include "scip/pub_conflict.h"
    65#include "scip/pub_cons.h"
    66#include "scip/pub_event.h"
    67#include "scip/pub_expr.h"
    68#include "scip/pub_lp.h"
    69#include "scip/pub_message.h"
    70#include "scip/pub_misc.h"
    71#include "scip/pub_misc_sort.h"
    72#include "scip/pub_var.h"
    73#include "scip/scip_branch.h"
    74#include "scip/scip_conflict.h"
    75#include "scip/scip_cons.h"
    76#include "scip/scip_copy.h"
    77#include "scip/scip_cut.h"
    78#include "scip/scip_event.h"
    79#include "scip/scip_general.h"
    80#include "scip/scip_lp.h"
    81#include "scip/scip_mem.h"
    82#include "scip/scip_message.h"
    83#include "scip/scip_numerics.h"
    84#include "scip/scip_param.h"
    85#include "scip/scip_prob.h"
    86#include "scip/scip_probing.h"
    87#include "scip/scip_sol.h"
    89#include "scip/scip_tree.h"
    90#include "scip/scip_var.h"
    91#include "scip/symmetry_graph.h"
    93#include "scip/dbldblarith.h"
    94
    95#define CONSHDLR_NAME "linear"
    96#define CONSHDLR_DESC "linear constraints of the form lhs <= a^T x <= rhs"
    97#define CONSHDLR_SEPAPRIORITY +100000 /**< priority of the constraint handler for separation */
    98#define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
    99#define CONSHDLR_CHECKPRIORITY -1000000 /**< priority of the constraint handler for checking feasibility */
    100#define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
    101#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
    102#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
    103 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
    104#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
    105#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
    106#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    107#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
    108
    109#define CONSHDLR_PRESOLTIMING (SCIP_PRESOLTIMING_FAST | SCIP_PRESOLTIMING_EXHAUSTIVE) /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
    110#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
    111
    112#define EVENTHDLR_NAME "linear"
    113#define EVENTHDLR_DESC "bound change event handler for linear constraints"
    114
    115#define CONFLICTHDLR_NAME "linear"
    116#define CONFLICTHDLR_DESC "conflict handler creating linear constraints"
    117#define CONFLICTHDLR_PRIORITY -1000000
    118
    119#define DEFAULT_TIGHTENBOUNDSFREQ 1 /**< multiplier on propagation frequency, how often the bounds are tightened */
    120#define DEFAULT_MAXROUNDS 5 /**< maximal number of separation rounds per node (-1: unlimited) */
    121#define DEFAULT_MAXROUNDSROOT -1 /**< maximal number of separation rounds in the root node (-1: unlimited) */
    122#define DEFAULT_MAXSEPACUTS 50 /**< maximal number of cuts separated per separation round */
    123#define DEFAULT_MAXSEPACUTSROOT 200 /**< maximal number of cuts separated per separation round in root node */
    124#define DEFAULT_PRESOLPAIRWISE TRUE /**< should pairwise constraint comparison be performed in presolving? */
    125#define DEFAULT_PRESOLUSEHASHING TRUE /**< should hash table be used for detecting redundant constraints in advance */
    126#define DEFAULT_NMINCOMPARISONS 200000 /**< number for minimal pairwise presolving comparisons */
    127#define DEFAULT_MINGAINPERNMINCOMP 1e-06 /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise
    128 * comparison round */
    129#define DEFAULT_SORTVARS TRUE /**< should variables be sorted after presolve w.r.t their coefficient absolute for faster
    130 * propagation? */
    131#define DEFAULT_CHECKRELMAXABS FALSE /**< should the violation for a constraint with side 0.0 be checked relative
    132 * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
    133#define DEFAULT_MAXAGGRNORMSCALE 0.0 /**< maximal allowed relative gain in maximum norm for constraint aggregation
    134 * (0.0: disable constraint aggregation) */
    135#define DEFAULT_MAXEASYACTIVITYDELTA 1e6 /**< maximum activity delta to run easy propagation on linear constraint
    136 * (faster, but numerically less stable) */
    137#define DEFAULT_MAXCARDBOUNDDIST 0.0 /**< maximal relative distance from current node's dual bound to primal bound compared
    138 * to best node's dual bound for separating knapsack cardinality cuts */
    139#define DEFAULT_SEPARATEALL FALSE /**< should all constraints be subject to cardinality cut generation instead of only
    140 * the ones with non-zero dual value? */
    141#define DEFAULT_AGGREGATEVARIABLES TRUE /**< should presolving search for redundant variables in equations */
    142#define DEFAULT_SIMPLIFYINEQUALITIES TRUE /**< should presolving try to simplify inequalities */
    143#define DEFAULT_DUALPRESOLVING TRUE /**< should dual presolving steps be performed? */
    144#define DEFAULT_SINGLETONSTUFFING TRUE /**< should stuffing of singleton continuous variables be performed? */
    145#define DEFAULT_SINGLEVARSTUFFING FALSE /**< should single variable stuffing be performed, which tries to fulfill
    146 * constraints using the cheapest variable? */
    147#define DEFAULT_DETECTCUTOFFBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
    148 * function defining an upper bound and prevent these constraints from
    149 * entering the LP */
    150#define DEFAULT_DETECTLOWERBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
    151 * function defining a lower bound and prevent these constraints from
    152 * entering the LP */
    153#define DEFAULT_DETECTPARTIALOBJECTIVE TRUE/**< should presolving try to detect subsets of constraints parallel to the
    154 * objective function */
    155#define DEFAULT_RANGEDROWPROPAGATION TRUE /**< should we perform ranged row propagation */
    156#define DEFAULT_RANGEDROWARTCONS TRUE /**< should presolving and propagation extract sub-constraints from ranged rows and equations? */
    157#define DEFAULT_RANGEDROWMAXDEPTH INT_MAX /**< maximum depth to apply ranged row propagation */
    158#define DEFAULT_RANGEDROWFREQ 1 /**< frequency for applying ranged row propagation */
    159
    160#define DEFAULT_MULTAGGRREMOVE FALSE /**< should multi-aggregations only be performed if the constraint can be
    161 * removed afterwards? */
    162#define DEFAULT_MAXMULTAGGRQUOT 1e+03 /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for multiaggregation */
    163#define DEFAULT_MAXDUALMULTAGGRQUOT 1e+20 /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for multiaggregation */
    164#define DEFAULT_EXTRACTCLIQUES TRUE /**< should cliques be extracted? */
    165
    166#define MAXDNOM 10000LL /**< maximal denominator for simple rational fixed values */
    167#define MAXSCALEDCOEF 0 /**< maximal coefficient value after scaling */
    168#define MAXSCALEDCOEFINTEGER 0 /**< maximal coefficient value after scaling if all variables are of integral
    169 * type
    170 */
    171#define MAXACTVAL 1e+09 /**< maximal absolute value of full and partial activities such that
    172 * redundancy-based simplifications are allowed to be applied
    173 */
    174
    175#define MAXVALRECOMP 1e+06 /**< maximal abolsute value we trust without recomputing the activity */
    176#define MINVALRECOMP 1e-05 /**< minimal abolsute value we trust without recomputing the activity */
    177
    178
    179#define NONLINCONSUPGD_PRIORITY 1000000 /**< priority of the constraint handler for upgrading of expressions constraints */
    180
    181/* @todo add multi-aggregation of variables that are in exactly two equations (, if not numerically an issue),
    182 * maybe in fullDualPresolve(), see convertLongEquality()
    183 */
    184
    185
    186/** constraint data for linear constraints */
    187struct SCIP_ConsData
    188{
    189 SCIP_Real lhs; /**< left hand side of row (for ranged rows) */
    190 SCIP_Real rhs; /**< right hand side of row */
    191 SCIP_Real maxabsval; /**< maximum absolute value of all coefficients */
    192 SCIP_Real minabsval; /**< minimal absolute value of all coefficients */
    193 QUAD_MEMBER(SCIP_Real minactivity); /**< minimal value w.r.t. the variable's local bounds for the constraint's
    194 * activity, ignoring the coefficients contributing with infinite value */
    195 QUAD_MEMBER(SCIP_Real maxactivity); /**< maximal value w.r.t. the variable's local bounds for the constraint's
    196 * activity, ignoring the coefficients contributing with infinite value */
    197 SCIP_Real lastminactivity; /**< last minimal activity which was computed by complete summation
    198 * over all contributing values */
    199 SCIP_Real lastmaxactivity; /**< last maximal activity which was computed by complete summation
    200 * over all contributing values */
    201 QUAD_MEMBER(SCIP_Real glbminactivity); /**< minimal value w.r.t. the variable's global bounds for the constraint's
    202 * activity, ignoring the coefficients contributing with infinite value */
    203 QUAD_MEMBER(SCIP_Real glbmaxactivity); /**< maximal value w.r.t. the variable's global bounds for the constraint's
    204 * activity, ignoring the coefficients contributing with infinite value */
    205 SCIP_Real lastglbminactivity; /**< last global minimal activity which was computed by complete summation
    206 * over all contributing values */
    207 SCIP_Real lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
    208 * over all contributing values */
    209 SCIP_Real maxactdelta; /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
    210 SCIP_VAR* maxactdeltavar; /**< variable with maximal activity contribution, or NULL if invalid */
    211 uint64_t possignature; /**< bit signature of coefficients that may take a positive value */
    212 uint64_t negsignature; /**< bit signature of coefficients that may take a negative value */
    213 SCIP_ROW* row; /**< LP row, if constraint is already stored in LP row format */
    214 SCIP_NLROW* nlrow; /**< NLP row, if constraint has been added to NLP relaxation */
    215 SCIP_VAR** vars; /**< variables of constraint entries */
    216 SCIP_Real* vals; /**< coefficients of constraint entries */
    217 SCIP_EVENTDATA** eventdata; /**< event data for bound change events of the variables */
    218 int minactivityneginf; /**< number of coefficients contributing with neg. infinite value to minactivity */
    219 int minactivityposinf; /**< number of coefficients contributing with pos. infinite value to minactivity */
    220 int maxactivityneginf; /**< number of coefficients contributing with neg. infinite value to maxactivity */
    221 int maxactivityposinf; /**< number of coefficients contributing with pos. infinite value to maxactivity */
    222 int minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
    223 int minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
    224 int maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
    225 int maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
    226 int glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
    227 int glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
    228 int glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
    229 int glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
    230 int glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
    231 int glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
    232 int glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
    233 int glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
    234 int varssize; /**< size of the vars- and vals-arrays */
    235 int nvars; /**< number of nonzeros in constraint */
    236 int nbinvars; /**< the number of binary variables in the constraint, only valid after
    237 * sorting in stage >= SCIP_STAGE_INITSOLVE
    238 */
    239 unsigned int boundstightened:2; /**< is constraint already propagated with bound tightening? */
    240 unsigned int rangedrowpropagated:2; /**< did we perform ranged row propagation on this constraint?
    241 * (0: no, 1: yes, 2: with potentially adding artificial constraint */
    242 unsigned int validmaxabsval:1; /**< is the maximum absolute value valid? */
    243 unsigned int validminabsval:1; /**< is the minimum absolute value valid? */
    244 unsigned int validactivities:1; /**< are the activity bounds (local and global) valid? */
    245 unsigned int validminact:1; /**< is the local minactivity valid? */
    246 unsigned int validmaxact:1; /**< is the local maxactivity valid? */
    247 unsigned int validglbminact:1; /**< is the global minactivity valid? */
    248 unsigned int validglbmaxact:1; /**< is the global maxactivity valid? */
    249 unsigned int presolved:1; /**< is constraint already presolved? */
    250 unsigned int removedfixings:1; /**< are all fixed variables removed from the constraint? */
    251 unsigned int validsignature:1; /**< is the bit signature valid? */
    252 unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
    253 unsigned int normalized:1; /**< is the constraint in normalized form? */
    254 unsigned int upgradetried:1; /**< was the constraint already tried to be upgraded? */
    255 unsigned int upgraded:1; /**< is the constraint upgraded and will it be removed after preprocessing? */
    256 unsigned int indexsorted:1; /**< are the constraint's variables sorted by type and index? */
    257 unsigned int merged:1; /**< are the constraint's equal variables already merged? */
    258 unsigned int cliquesadded:1; /**< were the cliques of the constraint already extracted? */
    259 unsigned int implsadded:1; /**< were the implications of the constraint already extracted? */
    260 unsigned int coefsorted:1; /**< are variables sorted by type and their absolute activity delta? */
    261 unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
    262 unsigned int hascontvar:1; /**< does the constraint contain at least one continuous variable? */
    263 unsigned int hasnonbinvar:1; /**< does the constraint contain at least one non-binary variable? */
    264 unsigned int hasnonbinvalid:1; /**< is the information stored in hasnonbinvar and hascontvar valid? */
    265 unsigned int checkabsolute:1; /**< should the constraint be checked w.r.t. an absolute feasibilty tolerance? */
    266};
    267
    268/** event data for bound change event */
    269struct SCIP_EventData
    270{
    271 SCIP_CONS* cons; /**< linear constraint to process the bound change for */
    272 int varpos; /**< position of variable in vars array */
    273 int filterpos; /**< position of event in variable's event filter */
    274};
    275
    276/** constraint handler data */
    277struct SCIP_ConshdlrData
    278{
    279 SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
    280 SCIP_LINCONSUPGRADE** linconsupgrades; /**< linear constraint upgrade methods for specializing linear constraints */
    281 SCIP_Real maxaggrnormscale; /**< maximal allowed relative gain in maximum norm for constraint aggregation
    282 * (0.0: disable constraint aggregation) */
    283 SCIP_Real maxcardbounddist; /**< maximal relative distance from current node's dual bound to primal bound compared
    284 * to best node's dual bound for separating knapsack cardinality cuts */
    285 SCIP_Real mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
    286 SCIP_Real maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
    287 * (faster, but numerically less stable) */
    288 int linconsupgradessize;/**< size of linconsupgrade array */
    289 int nlinconsupgrades; /**< number of linear constraint upgrade methods */
    290 int tightenboundsfreq; /**< multiplier on propagation frequency, how often the bounds are tightened */
    291 int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
    292 int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
    293 int maxsepacuts; /**< maximal number of cuts separated per separation round */
    294 int maxsepacutsroot; /**< maximal number of cuts separated per separation round in root node */
    295 int nmincomparisons; /**< number for minimal pairwise presolving comparisons */
    296 int naddconss; /**< number of added constraints */
    297 SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
    298 SCIP_Bool presolusehashing; /**< should hash table be used for detecting redundant constraints in advance */
    299 SCIP_Bool separateall; /**< should all constraints be subject to cardinality cut generation instead of only
    300 * the ones with non-zero dual value? */
    301 SCIP_Bool aggregatevariables; /**< should presolving search for redundant variables in equations */
    302 SCIP_Bool simplifyinequalities;/**< should presolving try to cancel down or delete coefficients in inequalities */
    303 SCIP_Bool dualpresolving; /**< should dual presolving steps be performed? */
    304 SCIP_Bool singletonstuffing; /**< should stuffing of singleton continuous variables be performed? */
    305 SCIP_Bool singlevarstuffing; /**< should single variable stuffing be performed, which tries to fulfill
    306 * constraints using the cheapest variable? */
    307 SCIP_Bool sortvars; /**< should binary variables be sorted for faster propagation? */
    308 SCIP_Bool checkrelmaxabs; /**< should the violation for a constraint with side 0.0 be checked relative
    309 * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
    310 SCIP_Bool detectcutoffbound; /**< should presolving try to detect constraints parallel to the objective
    311 * function defining an upper bound and prevent these constraints from
    312 * entering the LP */
    313 SCIP_Bool detectlowerbound; /**< should presolving try to detect constraints parallel to the objective
    314 * function defining a lower bound and prevent these constraints from
    315 * entering the LP */
    316 SCIP_Bool detectpartialobjective;/**< should presolving try to detect subsets of constraints parallel to
    317 * the objective function */
    318 SCIP_Bool rangedrowpropagation;/**< should presolving and propagation try to improve bounds, detect
    319 * infeasibility, and extract sub-constraints from ranged rows and
    320 * equations */
    321 SCIP_Bool rangedrowartcons; /**< should presolving and propagation extract sub-constraints from ranged rows and equations?*/
    322 int rangedrowmaxdepth; /**< maximum depth to apply ranged row propagation */
    323 int rangedrowfreq; /**< frequency for applying ranged row propagation */
    324 SCIP_Bool multaggrremove; /**< should multi-aggregations only be performed if the constraint can be
    325 * removed afterwards? */
    326 SCIP_Real maxmultaggrquot; /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation */
    327 SCIP_Real maxdualmultaggrquot;/**< maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation */
    328 SCIP_Bool extractcliques; /**< should cliques be extracted? */
    329};
    330
    331/** linear constraint update method */
    333{
    334 SCIP_DECL_LINCONSUPGD((*linconsupgd)); /**< method to call for upgrading linear constraint */
    335 int priority; /**< priority of upgrading method */
    336 SCIP_Bool active; /**< is upgrading enabled */
    337};
    338
    339
    340/*
    341 * Propagation rules
    342 */
    343
    345{
    346 PROPRULE_1_RHS = 1, /**< activity residuals of all other variables tighten bounds of single
    347 * variable due to the right hand side of the inequality */
    348 PROPRULE_1_LHS = 2, /**< activity residuals of all other variables tighten bounds of single
    349 * variable due to the left hand side of the inequality */
    350 PROPRULE_1_RANGEDROW = 3, /**< fixed variables and gcd of all left variables tighten bounds of a
    351 * single variable in this reanged row */
    352 PROPRULE_INVALID = 0 /**< propagation was applied without a specific propagation rule */
    354typedef enum Proprule PROPRULE;
    355
    356/** inference information */
    357struct InferInfo
    358{
    359 union
    360 {
    361 struct
    362 {
    363 unsigned int proprule:8; /**< propagation rule that was applied */
    364 unsigned int pos:24; /**< variable position, the propagation rule was applied at */
    365 } asbits;
    366 int asint; /**< inference information as a single int value */
    367 } val;
    368};
    369typedef struct InferInfo INFERINFO;
    370
    371/** converts an integer into an inference information */
    372static
    374 int i /**< integer to convert */
    375 )
    376{
    377 INFERINFO inferinfo;
    378
    379 inferinfo.val.asint = i;
    380
    381 return inferinfo;
    382}
    383
    384/** converts an inference information into an int */
    385static
    387 INFERINFO inferinfo /**< inference information to convert */
    388 )
    389{
    390 return inferinfo.val.asint;
    391}
    392
    393/** returns the propagation rule stored in the inference information */
    394static
    396 INFERINFO inferinfo /**< inference information to convert */
    397 )
    398{
    399 return (int) inferinfo.val.asbits.proprule;
    400}
    401
    402/** returns the position stored in the inference information */
    403static
    405 INFERINFO inferinfo /**< inference information to convert */
    406 )
    407{
    408 return (int) inferinfo.val.asbits.pos;
    409}
    410
    411/** constructs an inference information out of a propagation rule and a position number */
    412static
    414 PROPRULE proprule, /**< propagation rule that deduced the value */
    415 int pos /**< variable position, the propagation rule was applied at */
    416 )
    417{
    418 INFERINFO inferinfo;
    419
    420 assert(pos >= 0);
    421 /* in the inferinfo struct only 24 bits for 'pos' are reserved */
    422 assert(pos < (1<<24));
    423
    424 inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
    425 inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
    426
    427 return inferinfo;
    428}
    429
    430/** constructs an inference information out of a propagation rule and a position number, returns info as int */
    431static
    433 PROPRULE proprule, /**< propagation rule that deduced the value */
    434 int pos /**< variable position, the propagation rule was applied at */
    435 )
    436{
    437 return inferInfoToInt(getInferInfo(proprule, pos));
    438}
    439
    440
    441/*
    442 * memory growing methods for dynamically allocated arrays
    443 */
    444
    445/** ensures, that linconsupgrades array can store at least num entries */
    446static
    448 SCIP* scip, /**< SCIP data structure */
    449 SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
    450 int num /**< minimum number of entries to store */
    451 )
    452{
    453 assert(scip != NULL);
    454 assert(conshdlrdata != NULL);
    455 assert(conshdlrdata->nlinconsupgrades <= conshdlrdata->linconsupgradessize);
    456
    457 if( num > conshdlrdata->linconsupgradessize )
    458 {
    459 int newsize;
    460
    461 newsize = SCIPcalcMemGrowSize(scip, num);
    462 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &conshdlrdata->linconsupgrades, conshdlrdata->linconsupgradessize, newsize) );
    463 conshdlrdata->linconsupgradessize = newsize;
    464 }
    465 assert(num <= conshdlrdata->linconsupgradessize);
    466
    467 return SCIP_OKAY;
    468}
    469
    470/** ensures, that vars and vals arrays can store at least num entries */
    471static
    473 SCIP* scip, /**< SCIP data structure */
    474 SCIP_CONSDATA* consdata, /**< linear constraint data */
    475 int num /**< minimum number of entries to store */
    476 )
    477{
    478 assert(scip != NULL);
    479 assert(consdata != NULL);
    480 assert(consdata->nvars <= consdata->varssize);
    481
    482 if( num > consdata->varssize )
    483 {
    484 int newsize;
    485
    486 newsize = SCIPcalcMemGrowSize(scip, num);
    487 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
    488 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
    489 if( consdata->eventdata != NULL )
    490 {
    491 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
    492 }
    493 consdata->varssize = newsize;
    494 }
    495 assert(num <= consdata->varssize);
    496
    497 return SCIP_OKAY;
    498}
    499
    500
    501/*
    502 * local methods for managing linear constraint update methods
    503 */
    504
    505/** creates a linear constraint upgrade data object */
    506static
    508 SCIP* scip, /**< SCIP data structure */
    509 SCIP_LINCONSUPGRADE** linconsupgrade, /**< pointer to store the linear constraint upgrade */
    510 SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
    511 int priority /**< priority of upgrading method */
    512 )
    513{
    514 assert(scip != NULL);
    515 assert(linconsupgrade != NULL);
    516 assert(linconsupgd != NULL);
    517
    518 SCIP_CALL( SCIPallocBlockMemory(scip, linconsupgrade) );
    519 (*linconsupgrade)->linconsupgd = linconsupgd;
    520 (*linconsupgrade)->priority = priority;
    521 (*linconsupgrade)->active = TRUE;
    522
    523 return SCIP_OKAY;
    524}
    525
    526/** frees a linear constraint upgrade data object */
    527static
    529 SCIP* scip, /**< SCIP data structure */
    530 SCIP_LINCONSUPGRADE** linconsupgrade /**< pointer to the linear constraint upgrade */
    531 )
    532{
    533 assert(scip != NULL);
    534 assert(linconsupgrade != NULL);
    535 assert(*linconsupgrade != NULL);
    536
    537 SCIPfreeBlockMemory(scip, linconsupgrade);
    538}
    539
    540/** creates constraint handler data for linear constraint handler */
    541static
    543 SCIP* scip, /**< SCIP data structure */
    544 SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
    545 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    546 )
    547{
    548 assert(scip != NULL);
    549 assert(conshdlrdata != NULL);
    550 assert(eventhdlr != NULL);
    551
    552 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
    553 (*conshdlrdata)->linconsupgrades = NULL;
    554 (*conshdlrdata)->linconsupgradessize = 0;
    555 (*conshdlrdata)->nlinconsupgrades = 0;
    556 (*conshdlrdata)->naddconss = 0;
    557
    558 /* set event handler for updating linear constraint activity bounds */
    559 (*conshdlrdata)->eventhdlr = eventhdlr;
    560
    561 return SCIP_OKAY;
    562}
    563
    564/** frees constraint handler data for linear constraint handler */
    565static
    567 SCIP* scip, /**< SCIP data structure */
    568 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
    569 )
    570{
    571 int i;
    572
    573 assert(scip != NULL);
    574 assert(conshdlrdata != NULL);
    575 assert(*conshdlrdata != NULL);
    576
    577 for( i = 0; i < (*conshdlrdata)->nlinconsupgrades; ++i )
    578 {
    579 linconsupgradeFree(scip, &(*conshdlrdata)->linconsupgrades[i]);
    580 }
    581 SCIPfreeBlockMemoryArrayNull(scip, &(*conshdlrdata)->linconsupgrades, (*conshdlrdata)->linconsupgradessize);
    582
    583 SCIPfreeBlockMemory(scip, conshdlrdata);
    584}
    585
    586/** creates a linear constraint upgrade data object */
    587static
    589 SCIP* scip, /**< SCIP data structure */
    590 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    591 SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
    592 const char* conshdlrname /**< name of the constraint handler */
    593 )
    594{
    595 int i;
    596
    597 assert(scip != NULL);
    598 assert(conshdlrdata != NULL);
    599 assert(linconsupgd != NULL);
    600 assert(conshdlrname != NULL);
    601
    602 for( i = conshdlrdata->nlinconsupgrades - 1; i >= 0; --i )
    603 {
    604 if( conshdlrdata->linconsupgrades[i]->linconsupgd == linconsupgd )
    605 {
    606#ifdef SCIP_DEBUG
    607 SCIPwarningMessage(scip, "Try to add already known upgrade message for constraint handler %s.\n", conshdlrname);
    608#endif
    609 return TRUE;
    610 }
    611 }
    612
    613 return FALSE;
    614}
    615
    616/** adds a linear constraint update method to the constraint handler's data */
    617static
    619 SCIP* scip, /**< SCIP data structure */
    620 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    621 SCIP_LINCONSUPGRADE* linconsupgrade /**< linear constraint upgrade method */
    622 )
    623{
    624 int i;
    625
    626 assert(scip != NULL);
    627 assert(conshdlrdata != NULL);
    628 assert(linconsupgrade != NULL);
    629
    630 SCIP_CALL( conshdlrdataEnsureLinconsupgradesSize(scip, conshdlrdata, conshdlrdata->nlinconsupgrades+1) );
    631
    632 for( i = conshdlrdata->nlinconsupgrades;
    633 i > 0 && conshdlrdata->linconsupgrades[i-1]->priority < linconsupgrade->priority; --i )
    634 {
    635 conshdlrdata->linconsupgrades[i] = conshdlrdata->linconsupgrades[i-1];
    636 }
    637 assert(0 <= i && i <= conshdlrdata->nlinconsupgrades);
    638 conshdlrdata->linconsupgrades[i] = linconsupgrade;
    639 conshdlrdata->nlinconsupgrades++;
    640
    641 return SCIP_OKAY;
    642}
    643
    644/*
    645 * local methods
    646 */
    647
    648/** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
    649static
    651 SCIP* scip, /**< SCIP data structure */
    652 SCIP_CONS* cons, /**< linear constraint */
    653 SCIP_VAR* var, /**< variable of constraint entry */
    654 SCIP_Real val /**< coefficient of constraint entry */
    655 )
    656{
    657 SCIP_CONSDATA* consdata;
    658
    659 assert(scip != NULL);
    660 assert(cons != NULL);
    661 assert(var != NULL);
    662
    663 consdata = SCIPconsGetData(cons);
    664 assert(consdata != NULL);
    665 assert(!SCIPisZero(scip, val));
    666
    667 if( val < 0.0 )
    668 {
    669 SCIP_CALL( SCIPlockVarCons(scip, var, cons,
    670 !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
    671 }
    672 else
    673 {
    674 SCIP_CALL( SCIPlockVarCons(scip, var, cons,
    675 !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
    676 }
    677
    678 return SCIP_OKAY;
    679}
    680
    681/** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
    682static
    684 SCIP* scip, /**< SCIP data structure */
    685 SCIP_CONS* cons, /**< linear constraint */
    686 SCIP_VAR* var, /**< variable of constraint entry */
    687 SCIP_Real val /**< coefficient of constraint entry */
    688 )
    689{
    690 SCIP_CONSDATA* consdata;
    691
    692 assert(scip != NULL);
    693 assert(cons != NULL);
    694 assert(var != NULL);
    695
    696 consdata = SCIPconsGetData(cons);
    697 assert(consdata != NULL);
    698 assert(!SCIPisZero(scip, val));
    699
    700 if( val < 0.0 )
    701 {
    702 SCIP_CALL( SCIPunlockVarCons(scip, var, cons,
    703 !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
    704 }
    705 else
    706 {
    707 SCIP_CALL( SCIPunlockVarCons(scip, var, cons,
    708 !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
    709 }
    710
    711 return SCIP_OKAY;
    712}
    713
    714/** creates event data for variable at given position, and catches events */
    715/**! [SnippetDebugAssertions] */
    716static
    718 SCIP* scip, /**< SCIP data structure */
    719 SCIP_CONS* cons, /**< linear constraint */
    720 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    721 int pos /**< array position of variable to catch bound change events for */
    722 )
    723{
    724 SCIP_CONSDATA* consdata;
    725 assert(scip != NULL);
    726 assert(cons != NULL);
    727 assert(eventhdlr != NULL);
    728
    729 consdata = SCIPconsGetData(cons);
    730 assert(consdata != NULL);
    731
    732 assert(0 <= pos && pos < consdata->nvars);
    733 assert(consdata->vars != NULL);
    734 assert(consdata->vars[pos] != NULL);
    735 assert(SCIPvarIsTransformed(consdata->vars[pos]));
    736 assert(consdata->eventdata != NULL);
    737 assert(consdata->eventdata[pos] == NULL);
    738
    739 SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
    740 consdata->eventdata[pos]->cons = cons;
    741 consdata->eventdata[pos]->varpos = pos;
    742
    743 SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
    747 eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
    748
    749 consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(consdata->vars[pos]);
    750
    751 return SCIP_OKAY;
    752}
    753/**! [SnippetDebugAssertions] */
    754
    755/** deletes event data for variable at given position, and drops events */
    756static
    758 SCIP* scip, /**< SCIP data structure */
    759 SCIP_CONS* cons, /**< linear constraint */
    760 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    761 int pos /**< array position of variable to catch bound change events for */
    762 )
    763{
    764 SCIP_CONSDATA* consdata;
    765 assert(scip != NULL);
    766 assert(cons != NULL);
    767 assert(eventhdlr != NULL);
    768
    769 consdata = SCIPconsGetData(cons);
    770 assert(consdata != NULL);
    771
    772 assert(0 <= pos && pos < consdata->nvars);
    773 assert(consdata->vars[pos] != NULL);
    774 assert(consdata->eventdata != NULL);
    775 assert(consdata->eventdata[pos] != NULL);
    776 assert(consdata->eventdata[pos]->cons == cons);
    777 assert(consdata->eventdata[pos]->varpos == pos);
    778
    779 SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
    783 eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
    784
    785 SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
    786
    787 return SCIP_OKAY;
    788}
    789
    790/** catches bound change events for all variables in transformed linear constraint */
    791static
    793 SCIP* scip, /**< SCIP data structure */
    794 SCIP_CONS* cons, /**< linear constraint */
    795 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
    796 )
    797{
    798 SCIP_CONSDATA* consdata;
    799 int i;
    800
    801 assert(scip != NULL);
    802 assert(cons != NULL);
    803
    804 consdata = SCIPconsGetData(cons);
    805 assert(consdata != NULL);
    806 assert(consdata->eventdata == NULL);
    807
    808 /* allocate eventdata array */
    809 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
    810 assert(consdata->eventdata != NULL);
    811 BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
    812
    813 /* catch event for every single variable */
    814 for( i = 0; i < consdata->nvars; ++i )
    815 {
    816 SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
    817 }
    818
    819 return SCIP_OKAY;
    820}
    821
    822/** drops bound change events for all variables in transformed linear constraint */
    823static
    825 SCIP* scip, /**< SCIP data structure */
    826 SCIP_CONS* cons, /**< linear constraint */
    827 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
    828 )
    829{
    830 SCIP_CONSDATA* consdata;
    831 int i;
    832
    833 assert(scip != NULL);
    834 assert(cons != NULL);
    835
    836 consdata = SCIPconsGetData(cons);
    837 assert(consdata != NULL);
    838 assert(consdata->eventdata != NULL);
    839
    840 /* drop event of every single variable */
    841 for( i = consdata->nvars - 1; i >= 0; --i )
    842 {
    843 SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
    844 }
    845
    846 /* free eventdata array */
    847 SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
    848 assert(consdata->eventdata == NULL);
    849
    850 return SCIP_OKAY;
    851}
    852
    853/** creates a linear constraint data */
    854static
    856 SCIP* scip, /**< SCIP data structure */
    857 SCIP_CONSDATA** consdata, /**< pointer to linear constraint data */
    858 int nvars, /**< number of nonzeros in the constraint */
    859 SCIP_VAR** vars, /**< array with variables of constraint entries */
    860 SCIP_Real* vals, /**< array with coefficients of constraint entries */
    861 SCIP_Real lhs, /**< left hand side of row */
    862 SCIP_Real rhs /**< right hand side of row */
    863 )
    864{
    865 int v;
    866 SCIP_Real constant;
    867
    868 assert(scip != NULL);
    869 assert(consdata != NULL);
    870 assert(nvars == 0 || vars != NULL);
    871 assert(nvars == 0 || vals != NULL);
    872
    873 if( SCIPisInfinity(scip, rhs) )
    874 rhs = SCIPinfinity(scip);
    875 else if( SCIPisInfinity(scip, -rhs) )
    876 rhs = -SCIPinfinity(scip);
    877
    878 if( SCIPisInfinity(scip, -lhs) )
    879 lhs = -SCIPinfinity(scip);
    880 else if( SCIPisInfinity(scip, lhs) )
    881 lhs = SCIPinfinity(scip);
    882
    883 if( SCIPisGT(scip, lhs, rhs) )
    884 {
    885 SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
    886 SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", lhs, rhs);
    887 }
    888
    889 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
    890
    891 (*consdata)->varssize = 0;
    892 (*consdata)->nvars = nvars;
    893 (*consdata)->hascontvar = FALSE;
    894 (*consdata)->hasnonbinvar = FALSE;
    895 (*consdata)->hasnonbinvalid = TRUE;
    896 (*consdata)->vars = NULL;
    897 (*consdata)->vals = NULL;
    898
    899 constant = 0.0;
    900 if( nvars > 0 )
    901 {
    902 SCIP_VAR** varsbuffer;
    903 SCIP_Real* valsbuffer;
    904
    905 /* copy variables into temporary buffer */
    906 SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
    907 SCIP_CALL( SCIPallocBufferArray(scip, &valsbuffer, nvars) );
    908 nvars = 0;
    909
    910 /* loop over variables and sort out fixed ones */
    911 for( v = 0; v < (*consdata)->nvars; ++v )
    912 {
    913 SCIP_VAR* var;
    914 SCIP_Real val;
    915
    916 var = vars[v];
    917 assert(var != NULL);
    918 val = vals[v];
    919 assert(!SCIPisInfinity(scip, val));
    920
    921 if( !SCIPisZero(scip, val) )
    922 {
    923 /* treat fixed variable as a constant if problem compression is enabled */
    925 {
    926 constant += SCIPvarGetLbGlobal(var) * val;
    927 }
    928 else
    929 {
    930 varsbuffer[nvars] = var;
    931 valsbuffer[nvars] = val;
    932 ++nvars;
    933
    934 if( !(*consdata)->hascontvar && !SCIPvarIsBinary(var) )
    935 {
    936 (*consdata)->hasnonbinvar = TRUE;
    937
    938 if( !SCIPvarIsIntegral(var) )
    939 (*consdata)->hascontvar = TRUE;
    940 }
    941 }
    942 }
    943 }
    944 (*consdata)->nvars = nvars;
    945
    946 if( nvars > 0 )
    947 {
    948 /* copy the possibly reduced buffer arrays into block */
    949 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, nvars) );
    950 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, valsbuffer, nvars) );
    951 (*consdata)->varssize = nvars;
    952 }
    953 /* free temporary buffer */
    954 SCIPfreeBufferArray(scip, &valsbuffer);
    955 SCIPfreeBufferArray(scip, &varsbuffer);
    956 }
    957
    958 (*consdata)->eventdata = NULL;
    959
    960 /* due to compressed copying, we may have fixed variables contributing to the left and right hand side */
    961 if( !SCIPisZero(scip, constant) )
    962 {
    963 if( !SCIPisInfinity(scip, REALABS(lhs)) )
    964 lhs -= constant;
    965
    966 if( !SCIPisInfinity(scip, REALABS(rhs)) )
    967 rhs -= constant;
    968 }
    969
    970 (*consdata)->row = NULL;
    971 (*consdata)->nlrow = NULL;
    972 (*consdata)->lhs = lhs;
    973 (*consdata)->rhs = rhs;
    974 (*consdata)->maxabsval = SCIP_INVALID;
    975 (*consdata)->minabsval = SCIP_INVALID;
    976 QUAD_ASSIGN((*consdata)->minactivity, SCIP_INVALID);
    977 QUAD_ASSIGN((*consdata)->maxactivity, SCIP_INVALID);
    978 (*consdata)->lastminactivity = SCIP_INVALID;
    979 (*consdata)->lastmaxactivity = SCIP_INVALID;
    980 (*consdata)->maxactdelta = SCIP_INVALID;
    981 (*consdata)->maxactdeltavar = NULL;
    982 (*consdata)->minactivityneginf = -1;
    983 (*consdata)->minactivityposinf = -1;
    984 (*consdata)->maxactivityneginf = -1;
    985 (*consdata)->maxactivityposinf = -1;
    986 (*consdata)->minactivityneghuge = -1;
    987 (*consdata)->minactivityposhuge = -1;
    988 (*consdata)->maxactivityneghuge = -1;
    989 (*consdata)->maxactivityposhuge = -1;
    990 QUAD_ASSIGN((*consdata)->glbminactivity, SCIP_INVALID);
    991 QUAD_ASSIGN((*consdata)->glbmaxactivity, SCIP_INVALID);
    992 (*consdata)->lastglbminactivity = SCIP_INVALID;
    993 (*consdata)->lastglbmaxactivity = SCIP_INVALID;
    994 (*consdata)->glbminactivityneginf = -1;
    995 (*consdata)->glbminactivityposinf = -1;
    996 (*consdata)->glbmaxactivityneginf = -1;
    997 (*consdata)->glbmaxactivityposinf = -1;
    998 (*consdata)->glbminactivityneghuge = -1;
    999 (*consdata)->glbminactivityposhuge = -1;
    1000 (*consdata)->glbmaxactivityneghuge = -1;
    1001 (*consdata)->glbmaxactivityposhuge = -1;
    1002 (*consdata)->possignature = 0;
    1003 (*consdata)->negsignature = 0;
    1004 (*consdata)->validmaxabsval = FALSE;
    1005 (*consdata)->validminabsval = FALSE;
    1006 (*consdata)->validactivities = FALSE;
    1007 (*consdata)->validminact = FALSE;
    1008 (*consdata)->validmaxact = FALSE;
    1009 (*consdata)->validglbminact = FALSE;
    1010 (*consdata)->validglbmaxact = FALSE;
    1011 (*consdata)->boundstightened = 0;
    1012 (*consdata)->presolved = FALSE;
    1013 (*consdata)->removedfixings = FALSE;
    1014 (*consdata)->validsignature = FALSE;
    1015 (*consdata)->changed = TRUE;
    1016 (*consdata)->normalized = FALSE;
    1017 (*consdata)->upgradetried = FALSE;
    1018 (*consdata)->upgraded = FALSE;
    1019 (*consdata)->indexsorted = (nvars <= 1);
    1020 (*consdata)->merged = (nvars <= 1);
    1021 (*consdata)->cliquesadded = FALSE;
    1022 (*consdata)->implsadded = FALSE;
    1023 (*consdata)->coefsorted = FALSE;
    1024 (*consdata)->nbinvars = -1;
    1025 (*consdata)->varsdeleted = FALSE;
    1026 (*consdata)->rangedrowpropagated = 0;
    1027 (*consdata)->checkabsolute = FALSE;
    1028
    1029 if( SCIPisTransformed(scip) )
    1030 {
    1031 /* get transformed variables */
    1032 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
    1033 }
    1034
    1035 /* capture variables */
    1036 for( v = 0; v < (*consdata)->nvars; v++ )
    1037 {
    1038 /* likely implies a deleted variable */
    1039 if( (*consdata)->vars[v] == NULL )
    1040 {
    1041 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
    1042 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
    1043 SCIPfreeBlockMemory(scip, consdata);
    1044 return SCIP_INVALIDDATA;
    1045 }
    1046
    1047 assert(!SCIPisZero(scip, (*consdata)->vals[v]));
    1048 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
    1049 }
    1050
    1051 return SCIP_OKAY;
    1052}
    1053
    1054/** frees a linear constraint data */
    1055static
    1057 SCIP* scip, /**< SCIP data structure */
    1058 SCIP_CONSDATA** consdata /**< pointer to linear constraint data */
    1059 )
    1060{
    1061 int v;
    1062
    1063 assert(scip != NULL);
    1064 assert(consdata != NULL);
    1065 assert(*consdata != NULL);
    1066 assert((*consdata)->varssize >= 0);
    1067
    1068 /* release the row */
    1069 if( (*consdata)->row != NULL )
    1070 {
    1071 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row) );
    1072 }
    1073
    1074 /* release the nlrow */
    1075 if( (*consdata)->nlrow != NULL )
    1076 {
    1077 SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow) );
    1078 }
    1079
    1080 /* release variables */
    1081 for( v = 0; v < (*consdata)->nvars; v++ )
    1082 {
    1083 assert((*consdata)->vars[v] != NULL);
    1084 assert(!SCIPisZero(scip, (*consdata)->vals[v]));
    1085 SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
    1086 }
    1087
    1088 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
    1089 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
    1090 SCIPfreeBlockMemory(scip, consdata);
    1091
    1092 return SCIP_OKAY;
    1093}
    1094
    1095/** prints linear constraint in CIP format to file stream */
    1096static
    1098 SCIP* scip, /**< SCIP data structure */
    1099 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1100 FILE* file /**< output file (or NULL for standard output) */
    1101 )
    1102{
    1103 assert(scip != NULL);
    1104 assert(consdata != NULL);
    1105
    1106 /* print left hand side for ranged rows */
    1107 if( !SCIPisInfinity(scip, -consdata->lhs)
    1108 && !SCIPisInfinity(scip, consdata->rhs)
    1109 && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
    1110 SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
    1111
    1112 /* print coefficients and variables */
    1113 if( consdata->nvars == 0 )
    1114 SCIPinfoMessage(scip, file, "0");
    1115 else
    1116 {
    1117 /* post linear sum of the linear constraint */
    1118 SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
    1119 }
    1120
    1121 /* print right hand side */
    1122 if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
    1123 SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
    1124 else if( !SCIPisInfinity(scip, consdata->rhs) )
    1125 SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
    1126 else if( !SCIPisInfinity(scip, -consdata->lhs) )
    1127 SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
    1128 else
    1129 SCIPinfoMessage(scip, file, " [free]");
    1130
    1131 return SCIP_OKAY;
    1132}
    1133
    1134/** prints linear constraint and contained solution values of variables to file stream */
    1135static
    1137 SCIP* scip, /**< SCIP data structure */
    1138 SCIP_CONS* cons, /**< linear constraint */
    1139 SCIP_SOL* sol, /**< solution to print */
    1140 FILE* file /**< output file (or NULL for standard output) */
    1141 )
    1142{
    1143 SCIP_CONSDATA* consdata;
    1144
    1145 assert(scip != NULL);
    1146 assert(cons != NULL);
    1147
    1148 consdata = SCIPconsGetData(cons);
    1149 assert(consdata != NULL);
    1150
    1152
    1153 /* print left hand side for ranged rows */
    1154 if( !SCIPisInfinity(scip, -consdata->lhs)
    1155 && !SCIPisInfinity(scip, consdata->rhs)
    1156 && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
    1157 SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
    1158
    1159 /* print coefficients and variables */
    1160 if( consdata->nvars == 0 )
    1161 SCIPinfoMessage(scip, file, "0");
    1162 else
    1163 {
    1164 int v;
    1165
    1166 /* post linear sum of the linear constraint */
    1167 for( v = 0; v < consdata->nvars; ++v )
    1168 {
    1169 if( consdata->vals != NULL )
    1170 {
    1171 if( consdata->vals[v] == 1.0 )
    1172 {
    1173 if( v > 0 )
    1174 SCIPinfoMessage(scip, file, " +");
    1175 }
    1176 else if( consdata->vals[v] == -1.0 )
    1177 SCIPinfoMessage(scip, file, " -");
    1178 else
    1179 SCIPinfoMessage(scip, file, " %+.9g", consdata->vals[v]);
    1180 }
    1181 else if( consdata->nvars > 0 )
    1182 SCIPinfoMessage(scip, file, " +");
    1183
    1184 /* print variable name */
    1185 SCIP_CALL( SCIPwriteVarName(scip, file, consdata->vars[v], TRUE) );
    1186
    1187 SCIPinfoMessage(scip, file, " (%+.9g)", SCIPgetSolVal(scip, sol, consdata->vars[v]));
    1188 }
    1189 }
    1190
    1191 /* print right hand side */
    1192 if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
    1193 SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
    1194 else if( !SCIPisInfinity(scip, consdata->rhs) )
    1195 SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
    1196 else if( !SCIPisInfinity(scip, -consdata->lhs) )
    1197 SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
    1198 else
    1199 SCIPinfoMessage(scip, file, " [free]");
    1200
    1201 SCIPinfoMessage(scip, file, ";\n");
    1202
    1203 return SCIP_OKAY;
    1204}
    1205
    1206/** invalidates activity bounds, such that they are recalculated in next get */
    1207static
    1209 SCIP_CONSDATA* consdata /**< linear constraint */
    1210 )
    1211{
    1212 assert(consdata != NULL);
    1213
    1214 consdata->validactivities = FALSE;
    1215 consdata->validminact = FALSE;
    1216 consdata->validmaxact = FALSE;
    1217 consdata->validglbminact = FALSE;
    1218 consdata->validglbmaxact = FALSE;
    1219 consdata->validmaxabsval = FALSE;
    1220 consdata->validminabsval = FALSE;
    1221 consdata->hasnonbinvalid = FALSE;
    1222 QUAD_ASSIGN(consdata->minactivity, SCIP_INVALID);
    1223 QUAD_ASSIGN(consdata->maxactivity, SCIP_INVALID);
    1224 consdata->lastminactivity = SCIP_INVALID;
    1225 consdata->lastmaxactivity = SCIP_INVALID;
    1226 consdata->maxabsval = SCIP_INVALID;
    1227 consdata->minabsval = SCIP_INVALID;
    1228 consdata->maxactdelta = SCIP_INVALID;
    1229 consdata->maxactdeltavar = NULL;
    1230 consdata->minactivityneginf = -1;
    1231 consdata->minactivityposinf = -1;
    1232 consdata->maxactivityneginf = -1;
    1233 consdata->maxactivityposinf = -1;
    1234 consdata->minactivityneghuge = -1;
    1235 consdata->minactivityposhuge = -1;
    1236 consdata->maxactivityneghuge = -1;
    1237 consdata->maxactivityposhuge = -1;
    1238 QUAD_ASSIGN(consdata->glbminactivity, SCIP_INVALID);
    1239 QUAD_ASSIGN(consdata->glbmaxactivity, SCIP_INVALID);
    1240 consdata->lastglbminactivity = SCIP_INVALID;
    1241 consdata->lastglbmaxactivity = SCIP_INVALID;
    1242 consdata->glbminactivityneginf = -1;
    1243 consdata->glbminactivityposinf = -1;
    1244 consdata->glbmaxactivityneginf = -1;
    1245 consdata->glbmaxactivityposinf = -1;
    1246 consdata->glbminactivityneghuge = -1;
    1247 consdata->glbminactivityposhuge = -1;
    1248 consdata->glbmaxactivityneghuge = -1;
    1249 consdata->glbmaxactivityposhuge = -1;
    1250}
    1251
    1252/** compute the pseudo activity of a constraint */
    1253static
    1255 SCIP* scip, /**< SCIP data structure */
    1256 SCIP_CONSDATA* consdata /**< linear constraint data */
    1257 )
    1258{
    1259 int i;
    1260 int pseudoactivityposinf;
    1261 int pseudoactivityneginf;
    1262 SCIP_Real pseudoactivity;
    1264 SCIP_Real val;
    1265
    1266 pseudoactivity = 0;
    1267 pseudoactivityposinf = 0;
    1268 pseudoactivityneginf = 0;
    1269
    1270 for( i = consdata->nvars - 1; i >= 0; --i )
    1271 {
    1272 bound = SCIPvarGetBestBoundLocal(consdata->vars[i]);
    1273 val = consdata->vals[i];
    1274 assert(!SCIPisZero(scip, val));
    1275
    1276 if( SCIPisInfinity(scip, -bound) )
    1277 {
    1278 if( val < 0.0 )
    1279 ++pseudoactivityposinf;
    1280 else
    1281 ++pseudoactivityneginf;
    1282 }
    1283 else if( SCIPisInfinity(scip, bound) )
    1284 {
    1285 if( val < 0.0 )
    1286 ++pseudoactivityneginf;
    1287 else
    1288 ++pseudoactivityposinf;
    1289 }
    1290 else
    1291 pseudoactivity += val * bound;
    1292 }
    1293
    1294 /* invalidate pseudo activity for contradicting contributions */
    1295 if( pseudoactivityneginf > 0 && pseudoactivityposinf > 0 )
    1296 return SCIP_INVALID;
    1297 else if( pseudoactivityneginf > 0 )
    1298 return -SCIPinfinity(scip);
    1299 else if( pseudoactivityposinf > 0 )
    1300 return SCIPinfinity(scip);
    1301
    1302 return pseudoactivity;
    1303}
    1304
    1305/** recompute the minactivity of a constraint */
    1306static
    1308 SCIP* scip, /**< SCIP data structure */
    1309 SCIP_CONSDATA* consdata /**< linear constraint data */
    1310 )
    1311{
    1312 int i;
    1314
    1315 QUAD_ASSIGN(consdata->minactivity, 0.0);
    1316
    1317 for( i = consdata->nvars - 1; i >= 0; --i )
    1318 {
    1319 bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
    1321 && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
    1322 SCIPquadprecSumQD(consdata->minactivity, consdata->minactivity, consdata->vals[i] * bound);
    1323 }
    1324
    1325 /* the activity was just computed from scratch and is valid now */
    1326 consdata->validminact = TRUE;
    1327
    1328 /* the activity was just computed from scratch, mark it to be reliable */
    1329 consdata->lastminactivity = QUAD_TO_DBL(consdata->minactivity);
    1330}
    1331
    1332/** recompute the maxactivity of a constraint */
    1333static
    1335 SCIP* scip, /**< SCIP data structure */
    1336 SCIP_CONSDATA* consdata /**< linear constraint data */
    1337 )
    1338{
    1339 int i;
    1341
    1342 QUAD_ASSIGN(consdata->maxactivity, 0.0);
    1343
    1344 for( i = consdata->nvars - 1; i >= 0; --i )
    1345 {
    1346 bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbLocal(consdata->vars[i]) : SCIPvarGetLbLocal(consdata->vars[i]);
    1348 && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
    1349 SCIPquadprecSumQD(consdata->maxactivity, consdata->maxactivity, consdata->vals[i] * bound);
    1350 }
    1351
    1352 /* the activity was just computed from scratch and is valid now */
    1353 consdata->validmaxact = TRUE;
    1354
    1355 /* the activity was just computed from scratch, mark it to be reliable */
    1356 consdata->lastmaxactivity = QUAD_TO_DBL(consdata->maxactivity);
    1357}
    1358
    1359/** recompute the global minactivity of a constraint */
    1360static
    1362 SCIP* scip, /**< SCIP data structure */
    1363 SCIP_CONSDATA* consdata /**< linear constraint data */
    1364 )
    1365{
    1366 int i;
    1368
    1369 QUAD_ASSIGN(consdata->glbminactivity, 0.0);
    1370
    1371 for( i = consdata->nvars - 1; i >= 0; --i )
    1372 {
    1373 bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbGlobal(consdata->vars[i]) : SCIPvarGetUbGlobal(consdata->vars[i]);
    1375 && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
    1376 SCIPquadprecSumQD(consdata->glbminactivity, consdata->glbminactivity, consdata->vals[i] * bound);
    1377 }
    1378
    1379 /* the activity was just computed from scratch and is valid now */
    1380 consdata->validglbminact = TRUE;
    1381
    1382 /* the activity was just computed from scratch, mark it to be reliable */
    1383 consdata->lastglbminactivity = QUAD_TO_DBL(consdata->glbminactivity);
    1384}
    1385
    1386/** recompute the global maxactivity of a constraint */
    1387static
    1389 SCIP* scip, /**< SCIP data structure */
    1390 SCIP_CONSDATA* consdata /**< linear constraint data */
    1391 )
    1392{
    1393 int i;
    1395
    1396 QUAD_ASSIGN(consdata->glbmaxactivity, 0.0);
    1397
    1398 for( i = consdata->nvars - 1; i >= 0; --i )
    1399 {
    1400 bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbGlobal(consdata->vars[i]) : SCIPvarGetLbGlobal(consdata->vars[i]);
    1402 && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
    1403 SCIPquadprecSumQD(consdata->glbmaxactivity, consdata->glbmaxactivity, consdata->vals[i] * bound);
    1404 }
    1405
    1406 /* the activity was just computed from scratch and is valid now */
    1407 consdata->validglbmaxact = TRUE;
    1408
    1409 /* the activity was just computed from scratch, mark it to be reliable */
    1410 consdata->lastglbmaxactivity = QUAD_TO_DBL(consdata->glbmaxactivity);
    1411}
    1412
    1413/** calculates maximum absolute value of coefficients */
    1414static
    1416 SCIP_CONSDATA* consdata /**< linear constraint data */
    1417 )
    1418{
    1419 SCIP_Real absval;
    1420 int i;
    1421
    1422 assert(consdata != NULL);
    1423 assert(!consdata->validmaxabsval);
    1424 assert(consdata->maxabsval >= SCIP_INVALID);
    1425
    1426 consdata->validmaxabsval = TRUE;
    1427 consdata->maxabsval = 0.0;
    1428 for( i = 0; i < consdata->nvars; ++i )
    1429 {
    1430 absval = consdata->vals[i];
    1431 absval = REALABS(absval);
    1432 if( absval > consdata->maxabsval )
    1433 consdata->maxabsval = absval;
    1434 }
    1435}
    1436
    1437/** calculates minimum absolute value of coefficients */
    1438static
    1440 SCIP_CONSDATA* consdata /**< linear constraint data */
    1441 )
    1442{
    1443 SCIP_Real absval;
    1444 int i;
    1445
    1446 assert(consdata != NULL);
    1447 assert(!consdata->validminabsval);
    1448 assert(consdata->minabsval >= SCIP_INVALID);
    1449
    1450 consdata->validminabsval = TRUE;
    1451
    1452 if( consdata->nvars > 0 )
    1453 consdata->minabsval = REALABS(consdata->vals[0]);
    1454 else
    1455 consdata->minabsval = 0.0;
    1456
    1457 for( i = 1; i < consdata->nvars; ++i )
    1458 {
    1459 absval = consdata->vals[i];
    1460 absval = REALABS(absval);
    1461 if( absval < consdata->minabsval )
    1462 consdata->minabsval = absval;
    1463 }
    1464}
    1465
    1466/** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
    1467static
    1469 SCIP_CONSDATA* consdata /**< linear constraint data */
    1470 )
    1471{
    1472 int v;
    1473
    1474 assert(!consdata->hasnonbinvalid);
    1475 consdata->hasnonbinvar = FALSE;
    1476 consdata->hascontvar = FALSE;
    1477
    1478 for( v = consdata->nvars - 1; v >= 0; --v )
    1479 {
    1480 if( !SCIPvarIsBinary(consdata->vars[v]) )
    1481 {
    1482 consdata->hasnonbinvar = TRUE;
    1483
    1484 if( !SCIPvarIsIntegral(consdata->vars[v]) )
    1485 {
    1486 consdata->hascontvar = TRUE;
    1487 break;
    1488 }
    1489 }
    1490 }
    1491 assert(consdata->hascontvar || v < 0);
    1492
    1493 consdata->hasnonbinvalid = TRUE;
    1494}
    1495
    1496
    1497#ifdef CHECKMAXACTDELTA
    1498/** checks that the stored maximal activity delta (if not invalid) is correct */
    1499static
    1501 SCIP* scip, /**< SCIP data structure */
    1502 SCIP_CONSDATA* consdata /**< linear constraint data */
    1503 )
    1504{
    1505 if( consdata->maxactdelta != SCIP_INVALID )
    1506 {
    1507 SCIP_Real maxactdelta = 0.0;
    1508 SCIP_Real domain;
    1509 SCIP_Real delta;
    1510 SCIP_Real lb;
    1511 SCIP_Real ub;
    1512 int v;
    1513
    1514 for( v = consdata->nvars - 1; v >= 0; --v )
    1515 {
    1516 lb = SCIPvarGetLbLocal(consdata->vars[v]);
    1517 ub = SCIPvarGetUbLocal(consdata->vars[v]);
    1518
    1519 if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
    1520 {
    1521 maxactdelta = SCIPinfinity(scip);
    1522 break;
    1523 }
    1524
    1525 domain = ub - lb;
    1526 delta = REALABS(consdata->vals[v]) * domain;
    1527
    1528 if( delta > maxactdelta )
    1529 {
    1530 maxactdelta = delta;
    1531 }
    1532 }
    1533 assert(SCIPisFeasEQ(scip, maxactdelta, consdata->maxactdelta));
    1534 }
    1535}
    1536#else
    1537#define checkMaxActivityDelta(scip, consdata) /**/
    1538#endif
    1539
    1540/** recompute maximal activity contribution for a single variable */
    1541static
    1543 SCIP* scip, /**< SCIP data structure */
    1544 SCIP_CONSDATA* consdata /**< linear constraint data */
    1545 )
    1546{
    1547 SCIP_Real delta;
    1548 int v;
    1549
    1550 consdata->maxactdelta = 0.0;
    1551
    1552 if( !consdata->hasnonbinvalid )
    1553 consdataCheckNonbinvar(consdata);
    1554
    1555 /* easy case, the problem consists only of binary variables */
    1556 if( !consdata->hasnonbinvar )
    1557 {
    1558 for( v = consdata->nvars - 1; v >= 0; --v )
    1559 {
    1560 if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
    1561 {
    1562 delta = REALABS(consdata->vals[v]);
    1563
    1564 if( delta > consdata->maxactdelta )
    1565 {
    1566 consdata->maxactdelta = delta;
    1567 consdata->maxactdeltavar = consdata->vars[v];
    1568 }
    1569 }
    1570 }
    1571 return;
    1572 }
    1573
    1574 for( v = consdata->nvars - 1; v >= 0; --v )
    1575 {
    1576 SCIP_Real domain;
    1577 SCIP_Real lb;
    1578 SCIP_Real ub;
    1579
    1580 lb = SCIPvarGetLbLocal(consdata->vars[v]);
    1581 ub = SCIPvarGetUbLocal(consdata->vars[v]);
    1582
    1583 if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
    1584 {
    1585 consdata->maxactdelta = SCIPinfinity(scip);
    1586 consdata->maxactdeltavar = consdata->vars[v];
    1587 break;
    1588 }
    1589
    1590 domain = ub - lb;
    1591 delta = REALABS(consdata->vals[v]) * domain;
    1592
    1593 if( delta > consdata->maxactdelta )
    1594 {
    1595 consdata->maxactdelta = delta;
    1596 consdata->maxactdeltavar = consdata->vars[v];
    1597 }
    1598 }
    1599}
    1600
    1601
    1602/** updates activities for a change in a bound */
    1603static
    1605 SCIP* scip, /**< SCIP data structure */
    1606 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1607 SCIP_VAR* var, /**< variable that has been changed; can be NULL for global bound changes */
    1608 SCIP_Real oldbound, /**< old bound of variable */
    1609 SCIP_Real newbound, /**< new bound of variable */
    1610 SCIP_Real val, /**< coefficient of constraint entry */
    1611 SCIP_BOUNDTYPE boundtype, /**< type of the bound change */
    1612 SCIP_Bool global, /**< is it a global or a local bound change? */
    1613 SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
    1614 )
    1615{
    1616 QUAD_MEMBER(SCIP_Real* activity);
    1617 QUAD_MEMBER(SCIP_Real delta);
    1618 SCIP_Real* lastactivity;
    1619 int* activityposinf;
    1620 int* activityneginf;
    1621 int* activityposhuge;
    1622 int* activityneghuge;
    1623 SCIP_Real oldcontribution;
    1624 SCIP_Real newcontribution;
    1625 SCIP_Bool validact;
    1626 SCIP_Bool finitenewbound;
    1627 SCIP_Bool hugevalnewcont;
    1628
    1629 assert(scip != NULL);
    1630 assert(consdata != NULL);
    1631 assert(global || (var != NULL));
    1632 assert(consdata->validactivities);
    1633 assert(QUAD_TO_DBL(consdata->minactivity) < SCIP_INVALID);
    1634 assert(QUAD_TO_DBL(consdata->maxactivity) < SCIP_INVALID);
    1635 assert(consdata->lastminactivity < SCIP_INVALID);
    1636 assert(consdata->lastmaxactivity < SCIP_INVALID);
    1637 assert(consdata->minactivityneginf >= 0);
    1638 assert(consdata->minactivityposinf >= 0);
    1639 assert(consdata->maxactivityneginf >= 0);
    1640 assert(consdata->maxactivityposinf >= 0);
    1641 assert(consdata->minactivityneghuge >= 0);
    1642 assert(consdata->minactivityposhuge >= 0);
    1643 assert(consdata->maxactivityneghuge >= 0);
    1644 assert(consdata->maxactivityposhuge >= 0);
    1645 assert(QUAD_TO_DBL(consdata->glbminactivity) < SCIP_INVALID);
    1646 assert(QUAD_TO_DBL(consdata->glbmaxactivity) < SCIP_INVALID);
    1647 assert(consdata->lastglbminactivity < SCIP_INVALID);
    1648 assert(consdata->lastglbmaxactivity < SCIP_INVALID);
    1649 assert(consdata->glbminactivityneginf >= 0);
    1650 assert(consdata->glbminactivityposinf >= 0);
    1651 assert(consdata->glbmaxactivityneginf >= 0);
    1652 assert(consdata->glbmaxactivityposinf >= 0);
    1653 assert(consdata->glbminactivityneghuge >= 0);
    1654 assert(consdata->glbminactivityposhuge >= 0);
    1655 assert(consdata->glbmaxactivityneghuge >= 0);
    1656 assert(consdata->glbmaxactivityposhuge >= 0);
    1657
    1658 QUAD_ASSIGN(delta, 0.0);
    1659
    1660 /* we are updating global activities */
    1661 if( global )
    1662 {
    1663 /* depending on the boundtype and the coefficient, we choose the activity to be updated:
    1664 * lower bound + pos. coef: update minactivity
    1665 * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
    1666 * upper bound + pos. coef: update maxactivity
    1667 * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
    1668 */
    1669 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    1670 {
    1671 if( val > 0.0 )
    1672 {
    1673 QUAD_ASSIGN_Q(activity, &consdata->glbminactivity);
    1674 lastactivity = &(consdata->lastglbminactivity);
    1675 activityposinf = &(consdata->glbminactivityposinf);
    1676 activityneginf = &(consdata->glbminactivityneginf);
    1677 activityposhuge = &(consdata->glbminactivityposhuge);
    1678 activityneghuge = &(consdata->glbminactivityneghuge);
    1679 validact = consdata->validglbminact;
    1680 }
    1681 else
    1682 {
    1683 QUAD_ASSIGN_Q(activity, &consdata->glbmaxactivity);
    1684 lastactivity = &(consdata->lastglbmaxactivity);
    1685 activityposinf = &(consdata->glbmaxactivityneginf);
    1686 activityneginf = &(consdata->glbmaxactivityposinf);
    1687 activityposhuge = &(consdata->glbmaxactivityposhuge);
    1688 activityneghuge = &(consdata->glbmaxactivityneghuge);
    1689 validact = consdata->validglbmaxact;
    1690 }
    1691 }
    1692 else
    1693 {
    1694 if( val > 0.0 )
    1695 {
    1696 QUAD_ASSIGN_Q(activity, &consdata->glbmaxactivity);
    1697 lastactivity = &(consdata->lastglbmaxactivity);
    1698 activityposinf = &(consdata->glbmaxactivityposinf);
    1699 activityneginf = &(consdata->glbmaxactivityneginf);
    1700 activityposhuge = &(consdata->glbmaxactivityposhuge);
    1701 activityneghuge = &(consdata->glbmaxactivityneghuge);
    1702 validact = consdata->validglbmaxact;
    1703 }
    1704 else
    1705 {
    1706 QUAD_ASSIGN_Q(activity, &consdata->glbminactivity);
    1707 lastactivity = &(consdata->lastglbminactivity);
    1708 activityposinf = &(consdata->glbminactivityneginf);
    1709 activityneginf = &(consdata->glbminactivityposinf);
    1710 activityposhuge = &(consdata->glbminactivityposhuge);
    1711 activityneghuge = &(consdata->glbminactivityneghuge);
    1712 validact = consdata->validglbminact;
    1713 }
    1714 }
    1715 }
    1716 /* we are updating local activities */
    1717 else
    1718 {
    1719 /* depending on the boundtype and the coefficient, we choose the activity to be updated:
    1720 * lower bound + pos. coef: update minactivity
    1721 * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
    1722 * upper bound + pos. coef: update maxactivity
    1723 * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
    1724 */
    1725 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    1726 {
    1727 if( val > 0.0 )
    1728 {
    1729 QUAD_ASSIGN_Q(activity, &consdata->minactivity);
    1730 lastactivity = &(consdata->lastminactivity);
    1731 activityposinf = &(consdata->minactivityposinf);
    1732 activityneginf = &(consdata->minactivityneginf);
    1733 activityposhuge = &(consdata->minactivityposhuge);
    1734 activityneghuge = &(consdata->minactivityneghuge);
    1735 validact = consdata->validminact;
    1736 }
    1737 else
    1738 {
    1739 QUAD_ASSIGN_Q(activity, &consdata->maxactivity);
    1740 lastactivity = &(consdata->lastmaxactivity);
    1741 activityposinf = &(consdata->maxactivityneginf);
    1742 activityneginf = &(consdata->maxactivityposinf);
    1743 activityposhuge = &(consdata->maxactivityposhuge);
    1744 activityneghuge = &(consdata->maxactivityneghuge);
    1745 validact = consdata->validmaxact;
    1746 }
    1747 }
    1748 else
    1749 {
    1750 if( val > 0.0 )
    1751 {
    1752 QUAD_ASSIGN_Q(activity, &consdata->maxactivity);
    1753 lastactivity = &(consdata->lastmaxactivity);
    1754 activityposinf = &(consdata->maxactivityposinf);
    1755 activityneginf = &(consdata->maxactivityneginf);
    1756 activityposhuge = &(consdata->maxactivityposhuge);
    1757 activityneghuge = &(consdata->maxactivityneghuge);
    1758 validact = consdata->validmaxact;
    1759 }
    1760 else
    1761 {
    1762 QUAD_ASSIGN_Q(activity, &consdata->minactivity);
    1763 lastactivity = &(consdata->lastminactivity);
    1764 activityposinf = &(consdata->minactivityneginf);
    1765 activityneginf = &(consdata->minactivityposinf);
    1766 activityposhuge = &(consdata->minactivityposhuge);
    1767 activityneghuge = &(consdata->minactivityneghuge);
    1768 validact = consdata->validminact;
    1769 }
    1770 }
    1771 }
    1772
    1773 oldcontribution = val * oldbound;
    1774 newcontribution = val * newbound;
    1775 hugevalnewcont = SCIPisHugeValue(scip, REALABS(newcontribution));
    1776 finitenewbound = !SCIPisInfinity(scip, REALABS(newbound));
    1777
    1778 if( SCIPisInfinity(scip, REALABS(oldbound)) )
    1779 {
    1780 /* old bound was +infinity */
    1781 if( oldbound > 0.0 )
    1782 {
    1783 assert((*activityposinf) >= 1);
    1784
    1785 /* we only have to do something if the new bound is not again +infinity */
    1786 if( finitenewbound || newbound < 0.0 )
    1787 {
    1788 /* decrease the counter for positive infinite contributions */
    1789 (*activityposinf)--;
    1790
    1791 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
    1792 if( !finitenewbound && newbound < 0.0 )
    1793 (*activityneginf)++;
    1794 else if( hugevalnewcont )
    1795 {
    1796 /* if the contribution of this variable is too large, increase the counter for huge values */
    1797 if( newcontribution > 0.0 )
    1798 (*activityposhuge)++;
    1799 else
    1800 (*activityneghuge)++;
    1801 }
    1802 /* "normal case": just add the contribution to the activity */
    1803 else
    1804 QUAD_ASSIGN(delta, newcontribution);
    1805 }
    1806 }
    1807 /* old bound was -infinity */
    1808 else
    1809 {
    1810 assert(oldbound < 0.0);
    1811 assert((*activityneginf) >= 1);
    1812
    1813 /* we only have to do something ig the new bound is not again -infinity */
    1814 if( finitenewbound || newbound > 0.0 )
    1815 {
    1816 /* decrease the counter for negative infinite contributions */
    1817 (*activityneginf)--;
    1818
    1819 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
    1820 if( !finitenewbound && newbound > 0.0 )
    1821 (*activityposinf)++;
    1822 else if( hugevalnewcont )
    1823 {
    1824 /* if the contribution of this variable is too large, increase the counter for huge values */
    1825 if( newcontribution > 0.0 )
    1826 (*activityposhuge)++;
    1827 else
    1828 (*activityneghuge)++;
    1829 }
    1830 /* "normal case": just add the contribution to the activity */
    1831 else
    1832 QUAD_ASSIGN(delta, newcontribution);
    1833 }
    1834 }
    1835 }
    1836 else if( SCIPisHugeValue(scip, REALABS(oldcontribution)) )
    1837 {
    1838 /* old contribution was too large and positive */
    1839 if( oldcontribution > 0.0 )
    1840 {
    1841 assert((*activityposhuge) >= 1);
    1842
    1843 /* decrease the counter for huge positive contributions; it might be increased again later,
    1844 * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
    1845 */
    1846 (*activityposhuge)--;
    1847
    1848 if( !finitenewbound )
    1849 {
    1850 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
    1851 if( newbound > 0.0 )
    1852 (*activityposinf)++;
    1853 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
    1854 else
    1855 (*activityneginf)++;
    1856 }
    1857 else if( hugevalnewcont )
    1858 {
    1859 /* if the contribution of this variable is too large and positive, increase the corresponding counter */
    1860 if( newcontribution > 0.0 )
    1861 (*activityposhuge)++;
    1862 /* if the contribution of this variable is too large and negative, increase the corresponding counter */
    1863 else
    1864 (*activityneghuge)++;
    1865 }
    1866 /* "normal case": just add the contribution to the activity */
    1867 else
    1868 QUAD_ASSIGN(delta, newcontribution);
    1869 }
    1870 /* old contribution was too large and negative */
    1871 else
    1872 {
    1873 assert(oldcontribution < 0.0);
    1874 assert((*activityneghuge) >= 1);
    1875
    1876 /* decrease the counter for huge negative contributions; it might be increased again later,
    1877 * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
    1878 */
    1879 (*activityneghuge)--;
    1880
    1881 if( !finitenewbound )
    1882 {
    1883 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
    1884 if( newbound > 0.0 )
    1885 (*activityposinf)++;
    1886 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
    1887 else
    1888 (*activityneginf)++;
    1889 }
    1890 else if( hugevalnewcont )
    1891 {
    1892 /* if the contribution of this variable is too large and positive, increase the corresponding counter */
    1893 if( newcontribution > 0.0 )
    1894 (*activityposhuge)++;
    1895 /* if the contribution of this variable is too large and negative, increase the corresponding counter */
    1896 else
    1897 (*activityneghuge)++;
    1898 }
    1899 /* "normal case": just add the contribution to the activity */
    1900 else
    1901 QUAD_ASSIGN(delta, newcontribution);
    1902 }
    1903 }
    1904 /* old bound was finite and not too large */
    1905 else
    1906 {
    1907 if( !finitenewbound )
    1908 {
    1909 /* if the new bound is +infinity, the old contribution has to be subtracted
    1910 * and the counter for positive infinite contributions has to be increased
    1911 */
    1912 if( newbound > 0.0 )
    1913 {
    1914 (*activityposinf)++;
    1915 QUAD_ASSIGN(delta, -oldcontribution);
    1916 }
    1917 /* if the new bound is -infinity, the old contribution has to be subtracted
    1918 * and the counter for negative infinite contributions has to be increased
    1919 */
    1920 else
    1921 {
    1922 assert(newbound < 0.0 );
    1923
    1924 (*activityneginf)++;
    1925 QUAD_ASSIGN(delta, -oldcontribution);
    1926 }
    1927 }
    1928 /* if the contribution of this variable is too large, increase the counter for huge values */
    1929 else if( hugevalnewcont )
    1930 {
    1931 if( newcontribution > 0.0 )
    1932 {
    1933 (*activityposhuge)++;
    1934 QUAD_ASSIGN(delta, -oldcontribution);
    1935 }
    1936 else
    1937 {
    1938 (*activityneghuge)++;
    1939 QUAD_ASSIGN(delta, -oldcontribution);
    1940 }
    1941 }
    1942 /* "normal case": just update the activity */
    1943 else
    1944 {
    1945 QUAD_ASSIGN(delta, newcontribution);
    1946 SCIPquadprecSumQD(delta, delta, -oldcontribution);
    1947 }
    1948 }
    1949
    1950 /* update the activity, if the current value is valid and there was a change in the finite part */
    1951 if( validact && (QUAD_TO_DBL(delta) != 0.0) )
    1952 {
    1953 SCIP_Real curractivity;
    1954
    1955 /* if the absolute value of the activity is increased, this is regarded as reliable,
    1956 * otherwise, we check whether we can still trust the updated value
    1957 */
    1958 SCIPquadprecSumQD(*activity, *activity, QUAD_TO_DBL(delta));
    1959
    1960 curractivity = QUAD_TO_DBL(*activity);
    1961 assert(!SCIPisInfinity(scip, -curractivity) && !SCIPisInfinity(scip, curractivity));
    1962
    1963 if( REALABS((*lastactivity)) < REALABS(curractivity) )
    1964 {
    1965 (*lastactivity) = curractivity;
    1966 }
    1967 else
    1968 {
    1969 if( checkreliability && SCIPisUpdateUnreliable(scip, curractivity, (*lastactivity)) )
    1970 {
    1971 SCIPdebugMsg(scip, "%s activity of linear constraint unreliable after update: %16.9g\n",
    1972 (global ? "global " : ""), curractivity);
    1973
    1974 /* mark the activity that was just changed and is not reliable anymore to be invalid */
    1975 if( global )
    1976 {
    1977 if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
    1978 consdata->validglbminact = FALSE;
    1979 else
    1980 consdata->validglbmaxact = FALSE;
    1981 }
    1982 else
    1983 {
    1984 if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
    1985 consdata->validminact = FALSE;
    1986 else
    1987 consdata->validmaxact = FALSE;
    1988 }
    1989 }
    1990 }
    1991 }
    1992}
    1993
    1994/** updates minimum and maximum activity for a change in lower bound */
    1995static
    1997 SCIP* scip, /**< SCIP data structure */
    1998 SCIP_CONSDATA* consdata, /**< linear constraint data */
    1999 SCIP_VAR* var, /**< variable that has been changed */
    2000 SCIP_Real oldlb, /**< old lower bound of variable */
    2001 SCIP_Real newlb, /**< new lower bound of variable */
    2002 SCIP_Real val, /**< coefficient of constraint entry */
    2003 SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
    2004 )
    2005{
    2006 assert(scip != NULL);
    2007 assert(consdata != NULL);
    2008 assert(var != NULL);
    2009
    2010 if( consdata->validactivities )
    2011 {
    2012 consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE, checkreliability);
    2013
    2014 assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->minactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->minactivity)));
    2015 assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->maxactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->maxactivity)));
    2016 }
    2017}
    2018
    2019/** updates minimum and maximum activity for a change in upper bound */
    2020static
    2022 SCIP* scip, /**< SCIP data structure */
    2023 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2024 SCIP_VAR* var, /**< variable that has been changed */
    2025 SCIP_Real oldub, /**< old upper bound of variable */
    2026 SCIP_Real newub, /**< new upper bound of variable */
    2027 SCIP_Real val, /**< coefficient of constraint entry */
    2028 SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
    2029 )
    2030{
    2031 assert(scip != NULL);
    2032 assert(consdata != NULL);
    2033 assert(var != NULL);
    2034
    2035 if( consdata->validactivities )
    2036 {
    2037 consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE, checkreliability);
    2038
    2039 assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->minactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->minactivity)));
    2040 assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->maxactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->maxactivity)));
    2041 }
    2042}
    2043
    2044/** updates minimum and maximum global activity for a change in the global lower bound */
    2045static
    2047 SCIP* scip, /**< SCIP data structure */
    2048 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2049 SCIP_Real oldlb, /**< old lower bound of variable */
    2050 SCIP_Real newlb, /**< new lower bound of variable */
    2051 SCIP_Real val, /**< coefficient of constraint entry */
    2052 SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
    2053 )
    2054{
    2055 assert(scip != NULL);
    2056 assert(consdata != NULL);
    2057
    2058 if( consdata->validactivities )
    2059 {
    2060 consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE, checkreliability);
    2061
    2062 assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->glbminactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->glbminactivity)));
    2063 assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->glbmaxactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->glbmaxactivity)));
    2064 }
    2065}
    2066
    2067/** updates minimum and maximum global activity for a change in global upper bound */
    2068static
    2070 SCIP* scip, /**< SCIP data structure */
    2071 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2072 SCIP_Real oldub, /**< old upper bound of variable */
    2073 SCIP_Real newub, /**< new upper bound of variable */
    2074 SCIP_Real val, /**< coefficient of constraint entry */
    2075 SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
    2076 )
    2077{
    2078 assert(scip != NULL);
    2079 assert(consdata != NULL);
    2080
    2081 if( consdata->validactivities )
    2082 {
    2083 consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE, checkreliability);
    2084
    2085 assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->glbminactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->glbminactivity)));
    2086 assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->glbmaxactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->glbmaxactivity)));
    2087 }
    2088}
    2089
    2090/** updates minimum and maximum activity and maximum absolute value for coefficient addition */
    2091static
    2093 SCIP* scip, /**< SCIP data structure */
    2094 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2095 SCIP_VAR* var, /**< variable of constraint entry */
    2096 SCIP_Real val, /**< coefficient of constraint entry */
    2097 SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
    2098 )
    2099{
    2100 assert(scip != NULL);
    2101 assert(consdata != NULL);
    2102 assert(var != NULL);
    2103 assert(!SCIPisZero(scip, val));
    2104
    2105 /* update maximum absolute value */
    2106 if( consdata->validmaxabsval )
    2107 {
    2108 SCIP_Real absval;
    2109
    2110 assert(consdata->maxabsval < SCIP_INVALID);
    2111
    2112 absval = REALABS(val);
    2113 consdata->maxabsval = MAX(consdata->maxabsval, absval);
    2114 }
    2115
    2116 /* update minimum absolute value */
    2117 if( consdata->validminabsval )
    2118 {
    2119 SCIP_Real absval;
    2120
    2121 assert(consdata->minabsval < SCIP_INVALID);
    2122
    2123 absval = REALABS(val);
    2124 consdata->minabsval = MIN(consdata->minabsval, absval);
    2125 }
    2126
    2127 /* update minimum and maximum activity */
    2128 if( consdata->validactivities )
    2129 {
    2130 assert(QUAD_TO_DBL(consdata->minactivity) < SCIP_INVALID);
    2131 assert(QUAD_TO_DBL(consdata->maxactivity) < SCIP_INVALID);
    2132 assert(QUAD_TO_DBL(consdata->glbminactivity) < SCIP_INVALID);
    2133 assert(QUAD_TO_DBL(consdata->glbmaxactivity) < SCIP_INVALID);
    2134
    2135 consdataUpdateActivitiesLb(scip, consdata, var, 0.0, SCIPvarGetLbLocal(var), val, checkreliability);
    2136 consdataUpdateActivitiesUb(scip, consdata, var, 0.0, SCIPvarGetUbLocal(var), val, checkreliability);
    2137 consdataUpdateActivitiesGlbLb(scip, consdata, 0.0, SCIPvarGetLbGlobal(var), val, checkreliability);
    2138 consdataUpdateActivitiesGlbUb(scip, consdata, 0.0, SCIPvarGetUbGlobal(var), val, checkreliability);
    2139 }
    2140
    2141 /* update maximum activity delta */
    2142 if( consdata->maxactdeltavar == NULL || !SCIPisInfinity(scip, consdata->maxactdelta) )
    2143 {
    2144 SCIP_Real lb = SCIPvarGetLbLocal(var);
    2145 SCIP_Real ub = SCIPvarGetUbLocal(var);
    2146
    2147 if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
    2148 {
    2149 consdata->maxactdelta = SCIPinfinity(scip);
    2150 consdata->maxactdeltavar = var;
    2151 }
    2152 else if( consdata->maxactdeltavar != NULL )
    2153 {
    2154 SCIP_Real domain = ub - lb;
    2155 SCIP_Real delta = REALABS(val) * domain;
    2156
    2157 if( delta > consdata->maxactdelta )
    2158 {
    2159 consdata->maxactdelta = delta;
    2160 consdata->maxactdeltavar = var;
    2161 }
    2162 }
    2163 }
    2164}
    2165
    2166/** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
    2167static
    2169 SCIP* scip, /**< SCIP data structure */
    2170 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2171 SCIP_VAR* var, /**< variable of constraint entry */
    2172 SCIP_Real val, /**< coefficient of constraint entry */
    2173 SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
    2174 )
    2175{
    2176 assert(scip != NULL);
    2177 assert(consdata != NULL);
    2178 assert(var != NULL);
    2179 assert(!SCIPisZero(scip, val));
    2180
    2181 /* invalidate maximum absolute value, if this coefficient was the maximum */
    2182 if( consdata->validmaxabsval )
    2183 {
    2184 SCIP_Real absval;
    2185
    2186 absval = REALABS(val);
    2187
    2188 if( SCIPisEQ(scip, absval, consdata->maxabsval) )
    2189 {
    2190 consdata->validmaxabsval = FALSE;
    2191 consdata->maxabsval = SCIP_INVALID;
    2192 }
    2193 }
    2194
    2195 /* invalidate minimum absolute value, if this coefficient was the minimum */
    2196 if( consdata->validminabsval )
    2197 {
    2198 SCIP_Real absval;
    2199
    2200 absval = REALABS(val);
    2201
    2202 if( SCIPisEQ(scip, absval, consdata->minabsval) )
    2203 {
    2204 consdata->validminabsval = FALSE;
    2205 consdata->minabsval = SCIP_INVALID;
    2206 }
    2207 }
    2208
    2209 /* update minimum and maximum activity */
    2210 if( consdata->validactivities )
    2211 {
    2212 assert(QUAD_TO_DBL(consdata->minactivity) < SCIP_INVALID);
    2213 assert(QUAD_TO_DBL(consdata->maxactivity) < SCIP_INVALID);
    2214 assert(QUAD_TO_DBL(consdata->glbminactivity) < SCIP_INVALID);
    2215 assert(QUAD_TO_DBL(consdata->glbmaxactivity) < SCIP_INVALID);
    2216
    2217 consdataUpdateActivitiesLb(scip, consdata, var, SCIPvarGetLbLocal(var), 0.0, val, checkreliability);
    2218 consdataUpdateActivitiesUb(scip, consdata, var, SCIPvarGetUbLocal(var), 0.0, val, checkreliability);
    2219 consdataUpdateActivitiesGlbLb(scip, consdata, SCIPvarGetLbGlobal(var), 0.0, val, checkreliability);
    2220 consdataUpdateActivitiesGlbUb(scip, consdata, SCIPvarGetUbGlobal(var), 0.0, val, checkreliability);
    2221 }
    2222
    2223 /* reset maximum activity delta so that it will be recalculated on the next real propagation */
    2224 if( consdata->maxactdeltavar == var )
    2225 {
    2226 consdata->maxactdelta = SCIP_INVALID;
    2227 consdata->maxactdeltavar = NULL;
    2228 }
    2229}
    2230
    2231/** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
    2232static
    2234 SCIP* scip, /**< SCIP data structure */
    2235 SCIP_CONSDATA* consdata, /**< linear constraint data */
    2236 SCIP_VAR* var, /**< variable of constraint entry */
    2237 SCIP_Real oldval, /**< old coefficient of constraint entry */
    2238 SCIP_Real newval, /**< new coefficient of constraint entry */
    2239 SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
    2240 )
    2241{
    2242 /* @todo do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
    2243 consdataUpdateDelCoef(scip, consdata, var, oldval, checkreliability);
    2244 consdataUpdateAddCoef(scip, consdata, var, newval, checkreliability);
    2245}
    2246
    2247/** returns the maximum absolute value of all coefficients in the constraint */
    2248static
    2250 SCIP_CONSDATA* consdata /**< linear constraint data */
    2251 )
    2252{
    2253 assert(consdata != NULL);
    2254
    2255 if( !consdata->validmaxabsval )
    2256 consdataCalcMaxAbsval(consdata);
    2257 assert(consdata->validmaxabsval);
    2258 assert(consdata->maxabsval < SCIP_INVALID);
    2259
    2260 return consdata->maxabsval;
    2261}
    2262
    2263/** returns the minimum absolute value of all coefficients in the constraint */
    2264static
    2266 SCIP_CONSDATA* consdata /**< linear constraint data */
    2267 )
    2268{
    2269 assert(consdata != NULL);
    2270
    2271 if( !consdata->validminabsval )
    2272 consdataCalcMinAbsval(consdata);
    2273 assert(consdata->validminabsval);
    2274 assert(consdata->minabsval < SCIP_INVALID);
    2275
    2276 return consdata->minabsval;
    2277}
    2278
    2279/** calculates minimum and maximum local and global activity for constraint from scratch;
    2280 * additionally recalculates maximum absolute value of coefficients
    2281 */
    2282static
    2284 SCIP* scip, /**< SCIP data structure */
    2285 SCIP_CONSDATA* consdata /**< linear constraint data */
    2286 )
    2287{
    2288 int i;
    2289
    2290 assert(scip != NULL);
    2291 assert(consdata != NULL);
    2292 assert(!consdata->validactivities);
    2293 assert(QUAD_TO_DBL(consdata->minactivity) >= SCIP_INVALID || consdata->validminact);
    2294 assert(QUAD_TO_DBL(consdata->maxactivity) >= SCIP_INVALID || consdata->validmaxact);
    2295 assert(QUAD_TO_DBL(consdata->glbminactivity) >= SCIP_INVALID || consdata->validglbminact);
    2296 assert(QUAD_TO_DBL(consdata->glbmaxactivity) >= SCIP_INVALID || consdata->validglbmaxact);
    2297
    2298 consdata->validmaxabsval = TRUE;
    2299 consdata->validminabsval = TRUE;
    2300 consdata->validactivities = TRUE;
    2301 consdata->validminact = TRUE;
    2302 consdata->validmaxact = TRUE;
    2303 consdata->validglbminact = TRUE;
    2304 consdata->validglbmaxact = TRUE;
    2305 consdata->maxabsval = 0.0;
    2306 consdata->minabsval = (consdata->nvars == 0 ? 0.0 : REALABS(consdata->vals[0]));
    2307 QUAD_ASSIGN(consdata->minactivity, 0.0);
    2308 QUAD_ASSIGN(consdata->maxactivity, 0.0);
    2309 consdata->lastminactivity = 0.0;
    2310 consdata->lastmaxactivity = 0.0;
    2311 consdata->minactivityneginf = 0;
    2312 consdata->minactivityposinf = 0;
    2313 consdata->maxactivityneginf = 0;
    2314 consdata->maxactivityposinf = 0;
    2315 consdata->minactivityneghuge = 0;
    2316 consdata->minactivityposhuge = 0;
    2317 consdata->maxactivityneghuge = 0;
    2318 consdata->maxactivityposhuge = 0;
    2319 QUAD_ASSIGN(consdata->glbminactivity, 0.0);
    2320 QUAD_ASSIGN(consdata->glbmaxactivity, 0.0);
    2321 consdata->lastglbminactivity = 0.0;
    2322 consdata->lastglbmaxactivity = 0.0;
    2323 consdata->glbminactivityneginf = 0;
    2324 consdata->glbminactivityposinf = 0;
    2325 consdata->glbmaxactivityneginf = 0;
    2326 consdata->glbmaxactivityposinf = 0;
    2327 consdata->glbminactivityneghuge = 0;
    2328 consdata->glbminactivityposhuge = 0;
    2329 consdata->glbmaxactivityneghuge = 0;
    2330 consdata->glbmaxactivityposhuge = 0;
    2331
    2332 for( i = 0; i < consdata->nvars; ++i )
    2333 consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], FALSE);
    2334
    2335 consdata->lastminactivity = QUAD_TO_DBL(consdata->minactivity);
    2336 consdata->lastmaxactivity = QUAD_TO_DBL(consdata->maxactivity);
    2337 consdata->lastglbminactivity = QUAD_TO_DBL(consdata->glbminactivity);
    2338 consdata->lastglbmaxactivity = QUAD_TO_DBL(consdata->glbmaxactivity);
    2339}
    2340
    2341/** gets minimal activity for constraint and given values of counters for infinite and huge contributions
    2342 * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
    2343 */
    2344static
    2346 SCIP* scip, /**< SCIP data structure */
    2347 SCIP_CONSDATA* consdata, /**< linear constraint */
    2348 int posinf, /**< number of coefficients contributing pos. infinite value */
    2349 int neginf, /**< number of coefficients contributing neg. infinite value */
    2350 int poshuge, /**< number of coefficients contributing huge pos. value */
    2351 int neghuge, /**< number of coefficients contributing huge neg. value */
    2352 SCIP_Real delta, /**< value to subtract from stored minactivity
    2353 * (contribution of the variable set to zero when getting residual activity) */
    2354 SCIP_Bool global, /**< should the global or local minimal activity be returned? */
    2355 SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
    2356 SCIP_Real* minactivity, /**< pointer to store the minimal activity */
    2357 SCIP_Bool* istight, /**< pointer to store whether activity bound is tight to variable bounds
    2358 * i.e. is the actual minactivity (otherwise a lower bound is provided) */
    2359 SCIP_Bool* issettoinfinity /**< pointer to store whether minactivity was set to infinity or calculated */
    2360 )
    2361{
    2362 assert(scip != NULL);
    2363 assert(consdata != NULL);
    2364 assert(posinf >= 0);
    2365 assert(neginf >= 0);
    2366 assert(poshuge >= 0);
    2367 assert(neghuge >= 0);
    2368 assert(minactivity != NULL);
    2369 assert(istight != NULL);
    2370 assert(issettoinfinity != NULL);
    2371
    2372 /* if we have neg. infinite contributions, the minactivity is -infty */
    2373 if( neginf > 0 )
    2374 {
    2375 *minactivity = -SCIPinfinity(scip);
    2376 *issettoinfinity = TRUE;
    2377 *istight = posinf == 0;
    2378 }
    2379 /* if we have pos. (and no neg.) infinite contributions, the minactivity is +infty */
    2380 else if( posinf > 0 )
    2381 {
    2382 *minactivity = SCIPinfinity(scip);
    2383 *issettoinfinity = TRUE;
    2384 *istight = TRUE;
    2385 }
    2386 /* if we have neg. huge contributions or do not need a good relaxation, we just return -infty as minactivity */
    2387 else if( neghuge > 0 || ( poshuge > 0 && !goodrelax ) )
    2388 {
    2389 *minactivity = -SCIPinfinity(scip);
    2390 *issettoinfinity = TRUE;
    2391 *istight = FALSE;
    2392 }
    2393 else
    2394 {
    2395 SCIP_Real QUAD(tmpactivity);
    2396
    2397 /* recompute minactivity if it is not valid */
    2398 if( global )
    2399 {
    2400 if( !consdata->validglbminact )
    2402 assert(consdata->validglbminact);
    2403
    2404 QUAD_ASSIGN_Q(tmpactivity, consdata->glbminactivity);
    2405 }
    2406 else
    2407 {
    2408 if( !consdata->validminact )
    2410 assert(consdata->validminact);
    2411
    2412 QUAD_ASSIGN_Q(tmpactivity, consdata->minactivity);
    2413 }
    2414
    2415 /* calculate residual minactivity */
    2416 SCIPquadprecSumQD(tmpactivity, tmpactivity, -delta);
    2417
    2418 /* we have no infinite and no neg. huge contributions, but pos. huge contributions; a feasible relaxation of the
    2419 * minactivity is given by adding the number of positive huge contributions times the huge value
    2420 */
    2421 if( poshuge > 0 )
    2422 {
    2423 SCIPquadprecSumQD(tmpactivity, tmpactivity, poshuge * SCIPgetHugeValue(scip));
    2424 *istight = FALSE;
    2425 }
    2426 /* all counters are zero, so the minactivity is tight */
    2427 else
    2428 *istight = TRUE;
    2429
    2430 /* round residual minactivity */
    2431 *minactivity = QUAD_TO_DBL(tmpactivity);
    2432 *issettoinfinity = FALSE;
    2433 }
    2434}
    2435
    2436/** gets maximal activity for constraint and given values of counters for infinite and huge contributions
    2437 * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
    2438 */
    2439static
    2441 SCIP* scip, /**< SCIP data structure */
    2442 SCIP_CONSDATA* consdata, /**< linear constraint */
    2443 int posinf, /**< number of coefficients contributing pos. infinite value */
    2444 int neginf, /**< number of coefficients contributing neg. infinite value */
    2445 int poshuge, /**< number of coefficients contributing huge pos. value */
    2446 int neghuge, /**< number of coefficients contributing huge neg. value */
    2447 SCIP_Real delta, /**< value to subtract from stored maxactivity
    2448 * (contribution of the variable set to zero when getting residual activity) */
    2449 SCIP_Bool global, /**< should the global or local maximal activity be returned? */
    2450 SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
    2451 SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
    2452 SCIP_Bool* istight, /**< pointer to store whether activity bound is tight to variable bounds
    2453 * i.e. is the actual maxactivity (otherwise an upper bound is provided) */
    2454 SCIP_Bool* issettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
    2455 )
    2456{
    2457 assert(scip != NULL);
    2458 assert(consdata != NULL);
    2459 assert(posinf >= 0);
    2460 assert(neginf >= 0);
    2461 assert(poshuge >= 0);
    2462 assert(neghuge >= 0);
    2463 assert(maxactivity != NULL);
    2464 assert(istight != NULL);
    2465 assert(issettoinfinity != NULL);
    2466
    2467 /* if we have pos. infinite contributions, the maxactivity is +infty */
    2468 if( posinf > 0 )
    2469 {
    2470 *maxactivity = SCIPinfinity(scip);
    2471 *issettoinfinity = TRUE;
    2472 *istight = neginf == 0;
    2473 }
    2474 /* if we have neg. (and no pos.) infinite contributions, the maxactivity is -infty */
    2475 else if( neginf > 0 )
    2476 {
    2477 *maxactivity = -SCIPinfinity(scip);
    2478 *issettoinfinity = TRUE;
    2479 *istight = TRUE;
    2480 }
    2481 /* if we have pos. huge contributions or do not need a good relaxation, we just return +infty as maxactivity */
    2482 else if( poshuge > 0 || ( neghuge > 0 && !goodrelax ) )
    2483 {
    2484 *maxactivity = SCIPinfinity(scip);
    2485 *issettoinfinity = TRUE;
    2486 *istight = FALSE;
    2487 }
    2488 else
    2489 {
    2490 SCIP_Real QUAD(tmpactivity);
    2491
    2492 /* recompute maxactivity if it is not valid */
    2493 if( global )
    2494 {
    2495 if( !consdata->validglbmaxact )
    2497 assert(consdata->validglbmaxact);
    2498
    2499 QUAD_ASSIGN_Q(tmpactivity, consdata->glbmaxactivity);
    2500 }
    2501 else
    2502 {
    2503 if( !consdata->validmaxact )
    2505 assert(consdata->validmaxact);
    2506
    2507 QUAD_ASSIGN_Q(tmpactivity, consdata->maxactivity);
    2508 }
    2509
    2510 /* calculate residual maxactivity */
    2511 SCIPquadprecSumQD(tmpactivity, tmpactivity, -delta);
    2512
    2513 /* we have no infinite and no pos. huge contributions, but neg. huge contributions; a feasible relaxation of the
    2514 * maxactivity is given by subtracting the number of negative huge contributions times the huge value
    2515 */
    2516 if( neghuge > 0 )
    2517 {
    2518 SCIPquadprecSumQD(tmpactivity, tmpactivity, -neghuge * SCIPgetHugeValue(scip));
    2519 *istight = FALSE;
    2520 }
    2521 /* all counters are zero, so the maxactivity is tight */
    2522 else
    2523 *istight = TRUE;
    2524
    2525 /* round residual maxactivity */
    2526 *maxactivity = QUAD_TO_DBL(tmpactivity);
    2527 *issettoinfinity = FALSE;
    2528 }
    2529}
    2530
    2531/** gets activity bounds for constraint */
    2532static
    2534 SCIP* scip, /**< SCIP data structure */
    2535 SCIP_CONSDATA* consdata, /**< linear constraint */
    2536 SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
    2537 * relaxed activities ignored, anyway? */
    2538 SCIP_Real* minactivity, /**< pointer to store the minimal activity */
    2539 SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
    2540 SCIP_Bool* ismintight, /**< pointer to store whether the minactivity bound is tight
    2541 * i.e. is the actual minactivity (otherwise a lower bound is provided) */
    2542 SCIP_Bool* ismaxtight, /**< pointer to store whether the maxactivity bound is tight
    2543 * i.e. is the actual maxactivity (otherwise an upper bound is provided) */
    2544 SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minactivity was set to infinity or calculated */
    2545 SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
    2546
    2547 )
    2548{
    2549 assert(scip != NULL);
    2550 assert(consdata != NULL);
    2551 assert(minactivity != NULL);
    2552 assert(maxactivity != NULL);
    2553 assert(isminsettoinfinity != NULL);
    2554 assert(ismaxsettoinfinity != NULL);
    2555
    2556 if( !consdata->validactivities )
    2557 {
    2558 consdataCalcActivities(scip, consdata);
    2559 assert(consdata->validminact);
    2560 assert(consdata->validmaxact);
    2561 }
    2562 assert(QUAD_TO_DBL(consdata->minactivity) < SCIP_INVALID);
    2563 assert(QUAD_TO_DBL(consdata->maxactivity) < SCIP_INVALID);
    2564 assert(consdata->minactivityneginf >= 0);
    2565 assert(consdata->minactivityposinf >= 0);
    2566 assert(consdata->maxactivityneginf >= 0);
    2567 assert(consdata->maxactivityposinf >= 0);
    2568
    2569 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2570 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2571 minactivity, ismintight, isminsettoinfinity);
    2572
    2573 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2574 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2575 maxactivity, ismaxtight, ismaxsettoinfinity);
    2576}
    2577
    2578/** calculates activity bounds for constraint after setting variable to zero */
    2579static
    2581 SCIP* scip, /**< SCIP data structure */
    2582 SCIP_CONSDATA* consdata, /**< linear constraint */
    2583 SCIP_VAR* cancelvar, /**< variable to calculate activity residual for */
    2584 SCIP_Real* resactivity, /**< pointer to store the residual activity */
    2585 SCIP_Bool isminresact, /**< should minimal or maximal residual activity be calculated? */
    2586 SCIP_Bool useglobalbounds /**< should global or local bounds be used? */
    2587 )
    2588{
    2589 SCIP_VAR* var;
    2590 SCIP_Real val;
    2591 SCIP_Real lb;
    2592 SCIP_Real ub;
    2593 int v;
    2594
    2595 assert(scip != NULL);
    2596 assert(consdata != NULL);
    2597 assert(cancelvar != NULL);
    2598 assert(resactivity != NULL);
    2599
    2600 *resactivity = 0.0;
    2601
    2602 for( v = 0; v < consdata->nvars; ++v )
    2603 {
    2604 var = consdata->vars[v];
    2605 assert(var != NULL);
    2606 if( var == cancelvar )
    2607 continue;
    2608
    2609 val = consdata->vals[v];
    2610
    2611 if( useglobalbounds )
    2612 {
    2613 lb = SCIPvarGetLbGlobal(var);
    2614 ub = SCIPvarGetUbGlobal(var);
    2615 }
    2616 else
    2617 {
    2618 lb = SCIPvarGetLbLocal(var);
    2619 ub = SCIPvarGetUbLocal(var);
    2620 }
    2621
    2622 assert(!SCIPisZero(scip, val));
    2623 assert(SCIPisLE(scip, lb, ub));
    2624
    2625 if( val > 0.0 )
    2626 {
    2627 if( isminresact )
    2628 {
    2629 assert(!SCIPisInfinity(scip, -lb));
    2630 assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
    2631 *resactivity += val*lb;
    2632 }
    2633 else
    2634 {
    2635 assert(!SCIPisInfinity(scip, ub));
    2636 assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
    2637 *resactivity += val*ub;
    2638 }
    2639 }
    2640 else
    2641 {
    2642 if( isminresact)
    2643 {
    2644 assert(!SCIPisInfinity(scip, ub));
    2645 assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
    2646 *resactivity += val*ub;
    2647 }
    2648 else
    2649 {
    2650 assert(!SCIPisInfinity(scip, -lb));
    2651 assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
    2652 *resactivity += val*lb;
    2653 }
    2654 }
    2655 }
    2656 assert(!SCIPisInfinity(scip, *resactivity) && !SCIPisInfinity(scip, -(*resactivity)));
    2657}
    2658
    2659/** gets activity bounds for constraint after setting variable to zero */
    2660static
    2662 SCIP* scip, /**< SCIP data structure */
    2663 SCIP_CONSDATA* consdata, /**< linear constraint */
    2664 SCIP_VAR* var, /**< variable to calculate activity residual for */
    2665 SCIP_Real val, /**< coefficient value of variable in linear constraint */
    2666 SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
    2667 * relaxed acticities ignored, anyway? */
    2668 SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity */
    2669 SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity */
    2670 SCIP_Bool* ismintight, /**< pointer to store whether the residual minactivity bound is tight
    2671 * i.e. is the actual residual minactivity (otherwise a lower bound is provided) */
    2672 SCIP_Bool* ismaxtight, /**< pointer to store whether the residual maxactivity bound is tight
    2673 * i.e. is the actual residual maxactivity (otherwise an upper bound is provided) */
    2674 SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
    2675 SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
    2676 )
    2677{
    2678 SCIP_Real minactbound;
    2679 SCIP_Real maxactbound;
    2680 SCIP_Real absval;
    2681
    2682 assert(scip != NULL);
    2683 assert(consdata != NULL);
    2684 assert(var != NULL);
    2685 assert(minresactivity != NULL);
    2686 assert(maxresactivity != NULL);
    2687 assert(ismintight != NULL);
    2688 assert(ismaxtight != NULL);
    2689 assert(isminsettoinfinity != NULL);
    2690 assert(ismaxsettoinfinity != NULL);
    2691
    2692 /* get activity bounds of linear constraint */
    2693 if( !consdata->validactivities )
    2694 {
    2695 consdataCalcActivities(scip, consdata);
    2696 assert(consdata->validminact);
    2697 assert(consdata->validmaxact);
    2698 }
    2699 assert(QUAD_TO_DBL(consdata->minactivity) < SCIP_INVALID);
    2700 assert(QUAD_TO_DBL(consdata->maxactivity) < SCIP_INVALID);
    2701 assert(consdata->minactivityneginf >= 0);
    2702 assert(consdata->minactivityposinf >= 0);
    2703 assert(consdata->maxactivityneginf >= 0);
    2704 assert(consdata->maxactivityposinf >= 0);
    2705 assert(consdata->minactivityneghuge >= 0);
    2706 assert(consdata->minactivityposhuge >= 0);
    2707 assert(consdata->maxactivityneghuge >= 0);
    2708 assert(consdata->maxactivityposhuge >= 0);
    2709
    2710 if( val > 0.0 )
    2711 {
    2712 minactbound = SCIPvarGetLbLocal(var);
    2713 maxactbound = SCIPvarGetUbLocal(var);
    2714 absval = val;
    2715 }
    2716 else
    2717 {
    2718 minactbound = -SCIPvarGetUbLocal(var);
    2719 maxactbound = -SCIPvarGetLbLocal(var);
    2720 absval = -val;
    2721 }
    2722
    2723 /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
    2724 * and contribution of variable set to zero that has to be subtracted from finite part of activity
    2725 */
    2726 if( SCIPisInfinity(scip, minactbound) )
    2727 {
    2728 assert(consdata->minactivityposinf >= 1);
    2729
    2730 getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
    2731 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2732 minresactivity, ismintight, isminsettoinfinity);
    2733 }
    2734 else if( SCIPisInfinity(scip, -minactbound) )
    2735 {
    2736 assert(consdata->minactivityneginf >= 1);
    2737
    2738 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
    2739 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2740 minresactivity, ismintight, isminsettoinfinity);
    2741 }
    2742 else if( SCIPisHugeValue(scip, minactbound * absval) )
    2743 {
    2744 assert(consdata->minactivityposhuge >= 1);
    2745
    2746 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2747 consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
    2748 minresactivity, ismintight, isminsettoinfinity);
    2749 }
    2750 else if( SCIPisHugeValue(scip, -minactbound * absval) )
    2751 {
    2752 assert(consdata->minactivityneghuge >= 1);
    2753
    2754 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2755 consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
    2756 minresactivity, ismintight, isminsettoinfinity);
    2757 }
    2758 else
    2759 {
    2760 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
    2761 consdata->minactivityposhuge, consdata->minactivityneghuge, absval * minactbound, FALSE, goodrelax,
    2762 minresactivity, ismintight, isminsettoinfinity);
    2763 }
    2764
    2765 /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
    2766 * and contribution of variable set to zero that has to be subtracted from finite part of activity
    2767 */
    2768 if( SCIPisInfinity(scip, -maxactbound) )
    2769 {
    2770 assert(consdata->maxactivityneginf >= 1);
    2771
    2772 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
    2773 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2774 maxresactivity, ismaxtight, ismaxsettoinfinity);
    2775 }
    2776 else if( SCIPisInfinity(scip, maxactbound) )
    2777 {
    2778 assert(consdata->maxactivityposinf >= 1);
    2779
    2780 getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
    2781 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2782 maxresactivity, ismaxtight, ismaxsettoinfinity);
    2783 }
    2784 else if( SCIPisHugeValue(scip, absval * maxactbound) )
    2785 {
    2786 assert(consdata->maxactivityposhuge >= 1);
    2787
    2788 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2789 consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
    2790 maxresactivity, ismaxtight, ismaxsettoinfinity);
    2791 }
    2792 else if( SCIPisHugeValue(scip, -absval * maxactbound) )
    2793 {
    2794 assert(consdata->maxactivityneghuge >= 1);
    2795
    2796 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2797 consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
    2798 maxresactivity, ismaxtight, ismaxsettoinfinity);
    2799 }
    2800 else
    2801 {
    2802 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
    2803 consdata->maxactivityposhuge, consdata->maxactivityneghuge, absval * maxactbound, FALSE, goodrelax,
    2804 maxresactivity, ismaxtight, ismaxsettoinfinity);
    2805 }
    2806}
    2807
    2808/** gets global activity bounds for constraint */
    2809static
    2811 SCIP* scip, /**< SCIP data structure */
    2812 SCIP_CONSDATA* consdata, /**< linear constraint */
    2813 SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
    2814 * relaxed acticities ignored, anyway? */
    2815 SCIP_Real* glbminactivity, /**< pointer to store the minimal activity, or NULL, if not needed */
    2816 SCIP_Real* glbmaxactivity, /**< pointer to store the maximal activity, or NULL, if not needed */
    2817 SCIP_Bool* ismintight, /**< pointer to store whether the minactivity bound is tight
    2818 * i.e. is the actual minactivity (otherwise a lower bound is provided) */
    2819 SCIP_Bool* ismaxtight, /**< pointer to store whether the maxactivity bound is tight
    2820 * i.e. is the actual maxactivity (otherwise an upper bound is provided) */
    2821 SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
    2822 SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
    2823 )
    2824{
    2825 assert(scip != NULL);
    2826 assert(consdata != NULL);
    2827 assert((glbminactivity != NULL && ismintight != NULL && isminsettoinfinity != NULL)
    2828 || (glbmaxactivity != NULL && ismaxtight != NULL && ismaxsettoinfinity != NULL));
    2829
    2830 if( !consdata->validactivities )
    2831 {
    2832 consdataCalcActivities(scip, consdata);
    2833 assert(consdata->validglbminact);
    2834 assert(consdata->validglbmaxact);
    2835 }
    2836 assert(QUAD_TO_DBL(consdata->glbminactivity) < SCIP_INVALID);
    2837 assert(QUAD_TO_DBL(consdata->glbmaxactivity) < SCIP_INVALID);
    2838 assert(consdata->glbminactivityneginf >= 0);
    2839 assert(consdata->glbminactivityposinf >= 0);
    2840 assert(consdata->glbmaxactivityneginf >= 0);
    2841 assert(consdata->glbmaxactivityposinf >= 0);
    2842 assert(consdata->glbminactivityneghuge >= 0);
    2843 assert(consdata->glbminactivityposhuge >= 0);
    2844 assert(consdata->glbmaxactivityneghuge >= 0);
    2845 assert(consdata->glbmaxactivityposhuge >= 0);
    2846
    2847 if( glbminactivity != NULL )
    2848 {
    2849 assert(isminsettoinfinity != NULL);
    2850 assert(ismintight != NULL);
    2851
    2852 getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
    2853 consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
    2854 glbminactivity, ismintight, isminsettoinfinity);
    2855 }
    2856
    2857 if( glbmaxactivity != NULL )
    2858 {
    2859 assert(ismaxsettoinfinity != NULL);
    2860 assert(ismaxtight != NULL);
    2861
    2862 getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
    2863 consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
    2864 glbmaxactivity, ismaxtight, ismaxsettoinfinity);
    2865 }
    2866}
    2867
    2868/** gets global activity bounds for constraint after setting variable to zero */
    2869static
    2871 SCIP* scip, /**< SCIP data structure */
    2872 SCIP_CONSDATA* consdata, /**< linear constraint */
    2873 SCIP_VAR* var, /**< variable to calculate activity residual for */
    2874 SCIP_Real val, /**< coefficient value of variable in linear constraint */
    2875 SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
    2876 * relaxed acticities ignored, anyway? */
    2877 SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity, or NULL, if not needed */
    2878 SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity, or NULL, if not needed */
    2879 SCIP_Bool* ismintight, /**< pointer to store whether the residual minactivity bound is tight
    2880 * i.e. is the actual residual minactivity (otherwise a lower bound is provided) */
    2881 SCIP_Bool* ismaxtight, /**< pointer to store whether the residual maxactivity bound is tight
    2882 * i.e. is the actual residual maxactivity (otherwise an upper bound is provided) */
    2883 SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
    2884 SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
    2885 )
    2886{
    2887 SCIP_Real minactbound;
    2888 SCIP_Real maxactbound;
    2889 SCIP_Real absval;
    2890
    2891 assert(scip != NULL);
    2892 assert(consdata != NULL);
    2893 assert(var != NULL);
    2894 assert((minresactivity != NULL && ismintight != NULL && isminsettoinfinity != NULL )
    2895 || (maxresactivity != NULL && ismaxtight != NULL && ismaxsettoinfinity != NULL));
    2896
    2897 /* get activity bounds of linear constraint */
    2898 if( !consdata->validactivities )
    2899 consdataCalcActivities(scip, consdata);
    2900
    2901 assert(QUAD_TO_DBL(consdata->glbminactivity) < SCIP_INVALID);
    2902 assert(QUAD_TO_DBL(consdata->glbmaxactivity) < SCIP_INVALID);
    2903 assert(consdata->glbminactivityneginf >= 0);
    2904 assert(consdata->glbminactivityposinf >= 0);
    2905 assert(consdata->glbmaxactivityneginf >= 0);
    2906 assert(consdata->glbmaxactivityposinf >= 0);
    2907
    2908 if( val > 0.0 )
    2909 {
    2910 minactbound = SCIPvarGetLbGlobal(var);
    2911 maxactbound = SCIPvarGetUbGlobal(var);
    2912 absval = val;
    2913 }
    2914 else
    2915 {
    2916 minactbound = -SCIPvarGetUbGlobal(var);
    2917 maxactbound = -SCIPvarGetLbGlobal(var);
    2918 absval = -val;
    2919 }
    2920
    2921 if( minresactivity != NULL )
    2922 {
    2923 assert(isminsettoinfinity != NULL);
    2924 assert(ismintight != NULL);
    2925
    2926 /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
    2927 * and contribution of variable set to zero that has to be subtracted from finite part of activity
    2928 */
    2929 if( SCIPisInfinity(scip, minactbound) )
    2930 {
    2931 assert(consdata->glbminactivityposinf >= 1);
    2932
    2933 getMinActivity(scip, consdata, consdata->glbminactivityposinf - 1, consdata->glbminactivityneginf,
    2934 consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
    2935 minresactivity, ismintight, isminsettoinfinity);
    2936 }
    2937 else if( SCIPisInfinity(scip, -minactbound) )
    2938 {
    2939 assert(consdata->glbminactivityneginf >= 1);
    2940
    2941 getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf - 1,
    2942 consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
    2943 minresactivity, ismintight, isminsettoinfinity);
    2944 }
    2945 else if( SCIPisHugeValue(scip, minactbound * absval) )
    2946 {
    2947 assert(consdata->glbminactivityposhuge >= 1);
    2948
    2949 getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
    2950 consdata->glbminactivityposhuge - 1, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
    2951 minresactivity, ismintight, isminsettoinfinity);
    2952 }
    2953 else if( SCIPisHugeValue(scip, -minactbound * absval) )
    2954 {
    2955 assert(consdata->glbminactivityneghuge >= 1);
    2956
    2957 getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
    2958 consdata->glbminactivityposhuge, consdata->glbminactivityneghuge - 1, 0.0, TRUE, goodrelax,
    2959 minresactivity, ismintight, isminsettoinfinity);
    2960 }
    2961 else
    2962 {
    2963 getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
    2964 consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, absval * minactbound, TRUE,
    2965 goodrelax, minresactivity, ismintight, isminsettoinfinity);
    2966 }
    2967 }
    2968
    2969 if( maxresactivity != NULL )
    2970 {
    2971 assert(ismaxsettoinfinity != NULL);
    2972 assert(ismaxtight != NULL);
    2973
    2974 /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
    2975 * and contribution of variable set to zero that has to be subtracted from finite part of activity
    2976 */
    2977 if( SCIPisInfinity(scip, -maxactbound) )
    2978 {
    2979 assert(consdata->glbmaxactivityneginf >= 1);
    2980
    2981 getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf - 1,
    2982 consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
    2983 maxresactivity, ismaxtight, ismaxsettoinfinity);
    2984 }
    2985 else if( SCIPisInfinity(scip, maxactbound) )
    2986 {
    2987 assert(consdata->glbmaxactivityposinf >= 1);
    2988
    2989 getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf - 1, consdata->glbmaxactivityneginf,
    2990 consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
    2991 maxresactivity, ismaxtight, ismaxsettoinfinity);
    2992 }
    2993 else if( SCIPisHugeValue(scip, absval * maxactbound) )
    2994 {
    2995 assert(consdata->glbmaxactivityposhuge >= 1);
    2996
    2997 getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
    2998 consdata->glbmaxactivityposhuge - 1, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
    2999 maxresactivity, ismaxtight, ismaxsettoinfinity);
    3000 }
    3001 else if( SCIPisHugeValue(scip, -absval * maxactbound) )
    3002 {
    3003 assert(consdata->glbmaxactivityneghuge >= 1);
    3004
    3005 getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
    3006 consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge - 1, 0.0, TRUE, goodrelax,
    3007 maxresactivity, ismaxtight, ismaxsettoinfinity);
    3008 }
    3009 else
    3010 {
    3011 getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
    3012 consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, absval * maxactbound, TRUE,
    3013 goodrelax, maxresactivity, ismaxtight, ismaxsettoinfinity);
    3014 }
    3015 }
    3016}
    3017
    3018/** calculates the activity of the linear constraint for given solution */
    3019static
    3021 SCIP* scip, /**< SCIP data structure */
    3022 SCIP_CONSDATA* consdata, /**< linear constraint data */
    3023 SCIP_SOL* sol /**< solution to get activity for, NULL to current solution */
    3024 )
    3025{
    3026 SCIP_Real activity;
    3027
    3028 assert(scip != NULL);
    3029 assert(consdata != NULL);
    3030
    3031 if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
    3032 activity = consdataComputePseudoActivity(scip, consdata);
    3033 else
    3034 {
    3035 SCIP_Real solval;
    3036 int nposinf;
    3037 int nneginf;
    3038 SCIP_Bool negsign;
    3039 int v;
    3040
    3041 activity = 0.0;
    3042 nposinf = 0;
    3043 nneginf = 0;
    3044
    3045 for( v = 0; v < consdata->nvars; ++v )
    3046 {
    3047 solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
    3048
    3049 assert(!SCIPisZero(scip, consdata->vals[v]));
    3050 negsign = consdata->vals[v] < 0.0;
    3051
    3052 if( (SCIPisInfinity(scip, solval) && !negsign) || (SCIPisInfinity(scip, -solval) && negsign) )
    3053 ++nposinf;
    3054 else if( (SCIPisInfinity(scip, solval) && negsign) || (SCIPisInfinity(scip, -solval) && !negsign) )
    3055 ++nneginf;
    3056 else
    3057 activity += consdata->vals[v] * solval;
    3058 }
    3059 assert(nneginf >= 0 && nposinf >= 0);
    3060
    3061 SCIPdebugMsg(scip, "activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", activity, nposinf, nneginf);
    3062
    3063 /* invalidate activity for contradicting contributions */
    3064 if( nposinf > 0 && nneginf > 0 )
    3065 activity = SCIP_INVALID;
    3066 else if( nneginf > 0 )
    3067 activity = -SCIPinfinity(scip);
    3068 else if( nposinf > 0 )
    3069 activity = SCIPinfinity(scip);
    3070
    3071 SCIPdebugMsg(scip, "corrected activity of linear constraint: %.15g\n", activity);
    3072 }
    3073
    3074 if( activity == SCIP_INVALID ) /*lint !e777*/
    3075 return activity;
    3076 else if( activity < 0 )
    3077 activity = MAX(activity, -SCIPinfinity(scip)); /*lint !e666*/
    3078 else
    3079 activity = MIN(activity, SCIPinfinity(scip)); /*lint !e666*/
    3080
    3081 return activity;
    3082}
    3083
    3084/** calculates the feasibility of the linear constraint for given solution */
    3085static
    3087 SCIP* scip, /**< SCIP data structure */
    3088 SCIP_CONSDATA* consdata, /**< linear constraint data */
    3089 SCIP_SOL* sol /**< solution to get feasibility for, NULL to current solution */
    3090 )
    3091{
    3092 SCIP_Real activity;
    3093
    3094 assert(scip != NULL);
    3095 assert(consdata != NULL);
    3096
    3097 activity = consdataGetActivity(scip, consdata, sol);
    3098
    3099 if( activity == SCIP_INVALID ) /*lint !e777*/
    3100 return -SCIPinfinity(scip);
    3101
    3102 return MIN(consdata->rhs - activity, activity - consdata->lhs);
    3103}
    3104
    3105/** updates bit signatures after adding a single coefficient */
    3106static
    3108 SCIP_CONSDATA* consdata, /**< linear constraint data */
    3109 int pos /**< position of coefficient to update signatures for */
    3110 )
    3111{
    3112 uint64_t varsignature;
    3113 SCIP_Real lb;
    3114 SCIP_Real ub;
    3115 SCIP_Real val;
    3116
    3117 assert(consdata != NULL);
    3118 assert(consdata->validsignature);
    3119
    3120 varsignature = SCIPhashSignature64(SCIPvarGetIndex(consdata->vars[pos]));
    3121 lb = SCIPvarGetLbGlobal(consdata->vars[pos]);
    3122 ub = SCIPvarGetUbGlobal(consdata->vars[pos]);
    3123 val = consdata->vals[pos];
    3124 if( (val > 0.0 && ub > 0.0) || (val < 0.0 && lb < 0.0) )
    3125 consdata->possignature |= varsignature;
    3126 if( (val > 0.0 && lb < 0.0) || (val < 0.0 && ub > 0.0) )
    3127 consdata->negsignature |= varsignature;
    3128}
    3129
    3130/** calculates the bit signatures of the given constraint data */
    3131static
    3133 SCIP_CONSDATA* consdata /**< linear constraint data */
    3134 )
    3135{
    3136 assert(consdata != NULL);
    3137
    3138 if( !consdata->validsignature )
    3139 {
    3140 int i;
    3141
    3142 consdata->validsignature = TRUE;
    3143 consdata->possignature = 0;
    3144 consdata->negsignature = 0;
    3145 for( i = 0; i < consdata->nvars; ++i )
    3146 consdataUpdateSignatures(consdata, i);
    3147 }
    3148}
    3149
    3150/** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
    3151static
    3153{ /*lint --e{715}*/
    3154 SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
    3155 SCIP_VAR* var1;
    3156 SCIP_VAR* var2;
    3157
    3158 assert(consdata != NULL);
    3159 assert(0 <= ind1 && ind1 < consdata->nvars);
    3160 assert(0 <= ind2 && ind2 < consdata->nvars);
    3161
    3162 var1 = consdata->vars[ind1];
    3163 var2 = consdata->vars[ind2];
    3164
    3165 /* exactly one variable is binary */
    3166 if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
    3167 {
    3168 return (SCIPvarIsBinary(var1) ? -1 : +1);
    3169 }
    3170 /* both variables are binary */
    3171 else if( SCIPvarIsBinary(var1) )
    3172 {
    3173 return SCIPvarCompare(var1, var2);
    3174 }
    3175 else
    3176 {
    3179
    3180 if( vartype1 < vartype2 )
    3181 return -1;
    3182 else if( vartype1 > vartype2 )
    3183 return +1;
    3184 else
    3185 return SCIPvarCompare(var1, var2);
    3186 }
    3187}
    3188
    3189/** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
    3190static
    3191SCIP_DECL_SORTINDCOMP(consdataCompVarProp)
    3192{ /*lint --e{715}*/
    3193 SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
    3194 SCIP_VAR* var1;
    3195 SCIP_VAR* var2;
    3196
    3197 assert(consdata != NULL);
    3198 assert(0 <= ind1 && ind1 < consdata->nvars);
    3199 assert(0 <= ind2 && ind2 < consdata->nvars);
    3200
    3201 var1 = consdata->vars[ind1];
    3202 var2 = consdata->vars[ind2];
    3203
    3204 /* exactly one variable is binary */
    3205 if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
    3206 {
    3207 return (SCIPvarIsBinary(var1) ? -1 : +1);
    3208 }
    3209 /* both variables are binary */
    3210 else if( SCIPvarIsBinary(var1) )
    3211 {
    3212 SCIP_Real abscoef1 = REALABS(consdata->vals[ind1]);
    3213 SCIP_Real abscoef2 = REALABS(consdata->vals[ind2]);
    3214
    3215 if( EPSGT(abscoef1, abscoef2, 1e-9) )
    3216 return -1;
    3217 else if( EPSGT(abscoef2, abscoef1, 1e-9) )
    3218 return +1;
    3219 else
    3220 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
    3221 }
    3222 else
    3223 {
    3226
    3227 if( vartype1 < vartype2 )
    3228 {
    3229 return -1;
    3230 }
    3231 else if( vartype1 > vartype2 )
    3232 {
    3233 return +1;
    3234 }
    3235 else
    3236 {
    3237 /* both variables are continuous */
    3238 if( !SCIPvarIsIntegral(var1) )
    3239 {
    3240 assert(!SCIPvarIsIntegral(var2));
    3241 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
    3242 }
    3243 else
    3244 {
    3245 SCIP_Real abscont1 = REALABS(consdata->vals[ind1] * (SCIPvarGetUbGlobal(var1) - SCIPvarGetLbGlobal(var1)));
    3246 SCIP_Real abscont2 = REALABS(consdata->vals[ind2] * (SCIPvarGetUbGlobal(var2) - SCIPvarGetLbGlobal(var2)));
    3247
    3248 if( EPSGT(abscont1, abscont2, 1e-9) )
    3249 return -1;
    3250 else if( EPSGT(abscont2, abscont1, 1e-9) )
    3251 return +1;
    3252 else
    3253 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
    3254 }
    3255 }
    3256 }
    3257}
    3258
    3259/** permutes the constraint's variables according to a given permutation. */
    3260static
    3262 SCIP_CONSDATA* consdata, /**< the constraint data */
    3263 int* perm, /**< the target permutation */
    3264 int nvars /**< the number of variables */
    3265 )
    3266{ /*lint --e{715}*/
    3267 SCIP_VAR* varv;
    3268 SCIP_EVENTDATA* eventdatav;
    3269 SCIP_Real valv;
    3270 int v;
    3271 int i;
    3272 int nexti;
    3273
    3274 assert(perm != NULL);
    3275 assert(consdata != NULL);
    3276
    3277 /* permute the variables in the linear constraint according to the target permutation */
    3278 eventdatav = NULL;
    3279 for( v = 0; v < nvars; ++v )
    3280 {
    3281 if( perm[v] != v )
    3282 {
    3283 varv = consdata->vars[v];
    3284 valv = consdata->vals[v];
    3285 if( consdata->eventdata != NULL )
    3286 eventdatav = consdata->eventdata[v];
    3287 i = v;
    3288 do
    3289 {
    3290 assert(0 <= perm[i] && perm[i] < nvars);
    3291 assert(perm[i] != i);
    3292 consdata->vars[i] = consdata->vars[perm[i]];
    3293 consdata->vals[i] = consdata->vals[perm[i]];
    3294 if( consdata->eventdata != NULL )
    3295 {
    3296 consdata->eventdata[i] = consdata->eventdata[perm[i]];
    3297 consdata->eventdata[i]->varpos = i;
    3298 }
    3299 nexti = perm[i];
    3300 perm[i] = i;
    3301 i = nexti;
    3302 }
    3303 while( perm[i] != v );
    3304 consdata->vars[i] = varv;
    3305 consdata->vals[i] = valv;
    3306 if( consdata->eventdata != NULL )
    3307 {
    3308 consdata->eventdata[i] = eventdatav;
    3309 consdata->eventdata[i]->varpos = i;
    3310 }
    3311 perm[i] = i;
    3312 }
    3313 }
    3314#ifdef SCIP_DEBUG
    3315 /* check sorting */
    3316 for( v = 0; v < nvars; ++v )
    3317 {
    3318 assert(perm[v] == v);
    3319 assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
    3320 }
    3321#endif
    3322}
    3323
    3324/** sorts linear constraint's variables depending on the stage of the solving process:
    3325 * - during PRESOLVING
    3326 * sorts variables by binary, integer, implied integral, and continuous variables,
    3327 * and the variables of the same type by non-decreasing variable index
    3328 *
    3329 * - during SOLVING
    3330 * sorts variables of the remaining problem by binary, integer, implied integral, and continuous variables,
    3331 * and binary and integer variables by their global max activity delta (within each group),
    3332 * ties within a group are broken by problem index of the variable.
    3333 *
    3334 * This fastens the propagation time of the constraint handler.
    3335 */
    3336static
    3338 SCIP* scip, /**< SCIP data structure */
    3339 SCIP_CONSDATA* consdata /**< linear constraint data */
    3340 )
    3341{
    3342 assert(scip != NULL);
    3343 assert(consdata != NULL);
    3344
    3345 /* check if there are variables for sorting */
    3346 if( consdata->nvars <= 1 )
    3347 {
    3348 consdata->indexsorted = TRUE;
    3349 consdata->coefsorted = TRUE;
    3350 consdata->nbinvars = (consdata->nvars == 1 ? (int)SCIPvarIsBinary(consdata->vars[0]) : 0);
    3351 }
    3352 else if( (!consdata->indexsorted && SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE)
    3353 || (!consdata->coefsorted && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE) )
    3354 {
    3355 int* perm;
    3356 int v;
    3357
    3358 /* get temporary memory to store the sorted permutation */
    3359 SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
    3360
    3361 /* call sorting method */
    3363 SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
    3364 else
    3365 SCIPsort(perm, consdataCompVarProp, (void*)consdata, consdata->nvars);
    3366
    3367 permSortConsdata(consdata, perm, consdata->nvars);
    3368
    3369 /* free temporary memory */
    3370 SCIPfreeBufferArray(scip, &perm);
    3371
    3373 {
    3374 consdata->indexsorted = FALSE;
    3375 consdata->coefsorted = TRUE;
    3376
    3377 /* count binary variables in the sorted vars array */
    3378 consdata->nbinvars = 0;
    3379 for( v = 0; v < consdata->nvars; ++v )
    3380 {
    3381 if( SCIPvarIsBinary(consdata->vars[v]) )
    3382 ++consdata->nbinvars;
    3383 else
    3384 break;
    3385 }
    3386 }
    3387 else
    3388 {
    3389 consdata->indexsorted = TRUE;
    3390 consdata->coefsorted = FALSE;
    3391 }
    3392 }
    3393
    3394 return SCIP_OKAY;
    3395}
    3396
    3397
    3398/*
    3399 * local linear constraint handler methods
    3400 */
    3401
    3402/** sets left hand side of linear constraint */
    3403static
    3405 SCIP* scip, /**< SCIP data structure */
    3406 SCIP_CONS* cons, /**< linear constraint */
    3407 SCIP_Real lhs /**< new left hand side */
    3408 )
    3409{
    3410 SCIP_CONSDATA* consdata;
    3411 SCIP_Bool locked;
    3412 int i;
    3413
    3414 assert(scip != NULL);
    3415 assert(cons != NULL);
    3416
    3417 /* adjust value to be not beyond infinity */
    3418 if( SCIPisInfinity(scip, -lhs) )
    3419 lhs = -SCIPinfinity(scip);
    3420 else if( SCIPisInfinity(scip, lhs) )
    3421 lhs = SCIPinfinity(scip);
    3422
    3423 consdata = SCIPconsGetData(cons);
    3424 assert(consdata != NULL);
    3425 assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
    3426
    3427 /* check whether the side is not changed */
    3428 if( SCIPisEQ(scip, consdata->lhs, lhs) )
    3429 return SCIP_OKAY;
    3430
    3431 assert(!SCIPisInfinity(scip, ABS(consdata->lhs)) || !SCIPisInfinity(scip, ABS(lhs)));
    3432
    3433 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
    3434 if( SCIPisEQ(scip, lhs, consdata->rhs) )
    3435 {
    3436 consdata->rhs = lhs;
    3437 assert(consdata->row == NULL);
    3438 }
    3439
    3440 locked = FALSE;
    3441 for( i = 0; i < NLOCKTYPES && !locked; i++ )
    3442 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
    3443
    3444 /* if necessary, update the rounding locks of variables */
    3445 if( locked )
    3446 {
    3447 if( SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -lhs) )
    3448 {
    3449 SCIP_VAR** vars;
    3450 SCIP_Real* vals;
    3451 int v;
    3452
    3453 /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
    3454 vars = consdata->vars;
    3455 vals = consdata->vals;
    3456
    3457 for( v = 0; v < consdata->nvars; ++v )
    3458 {
    3459 assert(vars[v] != NULL);
    3460 assert(!SCIPisZero(scip, vals[v]));
    3461
    3462 if( SCIPisPositive(scip, vals[v]) )
    3463 {
    3464 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3465 }
    3466 else
    3467 {
    3468 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3469 }
    3470 }
    3471 }
    3472 else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -lhs) )
    3473 {
    3474 SCIP_VAR** vars;
    3475 SCIP_Real* vals;
    3476 int v;
    3477
    3478 /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
    3479 vars = consdata->vars;
    3480 vals = consdata->vals;
    3481
    3482 for( v = 0; v < consdata->nvars; ++v )
    3483 {
    3484 assert(vars[v] != NULL);
    3485 assert(!SCIPisZero(scip, vals[v]));
    3486
    3487 if( SCIPisPositive(scip, vals[v]) )
    3488 {
    3489 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3490 }
    3491 else
    3492 {
    3493 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3494 }
    3495 }
    3496 }
    3497 }
    3498
    3499 /* 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 */
    3500 if( !SCIPisInfinity(scip, ABS(lhs)) && SCIPisGT(scip, lhs, consdata->lhs) )
    3501 {
    3502 consdata->boundstightened = 0;
    3503 consdata->presolved = FALSE;
    3504 consdata->cliquesadded = FALSE;
    3505 consdata->implsadded = FALSE;
    3506
    3507 /* mark the constraint for propagation */
    3508 if( SCIPconsIsTransformed(cons) )
    3509 {
    3511 }
    3512 }
    3513
    3514 /* set new left hand side and update constraint data */
    3515 consdata->lhs = lhs;
    3516 consdata->changed = TRUE;
    3517 consdata->normalized = FALSE;
    3518 consdata->upgradetried = FALSE;
    3519 consdata->rangedrowpropagated = 0;
    3520
    3521 /* update the lhs of the LP row */
    3522 if( consdata->row != NULL )
    3523 {
    3524 SCIP_CALL( SCIPchgRowLhs(scip, consdata->row, lhs) );
    3525 }
    3526
    3527 return SCIP_OKAY;
    3528}
    3529
    3530/** sets right hand side of linear constraint */
    3531static
    3533 SCIP* scip, /**< SCIP data structure */
    3534 SCIP_CONS* cons, /**< linear constraint */
    3535 SCIP_Real rhs /**< new right hand side */
    3536 )
    3537{
    3538 SCIP_CONSDATA* consdata;
    3539 SCIP_Bool locked;
    3540 int i;
    3541
    3542 assert(scip != NULL);
    3543 assert(cons != NULL);
    3544
    3545 /* adjust value to be not beyond infinity */
    3546 if( SCIPisInfinity(scip, rhs) )
    3547 rhs = SCIPinfinity(scip);
    3548 else if( SCIPisInfinity(scip, -rhs) )
    3549 rhs = -SCIPinfinity(scip);
    3550
    3551 consdata = SCIPconsGetData(cons);
    3552 assert(consdata != NULL);
    3553 assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
    3554
    3555 /* check whether the side is not changed */
    3556 if( SCIPisEQ(scip, consdata->rhs, rhs) )
    3557 return SCIP_OKAY;
    3558
    3559 assert(!SCIPisInfinity(scip, ABS(consdata->rhs)) || !SCIPisInfinity(scip, ABS(rhs)));
    3560
    3561 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
    3562 if( SCIPisEQ(scip, rhs, consdata->lhs) )
    3563 {
    3564 consdata->lhs = rhs;
    3565 assert(consdata->row == NULL);
    3566 }
    3567
    3568 locked = FALSE;
    3569 for( i = 0; i < NLOCKTYPES && !locked; i++ )
    3570 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
    3571
    3572 /* if necessary, update the rounding locks of variables */
    3573 if( locked )
    3574 {
    3575 assert(SCIPconsIsTransformed(cons));
    3576
    3577 if( SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, rhs) )
    3578 {
    3579 SCIP_VAR** vars;
    3580 SCIP_Real* vals;
    3581 int v;
    3582
    3583 /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
    3584 vars = consdata->vars;
    3585 vals = consdata->vals;
    3586
    3587 for( v = 0; v < consdata->nvars; ++v )
    3588 {
    3589 assert(vars[v] != NULL);
    3590 assert(!SCIPisZero(scip, vals[v]));
    3591
    3592 if( SCIPisPositive(scip, vals[v]) )
    3593 {
    3594 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3595 }
    3596 else
    3597 {
    3598 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3599 }
    3600 }
    3601 }
    3602 else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, rhs) )
    3603 {
    3604 SCIP_VAR** vars;
    3605 SCIP_Real* vals;
    3606 int v;
    3607
    3608 /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
    3609 vars = consdata->vars;
    3610 vals = consdata->vals;
    3611
    3612 for( v = 0; v < consdata->nvars; ++v )
    3613 {
    3614 assert(vars[v] != NULL);
    3615 assert(!SCIPisZero(scip, vals[v]));
    3616
    3617 if( SCIPisPositive(scip, vals[v]) )
    3618 {
    3619 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
    3620 }
    3621 else
    3622 {
    3623 SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
    3624 }
    3625 }
    3626 }
    3627 }
    3628
    3629 /* 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 */
    3630 if( !SCIPisInfinity(scip, ABS(rhs)) && SCIPisLT(scip, rhs, consdata->rhs) )
    3631 {
    3632 consdata->boundstightened = 0;
    3633 consdata->presolved = FALSE;
    3634 consdata->cliquesadded = FALSE;
    3635 consdata->implsadded = FALSE;
    3636
    3637 /* mark the constraint for propagation */
    3638 if( SCIPconsIsTransformed(cons) )
    3639 {
    3641 }
    3642 }
    3643
    3644 /* set new right hand side and update constraint data */
    3645 consdata->rhs = rhs;
    3646 consdata->changed = TRUE;
    3647 consdata->normalized = FALSE;
    3648 consdata->upgradetried = FALSE;
    3649 consdata->rangedrowpropagated = 0;
    3650
    3651 /* update the rhs of the LP row */
    3652 if( consdata->row != NULL )
    3653 {
    3654 SCIP_CALL( SCIPchgRowRhs(scip, consdata->row, rhs) );
    3655 }
    3656
    3657 return SCIP_OKAY;
    3658}
    3659
    3660/** adds coefficient in linear constraint */
    3661static
    3663 SCIP* scip, /**< SCIP data structure */
    3664 SCIP_CONS* cons, /**< linear constraint */
    3665 SCIP_VAR* var, /**< variable of constraint entry */
    3666 SCIP_Real val /**< coefficient of constraint entry */
    3667 )
    3668{
    3669 SCIP_CONSDATA* consdata;
    3670 SCIP_Bool transformed;
    3671
    3672 assert(scip != NULL);
    3673 assert(cons != NULL);
    3674 assert(var != NULL);
    3675
    3676 /* relaxation-only variables must not be used in checked or enforced constraints */
    3677 assert(!SCIPvarIsRelaxationOnly(var) || (!SCIPconsIsChecked(cons) && !SCIPconsIsEnforced(cons)));
    3678 consdata = SCIPconsGetData(cons);
    3679 assert(consdata != NULL);
    3680
    3681 /* are we in the transformed problem? */
    3682 transformed = SCIPconsIsTransformed(cons);
    3683
    3684 /* always use transformed variables in transformed constraints */
    3685 if( transformed )
    3686 {
    3687 SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
    3688 }
    3689 assert(var != NULL);
    3690 assert(transformed == SCIPvarIsTransformed(var));
    3691
    3692 SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
    3693 consdata->vars[consdata->nvars] = var;
    3694 consdata->vals[consdata->nvars] = val;
    3695 consdata->nvars++;
    3696
    3697 /* capture variable */
    3698 SCIP_CALL( SCIPcaptureVar(scip, var) );
    3699
    3700 /* if we are in transformed problem, the variable needs an additional event data */
    3701 if( transformed )
    3702 {
    3703 if( consdata->eventdata != NULL )
    3704 {
    3705 SCIP_CONSHDLR* conshdlr;
    3706 SCIP_CONSHDLRDATA* conshdlrdata;
    3707
    3708 /* check for event handler */
    3709 conshdlr = SCIPconsGetHdlr(cons);
    3710 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3711 assert(conshdlrdata != NULL);
    3712 assert(conshdlrdata->eventhdlr != NULL);
    3713
    3714 /* initialize eventdata array */
    3715 consdata->eventdata[consdata->nvars-1] = NULL;
    3716
    3717 /* catch bound change events of variable */
    3718 SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
    3719 }
    3720
    3721 /* update minimum and maximum activities */
    3722 if( !SCIPisZero(scip, val) )
    3723 consdataUpdateAddCoef(scip, consdata, var, val, FALSE);
    3724 }
    3725
    3726 /* install rounding locks for new variable with non-zero coefficient */
    3727 if( !SCIPisZero(scip, val) )
    3728 {
    3729 SCIP_CALL( lockRounding(scip, cons, var, val) );
    3730 }
    3731
    3732 /* mark the constraint for propagation */
    3733 if( transformed )
    3734 {
    3736 }
    3737
    3738 consdata->boundstightened = 0;
    3739 consdata->presolved = FALSE;
    3740 consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
    3741
    3742 if( consdata->validsignature )
    3743 consdataUpdateSignatures(consdata, consdata->nvars-1);
    3744
    3745 consdata->changed = TRUE;
    3746 consdata->normalized = FALSE;
    3747 consdata->upgradetried = FALSE;
    3748 consdata->cliquesadded = FALSE;
    3749 consdata->implsadded = FALSE;
    3750 consdata->rangedrowpropagated = 0;
    3751 consdata->merged = FALSE;
    3752
    3753 if( consdata->nvars == 1 )
    3754 {
    3755 consdata->indexsorted = TRUE;
    3756 consdata->coefsorted = TRUE;
    3757 }
    3758 else
    3759 {
    3761 {
    3762 consdata->indexsorted = consdata->indexsorted && (consdataCompVar((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
    3763 consdata->coefsorted = FALSE;
    3764 }
    3765 else
    3766 {
    3767 consdata->indexsorted = FALSE;
    3768 consdata->coefsorted = consdata->coefsorted && (consdataCompVarProp((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
    3769 }
    3770 }
    3771
    3772 /* update hascontvar and hasnonbinvar flags */
    3773 if( consdata->hasnonbinvalid && !consdata->hascontvar )
    3774 {
    3775 if( !SCIPvarIsBinary(var) )
    3776 {
    3777 consdata->hasnonbinvar = TRUE;
    3778
    3779 if( !SCIPvarIsIntegral(var) )
    3780 consdata->hascontvar = TRUE;
    3781 }
    3782 }
    3783
    3784 /* add the new coefficient to the LP row */
    3785 if( consdata->row != NULL )
    3786 {
    3787 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, val) );
    3788 }
    3789
    3790 return SCIP_OKAY;
    3791}
    3792
    3793/** deletes coefficient at given position from linear constraint data */
    3794static
    3796 SCIP* scip, /**< SCIP data structure */
    3797 SCIP_CONS* cons, /**< linear constraint */
    3798 int pos /**< position of coefficient to delete */
    3799 )
    3800{
    3801 SCIP_CONSDATA* consdata;
    3802 SCIP_VAR* var;
    3803 SCIP_Real val;
    3804
    3805 assert(scip != NULL);
    3806 assert(cons != NULL);
    3807
    3808 consdata = SCIPconsGetData(cons);
    3809 assert(consdata != NULL);
    3810 assert(0 <= pos && pos < consdata->nvars);
    3811
    3812 var = consdata->vars[pos];
    3813 val = consdata->vals[pos];
    3814 assert(var != NULL);
    3815
    3816 /* remove rounding locks for deleted variable with non-zero coefficient */
    3817 if( !SCIPisZero(scip, val) )
    3818 {
    3819 SCIP_CALL( unlockRounding(scip, cons, var, val) );
    3820 }
    3821
    3822 /* if we are in transformed problem, delete the event data of the variable */
    3823 if( SCIPconsIsTransformed(cons) )
    3824 {
    3825 SCIP_CONSHDLR* conshdlr;
    3826 SCIP_CONSHDLRDATA* conshdlrdata;
    3827
    3828 /* check for event handler */
    3829 conshdlr = SCIPconsGetHdlr(cons);
    3830 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    3831 assert(conshdlrdata != NULL);
    3832 assert(conshdlrdata->eventhdlr != NULL);
    3833
    3834 /* drop bound change events of variable */
    3835 if( consdata->eventdata != NULL )
    3836 {
    3837 SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
    3838 assert(consdata->eventdata[pos] == NULL);
    3839 }
    3840 }
    3841
    3842 /* move the last variable to the free slot */
    3843 if( pos != consdata->nvars - 1 )
    3844 {
    3845 consdata->vars[pos] = consdata->vars[consdata->nvars-1];
    3846 consdata->vals[pos] = consdata->vals[consdata->nvars-1];
    3847
    3848 if( consdata->eventdata != NULL )
    3849 {
    3850 consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
    3851 assert(consdata->eventdata[pos] != NULL);
    3852 consdata->eventdata[pos]->varpos = pos;
    3853 }
    3854
    3855 consdata->indexsorted = consdata->indexsorted && (pos + 2 >= consdata->nvars);
    3856 consdata->coefsorted = consdata->coefsorted && (pos + 2 >= consdata->nvars);
    3857 }
    3858 consdata->nvars--;
    3859
    3860 /* if at most one variable is left, the activities should be recalculated (to correspond exactly to the bounds
    3861 * of the remaining variable, or give exactly 0.0)
    3862 */
    3863 if( consdata->nvars <= 1 )
    3865 else
    3866 {
    3867 /* if we are in transformed problem, update minimum and maximum activities */
    3868 if( SCIPconsIsTransformed(cons) && !SCIPisZero(scip, val) )
    3869 consdataUpdateDelCoef(scip, consdata, var, val, TRUE);
    3870 }
    3871
    3872 /* mark the constraint for propagation */
    3873 if( SCIPconsIsTransformed(cons) )
    3874 {
    3876 }
    3877
    3878 consdata->boundstightened = 0;
    3879 consdata->presolved = FALSE;
    3880 consdata->validsignature = FALSE;
    3881 consdata->changed = TRUE;
    3882 consdata->normalized = FALSE;
    3883 consdata->upgradetried = FALSE;
    3884 consdata->cliquesadded = FALSE;
    3885 consdata->implsadded = FALSE;
    3886 consdata->rangedrowpropagated = 0;
    3887
    3888 /* check if hasnonbinvar flag might be incorrect now */
    3889 if( consdata->hasnonbinvar && !SCIPvarIsBinary(var) )
    3890 {
    3891 consdata->hasnonbinvalid = FALSE;
    3892 }
    3893
    3894 /* delete coefficient from the LP row */
    3895 if( consdata->row != NULL )
    3896 {
    3897 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, -val) );
    3898 }
    3899
    3900 /* release variable */
    3901 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    3902
    3903 return SCIP_OKAY;
    3904}
    3905
    3906/** changes coefficient value at given position of linear constraint data */
    3907static
    3909 SCIP* scip, /**< SCIP data structure */
    3910 SCIP_CONS* cons, /**< linear constraint */
    3911 int pos, /**< position of coefficient to delete */
    3912 SCIP_Real newval /**< new value of coefficient */
    3913 )
    3914{
    3915 SCIP_CONSDATA* consdata;
    3916 SCIP_VAR* var;
    3917 SCIP_Real val;
    3918 SCIP_Bool locked;
    3919 int i;
    3920
    3921 assert(scip != NULL);
    3922 assert(cons != NULL);
    3923 consdata = SCIPconsGetData(cons);
    3924 assert(consdata != NULL);
    3925 assert(0 <= pos && pos < consdata->nvars);
    3926 var = consdata->vars[pos];
    3927 assert(var != NULL);
    3928 assert(SCIPvarIsTransformed(var) == SCIPconsIsTransformed(cons));
    3929 val = consdata->vals[pos];
    3930 assert(!SCIPisZero(scip, val) || !SCIPisZero(scip, newval));
    3931
    3932 locked = FALSE;
    3933 for( i = 0; i < NLOCKTYPES && !locked; i++ )
    3934 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
    3935
    3936 /* if necessary, update the rounding locks of the variable */
    3937 if( locked && ( !SCIPisNegative(scip, val) || !SCIPisNegative(scip, newval) )
    3938 && ( !SCIPisPositive(scip, val) || !SCIPisPositive(scip, newval) ) )
    3939 {
    3940 assert(SCIPconsIsTransformed(cons));
    3941
    3942 /* remove rounding locks for variable with old non-zero coefficient */
    3943 if( !SCIPisZero(scip, val) )
    3944 {
    3945 SCIP_CALL( unlockRounding(scip, cons, var, val) );
    3946 }
    3947
    3948 /* install rounding locks for variable with new non-zero coefficient */
    3949 if( !SCIPisZero(scip, newval) )
    3950 {
    3951 SCIP_CALL( lockRounding(scip, cons, var, newval) );
    3952 }
    3953 }
    3954
    3955 /* change the value */
    3956 consdata->vals[pos] = newval;
    3957
    3958 if( consdata->coefsorted )
    3959 {
    3960 if( pos > 0 )
    3961 consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos - 1, pos) <= 0);
    3962 if( consdata->coefsorted && pos < consdata->nvars - 1 )
    3963 consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos, pos + 1) <= 0);
    3964 }
    3965
    3966 /* update minimum and maximum activities */
    3967 if( SCIPconsIsTransformed(cons) )
    3968 {
    3969 if( SCIPisZero(scip, val) )
    3970 consdataUpdateAddCoef(scip, consdata, var, newval, TRUE);
    3971 else if( SCIPisZero(scip, newval) )
    3972 consdataUpdateDelCoef(scip, consdata, var, val, TRUE);
    3973 else
    3974 consdataUpdateChgCoef(scip, consdata, var, val, newval, TRUE);
    3975 }
    3976
    3977 /* mark the constraint for propagation */
    3978 if( SCIPconsIsTransformed(cons) )
    3979 {
    3981 }
    3982
    3983 consdata->boundstightened = 0;
    3984 consdata->presolved = FALSE;
    3985 consdata->validsignature = consdata->validsignature && (newval * val > 0.0);
    3986 consdata->changed = TRUE;
    3987 consdata->normalized = FALSE;
    3988 consdata->upgradetried = FALSE;
    3989 consdata->cliquesadded = FALSE;
    3990 consdata->implsadded = FALSE;
    3991 consdata->rangedrowpropagated = 0;
    3992
    3993 return SCIP_OKAY;
    3994}
    3995
    3996/** scales a linear constraint with a constant scalar */
    3997static
    3999 SCIP* scip, /**< SCIP data structure */
    4000 SCIP_CONS* cons, /**< linear constraint to scale */
    4001 SCIP_Real scalar /**< value to scale constraint with */
    4002 )
    4003{
    4004 SCIP_CONSDATA* consdata;
    4005 SCIP_Real newval;
    4006 SCIP_Real absscalar;
    4007 int i;
    4008
    4009 assert(scip != NULL);
    4010 assert(cons != NULL);
    4011
    4012 consdata = SCIPconsGetData(cons);
    4013 assert(consdata != NULL);
    4014 assert(consdata->row == NULL);
    4015 assert(scalar != 1.0);
    4016
    4017 if( (!SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -consdata->lhs * scalar))
    4018 || (!SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, consdata->rhs * scalar)) )
    4019 {
    4020 SCIPwarningMessage(scip, "skipped scaling for linear constraint <%s> to avoid numerical troubles (scalar: %.15g)\n",
    4021 SCIPconsGetName(cons), scalar);
    4022
    4023 return SCIP_OKAY;
    4024 }
    4025
    4026 /* scale the coefficients */
    4027 for( i = consdata->nvars - 1; i >= 0; --i )
    4028 {
    4029 newval = scalar * consdata->vals[i];
    4030
    4031 /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
    4032 * flooring down our new value
    4033 */
    4034 if( SCIPisScalingIntegral(scip, consdata->vals[i], scalar) )
    4035 newval = SCIPfeasFloor(scip, newval + 0.5);
    4036
    4037 if( SCIPisZero(scip, newval) )
    4038 {
    4039 SCIPwarningMessage(scip, "coefficient %.15g of variable <%s> in linear constraint <%s> scaled to zero (scalar: %.15g)\n",
    4040 consdata->vals[i], SCIPvarGetName(consdata->vars[i]), SCIPconsGetName(cons), scalar);
    4041 SCIP_CALL( delCoefPos(scip, cons, i) );
    4042 }
    4043 else
    4044 consdata->vals[i] = newval;
    4045 }
    4046
    4047 /* scale the sides */
    4048 if( scalar < 0.0 )
    4049 {
    4050 SCIP_Real lhs;
    4051
    4052 lhs = consdata->lhs;
    4053 consdata->lhs = -consdata->rhs;
    4054 consdata->rhs = -lhs;
    4055 }
    4056 absscalar = REALABS(scalar);
    4057 if( !SCIPisInfinity(scip, -consdata->lhs) )
    4058 {
    4059 newval = absscalar * consdata->lhs;
    4060
    4061 /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
    4062 * flooring down our new value
    4063 */
    4064 if( SCIPisScalingIntegral(scip, consdata->lhs, absscalar) )
    4065 consdata->lhs = SCIPfeasFloor(scip, newval + 0.5);
    4066 else
    4067 consdata->lhs = newval;
    4068 }
    4069 if( !SCIPisInfinity(scip, consdata->rhs) )
    4070 {
    4071 newval = absscalar * consdata->rhs;
    4072
    4073 /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasCeil, we subtract 0.5 before ceiling up
    4074 * our new value
    4075 */
    4076 if( SCIPisScalingIntegral(scip, consdata->rhs, absscalar) )
    4077 consdata->rhs = SCIPfeasCeil(scip, newval - 0.5);
    4078 else
    4079 consdata->rhs = newval;
    4080 }
    4081
    4083 consdata->cliquesadded = FALSE;
    4084 consdata->implsadded = FALSE;
    4085
    4086 return SCIP_OKAY;
    4087}
    4088
    4089/** perform deletion of variables in all constraints of the constraint handler */
    4090static
    4092 SCIP* scip, /**< SCIP data structure */
    4093 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    4094 SCIP_CONS** conss, /**< array of constraints */
    4095 int nconss /**< number of constraints */
    4096 )
    4097{
    4098 SCIP_CONSDATA* consdata;
    4099 int i;
    4100 int v;
    4101
    4102 assert(scip != NULL);
    4103 assert(conshdlr != NULL);
    4104 assert(conss != NULL);
    4105 assert(nconss >= 0);
    4106 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    4107
    4108 /* iterate over all constraints */
    4109 for( i = 0; i < nconss; i++ )
    4110 {
    4111 consdata = SCIPconsGetData(conss[i]);
    4112
    4113 /* constraint is marked, that some of its variables were deleted */
    4114 if( consdata->varsdeleted )
    4115 {
    4116 /* iterate over all variables of the constraint and delete them from the constraint */
    4117 for( v = consdata->nvars - 1; v >= 0; --v )
    4118 {
    4119 if( SCIPvarIsDeleted(consdata->vars[v]) )
    4120 {
    4121 SCIP_CALL( delCoefPos(scip, conss[i], v) );
    4122 }
    4123 }
    4124 consdata->varsdeleted = FALSE;
    4125 }
    4126 }
    4127
    4128 return SCIP_OKAY;
    4129}
    4130
    4131
    4132/** normalizes a linear constraint with the following rules:
    4133 * - if all coefficients have them same absolute value, change them to (-)1.0
    4134 * - multiplication with +1 or -1:
    4135 * Apply the following rules in the given order, until the sign of the factor is determined. Later rules only apply,
    4136 * if the current rule doesn't determine the sign):
    4137 * 1. the right hand side must not be negative
    4138 * 2. the right hand side must not be infinite
    4139 * 3. the absolute value of the right hand side must be greater than that of the left hand side
    4140 * 4. the number of positive coefficients must not be smaller than the number of negative coefficients
    4141 * 5. multiply with +1
    4142 * - rationals to integrals
    4143 * Try to identify a rational representation of the fractional coefficients, and multiply all coefficients
    4144 * by the smallest common multiple of all denominators to get integral coefficients.
    4145 * Forbid large denominators due to numerical stability.
    4146 * - division by greatest common divisor
    4147 * If all coefficients are integral, divide them by the greatest common divisor.
    4148 */
    4149static
    4151 SCIP* scip, /**< SCIP data structure */
    4152 SCIP_CONS* cons, /**< linear constraint to normalize */
    4153 SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
    4154 )
    4155{
    4156 SCIP_CONSDATA* consdata;
    4157 SCIP_Real* vals;
    4158 SCIP_Longint scm;
    4161 SCIP_Longint gcd;
    4162 SCIP_Longint maxmult;
    4163 SCIP_Real epsilon;
    4164 SCIP_Real feastol;
    4165 SCIP_Real maxabsval;
    4166 SCIP_Real minabsval;
    4167 SCIP_Bool success;
    4168 SCIP_Bool onlyintegral;
    4169 int nvars;
    4170 int mult;
    4171 int nposcoeffs;
    4172 int nnegcoeffs;
    4173 int i;
    4174
    4175 assert(scip != NULL);
    4176 assert(cons != NULL);
    4177 assert(infeasible != NULL);
    4178
    4179 *infeasible = FALSE;
    4180
    4181 /* we must not change a modifiable constraint in any way */
    4182 if( SCIPconsIsModifiable(cons) )
    4183 return SCIP_OKAY;
    4184
    4185 /* get constraint data */
    4186 consdata = SCIPconsGetData(cons);
    4187 assert(consdata != NULL);
    4188
    4189 /* check, if the constraint is already normalized */
    4190 if( consdata->normalized )
    4191 return SCIP_OKAY;
    4192
    4193 /* get coefficient arrays */
    4194 vals = consdata->vals;
    4195 nvars = consdata->nvars;
    4196 assert(nvars == 0 || vals != NULL);
    4197
    4198 if( nvars == 0 )
    4199 {
    4200 consdata->normalized = TRUE;
    4201 return SCIP_OKAY;
    4202 }
    4203
    4204 assert(vals != NULL);
    4205
    4206 /* get maximum and minimum absolute coefficient */
    4207 maxabsval = consdataGetMaxAbsval(consdata);
    4208 minabsval = consdataGetMinAbsval(consdata);
    4209
    4210 /* return if scaling by maxval will eliminate coefficients */
    4211 if( SCIPisZero(scip, minabsval/maxabsval) )
    4212 return SCIP_OKAY;
    4213
    4214 /* return if scaling by maxval will eliminate or generate non-zero sides */
    4215 if( !SCIPisInfinity(scip, consdata->lhs) && SCIPisFeasZero(scip, consdata->lhs) != SCIPisFeasZero(scip, consdata->lhs/maxabsval) )
    4216 return SCIP_OKAY;
    4217 if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisFeasZero(scip, consdata->rhs) != SCIPisFeasZero(scip, consdata->rhs/maxabsval) )
    4218 return SCIP_OKAY;
    4219
    4220 /* check if not all absolute coefficients are near 1.0 but scaling could do */
    4221 if( SCIPisLT(scip, minabsval, 1.0) != SCIPisGT(scip, maxabsval, 1.0) )
    4222 {
    4223 SCIP_Real scalar;
    4224
    4225 /* calculate scale of the average minimum and maximum absolute coefficient to 1.0 */
    4226 scalar = 2.0 / (minabsval + maxabsval);
    4227
    4228 /* check if all scaled absolute coefficients are near 1.0
    4229 * we can relax EQ(x,1.0) to LE(x,1.0), as LT(x,1.0) is not possible
    4230 */
    4231 if( SCIPisLE(scip, scalar * maxabsval, 1.0) )
    4232 {
    4233 SCIPdebugMsg(scip, "divide linear constraint with %g, because all coefficients are in absolute value the same\n", maxabsval);
    4235 SCIP_CALL( scaleCons(scip, cons, scalar) );
    4236
    4237 /* get new consdata information, because scaleCons() might have deleted variables */
    4238 vals = consdata->vals;
    4239 nvars = consdata->nvars;
    4240
    4241 assert(nvars == 0 || vals != NULL);
    4242 }
    4243 }
    4244
    4245 /* nvars might have changed */
    4246 if( nvars == 0 )
    4247 {
    4248 consdata->normalized = TRUE;
    4249 return SCIP_OKAY;
    4250 }
    4251
    4252 assert(vals != NULL);
    4253
    4254 /* calculate the maximal multiplier for common divisor calculation:
    4255 * |p/q - val| < epsilon and q < feastol/epsilon => |p - q*val| < feastol
    4256 * which means, a value of feastol/epsilon should be used as maximal multiplier;
    4257 * additionally, we don't want to scale the constraint if this would lead to too
    4258 * large coefficients
    4259 */
    4260 epsilon = SCIPepsilon(scip) * 0.9; /* slightly decrease epsilon to be safe in rational conversion below */
    4261 feastol = SCIPfeastol(scip);
    4262 maxmult = (SCIP_Longint)(feastol/epsilon + feastol);
    4263
    4264 if( !consdata->hasnonbinvalid )
    4265 consdataCheckNonbinvar(consdata);
    4266
    4267 /* get maximum absolute coefficient */
    4268 maxabsval = consdataGetMaxAbsval(consdata);
    4269
    4270 /* if all variables are of integral type we will allow a greater multiplier */
    4271 if( !consdata->hascontvar )
    4272 maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEFINTEGER / MAX(maxabsval, 1.0))); /*lint !e835*/
    4273 else
    4274 maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEF / MAX(maxabsval, 1.0))); /*lint !e835*/
    4275
    4276 /*
    4277 * multiplication with +1 or -1
    4278 */
    4279 mult = 0;
    4280
    4281 /* 1. the right hand side must not be negative */
    4282 if( SCIPisPositive(scip, consdata->lhs) )
    4283 mult = +1;
    4284 else if( SCIPisNegative(scip, consdata->rhs) )
    4285 mult = -1;
    4286
    4287 if( mult == 0 )
    4288 {
    4289 /* 2. the right hand side must not be infinite */
    4290 if( SCIPisInfinity(scip, -consdata->lhs) )
    4291 mult = +1;
    4292 else if( SCIPisInfinity(scip, consdata->rhs) )
    4293 mult = -1;
    4294 }
    4295
    4296 if( mult == 0 )
    4297 {
    4298 /* 3. the absolute value of the right hand side must be greater than that of the left hand side */
    4299 if( SCIPisGT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
    4300 mult = +1;
    4301 else if( SCIPisLT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
    4302 mult = -1;
    4303 }
    4304
    4305 if( mult == 0 )
    4306 {
    4307 /* 4. the number of positive coefficients must not be smaller than the number of negative coefficients */
    4308 nposcoeffs = 0;
    4309 nnegcoeffs = 0;
    4310 for( i = 0; i < nvars; ++i )
    4311 {
    4312 if( vals[i] > 0.0 )
    4313 nposcoeffs++;
    4314 else
    4315 nnegcoeffs++;
    4316 }
    4317 if( nposcoeffs > nnegcoeffs )
    4318 mult = +1;
    4319 else if( nposcoeffs < nnegcoeffs )
    4320 mult = -1;
    4321 }
    4322
    4323 if( mult == 0 )
    4324 {
    4325 /* 5. multiply with +1 */
    4326 mult = +1;
    4327 }
    4328
    4329 assert(mult == +1 || mult == -1);
    4330 if( mult == -1 )
    4331 {
    4332 /* scale the constraint with -1 */
    4333 SCIPdebugMsg(scip, "multiply linear constraint with -1.0\n");
    4335 SCIP_CALL( scaleCons(scip, cons, -1.0) );
    4336
    4337 /* scalecons() can delete variables, but scaling with -1 should not do that */
    4338 assert(nvars == consdata->nvars);
    4339 }
    4340
    4341 /*
    4342 * rationals to integrals
    4343 *
    4344 * @todo try scaling only on behalf of non-continuous variables
    4345 */
    4346 success = TRUE;
    4347 scm = 1;
    4348 for( i = 0; i < nvars && success && scm <= maxmult; ++i )
    4349 {
    4350 if( !SCIPisIntegral(scip, vals[i]) )
    4351 {
    4352 /* epsilon has been slightly decreased above - to be on the safe side */
    4353 success = SCIPrealToRational(vals[i], -epsilon, epsilon , maxmult, &numerator, &denominator);
    4354 if( success )
    4355 scm = SCIPcalcSmaComMul(scm, denominator);
    4356 }
    4357 }
    4358 assert(scm >= 1);
    4359
    4360 /* it might be that we have really big coefficients, but all are integral, in that case we want to divide them by
    4361 * their greatest common divisor
    4362 */
    4363 onlyintegral = TRUE;
    4364 if( scm == 1 )
    4365 {
    4366 for( i = nvars - 1; i >= 0; --i )
    4367 {
    4368 if( !SCIPisIntegral(scip, vals[i]) )
    4369 {
    4370 onlyintegral = FALSE;
    4371 break;
    4372 }
    4373 }
    4374 }
    4375
    4376 success = success && (scm <= maxmult || (scm == 1 && onlyintegral));
    4377 if( success && scm != 1 )
    4378 {
    4379 /* scale the constraint with the smallest common multiple of all denominators */
    4380 SCIPdebugMsg(scip, "scale linear constraint with %" SCIP_LONGINT_FORMAT " to make coefficients integral\n", scm);
    4382 SCIP_CALL( scaleCons(scip, cons, (SCIP_Real)scm) );
    4383
    4384 if( consdata->validmaxabsval )
    4385 {
    4386 consdata->maxabsval *= REALABS((SCIP_Real)scm);
    4387 if( !SCIPisIntegral(scip, consdata->maxabsval) )
    4388 {
    4389 consdata->validmaxabsval = FALSE;
    4390 consdata->maxabsval = SCIP_INVALID;
    4391 consdataCalcMaxAbsval(consdata);
    4392 }
    4393 }
    4394
    4395 if( consdata->validminabsval )
    4396 {
    4397 consdata->minabsval *= REALABS((SCIP_Real)scm);
    4398 if( !SCIPisIntegral(scip, consdata->minabsval) )
    4399 {
    4400 consdata->validminabsval = FALSE;
    4401 consdata->minabsval = SCIP_INVALID;
    4402 consdataCalcMinAbsval(consdata);
    4403 }
    4404 }
    4405
    4406 /* get new consdata information, because scalecons() might have deleted variables */
    4407 vals = consdata->vals;
    4408 nvars = consdata->nvars;
    4409 assert(nvars == 0 || vals != NULL);
    4410 }
    4411
    4412 /*
    4413 * division by greatest common divisor
    4414 */
    4415 if( success && nvars >= 1 )
    4416 {
    4417 /* all coefficients are integral: divide them by their greatest common divisor */
    4418 assert(SCIPisIntegral(scip, vals[0]));
    4419
    4420 gcd = (SCIP_Longint)(REALABS(vals[0]) + feastol);
    4421 for( i = 1; i < nvars && gcd > 1; ++i )
    4422 {
    4423 assert(SCIPisIntegral(scip, vals[i]));
    4424 gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[i]) + feastol));
    4425 }
    4426
    4427 if( gcd > 1 )
    4428 {
    4429 /* since the lhs/rhs is not respected for gcd calculation it can happen that we detect infeasibility */
    4430 if( !consdata->hascontvar && onlyintegral )
    4431 {
    4432 if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) && !SCIPisFeasIntegral(scip, consdata->rhs / gcd) )
    4433 {
    4434 *infeasible = TRUE;
    4435
    4436 SCIPdebugMsg(scip, "detected infeasibility of constraint after scaling with gcd=%" SCIP_LONGINT_FORMAT ":\n", gcd);
    4438
    4439 return SCIP_OKAY;
    4440 }
    4441 }
    4442
    4443 /* divide the constraint by the greatest common divisor of the coefficients */
    4444 SCIPdebugMsg(scip, "divide linear constraint by greatest common divisor %" SCIP_LONGINT_FORMAT "\n", gcd);
    4446 SCIP_CALL( scaleCons(scip, cons, 1.0/(SCIP_Real)gcd) );
    4447
    4448 if( consdata->validmaxabsval )
    4449 {
    4450 consdata->maxabsval /= REALABS((SCIP_Real)gcd);
    4451 }
    4452 if( consdata->validminabsval )
    4453 {
    4454 consdata->minabsval /= REALABS((SCIP_Real)gcd);
    4455 }
    4456 }
    4457 }
    4458
    4459 /* mark constraint to be normalized */
    4460 consdata->normalized = TRUE;
    4461
    4462 SCIPdebugMsg(scip, "normalized constraint:\n");
    4464
    4465 return SCIP_OKAY;
    4466}
    4467
    4468/** replaces multiple occurrences of a variable by a single non-zero coefficient */
    4469static
    4471 SCIP* scip, /**< SCIP data structure */
    4472 SCIP_CONS* cons /**< linear constraint */
    4473 )
    4474{
    4475 SCIP_CONSDATA* consdata;
    4476 SCIP_VAR* var;
    4477 SCIP_Real valsum;
    4478 int v;
    4479
    4480 assert(scip != NULL);
    4481 assert(cons != NULL);
    4482
    4483 consdata = SCIPconsGetData(cons);
    4484 assert(consdata != NULL);
    4485
    4486 if( consdata->merged )
    4487 return SCIP_OKAY;
    4488
    4489 /* sort the constraint */
    4490 SCIP_CALL( consdataSort(scip, consdata) );
    4491
    4492 v = consdata->nvars - 1;
    4493
    4494 /* go backwards through the constraint looking for multiple occurrences of the same variable;
    4495 * backward direction is necessary, since delCoefPos() modifies the given position and
    4496 * the subsequent ones
    4497 */
    4498 while( v >= 0 )
    4499 {
    4500 var = consdata->vars[v];
    4501 valsum = consdata->vals[v];
    4502
    4503 /* sum multiple occurrences */
    4504 while( v >= 1 && consdata->vars[v-1] == var )
    4505 {
    4506 SCIP_CALL( delCoefPos(scip, cons, v) );
    4507 --v;
    4508 valsum += consdata->vals[v];
    4509 }
    4510
    4511 assert(consdata->vars[v] == var);
    4512
    4513 /* modify the last existing occurrence of the variable */
    4514 if( SCIPisZero(scip, valsum) )
    4515 {
    4516 SCIP_CALL( delCoefPos(scip, cons, v) );
    4517 }
    4518 else if( valsum != consdata->vals[v] ) /*lint !e777*/
    4519 {
    4520 SCIP_CALL( chgCoefPos(scip, cons, v, valsum) );
    4521 }
    4522
    4523 --v;
    4524 }
    4525
    4526 consdata->merged = TRUE;
    4527
    4528 return SCIP_OKAY;
    4529}
    4530
    4531/** replaces all fixed and aggregated variables by their non-fixed counterparts */
    4532static
    4534 SCIP* scip, /**< SCIP data structure */
    4535 SCIP_CONS* cons, /**< linear constraint */
    4536 SCIP_Bool* infeasible /**< pointer to store if infeasibility is detected; or NULL if this
    4537 * information is not needed; in this case, we apply all fixings
    4538 * instead of stopping after the first infeasible one */
    4539 )
    4540{
    4541 SCIP_CONSDATA* consdata;
    4542 int v;
    4543
    4544 assert(scip != NULL);
    4545 assert(cons != NULL);
    4546
    4547 if( infeasible != NULL )
    4548 *infeasible = FALSE;
    4549
    4550 consdata = SCIPconsGetData(cons);
    4551 assert(consdata != NULL);
    4552
    4553 if( consdata->eventdata == NULL )
    4554 {
    4555 SCIP_CONSHDLR* conshdlr;
    4556 SCIP_CONSHDLRDATA* conshdlrdata;
    4557
    4558 conshdlr = SCIPconsGetHdlr(cons);
    4559 assert(conshdlr != NULL);
    4560
    4561 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    4562 assert(conshdlrdata != NULL);
    4563
    4564 /* catch bound change events of variables */
    4565 SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    4566 assert(consdata->eventdata != NULL);
    4567 }
    4568
    4569 if( !consdata->removedfixings )
    4570 {
    4571 SCIP_Real lhssubtrahend;
    4572 SCIP_Real rhssubtrahend;
    4573
    4574 /* if an unmodifiable row has been added to the LP, then we cannot apply fixing anymore (cannot change a row)
    4575 * this should not happen, as applyFixings is called in addRelaxation() before creating and adding a row
    4576 */
    4577 assert(consdata->row == NULL || !SCIProwIsInLP(consdata->row) || SCIProwIsModifiable(consdata->row));
    4578
    4579 lhssubtrahend = 0.0;
    4580 rhssubtrahend = 0.0;
    4581
    4582 SCIPdebugMsg(scip, "applying fixings:\n");
    4584
    4585 v = 0;
    4586 while( v < consdata->nvars )
    4587 {
    4588 SCIP_VAR* var = consdata->vars[v];
    4589 SCIP_Real scalar = consdata->vals[v];
    4590 SCIP_Real constant = 0.0;
    4591 assert(SCIPvarIsTransformed(var));
    4592
    4593 SCIP_CALL( SCIPgetProbvarSum(scip, &var, &scalar, &constant) );
    4594
    4595 switch( SCIPvarGetStatus(var) )
    4596 {
    4598 SCIPerrorMessage("original variable in transformed linear constraint\n");
    4599 return SCIP_INVALIDDATA;
    4600
    4603 SCIPerrorMessage("aggregated variable after resolving linear term\n");
    4604 return SCIP_INVALIDDATA;
    4605
    4608 if( var != consdata->vars[v] )
    4609 {
    4610 assert(scalar != 0.0);
    4611 SCIP_CALL( addCoef(scip, cons, var, scalar) );
    4612 SCIP_CALL( delCoefPos(scip, cons, v) );
    4613
    4614 assert(!SCIPisInfinity(scip, ABS(constant)));
    4615 if( !SCIPisInfinity(scip, -consdata->lhs) )
    4616 lhssubtrahend += constant;
    4617 if( !SCIPisInfinity(scip, consdata->rhs) )
    4618 rhssubtrahend += constant;
    4619 }
    4620 ++v;
    4621 break;
    4622
    4624 if( scalar != 0.0 )
    4625 {
    4626 SCIP_VAR** aggrvars;
    4627 SCIP_Real* aggrscalars;
    4628 SCIP_Real aggrconstant;
    4629 int naggrvars;
    4630 int i;
    4631
    4633 aggrvars = SCIPvarGetMultaggrVars(var);
    4634 aggrscalars = SCIPvarGetMultaggrScalars(var);
    4635 aggrconstant = SCIPvarGetMultaggrConstant(var);
    4636 naggrvars = SCIPvarGetMultaggrNVars(var);
    4637
    4638 for( i = 0; i < naggrvars; ++i )
    4639 {
    4640 SCIP_CALL( addCoef(scip, cons, aggrvars[i], scalar * aggrscalars[i]) );
    4641 }
    4642
    4643 constant += scalar * aggrconstant;
    4644 }
    4645 /*lint -fallthrough*/
    4646
    4648 if( !SCIPisInfinity(scip, -consdata->lhs) )
    4649 {
    4650 if( SCIPisInfinity(scip, ABS(constant)) )
    4651 {
    4652 /* if lhs gets infinity it means that the problem is infeasible */
    4653 if( constant < 0.0 )
    4654 {
    4656
    4657 if( infeasible != NULL )
    4658 {
    4659 *infeasible = TRUE;
    4660 return SCIP_OKAY;
    4661 }
    4662 }
    4663 else
    4664 {
    4665 SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
    4666 }
    4667 }
    4668 else
    4669 lhssubtrahend += constant;
    4670 }
    4671 if( !SCIPisInfinity(scip, consdata->rhs) )
    4672 {
    4673 if( SCIPisInfinity(scip, ABS(constant)) )
    4674 {
    4675 /* if rhs gets -infinity it means that the problem is infeasible */
    4676 if( constant > 0.0 )
    4677 {
    4678 SCIP_CALL( chgRhs(scip, cons, -SCIPinfinity(scip)) );
    4679
    4680 if( infeasible != NULL )
    4681 {
    4682 *infeasible = TRUE;
    4683 return SCIP_OKAY;
    4684 }
    4685 }
    4686 else
    4687 {
    4689 }
    4690 }
    4691 else
    4692 rhssubtrahend += constant;
    4693 }
    4694 SCIP_CALL( delCoefPos(scip, cons, v) );
    4695 break;
    4696
    4697 default:
    4698 SCIPerrorMessage("unknown variable status\n");
    4699 SCIPABORT();
    4700 return SCIP_INVALIDDATA; /*lint !e527*/
    4701 }
    4702 }
    4703
    4704 if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->lhs) )
    4705 {
    4706 /* check left hand side of unmodifiable empty constraint with former feasibility tolerance */
    4707 if( !SCIPconsIsModifiable(cons) && consdata->nvars == 0 )
    4708 {
    4709 if( SCIPisFeasLT(scip, lhssubtrahend, consdata->lhs) )
    4710 {
    4712
    4713 if( infeasible != NULL )
    4714 {
    4715 *infeasible = TRUE;
    4716 return SCIP_OKAY;
    4717 }
    4718 }
    4719 else
    4720 {
    4721 SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
    4722 }
    4723 }
    4724 /* for normal numbers that are relatively equal, subtraction can lead to cancellation,
    4725 * causing wrong fixings of other variables --> better use a real zero here
    4726 */
    4727 else if( SCIPisGE(scip, ABS(consdata->lhs), 1.0) && SCIPisEQ(scip, lhssubtrahend, consdata->lhs) )
    4728 {
    4729 SCIP_CALL( chgLhs(scip, cons, 0.0) );
    4730 }
    4731 else
    4732 {
    4733 SCIP_CALL( chgLhs(scip, cons, consdata->lhs - lhssubtrahend) );
    4734 }
    4735 }
    4736 if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->rhs) )
    4737 {
    4738 /* check right hand side of unmodifiable empty constraint with former feasibility tolerance */
    4739 if( !SCIPconsIsModifiable(cons) && consdata->nvars == 0 )
    4740 {
    4741 if( SCIPisFeasGT(scip, rhssubtrahend, consdata->rhs) )
    4742 {
    4743 SCIP_CALL( chgRhs(scip, cons, -SCIPinfinity(scip)) );
    4744
    4745 if( infeasible != NULL )
    4746 {
    4747 *infeasible = TRUE;
    4748 return SCIP_OKAY;
    4749 }
    4750 }
    4751 else
    4752 {
    4754 }
    4755 }
    4756 /* for normal numbers that are relatively equal, subtraction can lead to cancellation,
    4757 * causing wrong fixings of other variables --> better use a real zero here
    4758 */
    4759 else if( SCIPisGE(scip, ABS(consdata->rhs), 1.0) && SCIPisEQ(scip, rhssubtrahend, consdata->rhs) )
    4760 {
    4761 SCIP_CALL( chgRhs(scip, cons, 0.0) );
    4762 }
    4763 else
    4764 {
    4765 SCIP_CALL( chgRhs(scip, cons, consdata->rhs - rhssubtrahend) );
    4766 }
    4767 }
    4768 consdata->removedfixings = TRUE;
    4769
    4770 SCIPdebugMsg(scip, "after fixings:\n");
    4772
    4773 /* if aggregated variables have been replaced, multiple entries of the same variable are possible and we have
    4774 * to clean up the constraint
    4775 */
    4776 SCIP_CALL( mergeMultiples(scip, cons) );
    4777
    4778 SCIPdebugMsg(scip, "after merging:\n");
    4780 }
    4781 assert(consdata->removedfixings);
    4782
    4783#ifndef NDEBUG
    4784 /* check, if all fixings are applied */
    4785 for( v = 0; v < consdata->nvars; ++v )
    4786 assert(SCIPvarIsActive(consdata->vars[v]));
    4787#endif
    4788
    4789 return SCIP_OKAY;
    4790}
    4791
    4792/** for each variable in the linear constraint, except the inferred variable, adds one bound to the conflict analysis'
    4793 * candidate store (bound depends on sign of coefficient and whether the left or right hand side was the reason for the
    4794 * inference variable's bound change); the conflict analysis can be initialized with the linear constraint being the
    4795 * conflict detecting constraint by using NULL as inferred variable
    4796 */
    4797static
    4799 SCIP* scip, /**< SCIP data structure */
    4800 SCIP_CONS* cons, /**< constraint that inferred the bound change */
    4801 SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
    4802 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
    4803 int inferpos, /**< position of the inferred variable in the vars array */
    4804 SCIP_Bool reasonisrhs /**< is the right hand side responsible for the bound change? */
    4805 )
    4806{
    4807 SCIP_CONSDATA* consdata;
    4808 SCIP_VAR** vars;
    4809 SCIP_Real* vals;
    4810 int nvars;
    4811 int i;
    4812
    4813 assert(scip != NULL);
    4814 assert(cons != NULL);
    4815
    4816 consdata = SCIPconsGetData(cons);
    4817
    4818 assert(consdata != NULL);
    4819
    4820 vars = consdata->vars;
    4821 vals = consdata->vals;
    4822 nvars = consdata->nvars;
    4823
    4824 assert(vars != NULL || nvars == 0);
    4825 assert(vals != NULL || nvars == 0);
    4826
    4827 assert(-1 <= inferpos && inferpos < nvars);
    4828 assert((infervar == NULL) == (inferpos == -1));
    4829 assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
    4830
    4831 /* for each variable, add the bound to the conflict queue, that is responsible for the minimal or maximal
    4832 * residual value, depending on whether the left or right hand side is responsible for the bound change:
    4833 * - if the right hand side is the reason, the minimal residual activity is responsible
    4834 * - if the left hand side is the reason, the maximal residual activity is responsible
    4835 */
    4836
    4837 /* if the variable is integral we only need to add reason bounds until the propagation could be applied */
    4838 if( infervar == NULL || SCIPvarIsIntegral(infervar) )
    4839 {
    4840 SCIP_Real minresactivity;
    4841 SCIP_Real maxresactivity;
    4842 SCIP_Bool ismintight;
    4843 SCIP_Bool ismaxtight;
    4844 SCIP_Bool isminsettoinfinity;
    4845 SCIP_Bool ismaxsettoinfinity;
    4846
    4847 minresactivity = -SCIPinfinity(scip);
    4848 maxresactivity = SCIPinfinity(scip);
    4849
    4850 /* calculate the minimal and maximal global activity of all other variables involved in the constraint */
    4851 if( infervar != NULL )
    4852 {
    4853 assert(vals != NULL); /* for flexelint */
    4854 if( reasonisrhs )
    4855 consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, &minresactivity, NULL,
    4856 &ismintight, NULL, &isminsettoinfinity, NULL);
    4857 else
    4858 consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, NULL, &maxresactivity,
    4859 NULL, &ismaxtight, NULL, &ismaxsettoinfinity);
    4860 }
    4861 else
    4862 {
    4863 if( reasonisrhs )
    4864 consdataGetGlbActivityBounds(scip, consdata, FALSE, &minresactivity, NULL,
    4865 &ismintight, NULL, &isminsettoinfinity, NULL);
    4866 else
    4867 consdataGetGlbActivityBounds(scip, consdata, FALSE, NULL, &maxresactivity,
    4868 NULL, &ismaxtight, NULL, &ismaxsettoinfinity);
    4869 }
    4870
    4871 /* we can only do something clever, if the residual activity is finite and not relaxed */
    4872 if( (reasonisrhs && !isminsettoinfinity && ismintight) || (!reasonisrhs && !ismaxsettoinfinity && ismaxtight) ) /*lint !e644*/
    4873 {
    4874 SCIP_Real rescap;
    4875 SCIP_Bool resactisinf;
    4876
    4877 resactisinf = FALSE;
    4878
    4879 /* calculate the residual capacity that would be left, if the variable would be set to one more / one less
    4880 * than its inferred bound
    4881 */
    4882 if( infervar != NULL )
    4883 {
    4884 assert(vals != NULL); /* for flexelint */
    4885
    4886 if( reasonisrhs )
    4887 {
    4888 if( SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
    4889 {
    4890 consdataGetReliableResidualActivity(scip, consdata, infervar, &minresactivity, TRUE, TRUE);
    4891 if( SCIPisInfinity(scip, -minresactivity) )
    4892 resactisinf = TRUE;
    4893 }
    4894 rescap = consdata->rhs - minresactivity;
    4895 }
    4896 else
    4897 {
    4898 if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
    4899 {
    4900 consdataGetReliableResidualActivity(scip, consdata, infervar, &maxresactivity, FALSE, TRUE);
    4901 if( SCIPisInfinity(scip, maxresactivity) )
    4902 resactisinf = TRUE;
    4903 }
    4904 rescap = consdata->lhs - maxresactivity;
    4905 }
    4906
    4907 if( reasonisrhs == (vals[inferpos] > 0.0) )
    4908 rescap -= vals[inferpos] * (SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) + 1.0);
    4909 else
    4910 rescap -= vals[inferpos] * (SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) - 1.0);
    4911 }
    4912 else
    4913 rescap = (reasonisrhs ? consdata->rhs - minresactivity : consdata->lhs - maxresactivity);
    4914
    4915 if( !resactisinf )
    4916 {
    4917 /* now add bounds as reasons until the residual capacity is exceeded */
    4918 for( i = 0; i < nvars; ++i )
    4919 {
    4920 assert( vars != NULL && vals != NULL ); /* for lint */
    4921
    4922 /* zero coefficients and the inferred variable can be ignored */
    4923 if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
    4924 continue;
    4925
    4926 /* check if the residual capacity is exceeded */
    4927 if( (reasonisrhs && SCIPisFeasNegative(scip, rescap))
    4928 || (!reasonisrhs && SCIPisFeasPositive(scip, rescap)) )
    4929 break;
    4930
    4931 /* update the residual capacity due to the local bound of this variable */
    4932 if( reasonisrhs == (vals[i] > 0.0) )
    4933 {
    4934 /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound */
    4935 SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
    4936 rescap -= vals[i] * (SCIPgetVarLbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetLbGlobal(vars[i]));
    4937 }
    4938 else
    4939 {
    4940 /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound */
    4941 SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
    4942 rescap -= vals[i] * (SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetUbGlobal(vars[i]));
    4943 }
    4944 }
    4945 return SCIP_OKAY;
    4946 }
    4947 }
    4948 }
    4949
    4950 /* for a bound change on a continuous variable, all locally changed bounds are responsible */
    4951 for( i = 0; i < nvars; ++i )
    4952 {
    4953 assert(vars != NULL); /* for flexelint */
    4954 assert(vals != NULL); /* for flexelint */
    4955
    4956 /* zero coefficients and the inferred variable can be ignored */
    4957 if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
    4958 continue;
    4959
    4960 if( reasonisrhs == (vals[i] > 0.0) )
    4961 {
    4962 /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound is responsible */
    4963 SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
    4964 }
    4965 else
    4966 {
    4967 /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound is responsible */
    4968 SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
    4969 }
    4970 }
    4971
    4972 return SCIP_OKAY;
    4973}
    4974
    4975/** for each variable in the linear ranged row constraint, except the inferred variable, adds the bounds of all fixed
    4976 * variables to the conflict analysis' candidate store; the conflict analysis can be initialized
    4977 * with the linear constraint being the conflict detecting constraint by using NULL as inferred variable
    4978 */
    4979static
    4981 SCIP* scip, /**< SCIP data structure */
    4982 SCIP_CONS* cons, /**< constraint that inferred the bound change */
    4983 SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
    4984 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
    4985 int inferpos /**< position of the inferred variable in the vars array, or -1 */
    4986 )
    4987{
    4988 SCIP_CONSDATA* consdata;
    4989 SCIP_VAR** vars;
    4990 int nvars;
    4991 int v;
    4992
    4993 assert(scip != NULL);
    4994 assert(cons != NULL);
    4995
    4996 consdata = SCIPconsGetData(cons);
    4997 assert(consdata != NULL);
    4998 vars = consdata->vars;
    4999 nvars = consdata->nvars;
    5000 assert(vars != NULL || nvars == 0);
    5001 assert(-1 <= inferpos && inferpos < nvars);
    5002 assert((infervar == NULL) == (inferpos == -1));
    5003 assert(inferpos == -1 || vars != NULL);
    5004 assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
    5005
    5006 /* collect all fixed variables */
    5007 for( v = nvars - 1; v >= 0; --v )
    5008 {
    5009 assert(vars != NULL); /* for flexelint */
    5010
    5011 /* need to add old bounds before propagation of inferrence variable */
    5012 if( vars[v] == infervar )
    5013 {
    5014 assert(vars[v] != NULL);
    5015
    5016 if( !SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetLbGlobal(vars[v])) )
    5017 {
    5018 /* @todo get boundchange index before this last boundchange and correct the index */
    5019 SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
    5020 }
    5021
    5022 if( !SCIPisEQ(scip, SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetUbGlobal(vars[v])) )
    5023 {
    5024 /* @todo get boundchange index before this last boundchange and correct the index */
    5025 SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
    5026 }
    5027
    5028 continue;
    5029 }
    5030
    5031 /* check for fixed variables */
    5032 if( SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE)) )
    5033 {
    5034 /* add all bounds of fixed variables which lead to the boundchange of the given inference variable */
    5035 SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
    5036 SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
    5037 }
    5038 }
    5039
    5040 return SCIP_OKAY;
    5041}
    5042
    5043/** add reasoning variables to conflict candidate queue which led to the conflict */
    5044static
    5046 SCIP* scip, /**< SCIP data structure */
    5047 SCIP_VAR** vars, /**< variables reasoning the infeasibility */
    5048 int nvars, /**< number of variables reasoning the infeasibility */
    5049 SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
    5050 SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
    5051 )
    5052{
    5053 int v;
    5054
    5055 assert(scip != NULL);
    5056
    5057 /* collect all variables for which the local bounds differ from their global bounds */
    5058 for( v = nvars - 1; v >= 0; --v )
    5059 {
    5060 assert(vars != NULL);
    5061
    5062 /* check for local bound changes variables */
    5063 if( !SCIPisEQ(scip, SCIPvarGetLbLocal(vars[v]), SCIPvarGetLbGlobal(vars[v])) )
    5064 {
    5065 /* add conflict bound */
    5066 SCIP_CALL( SCIPaddConflictLb(scip, vars[v], 0) );
    5067 }
    5068
    5069 if( !SCIPisEQ(scip, SCIPvarGetUbLocal(vars[v]), SCIPvarGetUbGlobal(vars[v])) )
    5070 {
    5071 SCIP_CALL( SCIPaddConflictUb(scip, vars[v], 0) );
    5072 }
    5073 }
    5074
    5075 if( var != NULL )
    5076 {
    5077 if( bound < SCIPvarGetLbLocal(var) )
    5078 {
    5079 SCIP_CALL( SCIPaddConflictLb(scip, var, 0) );
    5080 }
    5081
    5082 if( bound > SCIPvarGetUbLocal(var) )
    5083 {
    5084 SCIP_CALL( SCIPaddConflictUb(scip, var, 0) );
    5085 }
    5086 }
    5087
    5088 return SCIP_OKAY;
    5089}
    5090
    5091/** resolves a propagation on the given variable by supplying the variables needed for applying the corresponding
    5092 * propagation rule (see propagateCons()):
    5093 * (1) activity residuals of all other variables tighten bounds of single variable
    5094 */
    5095static
    5097 SCIP* scip, /**< SCIP data structure */
    5098 SCIP_CONS* cons, /**< constraint that inferred the bound change */
    5099 SCIP_VAR* infervar, /**< variable that was deduced */
    5100 INFERINFO inferinfo, /**< inference information */
    5101 SCIP_BOUNDTYPE boundtype, /**< the type of the changed bound (lower or upper bound) */
    5102 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
    5103 SCIP_RESULT* result /**< pointer to store the result of the propagation conflict resolving call */
    5104 )
    5105{
    5106 SCIP_CONSDATA* consdata;
    5107 SCIP_VAR** vars;
    5108#ifndef NDEBUG
    5109 SCIP_Real* vals;
    5110#endif
    5111 int nvars;
    5112 int inferpos;
    5113
    5114 assert(scip != NULL);
    5115 assert(cons != NULL);
    5116 assert(result != NULL);
    5117
    5118 consdata = SCIPconsGetData(cons);
    5119 assert(consdata != NULL);
    5120 vars = consdata->vars;
    5121 nvars = consdata->nvars;
    5122#ifndef NDEBUG
    5123 vals = consdata->vals;
    5124 assert(vars != NULL);
    5125 assert(vals != NULL);
    5126#endif
    5127
    5128 /* get the position of the inferred variable in the vars array */
    5129 inferpos = inferInfoGetPos(inferinfo);
    5130 if( inferpos >= nvars || vars[inferpos] != infervar )
    5131 {
    5132 /* find inference variable in constraint */
    5133 /**@todo use a binary search here; the variables can be sorted by variable index */
    5134 for( inferpos = 0; inferpos < nvars && vars[inferpos] != infervar; ++inferpos )
    5135 {}
    5136 }
    5137 assert(inferpos < nvars);
    5138 assert(vars[inferpos] == infervar);
    5139 assert(!SCIPisZero(scip, vals[inferpos]));
    5140
    5141 switch( inferInfoGetProprule(inferinfo) )
    5142 {
    5143 case PROPRULE_1_RHS:
    5144 /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
    5145 * constraint (only taking the other variables into account) didn't leave enough space for a larger
    5146 * domain in order to not exceed the right hand side of the inequality
    5147 */
    5148 assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_UPPER));
    5149 SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, TRUE) );
    5150 *result = SCIP_SUCCESS;
    5151 break;
    5152
    5153 case PROPRULE_1_LHS:
    5154 /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
    5155 * constraint (only taking the other variables into account) didn't leave enough space for a larger
    5156 * domain in order to not fall below the left hand side of the inequality
    5157 */
    5158 assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_LOWER));
    5159 SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, FALSE) );
    5160 *result = SCIP_SUCCESS;
    5161 break;
    5162
    5164 /* the bound of the variable was tightened, because some variables were already fixed and the leftover only allow
    5165 * the given inference variable to their bounds in this given ranged row
    5166 */
    5167
    5168 /* check that we really have a ranged row here */
    5169 assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
    5170 SCIP_CALL( addConflictFixedVars(scip, cons, infervar, bdchgidx, inferpos) );
    5171 *result = SCIP_SUCCESS;
    5172 break;
    5173
    5174 case PROPRULE_INVALID:
    5175 default:
    5176 SCIPerrorMessage("invalid inference information %d in linear constraint <%s> at position %d for %s bound of variable <%s>\n",
    5177 inferInfoGetProprule(inferinfo), SCIPconsGetName(cons), inferInfoGetPos(inferinfo),
    5178 boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper", SCIPvarGetName(infervar));
    5179 SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
    5180 SCIPinfoMessage(scip, NULL, ";\n");
    5181 return SCIP_INVALIDDATA;
    5182 }
    5183
    5184 return SCIP_OKAY;
    5185}
    5186
    5187/** analyzes conflicting bounds on given constraint, and adds conflict constraint to problem */
    5188static
    5190 SCIP* scip, /**< SCIP data structure */
    5191 SCIP_CONS* cons, /**< conflict detecting constraint */
    5192 SCIP_Bool reasonisrhs /**< is the right hand side responsible for the conflict? */
    5193 )
    5194{
    5195 /* conflict analysis can only be applied in solving stage and if it is turned on */
    5197 return SCIP_OKAY;
    5198
    5199 /* initialize conflict analysis */
    5201
    5202 /* add the conflicting bound for each variable of infeasible constraint to conflict candidate queue */
    5203 SCIP_CALL( addConflictBounds(scip, cons, NULL, NULL, -1, reasonisrhs) );
    5204
    5205 /* analyze the conflict */
    5207
    5208 return SCIP_OKAY;
    5209}
    5210
    5211/** check if there is any hope of tightening some bounds */
    5212static
    5214 SCIP_CONS* cons /**< linear constraint */
    5215 )
    5216{
    5217 SCIP_CONSDATA* consdata;
    5218 int infcountmin;
    5219 int infcountmax;
    5220
    5221 consdata = SCIPconsGetData(cons);
    5222 assert(consdata != NULL);
    5223
    5224 infcountmin = consdata->minactivityneginf
    5225 + consdata->minactivityposinf
    5226 + consdata->minactivityneghuge
    5227 + consdata->minactivityposhuge;
    5228 infcountmax = consdata->maxactivityneginf
    5229 + consdata->maxactivityposinf
    5230 + consdata->maxactivityneghuge
    5231 + consdata->maxactivityposhuge;
    5232
    5233 if( infcountmin > 1 && infcountmax > 1 )
    5234 return FALSE;
    5235
    5236 return TRUE;
    5237}
    5238
    5239/** tighten upper bound */
    5240static
    5242 SCIP* scip, /**< SCIP data structure */
    5243 SCIP_CONS* cons, /**< linear constraint */
    5244 int pos, /**< variable position */
    5245 PROPRULE proprule, /**< propagation rule that deduced the value */
    5246 SCIP_Real newub, /**< new upper bound */
    5247 SCIP_Real oldub, /**< old upper bound */
    5248 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    5249 int* nchgbds, /**< pointer to count the total number of tightened bounds */
    5250 SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
    5251 )
    5252{
    5253 SCIP_CONSDATA* consdata;
    5254 SCIP_VAR* var;
    5255 SCIP_Real lb;
    5256 SCIP_Bool infeasible;
    5257 SCIP_Bool tightened;
    5258
    5259 assert(cons != NULL);
    5260 assert(!SCIPisInfinity(scip, newub));
    5261
    5262 consdata = SCIPconsGetData(cons);
    5263 assert(consdata != NULL);
    5264 var = consdata->vars[pos];
    5265 assert(var != NULL);
    5266
    5267 lb = SCIPvarGetLbLocal(var);
    5268 newub = SCIPadjustedVarUb(scip, var, newub);
    5269
    5270 if( force || SCIPisUbBetter(scip, newub, lb, oldub) )
    5271 {
    5272 SCIP_VARTYPE vartype = SCIPvarGetType(var);
    5273 SCIP_IMPLINTTYPE impltype = SCIPvarGetImplType(var);
    5274
    5275 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
    5276 SCIPconsGetName(cons), SCIPvarGetName(var), lb, oldub, consdata->vals[pos],
    5277 QUAD_TO_DBL(consdata->minactivity), QUAD_TO_DBL(consdata->maxactivity), consdata->lhs, consdata->rhs, newub);
    5278
    5279 /* tighten upper bound */
    5280 SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
    5281
    5282 if( infeasible )
    5283 {
    5284 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    5285 SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
    5286
    5287 /* analyze conflict */
    5289
    5290 *cutoff = TRUE;
    5291 }
    5292 else if( tightened )
    5293 {
    5294 assert(SCIPisFeasLE(scip, SCIPvarGetUbLocal(var), oldub));
    5295 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
    5296 SCIPconsGetName(cons), SCIPvarGetName(var), lb, SCIPvarGetUbLocal(var));
    5297
    5298 (*nchgbds)++;
    5299
    5300 /* if variable type was changed we might be able to upgrade the constraint */
    5301 if( SCIPvarGetType(var) != vartype || SCIPvarGetImplType(var) != impltype )
    5302 consdata->upgradetried = FALSE;
    5303 }
    5304 }
    5305 return SCIP_OKAY;
    5306}
    5307
    5308/** tighten lower bound */
    5309static
    5311 SCIP* scip, /**< SCIP data structure */
    5312 SCIP_CONS* cons, /**< linear constraint */
    5313 int pos, /**< variable position */
    5314 PROPRULE proprule, /**< propagation rule that deduced the value */
    5315 SCIP_Real newlb, /**< new lower bound */
    5316 SCIP_Real oldlb, /**< old lower bound */
    5317 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    5318 int* nchgbds, /**< pointer to count the total number of tightened bounds */
    5319 SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
    5320 )
    5321{
    5322 SCIP_CONSDATA* consdata;
    5323 SCIP_VAR* var;
    5324 SCIP_Real ub;
    5325 SCIP_Bool infeasible;
    5326 SCIP_Bool tightened;
    5327
    5328 assert(cons != NULL);
    5329 assert(!SCIPisInfinity(scip, newlb));
    5330
    5331 consdata = SCIPconsGetData(cons);
    5332 assert(consdata != NULL);
    5333 var = consdata->vars[pos];
    5334 assert(var != NULL);
    5335
    5336 ub = SCIPvarGetUbLocal(var);
    5337 newlb = SCIPadjustedVarLb(scip, var, newlb);
    5338
    5339 if( force || SCIPisLbBetter(scip, newlb, oldlb, ub) )
    5340 {
    5341 SCIP_VARTYPE vartype = SCIPvarGetType(var);
    5342 SCIP_IMPLINTTYPE impltype = SCIPvarGetImplType(var);
    5343
    5344 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
    5345 SCIPconsGetName(cons), SCIPvarGetName(var), oldlb, ub, consdata->vals[pos],
    5346 QUAD_TO_DBL(consdata->minactivity), QUAD_TO_DBL(consdata->maxactivity), consdata->lhs, consdata->rhs, newlb);
    5347
    5348 /* tighten lower bound */
    5349 SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
    5350
    5351 if( infeasible )
    5352 {
    5353 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    5354 SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
    5355
    5356 /* analyze conflict */
    5358
    5359 *cutoff = TRUE;
    5360 }
    5361 else if( tightened )
    5362 {
    5363 assert(SCIPisFeasGE(scip, SCIPvarGetLbLocal(var), oldlb));
    5364 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
    5365 SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetLbLocal(var), ub);
    5366
    5367 (*nchgbds)++;
    5368
    5369 /* if variable type was changed we might be able to upgrade the constraint */
    5370 if( SCIPvarGetType(var) != vartype || SCIPvarGetImplType(var) != impltype )
    5371 consdata->upgradetried = FALSE;
    5372 }
    5373 }
    5374 return SCIP_OKAY;
    5375}
    5376
    5377/** tightens bounds of a single variable due to activity bounds (easy case) */
    5378static
    5380 SCIP* scip, /**< SCIP data structure */
    5381 SCIP_CONS* cons, /**< linear constraint */
    5382 int pos, /**< position of the variable in the vars array */
    5383 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    5384 int* nchgbds, /**< pointer to count the total number of tightened bounds */
    5385 SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
    5386 )
    5387{
    5388 SCIP_CONSDATA* consdata;
    5389 SCIP_VAR* var;
    5390 SCIP_Real val;
    5391 SCIP_Real lb;
    5392 SCIP_Real ub;
    5393 SCIP_Real lhs;
    5394 SCIP_Real rhs;
    5395
    5396 assert(scip != NULL);
    5397 assert(cons != NULL);
    5398 assert(cutoff != NULL);
    5399 assert(nchgbds != NULL);
    5400
    5401 /* we cannot tighten variables' bounds, if the constraint may be not complete */
    5402 if( SCIPconsIsModifiable(cons) )
    5403 return SCIP_OKAY;
    5404
    5405 consdata = SCIPconsGetData(cons);
    5406 assert(consdata != NULL);
    5407 assert(0 <= pos && pos < consdata->nvars);
    5408
    5409 *cutoff = FALSE;
    5410
    5411 var = consdata->vars[pos];
    5412 assert(var != NULL);
    5413
    5414 /* we cannot tighten bounds of multi-aggregated variables */
    5416 return SCIP_OKAY;
    5417
    5418 val = consdata->vals[pos];
    5419 lhs = consdata->lhs;
    5420 rhs = consdata->rhs;
    5421 assert(!SCIPisZero(scip, val));
    5422 assert(!SCIPisInfinity(scip, lhs));
    5423 assert(!SCIPisInfinity(scip, -rhs));
    5424
    5425 lb = SCIPvarGetLbLocal(var);
    5426 ub = SCIPvarGetUbLocal(var);
    5427 assert(SCIPisLE(scip, lb, ub));
    5428
    5429 /* recompute activities if needed */
    5430 if( !consdata->validactivities )
    5431 consdataCalcActivities(scip, consdata);
    5432 assert(consdata->validactivities);
    5433 if( !consdata->validminact )
    5435 assert(consdata->validminact);
    5436
    5437 if( val > 0.0 )
    5438 {
    5439 /* check, if we can tighten the variable's upper bound */
    5440 if( !SCIPisInfinity(scip, rhs) )
    5441 {
    5442 SCIP_Real slack;
    5443 SCIP_Real alpha;
    5444
    5445 /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
    5446 assert(consdata->validminact);
    5447
    5448 /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
    5449 if( SCIPisFeasLT(scip, rhs, QUAD_TO_DBL(consdata->minactivity)) )
    5450 {
    5451 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
    5452 SCIPconsGetName(cons), SCIPvarGetName(var), QUAD_TO_DBL(consdata->minactivity), rhs);
    5453
    5454 *cutoff = TRUE;
    5455 return SCIP_OKAY;
    5456 }
    5457
    5458 slack = rhs - QUAD_TO_DBL(consdata->minactivity);
    5459
    5460 /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
    5461 * it to zero
    5462 */
    5463 if( !SCIPisPositive(scip, slack) )
    5464 slack = 0.0;
    5465
    5466 alpha = val * (ub - lb);
    5467 assert(!SCIPisNegative(scip, alpha));
    5468
    5469 if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
    5470 {
    5471 SCIP_Real newub;
    5472
    5473 /* compute new upper bound */
    5474 newub = lb + (slack / val);
    5475
    5476 SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_RHS, newub, ub, cutoff, nchgbds, force) );
    5477
    5478 if( *cutoff )
    5479 {
    5480 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    5481 SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
    5482
    5483 return SCIP_OKAY;
    5484 }
    5485
    5486 /* collect the new upper bound which is needed for the lower bound computation */
    5487 ub = SCIPvarGetUbLocal(var);
    5488 }
    5489 }
    5490
    5491 /* check, if we can tighten the variable's lower bound */
    5492 if( !SCIPisInfinity(scip, -lhs) )
    5493 {
    5494 SCIP_Real slack;
    5495 SCIP_Real alpha;
    5496
    5497 /* make sure the max activity is reliable */
    5498 if( !consdata->validmaxact )
    5499 {
    5501 }
    5502 assert(consdata->validmaxact);
    5503
    5504 /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
    5505 if( SCIPisFeasLT(scip, QUAD_TO_DBL(consdata->maxactivity), lhs) )
    5506 {
    5507 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
    5508 SCIPconsGetName(cons), SCIPvarGetName(var), QUAD_TO_DBL(consdata->maxactivity), lhs);
    5509
    5510 *cutoff = TRUE;
    5511 return SCIP_OKAY;
    5512 }
    5513
    5514 slack = QUAD_TO_DBL(consdata->maxactivity) - lhs;
    5515
    5516 /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
    5517 * it to zero
    5518 */
    5519 if( !SCIPisPositive(scip, slack) )
    5520 slack = 0.0;
    5521
    5522 alpha = val * (ub - lb);
    5523 assert(!SCIPisNegative(scip, alpha));
    5524
    5525 if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
    5526 {
    5527 SCIP_Real newlb;
    5528
    5529 /* compute new lower bound */
    5530 newlb = ub - (slack / val);
    5531
    5532 SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_LHS, newlb, lb, cutoff, nchgbds, force) );
    5533
    5534 if( *cutoff )
    5535 {
    5536 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    5537 SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
    5538
    5539 return SCIP_OKAY;
    5540 }
    5541 }
    5542 }
    5543 }
    5544 else
    5545 {
    5546 /* check, if we can tighten the variable's lower bound */
    5547 if( !SCIPisInfinity(scip, rhs) )
    5548 {
    5549 SCIP_Real slack;
    5550 SCIP_Real alpha;
    5551
    5552 /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
    5553 assert(consdata->validminact);
    5554
    5555 /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
    5556 if( SCIPisFeasLT(scip, rhs, QUAD_TO_DBL(consdata->minactivity)) )
    5557 {
    5558 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
    5559 SCIPconsGetName(cons), SCIPvarGetName(var), QUAD_TO_DBL(consdata->minactivity), rhs);
    5560
    5561 *cutoff = TRUE;
    5562 return SCIP_OKAY;
    5563 }
    5564
    5565 slack = rhs - QUAD_TO_DBL(consdata->minactivity);
    5566
    5567 /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
    5568 * it to zero
    5569 */
    5570 if( !SCIPisPositive(scip, slack) )
    5571 slack = 0.0;
    5572
    5573 alpha = val * (lb - ub);
    5574 assert(!SCIPisNegative(scip, alpha));
    5575
    5576 if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
    5577 {
    5578 SCIP_Real newlb;
    5579
    5580 /* compute new lower bound */
    5581 newlb = ub + slack / val;
    5582
    5583 SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_RHS, newlb, lb, cutoff, nchgbds, force) );
    5584
    5585 if( *cutoff )
    5586 {
    5587 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    5588 SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
    5589
    5590 return SCIP_OKAY;
    5591 }
    5592 /* collect the new lower bound which is needed for the upper bound computation */
    5593 lb = SCIPvarGetLbLocal(var);
    5594 }
    5595 }
    5596
    5597 /* check, if we can tighten the variable's upper bound */
    5598 if( !SCIPisInfinity(scip, -lhs) )
    5599 {
    5600 SCIP_Real slack;
    5601 SCIP_Real alpha;
    5602
    5603 /* make sure the max activity is reliable */
    5604 if( !consdata->validmaxact )
    5605 {
    5607 }
    5608 assert(consdata->validmaxact);
    5609
    5610 /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
    5611 if( SCIPisFeasLT(scip, QUAD_TO_DBL(consdata->maxactivity), lhs) )
    5612 {
    5613 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
    5614 SCIPconsGetName(cons), SCIPvarGetName(var), QUAD_TO_DBL(consdata->maxactivity), lhs);
    5615
    5616 *cutoff = TRUE;
    5617 return SCIP_OKAY;
    5618 }
    5619
    5620 slack = QUAD_TO_DBL(consdata->maxactivity) - lhs;
    5621
    5622 /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
    5623 * it to zero
    5624 */
    5625 if( !SCIPisPositive(scip, slack) )
    5626 slack = 0.0;
    5627
    5628 alpha = val * (lb - ub);
    5629 assert(!SCIPisNegative(scip, alpha));
    5630
    5631 if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
    5632 {
    5633 SCIP_Real newub;
    5634
    5635 /* compute new upper bound */
    5636 newub = lb - (slack / val);
    5637
    5638 SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_LHS, newub, ub, cutoff, nchgbds, force) );
    5639
    5640 if( *cutoff )
    5641 {
    5642 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    5643 SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
    5644
    5645 return SCIP_OKAY;
    5646 }
    5647 }
    5648 }
    5649 }
    5650
    5651 return SCIP_OKAY;
    5652}
    5653
    5654/** analyzes conflicting bounds on given ranged row constraint, and adds conflict constraint to problem */
    5655static
    5657 SCIP* scip, /**< SCIP data structure */
    5658 SCIP_CONS* cons, /**< conflict detecting constraint */
    5659 SCIP_VAR** vars, /**< variables reasoning the infeasibility */
    5660 int nvars, /**< number of variables reasoning the infeasibility */
    5661 SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
    5662 SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
    5663 )
    5664{
    5665#ifndef NDEBUG
    5666 SCIP_CONSDATA* consdata;
    5667
    5668 assert(scip != NULL);
    5669 assert(cons != NULL);
    5670
    5671 consdata = SCIPconsGetData(cons);
    5672 assert(consdata != NULL);
    5673 assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
    5674#endif
    5675
    5676 /* conflict analysis can only be applied in solving stage and if it is turned on */
    5678 return SCIP_OKAY;
    5679
    5680 /* initialize conflict analysis */
    5682
    5683 /* add the conflicting fixed variables of this ranged row constraint to conflict candidate queue */
    5685
    5686 /* add reasoning variables to conflict candidate queue which led to the conflict */
    5687 SCIP_CALL( addConflictReasonVars(scip, vars, nvars, var, bound) );
    5688
    5689 /* analyze the conflict */
    5691
    5692 return SCIP_OKAY;
    5693}
    5694
    5695/** propagate ranged rows
    5696 *
    5697 * Check ranged rows for possible solutions, possibly detect infeasibility, fix variables due to having only one possible
    5698 * solution, tighten bounds if having only two possible solutions or add constraints which propagate a subset of
    5699 * variables better.
    5700 *
    5701 * Example:
    5702 * c1: 12 x1 + 9 x2 - x3 = 0 with x1, x2 free and 1 <= x3 <= 2
    5703 *
    5704 * x3 needs to be a multiple of 3, so the instance is infeasible.
    5705 *
    5706 * Example:
    5707 * c1: 12 x1 + 9 x2 - x3 = 1 with x1, x2 free and 1 <= x3 <= 2
    5708 *
    5709 * The only possible value for x3 is 2, so the variable will be fixed.
    5710 *
    5711 * @todo add holes if possible
    5712 */
    5713static
    5715 SCIP* scip, /**< SCIP data structure */
    5716 SCIP_CONS* cons, /**< linear constraint */
    5717 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    5718 int* nfixedvars, /**< pointer to count number of fixed variables */
    5719 int* nchgbds, /**< pointer to count the number of bound changes */
    5720 int* naddconss /**< pointer to count number of added constraints */
    5721 )
    5722{
    5723 SCIP_CONSHDLRDATA* conshdlrdata;
    5724 SCIP_CONSHDLR* conshdlr;
    5725 SCIP_CONSDATA* consdata;
    5726 SCIP_VAR** infcheckvars;
    5727 SCIP_Real* infcheckvals;
    5728 SCIP_Real minactinfvars;
    5729 SCIP_Real maxactinfvars;
    5730 SCIP_Real lb;
    5731 SCIP_Real ub;
    5732 SCIP_Real feastol;
    5733 SCIP_Real fixedact;
    5734 SCIP_Real lhs;
    5735 SCIP_Real rhs;
    5736 SCIP_Real absminbincoef;
    5737 SCIP_Longint gcd;
    5738 SCIP_Longint gcdtmp;
    5739 SCIP_Bool minactinfvarsinvalid;
    5740 SCIP_Bool maxactinfvarsinvalid;
    5741 SCIP_Bool possiblegcd;
    5742 SCIP_Bool gcdisone;
    5743 SCIP_Bool addartconss;
    5744 int ninfcheckvars;
    5745 int nunfixedvars;
    5746 int nfixedconsvars;
    5747 int ncontvars;
    5748 int pos;
    5749 int v;
    5750
    5751 assert(scip != NULL);
    5752 assert(cons != NULL);
    5753 assert(cutoff != NULL);
    5754 assert(nfixedvars != NULL);
    5755 assert(nchgbds != NULL);
    5756 assert(naddconss != NULL);
    5757
    5758 /* modifiable constraint can be changed so we do not have all necessary information */
    5759 if( SCIPconsIsModifiable(cons) )
    5760 return SCIP_OKAY;
    5761
    5762 consdata = SCIPconsGetData(cons);
    5763 assert(consdata != NULL);
    5764
    5765 /* we already did full ranged row propagation */
    5766 if( consdata->rangedrowpropagated == 2 )
    5767 return SCIP_OKAY;
    5768
    5769 /* at least three variables are needed */
    5770 if( consdata->nvars < 3 )
    5771 return SCIP_OKAY;
    5772
    5773 /* do nothing on normal inequalities */
    5774 if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
    5775 return SCIP_OKAY;
    5776
    5777 /* get constraint handler data */
    5778 conshdlr = SCIPconsGetHdlr(cons);
    5779 assert(conshdlr != NULL);
    5780 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    5781 assert(conshdlrdata != NULL);
    5782
    5783 addartconss = conshdlrdata->rangedrowartcons && SCIPgetDepth(scip) < 1 && !SCIPinProbing(scip) && !SCIPinRepropagation(scip);
    5784
    5785 /* we may add artificial constraints */
    5786 if( addartconss )
    5787 consdata->rangedrowpropagated = 2;
    5788 /* we are not allowed to add artificial constraints during propagation; if nothing changed on this constraint since
    5789 * the last rangedrowpropagation, we can stop; otherwise, we mark this constraint to be rangedrowpropagated without
    5790 * artificial constraints
    5791 */
    5792 else
    5793 {
    5794 if( consdata->rangedrowpropagated > 0 )
    5795 return SCIP_OKAY;
    5796
    5797 consdata->rangedrowpropagated = 1;
    5798 }
    5799 fixedact = 0;
    5800 nfixedconsvars = 0;
    5801 /* calculate fixed activity and number of fixed variables */
    5802 for( v = consdata->nvars - 1; v >= 0; --v )
    5803 {
    5804 /* all zero coefficients should be eliminated */
    5805 assert(!SCIPisZero(scip, consdata->vals[v]));
    5806
    5807 if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
    5808 {
    5809 fixedact += SCIPvarGetLbLocal(consdata->vars[v]) * consdata->vals[v];
    5810 ++nfixedconsvars;
    5811 }
    5812 }
    5813
    5814 /* do not work with huge fixed activities */
    5815 if( SCIPisHugeValue(scip, REALABS(fixedact)) )
    5816 return SCIP_OKAY;
    5817
    5818 /* compute lhs and rhs for unfixed variables only and get number of unfixed variables */
    5819 assert(!SCIPisInfinity(scip, -fixedact) && !SCIPisInfinity(scip, fixedact));
    5820 lhs = consdata->lhs - fixedact;
    5821 rhs = consdata->rhs - fixedact;
    5822 nunfixedvars = consdata->nvars - nfixedconsvars;
    5823
    5824 /* allocate temporary memory for variables and coefficients which may lead to infeasibility */
    5825 SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvars, nunfixedvars) );
    5826 SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvals, nunfixedvars) );
    5827
    5828 absminbincoef = SCIP_REAL_MAX;
    5829 ncontvars = 0;
    5830 gcdisone = TRUE;
    5831 possiblegcd = TRUE;
    5832
    5833 /* we now partition all unfixed variables in two groups:
    5834 *
    5835 * the first one contains all integral variable with integral
    5836 * coefficient so that all variables in this group will have a gcd greater than 1, this group will be implicitly
    5837 * given
    5838 *
    5839 * the second group will contain all left unfixed variables and will be saved as infcheckvars with corresponding
    5840 * coefficients as infcheckvals, the order of these variables should be the same as in the consdata object
    5841 */
    5842
    5843 /* find first integral variables with integral coefficient greater than 1, thereby collecting all other unfixed
    5844 * variables
    5845 */
    5846 ninfcheckvars = 0;
    5847 v = -1;
    5848 pos = -1;
    5849 do
    5850 {
    5851 ++v;
    5852
    5853 /* partition the variables, do not change the order of collection, because it might be used later on */
    5854 while( v < consdata->nvars && ( !SCIPvarIsIntegral(consdata->vars[v])
    5855 || !SCIPisIntegral(scip, consdata->vals[v]) || SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0) ) )
    5856 {
    5857 if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
    5858 {
    5859 if( !SCIPvarIsIntegral(consdata->vars[v]) )
    5860 ++ncontvars;
    5861 else if( SCIPvarIsBinary(consdata->vars[v]) )
    5862 {
    5863 SCIP_Real absval;
    5864
    5865 absval = REALABS(consdata->vals[v]);
    5866
    5867 if( absminbincoef > absval )
    5868 absminbincoef = absval;
    5869 }
    5870
    5871 gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
    5872 possiblegcd = FALSE;
    5873 infcheckvars[ninfcheckvars] = consdata->vars[v];
    5874 infcheckvals[ninfcheckvars] = consdata->vals[v];
    5875 ++ninfcheckvars;
    5876
    5877 if( pos == -1 )
    5878 pos = v;
    5879 }
    5880 ++v;
    5881 }
    5882 }
    5883 while( v < consdata->nvars && SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) );
    5884
    5885 /* if the first group of variables is empty, we stop */
    5886 /* @todo try to propagate/split up a constraint of the form:
    5887 * x_1 + ... + x_m + a_1*y_1 + ... + a_n*y_n = k + c,
    5888 * with k \in Z, c \in (d,d + 1], d \in Z, (a_1*y_1 + ... + a_n*y_n) \in (c-1 + d,d + 1]
    5889 */
    5890 if( v == consdata->nvars )
    5891 goto TERMINATE;
    5892
    5893 /* we need at least two non-continuous variables */
    5894 if( ncontvars + 2 > nunfixedvars )
    5895 goto TERMINATE;
    5896
    5897 assert(!SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])));
    5898 assert(SCIPvarIsIntegral(consdata->vars[v]) && SCIPisIntegral(scip, consdata->vals[v]) && REALABS(consdata->vals[v]) > 1.5);
    5899
    5900 feastol = SCIPfeastol(scip);
    5901
    5902 gcd = (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol);
    5903 assert(gcd >= 2);
    5904
    5905 /* go on to partition the variables, do not change the order of collection, because it might be used later on;
    5906 * calculate gcd over the first part of variables */
    5907 for( ; v < consdata->nvars; ++v )
    5908 {
    5909 if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
    5910 continue;
    5911
    5912 if( SCIPvarIsBinary(consdata->vars[v]) )
    5913 {
    5914 SCIP_Real absval;
    5915
    5916 absval = REALABS(consdata->vals[v]);
    5917
    5918 if( absminbincoef > absval )
    5919 absminbincoef = absval;
    5920 }
    5921
    5922 if( !SCIPvarIsIntegral(consdata->vars[v]) || !SCIPisIntegral(scip, consdata->vals[v])
    5923 || SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0) )
    5924 {
    5925 if( !SCIPvarIsIntegral(consdata->vars[v]) )
    5926 ++ncontvars;
    5927
    5928 gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
    5929 possiblegcd = FALSE;
    5930 infcheckvars[ninfcheckvars] = consdata->vars[v];
    5931 infcheckvals[ninfcheckvars] = consdata->vals[v];
    5932
    5933 ++ninfcheckvars;
    5934
    5935 if( pos == -1 )
    5936 pos = v;
    5937 }
    5938 else
    5939 {
    5940 assert(REALABS(consdata->vals[v]) > 1.5);
    5941
    5942 gcdtmp = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol));
    5943 assert(gcdtmp >= 1);
    5944
    5945 if( gcdtmp == 1 )
    5946 {
    5947 infcheckvars[ninfcheckvars] = consdata->vars[v];
    5948 infcheckvals[ninfcheckvars] = consdata->vals[v];
    5949
    5950 ++ninfcheckvars;
    5951
    5952 if( pos == -1 )
    5953 pos = v;
    5954 }
    5955 else
    5956 gcd = gcdtmp;
    5957 }
    5958 }
    5959 assert(gcd >= 2);
    5960
    5961 /* it should not happen that all variables are of integral type and have a gcd >= 2, this should be done by
    5962 * normalizeCons() */
    5963 if( ninfcheckvars == 0 )
    5964 goto TERMINATE;
    5965
    5966 assert(pos >= 0);
    5967
    5968 minactinfvarsinvalid = FALSE;
    5969 maxactinfvarsinvalid = FALSE;
    5970 maxactinfvars = 0.0;
    5971 minactinfvars = 0.0;
    5972
    5973 /* calculate activities over all infcheckvars */
    5974 for( v = ninfcheckvars - 1; v >= 0; --v )
    5975 {
    5976 lb = SCIPvarGetLbLocal(infcheckvars[v]);
    5977 ub = SCIPvarGetUbLocal(infcheckvars[v]);
    5978
    5979 if( SCIPisInfinity(scip, -lb) )
    5980 {
    5981 if( infcheckvals[v] < 0.0 )
    5982 maxactinfvarsinvalid = TRUE;
    5983 else
    5984 minactinfvarsinvalid = TRUE;
    5985 }
    5986 else
    5987 {
    5988 if( infcheckvals[v] < 0.0 )
    5989 maxactinfvars += infcheckvals[v] * lb;
    5990 else
    5991 minactinfvars += infcheckvals[v] * lb;
    5992 }
    5993
    5994 if( SCIPisInfinity(scip, ub) )
    5995 {
    5996 if( infcheckvals[v] > 0.0 )
    5997 maxactinfvarsinvalid = TRUE;
    5998 else
    5999 minactinfvarsinvalid = TRUE;
    6000 }
    6001 else
    6002 {
    6003 if( infcheckvals[v] > 0.0 )
    6004 maxactinfvars += infcheckvals[v] * ub;
    6005 else
    6006 minactinfvars += infcheckvals[v] * ub;
    6007 }
    6008
    6009 /* better abort on to big values */
    6010 if( SCIPisHugeValue(scip, -minactinfvars) )
    6011 minactinfvarsinvalid = TRUE;
    6012 if( SCIPisHugeValue(scip, maxactinfvars) )
    6013 maxactinfvarsinvalid = TRUE;
    6014
    6015 if( minactinfvarsinvalid || maxactinfvarsinvalid )
    6016 goto TERMINATE;
    6017 }
    6018 assert(!minactinfvarsinvalid && !maxactinfvarsinvalid);
    6019
    6020 SCIPdebugMsg(scip, "minactinfvarsinvalid = %u, minactinfvars = %g, maxactinfvarsinvalid = %u, maxactinfvars = %g, gcd = %lld, ninfcheckvars = %d, ncontvars = %d\n",
    6021 minactinfvarsinvalid, minactinfvars, maxactinfvarsinvalid, maxactinfvars, gcd, ninfcheckvars, ncontvars);
    6022
    6023 /* @todo maybe we took the wrong variables as infcheckvars we could try to exchange integer variables */
    6024 /* @todo if minactinfvarsinvalid or maxactinfvarsinvalid are true, try to exchange both partitions to maybe get valid
    6025 * activities */
    6026 /* @todo calculate minactivity and maxactivity for all non-intcheckvars, and use this for better bounding,
    6027 * !!!note!!!
    6028 * that therefore the conflict variables in addConflictFixedVars() need to be extended by all variables which
    6029 * are not at their global bound
    6030 */
    6031
    6032 /* check if between left hand side and right hand side exist a feasible point, if not the constraint leads to
    6033 * infeasibility */
    6034 if( !SCIPisIntegral(scip, (lhs - maxactinfvars) / gcd) &&
    6035 SCIPisGT(scip, SCIPceil(scip, (lhs - maxactinfvars) / gcd) * gcd, rhs - minactinfvars) )
    6036 {
    6037 SCIPdebugMsg(scip, "no feasible value exist, constraint <%s> lead to infeasibility", SCIPconsGetName(cons));
    6039
    6040 /* start conflict analysis */
    6041 /* @todo improve conflict analysis by adding relaxed bounds */
    6042 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
    6043
    6044 *cutoff = TRUE;
    6045 }
    6046 else if( ncontvars == 0 )
    6047 {
    6048 SCIP_Longint gcdinfvars = -1;
    6049
    6050 /* check for gcd over all infcheckvars */
    6051 if( possiblegcd )
    6052 {
    6053 v = ninfcheckvars - 1;
    6054 gcdinfvars = (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol);
    6055 assert(gcdinfvars >= 2);
    6056
    6057 for( ; v >= 0 && gcdinfvars >= 2; --v )
    6058 {
    6059 gcdinfvars = SCIPcalcGreComDiv(gcdinfvars, (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol));
    6060 }
    6061 }
    6062 else if( gcdisone )
    6063 gcdinfvars = 1;
    6064
    6065 SCIPdebugMsg(scip, "gcdinfvars =%lld, possiblegcd = %u\n", gcdinfvars, possiblegcd);
    6066
    6067 /* compute solutions for this ranged row, if all variables are of integral type with integral coefficients */
    6068 if( gcdinfvars >= 1 )
    6069 {
    6070 SCIP_Real value;
    6071 SCIP_Real value2;
    6072 SCIP_Real minvalue = SCIP_INVALID;
    6073 SCIP_Real maxvalue = SCIP_INVALID;
    6074 int nsols = 0;
    6075
    6076 value = SCIPceil(scip, minactinfvars - SCIPfeastol(scip));
    6077
    6078 /* check how many possible solutions exist */
    6079 while( SCIPisLE(scip, value, maxactinfvars) )
    6080 {
    6081 value2 = value + gcd * (SCIPceil(scip, (lhs - value) / gcd));
    6082
    6083 /* value2 might violate lhs due to numerics, in this case take the next divisible number */
    6084 if( !SCIPisGE(scip, value2, lhs) )
    6085 {
    6086 value2 += gcd;
    6087 }
    6088
    6089 if( SCIPisLE(scip, value2, rhs) )
    6090 {
    6091 ++nsols;
    6092
    6093 /* early termination if we found more than two solutions */
    6094 if( nsols == 3 )
    6095 break;
    6096
    6097 if( minvalue == SCIP_INVALID ) /*lint !e777*/
    6098 minvalue = value;
    6099
    6100 maxvalue = value;
    6101 }
    6102 value += gcdinfvars;
    6103 }
    6104 assert(nsols < 2 || minvalue <= maxvalue);
    6105
    6106 /* determine last possible solution for better bounding */
    6107 if( nsols == 3 )
    6108 {
    6109#ifndef NDEBUG
    6110 SCIP_Real secondsolval = maxvalue;
    6111#endif
    6112 value = SCIPfloor(scip, maxactinfvars + SCIPfeastol(scip));
    6113
    6114 /* check how many possible solutions exist */
    6115 while( SCIPisGE(scip, value, minactinfvars) )
    6116 {
    6117 value2 = value + gcd * (SCIPfloor(scip, (rhs - value) / gcd));
    6118
    6119 /* value2 might violate rhs due to numerics, in this case take the next divisible number */
    6120 if( !SCIPisLE(scip, value2, rhs) )
    6121 {
    6122 value2 -= gcd;
    6123 }
    6124
    6125 if( SCIPisGE(scip, value2, lhs) )
    6126 {
    6127 maxvalue = value;
    6128 assert(maxvalue > minvalue);
    6129 break;
    6130 }
    6131 value -= gcdinfvars;
    6132 }
    6133 assert(maxvalue > secondsolval);
    6134 }
    6135
    6136 SCIPdebugMsg(scip, "here nsols %s %d, minsolvalue = %g, maxsolvalue = %g, ninfcheckvars = %d, nunfixedvars = %d\n",
    6137 nsols > 2 ? ">=" : "=", nsols, minvalue, maxvalue, ninfcheckvars, nunfixedvars);
    6138
    6139 /* no possible solution found */
    6140 if( nsols == 0 )
    6141 {
    6142 SCIPdebugMsg(scip, "gcdinfvars = %lld, gcd = %lld, correctedlhs = %g, correctedrhs = %g\n",
    6143 gcdinfvars, gcd, lhs, rhs);
    6144 SCIPdebugMsg(scip, "no solution found; constraint <%s> lead to infeasibility\n", SCIPconsGetName(cons));
    6146
    6147 /* start conflict analysis */
    6148 /* @todo improve conflict analysis by adding relaxed bounds */
    6149 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
    6150
    6151 *cutoff = TRUE;
    6152 }
    6153 /* if only one solution exist we can extract a new constraint or fix variables */
    6154 else if( nsols == 1 )
    6155 {
    6156 assert(minvalue == maxvalue); /*lint !e777*/
    6157
    6158 /* we can fix the only variable in our second set of variables */
    6159 if( ninfcheckvars == 1 )
    6160 {
    6161 SCIP_Bool fixed;
    6162
    6163 assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
    6164
    6165 SCIPdebugMsg(scip, "fixing single variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
    6166 SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]),
    6167 SCIPvarGetUbLocal(infcheckvars[0]), maxvalue/infcheckvals[0]);
    6168
    6169 /* fix variable to only possible value */
    6170 SCIP_CALL( SCIPinferVarFixCons(scip, infcheckvars[0], maxvalue/infcheckvals[0], cons,
    6171 getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &fixed) );
    6172
    6173 if( *cutoff )
    6174 {
    6175 /* start conflict analysis */
    6176 /* @todo improve conflict analysis by adding relaxed bounds */
    6177 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
    6178 }
    6179
    6180 if( fixed )
    6181 ++(*nfixedvars);
    6182 }
    6183 else
    6184 {
    6185 /* check for exactly one unfixed variable which is not part of the infcheckvars */
    6186 if( ninfcheckvars == nunfixedvars - 1 )
    6187 {
    6189 SCIP_Bool foundvar = FALSE;
    6190 SCIP_Bool fixed;
    6191 int w = 0;
    6192
    6193 assert(ninfcheckvars > 0);
    6194
    6195 /* find variable which is not an infcheckvar and fix it */
    6196 for( v = 0; v < consdata->nvars - 1; ++v )
    6197 {
    6198 if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
    6199 {
    6200 if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
    6201 {
    6202#ifndef NDEBUG
    6203 int v2 = v + 1;
    6204 int w2 = w;
    6205
    6206 assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
    6207
    6208 for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
    6209 {
    6210 if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
    6211 continue;
    6212
    6213 assert(consdata->vars[v2] == infcheckvars[w2]);
    6214 ++w2;
    6215 }
    6216 assert(w2 == ninfcheckvars);
    6217#endif
    6218 assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
    6219
    6220 foundvar = TRUE;
    6221
    6222 if( consdata->vals[v] < 0 )
    6223 {
    6224 bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
    6225 }
    6226 else
    6227 {
    6228 bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
    6229 }
    6230
    6231 SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
    6232 SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
    6233 SCIPvarGetUbLocal(consdata->vars[v]), bound);
    6234
    6235 /* fix variable to only possible value */
    6236 SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
    6237 getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
    6238
    6239 if( *cutoff )
    6240 {
    6241 /* start conflict analysis */
    6242 /* @todo improve conflict analysis by adding relaxed bounds */
    6243 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
    6244 consdata->vars[v], bound) );
    6245 }
    6246
    6247 if( fixed )
    6248 ++(*nfixedvars);
    6249
    6250 break;
    6251 }
    6252
    6253 ++w;
    6254 }
    6255 }
    6256
    6257 /* maybe last variable was the not infcheckvar */
    6258 if( !foundvar )
    6259 {
    6260 assert(v == consdata->nvars - 1);
    6261 assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
    6262
    6263 if( consdata->vals[v] < 0 )
    6264 {
    6265 bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
    6266 }
    6267 else
    6268 {
    6269 bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
    6270 }
    6271
    6272 SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
    6273 SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
    6274 SCIPvarGetUbLocal(consdata->vars[v]), bound);
    6275
    6276 /* fix variable to only possible value */
    6277 SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
    6278 getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
    6279
    6280 if( *cutoff )
    6281 {
    6282 /* start conflict analysis */
    6283 /* @todo improve conflict analysis by adding relaxed bounds */
    6284 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
    6285 consdata->vars[v], bound) );
    6286 }
    6287
    6288 if( fixed )
    6289 ++(*nfixedvars);
    6290 }
    6291 }
    6292 else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
    6293 {
    6294 /* aggregation possible if we have two variables, but this will be done later on */
    6295 SCIP_CONS* newcons;
    6296 char name[SCIP_MAXSTRLEN];
    6297
    6298 /* create, add, and release new artificial constraint */
    6299 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
    6300 ++conshdlrdata->naddconss;
    6301
    6302 SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
    6303
    6304 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals,
    6305 maxvalue, maxvalue, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
    6306 SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
    6307
    6308 SCIPdebugPrintCons(scip, newcons, NULL);
    6309
    6310 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    6311
    6312 ++(*naddconss);
    6313 }
    6314 }
    6315 }
    6316 /* at least two solutions */
    6317 else
    6318 {
    6319 /* @todo if we found more then one solution, we may reduced domains due to dualpresolving? */
    6320
    6321 /* only one variable in the second set, so we can bound this variables */
    6322 if( ninfcheckvars == 1 )
    6323 {
    6324 SCIP_Bool tightened;
    6325 SCIP_Real newlb;
    6326 SCIP_Real newub;
    6327
    6328 assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
    6329
    6330 if( infcheckvals[0] < 0 )
    6331 {
    6332 newlb = maxvalue/infcheckvals[0];
    6333 newub = minvalue/infcheckvals[0];
    6334 }
    6335 else
    6336 {
    6337 newlb = minvalue/infcheckvals[0];
    6338 newub = maxvalue/infcheckvals[0];
    6339 }
    6340 assert(newlb < newub);
    6341
    6342 if( newlb > SCIPvarGetLbLocal(infcheckvars[0]) )
    6343 {
    6344 /* update lower bound of variable */
    6345 SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
    6346 SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]), newlb);
    6347
    6348 /* tighten variable lower bound to minimal possible value */
    6349 SCIP_CALL( SCIPinferVarLbCons(scip, infcheckvars[0], newlb, cons,
    6350 getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
    6351
    6352 if( *cutoff )
    6353 {
    6354 /* start conflict analysis */
    6355 /* @todo improve conflict analysis by adding relaxed bounds */
    6356 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
    6357 }
    6358
    6359 if( tightened )
    6360 ++(*nchgbds);
    6361 }
    6362
    6363 if( newub < SCIPvarGetUbLocal(infcheckvars[0]) )
    6364 {
    6365 /* update upper bound of variable */
    6366 SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
    6367 SCIPvarGetName(infcheckvars[0]), SCIPvarGetUbLocal(infcheckvars[0]), newub);
    6368
    6369 /* tighten variable upper bound to maximal possible value */
    6370 SCIP_CALL( SCIPinferVarUbCons(scip, infcheckvars[0], newub, cons,
    6371 getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
    6372
    6373 if( *cutoff )
    6374 {
    6375 /* start conflict analysis */
    6376 /* @todo improve conflict analysis by adding relaxed bounds */
    6377 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
    6378 }
    6379
    6380 if( tightened )
    6381 ++(*nchgbds);
    6382 }
    6383 }
    6384 /* check if we have only one not infcheckvars, if so we can tighten this variable */
    6385 else if( ninfcheckvars == nunfixedvars - 1 )
    6386 {
    6387 SCIP_Bool foundvar = FALSE;
    6388 SCIP_Bool tightened;
    6389 SCIP_Real newlb;
    6390 SCIP_Real newub;
    6391 int w = 0;
    6392
    6393 assert(ninfcheckvars > 0);
    6394 assert(minvalue < maxvalue);
    6395
    6396 /* find variable which is not an infcheckvar and fix it */
    6397 for( v = 0; v < consdata->nvars - 1; ++v )
    6398 {
    6399 if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
    6400 {
    6401 if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
    6402 {
    6403#ifndef NDEBUG
    6404 int v2 = v + 1;
    6405 int w2 = w;
    6406
    6407 assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
    6408
    6409 for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
    6410 {
    6411 if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
    6412 continue;
    6413
    6414 assert(consdata->vars[v2] == infcheckvars[w2]);
    6415 ++w2;
    6416 }
    6417 assert(w2 == ninfcheckvars);
    6418#endif
    6419
    6420 assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
    6421 foundvar = TRUE;
    6422
    6423 if( consdata->vals[v] < 0 )
    6424 {
    6425 newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
    6426 newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
    6427 }
    6428 else
    6429 {
    6430 newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
    6431 newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
    6432 }
    6433 assert(SCIPisLE(scip, newlb, newub));
    6434
    6435 if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
    6436 {
    6437 /* update lower bound of variable */
    6438 SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
    6439 SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
    6440
    6441 /* tighten variable lower bound to minimal possible value */
    6442 SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
    6443 getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
    6444
    6445 if( *cutoff )
    6446 {
    6447 /* start conflict analysis */
    6448 /* @todo improve conflict analysis by adding relaxed bounds */
    6449 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
    6450 consdata->vars[v], newlb) );
    6451 }
    6452
    6453 if( tightened )
    6454 ++(*nchgbds);
    6455 }
    6456
    6457 if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
    6458 {
    6459 /* update upper bound of variable */
    6460 SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
    6461 SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
    6462
    6463 /* tighten variable upper bound to maximal possible value */
    6464 SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
    6465 getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
    6466
    6467 if( *cutoff )
    6468 {
    6469 /* start conflict analysis */
    6470 /* @todo improve conflict analysis by adding relaxed bounds */
    6471 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
    6472 consdata->vars[v], newub) );
    6473 }
    6474
    6475 if( tightened )
    6476 ++(*nchgbds);
    6477 }
    6478
    6479 break;
    6480 }
    6481
    6482 ++w;
    6483 }
    6484 }
    6485
    6486 /* maybe last variable was the not infcheckvar */
    6487 if( !foundvar )
    6488 {
    6489 assert(v == consdata->nvars - 1);
    6490 assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
    6491
    6492 if( consdata->vals[v] < 0 )
    6493 {
    6494 newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
    6495 newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
    6496 }
    6497 else
    6498 {
    6499 newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
    6500 newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
    6501 }
    6502 assert(SCIPisLE(scip, newlb, newub));
    6503
    6504 if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
    6505 {
    6506 /* update lower bound of variable */
    6507 SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
    6508 SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
    6509
    6510 /* tighten variable lower bound to minimal possible value */
    6511 SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
    6512 getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
    6513
    6514 if( *cutoff )
    6515 {
    6516 /* start conflict analysis */
    6517 /* @todo improve conflict analysis by adding relaxed bounds */
    6518 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newlb) );
    6519 }
    6520
    6521 if( tightened )
    6522 ++(*nchgbds);
    6523 }
    6524
    6525 if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
    6526 {
    6527 /* update upper bound of variable */
    6528 SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
    6529 SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
    6530
    6531 /* tighten variable upper bound to maximal possible value */
    6532 SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
    6533 getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
    6534
    6535 if( *cutoff )
    6536 {
    6537 /* start conflict analysis */
    6538 /* @todo improve conflict analysis by adding relaxed bounds */
    6539 SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newub) );
    6540 }
    6541
    6542 if( tightened )
    6543 ++(*nchgbds);
    6544 }
    6545 }
    6546 }
    6547 /* at least two solutions and more than one variable, so we add a new constraint which bounds the feasible
    6548 * region for our infcheckvars, if possible
    6549 */
    6550 else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
    6551 {
    6552 SCIP_CONS* newcons;
    6553 char name[SCIP_MAXSTRLEN];
    6554 SCIP_Real newlhs;
    6555 SCIP_Real newrhs;
    6556
    6557 assert(maxvalue > minvalue);
    6558
    6559 if( SCIPisGT(scip, minvalue, minactinfvars) )
    6560 newlhs = minvalue;
    6561 else
    6562 newlhs = -SCIPinfinity(scip);
    6563
    6564 if( SCIPisLT(scip, maxvalue, maxactinfvars) )
    6565 newrhs = maxvalue;
    6566 else
    6567 newrhs = SCIPinfinity(scip);
    6568
    6569 if( !SCIPisInfinity(scip, -newlhs) || !SCIPisInfinity(scip, newrhs) )
    6570 {
    6571 /* create, add, and release new artificial constraint */
    6572 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons1_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
    6573 ++conshdlrdata->naddconss;
    6574
    6575 SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
    6576
    6577 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
    6579 SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
    6580
    6581 SCIPdebugPrintCons(scip, newcons, NULL);
    6582 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    6583
    6584 ++(*naddconss);
    6585 }
    6586 /* @todo maybe add constraint for all variables which are not infcheckvars, lhs should be minvalue, rhs
    6587 * should be maxvalue */
    6588 }
    6589 }
    6590 }
    6591 }
    6592 else if( addartconss && ncontvars < ninfcheckvars )
    6593 {
    6594 SCIP_Real maxact = 0.0;
    6595 SCIP_Real minact = 0.0;
    6596 int w = 0;
    6597
    6598 /* compute activities of non-infcheckvars */
    6599 for( v = 0; v < consdata->nvars; ++v )
    6600 {
    6601 if( w < ninfcheckvars && consdata->vars[v] == infcheckvars[w] )
    6602 {
    6603 ++w;
    6604 continue;
    6605 }
    6606
    6607 if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
    6608 {
    6609 if( SCIPvarIsBinary(consdata->vars[v]) )
    6610 {
    6611 if( consdata->vals[v] > 0.0 )
    6612 maxact += consdata->vals[v];
    6613 else
    6614 minact += consdata->vals[v];
    6615 }
    6616 else
    6617 {
    6618 SCIP_Real tmpval;
    6619
    6620 assert(SCIPvarIsIntegral(consdata->vars[v]));
    6621
    6622 if( consdata->vals[v] > 0.0 )
    6623 {
    6624 tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
    6625
    6626 if( SCIPisHugeValue(scip, -tmpval) )
    6627 break;
    6628
    6629 minact += tmpval;
    6630
    6631 tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
    6632
    6633 if( SCIPisHugeValue(scip, tmpval) )
    6634 break;
    6635
    6636 maxact += tmpval;
    6637 }
    6638 else
    6639 {
    6640 tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
    6641
    6642 if( SCIPisHugeValue(scip, -tmpval) )
    6643 break;
    6644
    6645 minact += tmpval;
    6646
    6647 tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
    6648
    6649 if( SCIPisHugeValue(scip, tmpval) )
    6650 break;
    6651
    6652 maxact += tmpval;
    6653 }
    6654 }
    6655 }
    6656 }
    6657 if( v == consdata->nvars && !SCIPisHugeValue(scip, -minact) && !SCIPisHugeValue(scip, maxact) )
    6658 {
    6659 SCIP_CONS* newcons;
    6660 char name[SCIP_MAXSTRLEN];
    6661 SCIP_Real newlhs;
    6662 SCIP_Real newrhs;
    6663
    6664 assert(maxact > minact);
    6665 assert(w == ninfcheckvars);
    6666
    6667 newlhs = lhs - maxact;
    6668 newrhs = rhs - minact;
    6669 assert(newlhs < newrhs);
    6670
    6671 /* create, add, and release new artificial constraint */
    6672 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons2_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
    6673 ++conshdlrdata->naddconss;
    6674
    6675 SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
    6676
    6677 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
    6679 SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
    6680
    6681 SCIPdebugPrintCons(scip, newcons, NULL);
    6682 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    6683
    6684 ++(*naddconss);
    6685 }
    6686 }
    6687
    6688 TERMINATE:
    6689 SCIPfreeBufferArray(scip, &infcheckvals);
    6690 SCIPfreeBufferArray(scip, &infcheckvars);
    6691
    6692 return SCIP_OKAY;
    6693}
    6694
    6695/** tightens bounds of a single variable due to activity bounds */
    6696static
    6698 SCIP* scip, /**< SCIP data structure */
    6699 SCIP_CONS* cons, /**< linear constraint */
    6700 int pos, /**< position of the variable in the vars array */
    6701 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    6702 int* nchgbds, /**< pointer to count the total number of tightened bounds */
    6703 SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
    6704 )
    6705{
    6706 SCIP_CONSDATA* consdata;
    6707 SCIP_VAR* var;
    6708 SCIP_Real val;
    6709 SCIP_Real lb;
    6710 SCIP_Real ub;
    6711 SCIP_Real minresactivity;
    6712 SCIP_Real maxresactivity;
    6713 SCIP_Real lhs;
    6714 SCIP_Real rhs;
    6715 SCIP_Bool infeasible;
    6716 SCIP_Bool tightened;
    6717 SCIP_Bool ismintight;
    6718 SCIP_Bool ismaxtight;
    6719 SCIP_Bool isminsettoinfinity;
    6720 SCIP_Bool ismaxsettoinfinity;
    6721
    6722 assert(scip != NULL);
    6723 assert(cons != NULL);
    6724 assert(cutoff != NULL);
    6725 assert(nchgbds != NULL);
    6726
    6727 /* we cannot tighten variables' bounds, if the constraint may be not complete */
    6728 if( SCIPconsIsModifiable(cons) )
    6729 return SCIP_OKAY;
    6730
    6731 consdata = SCIPconsGetData(cons);
    6732 assert(consdata != NULL);
    6733 assert(0 <= pos && pos < consdata->nvars);
    6734
    6735 *cutoff = FALSE;
    6736
    6737 var = consdata->vars[pos];
    6738
    6739 /* we cannot tighten bounds of multi-aggregated variables */
    6741 return SCIP_OKAY;
    6742
    6743 val = consdata->vals[pos];
    6744 lhs = consdata->lhs;
    6745 rhs = consdata->rhs;
    6746 consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
    6747 &ismintight, &ismaxtight, &isminsettoinfinity, &ismaxsettoinfinity);
    6748 assert(var != NULL);
    6749 assert(!SCIPisZero(scip, val));
    6750 assert(!SCIPisInfinity(scip, lhs));
    6751 assert(!SCIPisInfinity(scip, -rhs));
    6752
    6753 lb = SCIPvarGetLbLocal(var);
    6754 ub = SCIPvarGetUbLocal(var);
    6755 assert(SCIPisLE(scip, lb, ub));
    6756
    6757 if( val > 0.0 )
    6758 {
    6759 /* check, if we can tighten the variable's bounds reliably, therefore only consider sides which are small or
    6760 * relatively different to the residual activity bound to avoid cancellation leading to numerical difficulties
    6761 */
    6762 if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && ismintight
    6763 && ( SCIPisLT(scip, ABS(rhs), 1.0) || !SCIPisEQ(scip, minresactivity / rhs, 1.0) ) )
    6764 {
    6765 SCIP_Real newub;
    6766
    6767 newub = (rhs - minresactivity)/val;
    6768
    6769 if( !SCIPisInfinity(scip, newub) &&
    6770 ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
    6771 {
    6772 SCIP_Bool activityunreliable;
    6773 activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
    6774
    6775 /* check minresactivities for reliability */
    6776 if( activityunreliable )
    6777 {
    6778 consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
    6779 newub = (rhs - minresactivity)/val;
    6780 activityunreliable = SCIPisInfinity(scip, -minresactivity) ||
    6781 (!SCIPisUbBetter(scip, newub, lb, ub) && (!SCIPisFeasLT(scip, newub, ub) || !SCIPvarIsIntegral(var))
    6782 && (!force || !SCIPisLT(scip, newub, ub)));
    6783 }
    6784
    6785 if( !activityunreliable )
    6786 {
    6787 /* tighten upper bound */
    6788 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
    6789 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
    6790 SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_RHS, pos), force,
    6791 &infeasible, &tightened) );
    6792 if( infeasible )
    6793 {
    6794 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    6795 SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
    6796
    6797 /* analyze conflict */
    6799
    6800 *cutoff = TRUE;
    6801 return SCIP_OKAY;
    6802 }
    6803 if( tightened )
    6804 {
    6805 ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
    6806 assert(SCIPisFeasLE(scip, ub, newub));
    6807 (*nchgbds)++;
    6808
    6809 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
    6810 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
    6811 }
    6812 }
    6813 }
    6814 }
    6815
    6816 if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && ismaxtight
    6817 && ( SCIPisLT(scip, ABS(lhs), 1.0) || !SCIPisEQ(scip, maxresactivity / lhs, 1.0) ) )
    6818 {
    6819 SCIP_Real newlb;
    6820
    6821 newlb = (lhs - maxresactivity)/val;
    6822 if( !SCIPisInfinity(scip, -newlb) &&
    6823 ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
    6824 {
    6825 /* check maxresactivities for reliability */
    6826 if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
    6827 {
    6828 consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
    6829 newlb = (lhs - maxresactivity)/val;
    6830
    6831 if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisLbBetter(scip, newlb, lb, ub)
    6832 && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
    6833 && (!force || !SCIPisGT(scip, newlb, lb))) )
    6834 return SCIP_OKAY;
    6835 }
    6836
    6837 /* tighten lower bound */
    6838 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
    6839 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
    6840 SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_LHS, pos), force,
    6841 &infeasible, &tightened) );
    6842 if( infeasible )
    6843 {
    6844 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    6845 SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
    6846
    6847 /* analyze conflict */
    6849
    6850 *cutoff = TRUE;
    6851 return SCIP_OKAY;
    6852 }
    6853 if( tightened )
    6854 {
    6855 lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
    6856 assert(SCIPisFeasGE(scip, lb, newlb));
    6857 (*nchgbds)++;
    6858 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
    6859 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
    6860 }
    6861 }
    6862 }
    6863 }
    6864 else
    6865 {
    6866 /* check, if we can tighten the variable's bounds reliably, therefore only consider sides which are small or
    6867 * relatively different to the residual activity bound to avoid cancellation leading to numerical difficulties
    6868 */
    6869 if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && ismintight
    6870 && ( SCIPisLT(scip, ABS(rhs), 1.0) || !SCIPisEQ(scip, minresactivity / rhs, 1.0) ) )
    6871 {
    6872 SCIP_Real newlb;
    6873
    6874 newlb = (rhs - minresactivity)/val;
    6875 if( !SCIPisInfinity(scip, -newlb) &&
    6876 ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
    6877 {
    6878 SCIP_Bool activityunreliable;
    6879 activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
    6880 /* check minresactivities for reliability */
    6881 if( activityunreliable )
    6882 {
    6883 consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
    6884 newlb = (rhs - minresactivity)/val;
    6885
    6886 activityunreliable = SCIPisInfinity(scip, -minresactivity)
    6887 || (!SCIPisLbBetter(scip, newlb, lb, ub) && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
    6888 && (!force || !SCIPisGT(scip, newlb, lb)));
    6889 }
    6890
    6891 if( !activityunreliable )
    6892 {
    6893 /* tighten lower bound */
    6894 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
    6895 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
    6896 SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_RHS, pos), force,
    6897 &infeasible, &tightened) );
    6898 if( infeasible )
    6899 {
    6900 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    6901 SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
    6902
    6903 /* analyze conflict */
    6905
    6906 *cutoff = TRUE;
    6907 return SCIP_OKAY;
    6908 }
    6909 if( tightened )
    6910 {
    6911 lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
    6912 assert(SCIPisFeasGE(scip, lb, newlb));
    6913 (*nchgbds)++;
    6914 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
    6915 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
    6916 }
    6917 }
    6918 }
    6919 }
    6920
    6921 if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && ismaxtight
    6922 && ( SCIPisLT(scip, ABS(lhs), 1.0) || !SCIPisEQ(scip, maxresactivity / lhs, 1.0) ) )
    6923 {
    6924 SCIP_Real newub;
    6925
    6926 newub = (lhs - maxresactivity)/val;
    6927 if( !SCIPisInfinity(scip, newub) &&
    6928 ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
    6929 {
    6930 /* check maxresactivities for reliability */
    6931 if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
    6932 {
    6933 consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
    6934 newub = (lhs - maxresactivity)/val;
    6935
    6936 if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisUbBetter(scip, newub, lb, ub)
    6937 && (!SCIPisFeasLT(scip, newub, ub) && !SCIPvarIsIntegral(var))
    6938 && (!force || !SCIPisLT(scip, newub, ub))) )
    6939 return SCIP_OKAY;
    6940 }
    6941
    6942 /* tighten upper bound */
    6943 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g], newub=%.15g\n",
    6944 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
    6945 SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_LHS, pos), force,
    6946 &infeasible, &tightened) );
    6947 if( infeasible )
    6948 {
    6949 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
    6950 SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
    6951
    6952 /* analyze conflict */
    6954
    6955 *cutoff = TRUE;
    6956 return SCIP_OKAY;
    6957 }
    6958 if( tightened )
    6959 {
    6960 ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
    6961 assert(SCIPisFeasLE(scip, ub, newub));
    6962 (*nchgbds)++;
    6963 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
    6964 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
    6965 }
    6966 }
    6967 }
    6968 }
    6969
    6970 return SCIP_OKAY;
    6971}
    6972
    6973#define MAXTIGHTENROUNDS 10
    6974
    6975/** tightens bounds of variables in constraint due to activity bounds */
    6976static
    6978 SCIP* scip, /**< SCIP data structure */
    6979 SCIP_CONS* cons, /**< linear constraint */
    6980 SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
    6981 SCIP_Bool sortvars, /**< should variables be used in sorted order? */
    6982 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    6983 int* nchgbds /**< pointer to count the total number of tightened bounds */
    6984 )
    6985{
    6986 SCIP_CONSDATA* consdata;
    6987 unsigned int tightenmode;
    6988 int nvars;
    6989 int nrounds;
    6990 int lastchange;
    6991 int oldnchgbds;
    6992#ifndef SCIP_DEBUG
    6993 int oldnchgbdstotal;
    6994#endif
    6995 int v;
    6996 SCIP_Bool force;
    6997 SCIP_Bool easycase;
    6998
    6999 assert(scip != NULL);
    7000 assert(cons != NULL);
    7001 assert(nchgbds != NULL);
    7002 assert(cutoff != NULL);
    7003
    7004 *cutoff = FALSE;
    7005
    7006 /* we cannot tighten variables' bounds, if the constraint may be not complete */
    7007 if( SCIPconsIsModifiable(cons) )
    7008 return SCIP_OKAY;
    7009
    7010 /* if a constraint was created after presolve, then it may hold fixed variables
    7011 * if there are even multi-aggregated variables, then we cannot do bound tightening on these
    7012 * thus, ensure here again that variable fixings have been applied
    7013 */
    7014 SCIP_CALL( applyFixings(scip, cons, cutoff) );
    7015 if( *cutoff )
    7016 return SCIP_OKAY;
    7017
    7018 /* check if constraint has any chances of tightening bounds */
    7019 if( !canTightenBounds(cons) )
    7020 return SCIP_OKAY;
    7021
    7022 consdata = SCIPconsGetData(cons);
    7023 assert(consdata != NULL);
    7024
    7025 nvars = consdata->nvars;
    7026 force = (nvars == 1) && !SCIPconsIsModifiable(cons);
    7027
    7028 /* we are at the root node or during presolving */
    7029 if( SCIPgetDepth(scip) < 1 )
    7030 tightenmode = 2;
    7031 else
    7032 tightenmode = 1;
    7033
    7034 /* stop if we already tightened the constraint and the tightening is not forced */
    7035 if( !force && (consdata->boundstightened >= tightenmode) ) /*lint !e574*/
    7036 return SCIP_OKAY;
    7037
    7038 /* ensure that the variables are properly sorted */
    7039 if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
    7040 {
    7041 SCIP_CALL( consdataSort(scip, consdata) );
    7042 assert(consdata->coefsorted);
    7043 }
    7044
    7045 /* update maximal activity delta if necessary */
    7046 if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
    7048
    7049 assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
    7050 assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
    7051 checkMaxActivityDelta(scip, consdata);
    7052
    7053 /* this may happen if all variables are fixed */
    7054 if( SCIPisFeasZero(scip, consdata->maxactdelta) )
    7055 return SCIP_OKAY;
    7056
    7057 if( !SCIPisInfinity(scip, consdata->maxactdelta) )
    7058 {
    7059 SCIP_Real slack;
    7060 SCIP_Real surplus;
    7061 SCIP_Real minactivity;
    7062 SCIP_Real maxactivity;
    7063 SCIP_Bool ismintight;
    7064 SCIP_Bool ismaxtight;
    7065 SCIP_Bool isminsettoinfinity;
    7066 SCIP_Bool ismaxsettoinfinity;
    7067
    7068 /* use maximal activity delta to skip propagation (cannot deduce anything) */
    7069 consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &ismintight, &ismaxtight,
    7070 &isminsettoinfinity, &ismaxsettoinfinity);
    7071 assert(!SCIPisInfinity(scip, minactivity));
    7072 assert(!SCIPisInfinity(scip, -maxactivity));
    7073
    7074 slack = (SCIPisInfinity(scip, consdata->rhs) || isminsettoinfinity) ? SCIPinfinity(scip) : (consdata->rhs - minactivity);
    7075 surplus = (SCIPisInfinity(scip, -consdata->lhs) || ismaxsettoinfinity) ? SCIPinfinity(scip) : (maxactivity - consdata->lhs);
    7076
    7077 /* check if the constraint will propagate */
    7078 if( SCIPisLE(scip, consdata->maxactdelta, MIN(slack, surplus)) )
    7079 return SCIP_OKAY;
    7080 }
    7081
    7082 /* check if we can use fast implementation for easy and numerically well behaved cases */
    7083 easycase = SCIPisLT(scip, consdata->maxactdelta, maxeasyactivitydelta);
    7084
    7085 /* as long as the bounds might be tightened again, try to tighten them; abort after a maximal number of rounds */
    7086 lastchange = -1;
    7087
    7088#ifndef SCIP_DEBUG
    7089 oldnchgbds = 0;
    7090 oldnchgbdstotal = *nchgbds;
    7091#endif
    7092
    7093 for( nrounds = 0; (force || consdata->boundstightened < tightenmode) && nrounds < MAXTIGHTENROUNDS; ++nrounds ) /*lint !e574*/
    7094 {
    7095 /* ensure that the variables are properly sorted
    7096 *
    7097 * note: it might happen that integer variables become binary during bound tightening at the root node
    7098 */
    7099 if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
    7100 {
    7101 SCIP_CALL( consdataSort(scip, consdata) );
    7102 assert(consdata->coefsorted);
    7103 }
    7104
    7105 /* mark the constraint to have the variables' bounds tightened */
    7106 consdata->boundstightened = (unsigned int)tightenmode;
    7107
    7108 /* try to tighten the bounds of each variable in the constraint. During solving process, the binary variable
    7109 * sorting enables skipping variables
    7110 */
    7111 v = 0;
    7112 while( v < nvars && v != lastchange && !(*cutoff) )
    7113 {
    7114 oldnchgbds = *nchgbds;
    7115
    7116 if( easycase )
    7117 {
    7118 SCIP_CALL( tightenVarBoundsEasy(scip, cons, v, cutoff, nchgbds, force) );
    7119 }
    7120 else
    7121 {
    7122 SCIP_CALL( tightenVarBounds(scip, cons, v, cutoff, nchgbds, force) );
    7123 }
    7124
    7125 /* if there was no progress, skip the rest of the binary variables */
    7126 if( *nchgbds > oldnchgbds )
    7127 {
    7128 lastchange = v;
    7129 ++v;
    7130 }
    7131 else if( consdata->coefsorted && v < consdata->nbinvars - 1
    7132 && !SCIPisFeasEQ(scip, SCIPvarGetUbLocal(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v])) )
    7133 v = consdata->nbinvars;
    7134 else
    7135 ++v;
    7136 }
    7137
    7138#ifndef SCIP_DEBUG
    7139 SCIPdebugMessage("linear constraint <%s> found %d bound changes in round %d\n", SCIPconsGetName(cons),
    7140 *nchgbds - oldnchgbdstotal, nrounds);
    7141 oldnchgbdstotal += oldnchgbds;
    7142#endif
    7143 }
    7144
    7145#ifndef NDEBUG
    7146 if( force && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
    7147 assert(*cutoff || SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->vars[0]), SCIPvarGetUbLocal(consdata->vars[0])));
    7148#endif
    7149
    7150 return SCIP_OKAY;
    7151}
    7152
    7153/** checks linear constraint for feasibility of given solution or current solution */
    7154static
    7156 SCIP* scip, /**< SCIP data structure */
    7157 SCIP_CONS* cons, /**< linear constraint */
    7158 SCIP_SOL* sol, /**< solution to be checked, or NULL for current solution */
    7159 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
    7160 SCIP_Bool checkrelmaxabs, /**< Should the violation for a constraint with side 0.0 be checked relative
    7161 * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
    7162 SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
    7163 )
    7164{
    7165 SCIP_CONSDATA* consdata;
    7166 SCIP_Real activity;
    7167 SCIP_Real absviol;
    7168 SCIP_Real relviol;
    7169 SCIP_Real lhsviol;
    7170 SCIP_Real rhsviol;
    7171
    7172 assert(scip != NULL);
    7173 assert(cons != NULL);
    7174 assert(violated != NULL);
    7175
    7176 SCIPdebugMsg(scip, "checking linear constraint <%s>\n", SCIPconsGetName(cons));
    7178
    7179 consdata = SCIPconsGetData(cons);
    7180 assert(consdata != NULL);
    7181
    7182 *violated = FALSE;
    7183
    7184 if( consdata->row != NULL )
    7185 {
    7186 if( !checklprows && SCIProwIsInLP(consdata->row) )
    7187 return SCIP_OKAY;
    7188 else if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
    7189 activity = consdataComputePseudoActivity(scip, consdata);
    7190 else
    7191 activity = SCIPgetRowSolActivity(scip, consdata->row, sol);
    7192 }
    7193 else
    7194 activity = consdataGetActivity(scip, consdata, sol);
    7195
    7196 SCIPdebugMsg(scip, " consdata activity=%.15g (lhs=%.15g, rhs=%.15g, row=%p, checklprows=%u, rowinlp=%u, sol=%p, hascurrentnodelp=%u)\n",
    7197 activity, consdata->lhs, consdata->rhs, (void*)consdata->row, checklprows,
    7198 consdata->row == NULL ? 0 : SCIProwIsInLP(consdata->row), (void*)sol,
    7199 consdata->row == NULL ? FALSE : SCIPhasCurrentNodeLP(scip));
    7200
    7201 /* calculate absolute and relative bound violations */
    7202 lhsviol = consdata->lhs - activity;
    7203 rhsviol = activity - consdata->rhs;
    7204
    7205 absviol = 0.0;
    7206 relviol = 0.0;
    7207 if( (lhsviol > 0) && (lhsviol > rhsviol) )
    7208 {
    7209 absviol = lhsviol;
    7210 relviol = SCIPrelDiff(consdata->lhs, activity);
    7211 }
    7212 else if( rhsviol > 0 )
    7213 {
    7214 absviol = rhsviol;
    7215 relviol = SCIPrelDiff(activity, consdata->rhs);
    7216 }
    7217
    7218 /* the activity of pseudo solutions may be invalid if it comprises positive and negative infinity contributions; we
    7219 * return infeasible for safety
    7220 */
    7221 if( activity == SCIP_INVALID ) /*lint !e777*/
    7222 {
    7223 assert(sol == NULL);
    7224 *violated = TRUE;
    7225
    7226 /* set violation of invalid pseudo solutions */
    7227 absviol = SCIP_INVALID;
    7228 relviol = SCIP_INVALID;
    7229
    7230 /* reset constraint age since we are in enforcement */
    7232 }
    7233 /* check with relative tolerances (the default) */
    7234 else if( !consdata->checkabsolute && (SCIPisFeasLT(scip, activity, consdata->lhs) || SCIPisFeasGT(scip, activity, consdata->rhs)) )
    7235 {
    7236 /* the "normal" check: one of the two sides is violated */
    7237 if( !checkrelmaxabs )
    7238 {
    7239 *violated = TRUE;
    7240
    7241 /* only reset constraint age if we are in enforcement */
    7242 if( sol == NULL )
    7243 {
    7245 }
    7246 }
    7247 /* the (much) more complicated check: we try to disregard random noise and violations of a 0.0 side which are
    7248 * small compared to the absolute values occurring in the activity
    7249 */
    7250 else
    7251 {
    7252 SCIP_Real maxabs;
    7253 SCIP_Real coef;
    7254 SCIP_Real absval;
    7255 SCIP_Real solval;
    7256 int v;
    7257
    7258 maxabs = 1.0;
    7259
    7260 /* compute maximum absolute value */
    7261 for( v = 0; v < consdata->nvars; ++v )
    7262 {
    7263 if( consdata->vals != NULL )
    7264 {
    7265 coef = consdata->vals[v];
    7266 }
    7267 else
    7268 coef = 1.0;
    7269
    7270 solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
    7271 absval = REALABS( coef * solval );
    7272 maxabs = MAX( maxabs, absval );
    7273 }
    7274
    7275 /* regard left hand side, first */
    7276 if( SCIPisFeasLT(scip, activity, consdata->lhs) )
    7277 {
    7278 /* check whether violation is random noise */
    7279 if( (consdata->lhs - activity) <= (1e-15 * maxabs) )
    7280 {
    7281 SCIPdebugMsg(scip, " lhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
    7282 consdata->lhs - activity, maxabs);
    7283 SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
    7284
    7285 /* only increase constraint age if we are in enforcement */
    7286 if( sol == NULL )
    7287 {
    7288 SCIP_CALL( SCIPincConsAge(scip, cons) );
    7289 }
    7290 }
    7291 /* lhs is violated and lhs is 0.0: use relative tolerance w.r.t. largest absolute value */
    7292 else if( SCIPisZero(scip, consdata->lhs) )
    7293 {
    7294 if( (consdata->lhs - activity) <= (SCIPfeastol(scip) * maxabs) )
    7295 {
    7296 SCIPdebugMsg(scip, " lhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
    7297 consdata->lhs - activity, maxabs);
    7298 SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
    7299
    7300 /* only increase constraint age if we are in enforcement */
    7301 if( sol == NULL )
    7302 {
    7303 SCIP_CALL( SCIPincConsAge(scip, cons) );
    7304 }
    7305 }
    7306 else
    7307 {
    7308 *violated = TRUE;
    7309
    7310 /* only reset constraint age if we are in enforcement */
    7311 if( sol == NULL )
    7312 {
    7314 }
    7315 }
    7316 }
    7317 else
    7318 {
    7319 *violated = TRUE;
    7320
    7321 /* only reset constraint age if we are in enforcement */
    7322 if( sol == NULL )
    7323 {
    7325 }
    7326 }
    7327 }
    7328
    7329 /* now regard right hand side */
    7330 if( SCIPisFeasGT(scip, activity, consdata->rhs) )
    7331 {
    7332 /* check whether violation is random noise */
    7333 if( (activity - consdata->rhs) <= (1e-15 * maxabs) )
    7334 {
    7335 SCIPdebugMsg(scip, " rhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
    7336 activity - consdata->rhs, maxabs);
    7337 SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
    7338
    7339 /* only increase constraint age if we are in enforcement */
    7340 if( sol == NULL )
    7341 {
    7342 SCIP_CALL( SCIPincConsAge(scip, cons) );
    7343 }
    7344 }
    7345 /* rhs is violated and rhs is 0.0, use relative tolerance w.r.t. largest absolute value */
    7346 else if( SCIPisZero(scip, consdata->rhs) )
    7347 {
    7348 if( (activity - consdata->rhs) <= (SCIPfeastol(scip) * maxabs) )
    7349 {
    7350 SCIPdebugMsg(scip, " rhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
    7351 activity - consdata->rhs, maxabs);
    7352 SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
    7353
    7354 /* only increase constraint age if we are in enforcement */
    7355 if( sol == NULL )
    7356 {
    7357 SCIP_CALL( SCIPincConsAge(scip, cons) );
    7358 }
    7359 }
    7360 else
    7361 {
    7362 *violated = TRUE;
    7363
    7364 /* only reset constraint age if we are in enforcement */
    7365 if( sol == NULL )
    7366 {
    7368 }
    7369 }
    7370 }
    7371 else
    7372 {
    7373 *violated = TRUE;
    7374
    7375 /* only reset constraint age if we are in enforcement */
    7376 if( sol == NULL )
    7377 {
    7379 }
    7380 }
    7381 }
    7382 }
    7383 }
    7384 /* check with absolute tolerances */
    7385 else if( consdata->checkabsolute &&
    7386 ((!SCIPisInfinity(scip, -consdata->lhs) && SCIPisGT(scip, consdata->lhs-activity, SCIPfeastol(scip))) ||
    7387 (!SCIPisInfinity(scip, consdata->rhs) && SCIPisGT(scip, activity-consdata->rhs, SCIPfeastol(scip)))) )
    7388 {
    7389 *violated = TRUE;
    7390
    7391 /* only reset constraint age if we are in enforcement */
    7392 if( sol == NULL )
    7393 {
    7395 }
    7396 }
    7397 else
    7398 {
    7399 /* only increase constraint age if we are in enforcement */
    7400 if( sol == NULL )
    7401 {
    7402 SCIP_CALL( SCIPincConsAge(scip, cons) );
    7403 }
    7404 }
    7405
    7406 /* update absolute and relative violation of the solution */
    7407 if( sol != NULL )
    7408 SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
    7409
    7410 return SCIP_OKAY;
    7411}
    7412
    7413/** creates an LP row in a linear constraint data */
    7414static
    7416 SCIP* scip, /**< SCIP data structure */
    7417 SCIP_CONS* cons /**< linear constraint */
    7418 )
    7419{
    7420 SCIP_CONSDATA* consdata;
    7421
    7422 assert(scip != NULL);
    7423 assert(cons != NULL);
    7424
    7425 consdata = SCIPconsGetData(cons);
    7426 assert(consdata != NULL);
    7427 assert(consdata->row == NULL);
    7428
    7429 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, cons, SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
    7431
    7432 SCIP_CALL( SCIPaddVarsToRow(scip, consdata->row, consdata->nvars, consdata->vars, consdata->vals) );
    7433
    7434 return SCIP_OKAY;
    7435}
    7436
    7437/** adds linear constraint as cut to the LP */
    7438static
    7440 SCIP* scip, /**< SCIP data structure */
    7441 SCIP_CONS* cons, /**< linear constraint */
    7442 SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
    7443 )
    7444{
    7445 SCIP_CONSDATA* consdata;
    7446
    7447 assert(scip != NULL);
    7448 assert(cons != NULL);
    7449
    7450 consdata = SCIPconsGetData(cons);
    7451 assert(consdata != NULL);
    7452
    7453 if( consdata->row == NULL )
    7454 {
    7455 if( !SCIPconsIsModifiable(cons) )
    7456 {
    7457 /* replace all fixed variables by active counterparts, as we have no chance to do this anymore after the row has been added to the LP
    7458 * removing this here will make test cons/linear/fixedvar.c fail (as of 2018-12-03)
    7459 */
    7460 SCIP_CALL( applyFixings(scip, cons, cutoff) );
    7461 if( *cutoff )
    7462 return SCIP_OKAY;
    7463 }
    7464
    7465 /* convert consdata object into LP row */
    7466 SCIP_CALL( createRow(scip, cons) );
    7467 }
    7468 assert(consdata->row != NULL);
    7469
    7470 if( consdata->nvars == 0 )
    7471 {
    7472 SCIPdebugMsg(scip, "Empty linear constraint enters LP: <%s>\n", SCIPconsGetName(cons));
    7473 }
    7474
    7475 /* insert LP row as cut */
    7476 if( !SCIProwIsInLP(consdata->row) )
    7477 {
    7478 SCIPdebugMsg(scip, "adding relaxation of linear constraint <%s>: ", SCIPconsGetName(cons));
    7479 SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->row, NULL)) );
    7480 /* if presolving is turned off, the row might be trivial */
    7481 if ( ! SCIPisInfinity(scip, -consdata->lhs) || ! SCIPisInfinity(scip, consdata->rhs) )
    7482 {
    7483 SCIP_CALL( SCIPaddRow(scip, consdata->row, FALSE, cutoff) );
    7484 }
    7485#ifndef NDEBUG
    7486 else
    7487 {
    7488 int pr;
    7489 int cr;
    7490 SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrounds", &pr) );
    7491 SCIP_CALL( SCIPgetIntParam(scip, "constraints/linear/maxprerounds", &cr) );
    7492 assert( pr == 0 || cr == 0 );
    7493 }
    7494#endif
    7495 }
    7496
    7497 return SCIP_OKAY;
    7498}
    7499
    7500/** adds linear constraint as row to the NLP, if not added yet */
    7501static
    7503 SCIP* scip, /**< SCIP data structure */
    7504 SCIP_CONS* cons /**< linear constraint */
    7505 )
    7506{
    7507 SCIP_CONSDATA* consdata;
    7508
    7509 assert(SCIPisNLPConstructed(scip));
    7510
    7511 /* skip deactivated, redundant, or local linear constraints (the NLP does not allow for local rows at the moment) */
    7512 if( !SCIPconsIsActive(cons) || !SCIPconsIsChecked(cons) || SCIPconsIsLocal(cons) )
    7513 return SCIP_OKAY;
    7514
    7515 consdata = SCIPconsGetData(cons);
    7516 assert(consdata != NULL);
    7517
    7518 if( consdata->nlrow == NULL )
    7519 {
    7520 assert(consdata->lhs <= consdata->rhs);
    7521
    7522 SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow, SCIPconsGetName(cons),
    7523 0.0, consdata->nvars, consdata->vars, consdata->vals, NULL, consdata->lhs, consdata->rhs, SCIP_EXPRCURV_LINEAR) );
    7524
    7525 assert(consdata->nlrow != NULL);
    7526 }
    7527
    7528 if( !SCIPnlrowIsInNLP(consdata->nlrow) )
    7529 {
    7530 SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow) );
    7531 }
    7532
    7533 return SCIP_OKAY;
    7534}
    7535
    7536/** separates linear constraint: adds linear constraint as cut, if violated by given solution */
    7537static
    7539 SCIP* scip, /**< SCIP data structure */
    7540 SCIP_CONS* cons, /**< linear constraint */
    7541 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
    7542 SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
    7543 SCIP_Bool separatecards, /**< should knapsack cardinality cuts be generated? */
    7544 SCIP_Bool separateall, /**< should all constraints be subject to cardinality cut generation instead of only
    7545 * the ones with non-zero dual value? */
    7546 int* ncuts, /**< pointer to add up the number of found cuts */
    7547 SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
    7548 )
    7549{
    7550 SCIP_CONSDATA* consdata;
    7551 SCIP_Bool violated;
    7552 int oldncuts;
    7553
    7554 assert(scip != NULL);
    7555 assert(conshdlrdata != NULL);
    7556 assert(cons != NULL);
    7557 assert(cutoff != NULL);
    7558
    7559 consdata = SCIPconsGetData(cons);
    7560 assert(ncuts != NULL);
    7561 assert(consdata != NULL);
    7562
    7563 oldncuts = *ncuts;
    7564 *cutoff = FALSE;
    7565
    7566 SCIP_CALL( checkCons(scip, cons, sol, (sol != NULL), conshdlrdata->checkrelmaxabs, &violated) );
    7567
    7568 if( violated )
    7569 {
    7570 /* insert LP row as cut */
    7571 SCIP_CALL( addRelaxation(scip, cons, cutoff) );
    7572 (*ncuts)++;
    7573 }
    7574 else if( !SCIPconsIsModifiable(cons) && separatecards && consdata->nvars > 0 )
    7575 {
    7576 /* relax linear constraint into knapsack constraint and separate lifted cardinality cuts */
    7577 if( !separateall && sol == NULL )
    7578 {
    7579 /* we only want to call the knapsack cardinality cut separator for rows that have a non-zero dual solution */
    7580 if( consdata->row != NULL && SCIProwIsInLP(consdata->row) )
    7581 {
    7582 SCIP_Real dualsol;
    7583
    7584 dualsol = SCIProwGetDualsol(consdata->row);
    7585 if( SCIPisFeasNegative(scip, dualsol) )
    7586 {
    7587 if( !SCIPisInfinity(scip, consdata->rhs) )
    7588 {
    7589 SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
    7590 consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
    7591 }
    7592 }
    7593 else if( SCIPisFeasPositive(scip, dualsol) )
    7594 {
    7595 if( !SCIPisInfinity(scip, -consdata->lhs) )
    7596 {
    7597 SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
    7598 consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
    7599 }
    7600 }
    7601 }
    7602 }
    7603 else
    7604 {
    7605 if( !SCIPisInfinity(scip, consdata->rhs) )
    7606 {
    7607 SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
    7608 consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
    7609 }
    7610 if( !SCIPisInfinity(scip, -consdata->lhs) )
    7611 {
    7612 SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
    7613 consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
    7614 }
    7615 }
    7616 }
    7617
    7618 if( *ncuts > oldncuts )
    7619 {
    7621 }
    7622
    7623 return SCIP_OKAY;
    7624}
    7625
    7626/** propagation method for linear constraints */
    7627static
    7629 SCIP* scip, /**< SCIP data structure */
    7630 SCIP_CONS* cons, /**< linear constraint */
    7631 SCIP_Bool tightenbounds, /**< should the variable's bounds be tightened? */
    7632 SCIP_Bool rangedrowpropagation,/**< should ranged row propagation be performed? */
    7633 SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
    7634 SCIP_Bool sortvars, /**< should variable sorting for faster propagation be used? */
    7635 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    7636 int* nchgbds /**< pointer to count the total number of tightened bounds */
    7637 )
    7638{
    7639 SCIP_CONSDATA* consdata;
    7640 SCIP_Real minactivity;
    7641 SCIP_Real maxactivity;
    7642 SCIP_Bool isminacttight;
    7643 SCIP_Bool ismaxacttight;
    7644 SCIP_Bool isminsettoinfinity;
    7645 SCIP_Bool ismaxsettoinfinity;
    7646
    7647 assert(scip != NULL);
    7648 assert(cons != NULL);
    7649 assert(cutoff != NULL);
    7650 assert(nchgbds != NULL);
    7651
    7652 /*SCIPdebugMsg(scip, "propagating linear constraint <%s>\n", SCIPconsGetName(cons));*/
    7653
    7654 consdata = SCIPconsGetData(cons);
    7655 assert(consdata != NULL);
    7656
    7657 if( consdata->eventdata == NULL )
    7658 {
    7659 SCIP_CONSHDLR* conshdlr;
    7660 SCIP_CONSHDLRDATA* conshdlrdata;
    7661
    7662 conshdlr = SCIPconsGetHdlr(cons);
    7663 assert(conshdlr != NULL);
    7664
    7665 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    7666 assert(conshdlrdata != NULL);
    7667
    7668 /* catch bound change events of variables */
    7669 SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    7670 assert(consdata->eventdata != NULL);
    7671 }
    7672
    7673 *cutoff = FALSE;
    7674
    7675 /* we can only infer activity bounds of the linear constraint, if it is not modifiable */
    7676 if( !SCIPconsIsModifiable(cons) )
    7677 {
    7678 /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
    7680 {
    7681 SCIP_CALL( SCIPincConsAge(scip, cons) );
    7682 }
    7683
    7684 /* tighten the variable's bounds */
    7685 if( tightenbounds )
    7686 {
    7687 int oldnchgbds;
    7688
    7689 oldnchgbds = *nchgbds;
    7690
    7691 SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
    7692
    7693 if( *nchgbds > oldnchgbds )
    7694 {
    7696 }
    7697 }
    7698
    7699 /* propagate ranged rows */
    7700 if( rangedrowpropagation && tightenbounds && !(*cutoff) )
    7701 {
    7702 int nfixedvars;
    7703 int naddconss;
    7704 SCIPdebug( int oldnchgbds = *nchgbds; )
    7705
    7706 nfixedvars = 0;
    7707 naddconss = 0;
    7708
    7709 SCIP_CALL( rangedRowPropagation(scip, cons, cutoff, &nfixedvars, nchgbds, &naddconss) );
    7710
    7711 if( *cutoff )
    7712 {
    7713 SCIPdebugMsg(scip, "linear constraint <%s> is infeasible\n", SCIPconsGetName(cons));
    7714 }
    7715 else
    7716 {
    7717 SCIPdebug( SCIPdebugMsg(scip, "linear constraint <%s> found %d bound changes and %d fixings\n", SCIPconsGetName(cons), *nchgbds - oldnchgbds, nfixedvars); )
    7718 }
    7719
    7720 if( nfixedvars > 0 )
    7721 *nchgbds += 2*nfixedvars;
    7722 } /*lint !e438*/
    7723
    7724 /* check constraint for infeasibility and redundancy */
    7725 if( !(*cutoff) )
    7726 {
    7727 consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &isminacttight, &ismaxacttight,
    7728 &isminsettoinfinity, &ismaxsettoinfinity);
    7729
    7730 if( SCIPisFeasGT(scip, minactivity, consdata->rhs) )
    7731 {
    7732 SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (rhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
    7733 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
    7734
    7735 /* analyze conflict */
    7737
    7739 *cutoff = TRUE;
    7740 }
    7741 else if( SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
    7742 {
    7743 SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (lhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
    7744 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
    7745
    7746 /* analyze conflict */
    7748
    7750 *cutoff = TRUE;
    7751 }
    7752 else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
    7753 {
    7754 SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
    7755 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
    7756
    7757 /* remove the constraint locally unless it has become empty, in which case it is removed globally */
    7758 if( consdata->nvars > 0 )
    7760 else
    7761 SCIP_CALL( SCIPdelCons(scip, cons) );
    7762 }
    7763 }
    7764 }
    7765
    7766 return SCIP_OKAY;
    7767}
    7768
    7769
    7770/*
    7771 * Presolving methods
    7772 */
    7773
    7774/** converts all variables with fixed domain into FIXED variables */
    7775static
    7777 SCIP* scip, /**< SCIP data structure */
    7778 SCIP_CONS* cons, /**< linear constraint */
    7779 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    7780 int* nfixedvars /**< pointer to count the total number of fixed variables */
    7781 )
    7782{
    7783 SCIP_CONSDATA* consdata;
    7784 SCIP_VAR* var;
    7785 SCIP_VARSTATUS varstatus;
    7786 SCIP_Real lb;
    7787 SCIP_Real ub;
    7788 SCIP_Bool fixed;
    7789 SCIP_Bool infeasible;
    7790 int v;
    7791
    7792 assert(scip != NULL);
    7793 assert(cons != NULL);
    7794 assert(cutoff != NULL);
    7795 assert(nfixedvars != NULL);
    7796
    7797 consdata = SCIPconsGetData(cons);
    7798 assert(consdata != NULL);
    7799
    7800 for( v = 0; v < consdata->nvars; ++v )
    7801 {
    7802 assert(consdata->vars != NULL);
    7803 var = consdata->vars[v];
    7804 varstatus = SCIPvarGetStatus(var);
    7805
    7806 if( varstatus != SCIP_VARSTATUS_FIXED )
    7807 {
    7808 lb = SCIPvarGetLbGlobal(var);
    7809 ub = SCIPvarGetUbGlobal(var);
    7810 if( SCIPisEQ(scip, lb, ub) )
    7811 {
    7812 SCIP_Real fixval;
    7813
    7814 fixval = SCIPselectSimpleValue(lb, ub, MAXDNOM);
    7815 SCIPdebugMsg(scip, "converting variable <%s> with fixed bounds [%.15g,%.15g] into fixed variable fixed at %.15g\n",
    7816 SCIPvarGetName(var), lb, ub, fixval);
    7817 SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
    7818 if( infeasible )
    7819 {
    7820 SCIPdebugMsg(scip, " -> infeasible fixing\n");
    7821 *cutoff = TRUE;
    7822 return SCIP_OKAY;
    7823 }
    7824 if( fixed )
    7825 (*nfixedvars)++;
    7826 }
    7827 }
    7828 }
    7829
    7830 SCIP_CALL( applyFixings(scip, cons, &infeasible) );
    7831
    7832 if( infeasible )
    7833 {
    7834 SCIPdebugMsg(scip, " -> infeasible fixing\n");
    7835 *cutoff = TRUE;
    7836 return SCIP_OKAY;
    7837 }
    7838
    7839 assert(consdata->removedfixings);
    7840
    7841 return SCIP_OKAY;
    7842}
    7843
    7844#define MAX_CLIQUE_NONZEROS_PER_CONS 1000000
    7845
    7846/** extracts cliques of the constraint and adds them to SCIP
    7847 *
    7848 * The following clique extraction mechanism are implemeneted
    7849 *
    7850 * 1. collect binary variables and sort them in non increasing order, then
    7851 *
    7852 * a) if the constraint has a finite right hand side and the negative infinity counters for the minactivity are zero
    7853 * then add the variables as a clique for which all successive pairs of coefficients fullfill the following
    7854 * condition
    7855 *
    7856 * minactivity + vals[i] + vals[i+1] > rhs
    7857 *
    7858 * and also add the binary to binary implication also for non-successive variables for which the same argument
    7859 * holds
    7860 *
    7861 * minactivity + vals[i] + vals[j] > rhs
    7862 *
    7863 * e.g. 5.3 x1 + 3.6 x2 + 3.3 x3 + 2.1 x4 <= 5.5 (all x are binary) would lead to the clique (x1, x2, x3) and the
    7864 * binary to binary implications x1 = 1 => x4 = 0 and x2 = 1 => x4 = 0
    7865 *
    7866 * b) if the constraint has a finite left hand side and the positive infinity counters for the maxactivity are zero
    7867 * then add the variables as a clique for which all successive pairs of coefficients fullfill the follwoing
    7868 * condition
    7869 *
    7870 * maxactivity + vals[i] + vals[i-1] < lhs
    7871 *
    7872 * and also add the binary to binary implication also for non-successive variables for which the same argument
    7873 * holds
    7874 *
    7875 * maxactivity + vals[i] + vals[j] < lhs
    7876 *
    7877 * e.g. you could multiply the above example by -1
    7878 *
    7879 * c) the constraint has a finite right hand side and a finite minactivity then add the variables as a negated
    7880 * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
    7881 * condition
    7882 *
    7883 * minactivity - vals[i] - vals[i-1] > rhs
    7884 *
    7885 * and also add the binary to binary implication also for non-successive variables for which the
    7886 * same argument holds
    7887 *
    7888 * minactivity - vals[i] - vals[j] > rhs
    7889 *
    7890 * e.g. -4 x1 -3 x2 - 2 x3 + 2 x4 <= -4 would lead to the (negated) clique (~x1, ~x2) and the binary to binary
    7891 * implication x1 = 0 => x3 = 1
    7892 *
    7893 * d) the constraint has a finite left hand side and a finite maxactivity then add the variables as a negated
    7894 * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
    7895 * condition
    7896 *
    7897 * maxactivity - vals[i] - vals[i+1] < lhs
    7898 *
    7899 * and also add the binary to binary implication also for non-successive variables for which the same argument
    7900 * holds
    7901 *
    7902 * maxactivity - vals[i] - vals[j] < lhs
    7903 *
    7904 * e.g. you could multiply the above example by -1
    7905 *
    7906 * 2. if the linear constraint represents a set-packing or set-partitioning constraint, the whole constraint is added
    7907 * as clique, (this part is done at the end of the method)
    7908 *
    7909 */
    7910static
    7912 SCIP* scip, /**< SCIP data structure */
    7913 SCIP_CONS* cons, /**< linear constraint */
    7914 SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
    7915 SCIP_Bool sortvars, /**< should variables be used in sorted order? */
    7916 int* nfixedvars, /**< pointer to count number of fixed variables */
    7917 int* nchgbds, /**< pointer to count the total number of tightened bounds */
    7918 SCIP_Bool* cutoff /**< pointer to store TRUE, if a cutoff was found */
    7919 )
    7920{
    7921 SCIP_VAR** vars;
    7922 SCIP_Real* vals;
    7923 SCIP_CONSDATA* consdata;
    7924 SCIP_Bool lhsclique;
    7925 SCIP_Bool rhsclique;
    7926 SCIP_Bool finitelhs;
    7927 SCIP_Bool finiterhs;
    7928 SCIP_Bool finiteminact;
    7929 SCIP_Bool finitemaxact;
    7930 SCIP_Bool finitenegminact;
    7931 SCIP_Bool finitenegmaxact;
    7932 SCIP_Bool finiteposminact;
    7933 SCIP_Bool finiteposmaxact;
    7934 SCIP_Bool infeasible;
    7935 SCIP_Bool stopped;
    7936 int cliquenonzerosadded;
    7937 int v;
    7938 int i;
    7939 int nposcoefs;
    7940 int nnegcoefs;
    7941 int nvars;
    7942
    7943 assert(scip != NULL);
    7944 assert(cons != NULL);
    7945 assert(nfixedvars != NULL);
    7946 assert(nchgbds != NULL);
    7947 assert(cutoff != NULL);
    7948 assert(!SCIPconsIsDeleted(cons));
    7949
    7950 consdata = SCIPconsGetData(cons);
    7951 assert(consdata != NULL);
    7952
    7953 if( consdata->nvars < 2 )
    7954 return SCIP_OKAY;
    7955
    7956 /* add implications if possible
    7957 *
    7958 * for now we only add binary to non-binary implications, and this is only done for the binary variable with the
    7959 * maximal absolute contribution and also only if this variable would force all other variables to their bound
    7960 * corresponding to the global minimal activity of the constraint
    7961 */
    7962 if( !consdata->implsadded )
    7963 {
    7964 /* sort variables by variable type */
    7965 SCIP_CALL( consdataSort(scip, consdata) );
    7966
    7967 /* @todo we might extract implications/cliques if SCIPvarIsBinary() variables exist and we have integer variables
    7968 * up front, might change sorting correspondingly
    7969 */
    7970 /* fast abort if no binaries seem to exist
    7971 * "seem to", because there are rare situations in which variables may actually not be sorted by type, even though consdataSort has been called
    7972 * this situation can occur if, e.g., the type of consdata->vars[1] has been changed to binary, but the corresponding variable event has
    7973 * not been executed yet, because it is the eventExecLinear() which marks the variables array as unsorted (set consdata->indexsorted to FALSE),
    7974 * which is the requirement for consdataSort() to actually resort the variables
    7975 * we assume that in this situation the below code may be executed in a future presolve round, after the variable events have been executed
    7976 */
    7977 if( !SCIPvarIsBinary(consdata->vars[0]) )
    7978 return SCIP_OKAY;
    7979
    7980 nvars = consdata->nvars;
    7981 vars = consdata->vars;
    7982 vals = consdata->vals;
    7983
    7984 /* recompute activities if needed */
    7985 if( !consdata->validactivities )
    7986 consdataCalcActivities(scip, consdata);
    7987 assert(consdata->validactivities);
    7988
    7989 finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
    7990 finiterhs = !SCIPisInfinity(scip, consdata->rhs);
    7991 finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
    7992 finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
    7993 finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
    7994 finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
    7995 finiteminact = (finitenegminact && finiteposminact);
    7996 finitemaxact = (finitenegmaxact && finiteposmaxact);
    7997
    7998 if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
    7999 {
    8000 SCIP_Real maxabscontrib = -1.0;
    8001 SCIP_Bool posval = FALSE;
    8002 SCIP_Bool allbinary = TRUE;
    8003 int oldnchgbds = *nchgbds;
    8004 int nbdchgs = 0;
    8005 int nimpls = 0;
    8006 int position = -1;
    8007
    8008 /* we need a valid minimal/maximal activity to add cliques */
    8009 if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
    8010 {
    8012 assert(consdata->validglbminact);
    8013 }
    8014
    8015 if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
    8016 {
    8018 assert(consdata->validglbmaxact);
    8019 }
    8020 assert(consdata->validglbminact || consdata->validglbmaxact);
    8021
    8022 /* @todo extend this to local/constraint probing */
    8023
    8024 /* determine maximal contribution to the activity */
    8025 for( v = nvars - 1; v >= 0; --v )
    8026 {
    8027 if( SCIPvarIsBinary(vars[v]) )
    8028 {
    8029 if( vals[v] > 0 )
    8030 {
    8031 SCIP_Real value = vals[v] * SCIPvarGetUbGlobal(vars[v]);
    8032
    8033 if( value > maxabscontrib )
    8034 {
    8035 maxabscontrib = value;
    8036 position = v;
    8037 posval = TRUE;
    8038 }
    8039 }
    8040 else
    8041 {
    8042 SCIP_Real value = vals[v] * SCIPvarGetLbGlobal(vars[v]);
    8043
    8044 value = REALABS(value);
    8045
    8046 if( value > maxabscontrib )
    8047 {
    8048 maxabscontrib = value;
    8049 position = v;
    8050 posval = FALSE;
    8051 }
    8052 }
    8053 }
    8054 else
    8055 allbinary = FALSE;
    8056 }
    8057 assert(0 <= position && position < nvars);
    8058
    8059 if( !SCIPisEQ(scip, maxabscontrib, 1.0) && !allbinary )
    8060 {
    8061 /* if the right hand side and the minimal activity are finite and changing the variable with the biggest
    8062 * influence to their bound forces all other variables to be at their minimal contribution, we can add these
    8063 * implications
    8064 */
    8065 if( finiterhs && finiteminact && SCIPisEQ(scip, QUAD_TO_DBL(consdata->glbminactivity), consdata->rhs - maxabscontrib) )
    8066 {
    8067 for( v = nvars - 1; v >= 0; --v )
    8068 {
    8069 /* binary to binary implications will be collected when extrating cliques */
    8070 if( !SCIPvarIsBinary(vars[v]) )
    8071 {
    8072 if( v != position )
    8073 {
    8074 if( vals[v] > 0 )
    8075 {
    8076 /* add implications */
    8077 SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
    8078 ++nimpls;
    8079 *nchgbds += nbdchgs;
    8080 }
    8081 else
    8082 {
    8083 /* add implications */
    8084 SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
    8085 ++nimpls;
    8086 *nchgbds += nbdchgs;
    8087 }
    8088
    8089 if( infeasible )
    8090 {
    8091 *cutoff = TRUE;
    8092 break;
    8093 }
    8094 }
    8095 }
    8096 /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
    8097 else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY && !SCIPvarIsImpliedIntegral(vars[v]) )
    8098 break;
    8099 }
    8100 }
    8101
    8102 /* if the left hand side and the maximal activity are finite and changing the variable with the biggest
    8103 * influence to their bound forces all other variables to be at their minimal contribution, we can add these
    8104 * implications
    8105 */
    8106 if( finitelhs && finitemaxact && SCIPisEQ(scip, QUAD_TO_DBL(consdata->glbmaxactivity), consdata->lhs - maxabscontrib) )
    8107 {
    8108 for( v = nvars - 1; v >= 0; --v )
    8109 {
    8110 /* binary to binary implications will be collected when extrating cliques */
    8111 if( !SCIPvarIsBinary(vars[v]) )
    8112 {
    8113 if( v != position )
    8114 {
    8115 if( vals[v] > 0 )
    8116 {
    8117 /* add implications */
    8118 SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
    8119 ++nimpls;
    8120 *nchgbds += nbdchgs;
    8121 }
    8122 else
    8123 {
    8124 /* add implications */
    8125 SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
    8126 ++nimpls;
    8127 *nchgbds += nbdchgs;
    8128 }
    8129
    8130 if( infeasible )
    8131 {
    8132 *cutoff = TRUE;
    8133 break;
    8134 }
    8135 }
    8136 }
    8137 /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
    8138 else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
    8139 break;
    8140 }
    8141 }
    8142
    8143 /* did we find some implications */
    8144 if( nimpls > 0 )
    8145 {
    8146 SCIPdebugMsg(scip, "extracted %d implications from constraint %s which led to %d bound changes, %scutoff detetcted\n", nimpls, SCIPconsGetName(cons), *nchgbds - oldnchgbds, *cutoff ? "" : "no ");
    8147
    8148 if( *cutoff )
    8149 return SCIP_OKAY;
    8150
    8151 /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
    8152 if( *nchgbds - oldnchgbds > 0 )
    8153 {
    8154 /* check for fixed variables */
    8155 SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
    8156 if( *cutoff )
    8157 return SCIP_OKAY;
    8158
    8159 /* tighten variable's bounds */
    8160 SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
    8161 if( *cutoff )
    8162 return SCIP_OKAY;
    8163
    8164 /* check for fixed variables */
    8165 SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
    8166 if( *cutoff )
    8167 return SCIP_OKAY;
    8168 }
    8169 }
    8170 }
    8171 }
    8172
    8173 consdata->implsadded = TRUE;
    8174 }
    8175
    8176 /* check if we already added the cliques of this constraint */
    8177 if( consdata->cliquesadded )
    8178 return SCIP_OKAY;
    8179
    8180 consdata->cliquesadded = TRUE;
    8181 cliquenonzerosadded = 0;
    8182 stopped = FALSE;
    8183
    8184 /* sort variables by variable type */
    8185 SCIP_CALL( consdataSort(scip, consdata) );
    8186
    8187 nvars = consdata->nvars;
    8188 vars = consdata->vars;
    8189 vals = consdata->vals;
    8190
    8191 /**@todo extract more cliques, implications and variable bounds from linear constraints */
    8192
    8193 /* recompute activities if needed */
    8194 if( !consdata->validactivities )
    8195 consdataCalcActivities(scip, consdata);
    8196 assert(consdata->validactivities);
    8197
    8198 finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
    8199 finiterhs = !SCIPisInfinity(scip, consdata->rhs);
    8200 finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
    8201 finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
    8202 finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
    8203 finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
    8204 finiteminact = (finitenegminact && finiteposminact);
    8205 finitemaxact = (finitenegmaxact && finiteposmaxact);
    8206
    8207 /* 1. we wheck whether some variables do not fit together into this constraint and add the corresponding clique
    8208 * information
    8209 */
    8210 if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
    8211 {
    8212 SCIP_VAR** binvars;
    8213 SCIP_Real* binvarvals;
    8214 int nposbinvars = 0;
    8215 int nnegbinvars = 0;
    8216 int allonebinary = 0;
    8217
    8218 SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nvars) );
    8219 SCIP_CALL( SCIPallocBufferArray(scip, &binvarvals, nvars) );
    8220
    8221 /* collect binary variables */
    8222 for( i = 0; i < nvars; ++i )
    8223 {
    8224 if( SCIPvarIsBinary(vars[i]) )
    8225 {
    8226 assert(!SCIPisZero(scip, vals[i]));
    8227
    8228 if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
    8229 ++allonebinary;
    8230
    8231 binvars[nposbinvars + nnegbinvars] = vars[i];
    8232 binvarvals[nposbinvars + nnegbinvars] = vals[i];
    8233
    8234 if( SCIPisPositive(scip, vals[i]) )
    8235 ++nposbinvars;
    8236 else
    8237 ++nnegbinvars;
    8238
    8239 assert(nposbinvars + nnegbinvars <= nvars);
    8240 }
    8241 /* stop searching for binary variables, because the constraint data is sorted */
    8242 else if( !SCIPvarIsIntegral(vars[i]) )
    8243 break;
    8244 }
    8245 assert(nposbinvars + nnegbinvars <= nvars);
    8246
    8247 /* setppc constraints will be handled later; we need at least two binary variables with same sign to extract
    8248 * cliques
    8249 */
    8250 if( allonebinary < nvars && (nposbinvars >= 2 || nnegbinvars >= 2) )
    8251 {
    8252 SCIP_Real threshold;
    8253 int oldnchgbds = *nchgbds;
    8254 int nbdchgs;
    8255 int jstart;
    8256 int j;
    8257
    8258 /* we need a valid minimal/maximal activity to add cliques */
    8259 if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
    8260 {
    8262 assert(consdata->validglbminact);
    8263 }
    8264
    8265 if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
    8266 {
    8268 assert(consdata->validglbmaxact);
    8269 }
    8270 assert(consdata->validglbminact || consdata->validglbmaxact);
    8271
    8272 /* sort coefficients non-increasing to be faster in the clique search */
    8273 SCIPsortDownRealPtr(binvarvals, (void**) binvars, nposbinvars + nnegbinvars);
    8274
    8275 /* case a) */
    8276 if( finiterhs && finitenegminact && nposbinvars >= 2 )
    8277 {
    8278 /* compute value that needs to be exceeded */
    8279 threshold = consdata->rhs - QUAD_TO_DBL(consdata->glbminactivity);
    8280
    8281 j = 1;
    8282#ifdef SCIP_DISABLED_CODE /* assertion should only hold when constraints were fully propagated and boundstightened */
    8283 /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
    8284 assert(SCIPisFeasLE(scip, binvarvals[0], threshold));
    8285#endif
    8286 /* check if at least two variables are in a clique */
    8287 if( SCIPisFeasGT(scip, binvarvals[0] + binvarvals[j], threshold) )
    8288 {
    8289 ++j;
    8290 /* check for extending the clique */
    8291 while( j < nposbinvars )
    8292 {
    8293 if( !SCIPisFeasGT(scip, binvarvals[j-1] + binvarvals[j], threshold) )
    8294 break;
    8295 ++j;
    8296 }
    8297 assert(j >= 2);
    8298
    8299 /* add clique with at least two variables */
    8300 SCIP_CALL( SCIPaddClique(scip, binvars, NULL, j, FALSE, &infeasible, &nbdchgs) );
    8301
    8302 if( infeasible )
    8303 *cutoff = TRUE;
    8304
    8305 *nchgbds += nbdchgs;
    8306
    8307 cliquenonzerosadded += j;
    8308 if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
    8309 stopped = TRUE;
    8310
    8311 /* exchange the last variable in the clique if possible and add all new ones */
    8312 if( !stopped && !(*cutoff) && j < nposbinvars )
    8313 {
    8314 SCIP_VAR** clqvars;
    8315 int lastfit = j - 2;
    8316 assert(lastfit >= 0);
    8317
    8318 /* copy all 'main'-clique variables */
    8319 SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, binvars, j) );
    8320
    8321 /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
    8322 while( lastfit >= 0 && j < nposbinvars )
    8323 {
    8324 /* check if two variables are in a clique */
    8325 if( SCIPisFeasGT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
    8326 {
    8327 clqvars[lastfit + 1] = binvars[j];
    8328
    8329 /* add clique with at least two variables */
    8330 SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, lastfit + 2, FALSE, &infeasible, &nbdchgs) );
    8331
    8332 if( infeasible )
    8333 {
    8334 *cutoff = TRUE;
    8335 break;
    8336 }
    8337
    8338 *nchgbds += nbdchgs;
    8339
    8340 cliquenonzerosadded += (lastfit + 2);
    8341 if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
    8342 {
    8343 stopped = TRUE;
    8344 break;
    8345 }
    8346
    8347 ++j;
    8348 }
    8349 else
    8350 --lastfit;
    8351 }
    8352
    8353 SCIPfreeBufferArray(scip, &clqvars);
    8354 }
    8355 }
    8356 }
    8357
    8358 /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
    8359 if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
    8360 {
    8361 /* check for fixed variables */
    8362 SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
    8363
    8364 if( !*cutoff )
    8365 {
    8366 /* tighten variable's bounds */
    8367 SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
    8368
    8369 if( !*cutoff )
    8370 {
    8371 /* check for fixed variables */
    8372 SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
    8373
    8374 if( !*cutoff )
    8375 {
    8376 /* sort variables by variable type */
    8377 SCIP_CALL( consdataSort(scip, consdata) );
    8378
    8379 /* recompute activities if needed */
    8380 if( !consdata->validactivities )
    8381 consdataCalcActivities(scip, consdata);
    8382 assert(consdata->validactivities);
    8383
    8384 nvars = consdata->nvars;
    8385 vars = consdata->vars;
    8386 vals = consdata->vals;
    8387 nposbinvars = 0;
    8388 nnegbinvars = 0;
    8389 allonebinary = 0;
    8390
    8391 /* update binary variables */
    8392 for( i = 0; i < nvars; ++i )
    8393 {
    8394 if( SCIPvarIsBinary(vars[i]) )
    8395 {
    8396 assert(!SCIPisZero(scip, vals[i]));
    8397
    8398 if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
    8399 ++allonebinary;
    8400
    8401 binvars[nposbinvars + nnegbinvars] = vars[i];
    8402 binvarvals[nposbinvars + nnegbinvars] = vals[i];
    8403
    8404 if( SCIPisPositive(scip, vals[i]) )
    8405 ++nposbinvars;
    8406 else
    8407 ++nnegbinvars;
    8408
    8409 assert(nposbinvars + nnegbinvars <= nvars);
    8410 }
    8411 /* stop searching for binary variables, because the constraint data is sorted */
    8412 else if( !SCIPvarIsIntegral(vars[i]) )
    8413 break;
    8414 }
    8415 assert(nposbinvars + nnegbinvars <= nvars);
    8416 }
    8417 }
    8418 }
    8419
    8420 oldnchgbds = *nchgbds;
    8421 }
    8422
    8423 /* case b) */
    8424 if( !stopped && !(*cutoff) && finitelhs && finiteposmaxact && nnegbinvars >= 2 )
    8425 {
    8426 /* compute value that needs to be deceeded */
    8427 threshold = consdata->lhs - QUAD_TO_DBL(consdata->glbmaxactivity);
    8428
    8429 i = nposbinvars + nnegbinvars - 1;
    8430 j = i - 1;
    8431#ifdef SCIP_DISABLED_CODE
    8432 /* assertion should only hold when constraints were fully propagated and boundstightened */
    8433 /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
    8434 assert(SCIPisFeasGE(scip, binvarvals[i], threshold));
    8435#endif
    8436 /* check if two variables are in a clique */
    8437 if( SCIPisFeasLT(scip, binvarvals[i] + binvarvals[j], threshold) )
    8438 {
    8439 --j;
    8440 /* check for extending the clique */
    8441 while( j >= nposbinvars )
    8442 {
    8443 if( !SCIPisFeasLT(scip, binvarvals[j+1] + binvarvals[j], threshold) )
    8444 break;
    8445 --j;
    8446 }
    8447 jstart = j;
    8448
    8449 assert(i - j >= 2);
    8450 /* add clique with at least two variables */
    8451 SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), NULL, i - j, FALSE, &infeasible, &nbdchgs) );
    8452
    8453 if( infeasible )
    8454 *cutoff = TRUE;
    8455
    8456 *nchgbds += nbdchgs;
    8457
    8458 cliquenonzerosadded += (i - j);
    8459 if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
    8460 stopped = TRUE;
    8461
    8462 /* exchange the last variable in the clique if possible and add all new ones */
    8463 if( !stopped && !(*cutoff) && jstart >= nposbinvars )
    8464 {
    8465 SCIP_VAR** clqvars;
    8466 int lastfit = jstart + 1;
    8467 assert(lastfit < i);
    8468
    8469 /* copy all 'main'-clique variables */
    8470 SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
    8471 ++lastfit;
    8472
    8473 /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
    8474 while( lastfit <= i && j >= nposbinvars )
    8475 {
    8476 /* check if two variables are in a clique */
    8477 if( SCIPisFeasLT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
    8478 {
    8479 assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
    8480 clqvars[lastfit - jstart - 2] = binvars[j];
    8481
    8482 assert(i - lastfit + 2 >= 2);
    8483 /* add clique with at least two variables */
    8484 SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), NULL, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
    8485
    8486 if( infeasible )
    8487 {
    8488 *cutoff = TRUE;
    8489 break;
    8490 }
    8491
    8492 *nchgbds += nbdchgs;
    8493
    8494 cliquenonzerosadded += (i - lastfit + 2);
    8495 if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
    8496 {
    8497 stopped = TRUE;
    8498 break;
    8499 }
    8500
    8501 --j;
    8502 }
    8503 else
    8504 ++lastfit;
    8505 }
    8506
    8507 SCIPfreeBufferArray(scip, &clqvars);
    8508 }
    8509 }
    8510 }
    8511
    8512 /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
    8513 if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
    8514 {
    8515 /* check for fixed variables */
    8516 SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
    8517
    8518 if( !*cutoff )
    8519 {
    8520 /* tighten variable's bounds */
    8521 SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
    8522
    8523 if( !*cutoff )
    8524 {
    8525 /* check for fixed variables */
    8526 SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
    8527
    8528 if( !*cutoff )
    8529 {
    8530 /* sort variables by variable type */
    8531 SCIP_CALL( consdataSort(scip, consdata) );
    8532
    8533 /* recompute activities if needed */
    8534 if( !consdata->validactivities )
    8535 consdataCalcActivities(scip, consdata);
    8536 assert(consdata->validactivities);
    8537
    8538 nvars = consdata->nvars;
    8539 vars = consdata->vars;
    8540 vals = consdata->vals;
    8541 nposbinvars = 0;
    8542 nnegbinvars = 0;
    8543 allonebinary = 0;
    8544
    8545 /* update binary variables */
    8546 for( i = 0; i < nvars; ++i )
    8547 {
    8548 if( SCIPvarIsBinary(vars[i]) )
    8549 {
    8550 assert(!SCIPisZero(scip, vals[i]));
    8551
    8552 if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
    8553 ++allonebinary;
    8554
    8555 binvars[nposbinvars + nnegbinvars] = vars[i];
    8556 binvarvals[nposbinvars + nnegbinvars] = vals[i];
    8557
    8558 if( SCIPisPositive(scip, vals[i]) )
    8559 ++nposbinvars;
    8560 else
    8561 ++nnegbinvars;
    8562
    8563 assert(nposbinvars + nnegbinvars <= nvars);
    8564 }
    8565 /* stop searching for binary variables, because the constraint data is sorted */
    8566 else if( !SCIPvarIsIntegral(vars[i]) )
    8567 break;
    8568 }
    8569 assert(nposbinvars + nnegbinvars <= nvars);
    8570 }
    8571 }
    8572 }
    8573
    8574 oldnchgbds = *nchgbds;
    8575 }
    8576
    8577 /* case c) */
    8578 if( !(*cutoff) && finiterhs && finiteminact && nnegbinvars >= 2 )
    8579 {
    8580 SCIP_Bool* values;
    8581
    8582 /* initialize clique values array for adding a negated clique */
    8583 SCIP_CALL( SCIPallocBufferArray(scip, &values, nnegbinvars) );
    8584 BMSclearMemoryArray(values, nnegbinvars);
    8585
    8586 /* compute value that needs to be exceeded */
    8587 threshold = consdata->rhs - QUAD_TO_DBL(consdata->glbminactivity);
    8588
    8589 i = nposbinvars + nnegbinvars - 1;
    8590 j = i - 1;
    8591
    8592#ifdef SCIP_DISABLED_CODE
    8593 /* assertion should only hold when constraints were fully propagated and boundstightened */
    8594 /* check if the variable should not have already been fixed to one */
    8595 assert(!SCIPisFeasGT(scip, binvarvals[i], threshold));
    8596#endif
    8597
    8598 if( SCIPisFeasGT(scip, -binvarvals[i] - binvarvals[j], threshold) )
    8599 {
    8600 --j;
    8601 /* check for extending the clique */
    8602 while( j >= nposbinvars )
    8603 {
    8604 if( !SCIPisFeasGT(scip, -binvarvals[j+1] - binvarvals[j], threshold) )
    8605 break;
    8606 --j;
    8607 }
    8608 jstart = j;
    8609
    8610 assert(i - j >= 2);
    8611 /* add negated clique with at least two variables */
    8612 SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), values, i - j, FALSE, &infeasible, &nbdchgs) );
    8613
    8614 if( infeasible )
    8615 *cutoff = TRUE;
    8616
    8617 *nchgbds += nbdchgs;
    8618
    8619 cliquenonzerosadded += (i - j);
    8620 if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
    8621 stopped = TRUE;
    8622
    8623 /* exchange the last variable in the clique if possible and add all new ones */
    8624 if( !stopped && !(*cutoff) && jstart >= nposbinvars )
    8625 {
    8626 SCIP_VAR** clqvars;
    8627 int lastfit = j + 1;
    8628 assert(lastfit < i);
    8629
    8630 /* copy all 'main'-clique variables */
    8631 SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
    8632 ++lastfit;
    8633
    8634 /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
    8635 while( lastfit <= i && j >= nposbinvars )
    8636 {
    8637 /* check if two variables are in a negated clique */
    8638 if( SCIPisFeasGT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
    8639 {
    8640 assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
    8641 clqvars[lastfit - jstart - 2] = binvars[j];
    8642
    8643 assert(i - lastfit + 2 >= 2);
    8644 /* add clique with at least two variables */
    8645 SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), values, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
    8646
    8647 if( infeasible )
    8648 {
    8649 *cutoff = TRUE;
    8650 break;
    8651 }
    8652
    8653 *nchgbds += nbdchgs;
    8654
    8655 cliquenonzerosadded += (i - lastfit + 2);
    8656 if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
    8657 {
    8658 stopped = TRUE;
    8659 break;
    8660 }
    8661
    8662 --j;
    8663 }
    8664 else
    8665 ++lastfit;
    8666 }
    8667
    8668 SCIPfreeBufferArray(scip, &clqvars);
    8669 }
    8670 }
    8671
    8672 SCIPfreeBufferArray(scip, &values);
    8673 }
    8674
    8675 /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
    8676 if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
    8677 {
    8678 /* check for fixed variables */
    8679 SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
    8680
    8681 if( !*cutoff )
    8682 {
    8683 /* tighten variable's bounds */
    8684 SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
    8685
    8686 if( !*cutoff )
    8687 {
    8688 /* check for fixed variables */
    8689 SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
    8690
    8691 if( !*cutoff )
    8692 {
    8693 /* sort variables by variable type */
    8694 SCIP_CALL( consdataSort(scip, consdata) );
    8695
    8696 /* recompute activities if needed */
    8697 if( !consdata->validactivities )
    8698 consdataCalcActivities(scip, consdata);
    8699 assert(consdata->validactivities);
    8700
    8701 nvars = consdata->nvars;
    8702 vars = consdata->vars;
    8703 vals = consdata->vals;
    8704 nposbinvars = 0;
    8705 nnegbinvars = 0;
    8706 allonebinary = 0;
    8707
    8708 /* update binary variables */
    8709 for( i = 0; i < nvars; ++i )
    8710 {
    8711 if( SCIPvarIsBinary(vars[i]) )
    8712 {
    8713 assert(!SCIPisZero(scip, vals[i]));
    8714
    8715 if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
    8716 ++allonebinary;
    8717
    8718 binvars[nposbinvars + nnegbinvars] = vars[i];
    8719 binvarvals[nposbinvars + nnegbinvars] = vals[i];
    8720
    8721 if( SCIPisPositive(scip, vals[i]) )
    8722 ++nposbinvars;
    8723 else
    8724 ++nnegbinvars;
    8725
    8726 assert(nposbinvars + nnegbinvars <= nvars);
    8727 }
    8728 /* stop searching for binary variables, because the constraint data is sorted */
    8729 else if( !SCIPvarIsIntegral(vars[i]) )
    8730 break;
    8731 }
    8732 assert(nposbinvars + nnegbinvars <= nvars);
    8733 }
    8734 }
    8735 }
    8736 }
    8737
    8738 /* case d) */
    8739 if( !stopped && !(*cutoff) && finitelhs && finitemaxact && nposbinvars >= 2 )
    8740 {
    8741 SCIP_Bool* values;
    8742
    8743 /* initialize clique values array for adding a negated clique */
    8744 SCIP_CALL( SCIPallocBufferArray(scip, &values, nposbinvars) );
    8745 BMSclearMemoryArray(values, nposbinvars);
    8746
    8747 /* compute value that needs to be exceeded */
    8748 threshold = consdata->lhs - QUAD_TO_DBL(consdata->glbmaxactivity);
    8749
    8750 j = 1;
    8751
    8752#ifdef SCIP_DISABLED_CODE
    8753 /* assertion should only hold when constraints were fully propagated and boundstightened */
    8754 /* check if the variable should not have already been fixed to one */
    8755 assert(!SCIPisFeasLT(scip, -binvarvals[0], threshold));
    8756#endif
    8757
    8758 if( SCIPisFeasLT(scip, -binvarvals[0] - binvarvals[j], threshold) )
    8759 {
    8760 ++j;
    8761 /* check for extending the clique */
    8762 while( j < nposbinvars )
    8763 {
    8764 if( !SCIPisFeasLT(scip, -binvarvals[j-1] - binvarvals[j], threshold) )
    8765 break;
    8766 ++j;
    8767 }
    8768 assert(j >= 2);
    8769
    8770 /* add negated clique with at least two variables */
    8771 SCIP_CALL( SCIPaddClique(scip, binvars, values, j, FALSE, &infeasible, &nbdchgs) );
    8772
    8773 if( infeasible )
    8774 *cutoff = TRUE;
    8775
    8776 *nchgbds += nbdchgs;
    8777
    8778 cliquenonzerosadded += j;
    8779 if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
    8780 stopped = TRUE;
    8781
    8782 /* exchange the last variable in the clique if possible and add all new ones */
    8783 if( !stopped && !(*cutoff) && j < nposbinvars )
    8784 {
    8785 SCIP_VAR** clqvars;
    8786 int lastfit = j - 2;
    8787 assert(lastfit >= 0);
    8788
    8789 /* copy all 'main'-clique variables */
    8790 SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, binvars, j) );
    8791
    8792 /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
    8793 while( lastfit >= 0 && j < nposbinvars )
    8794 {
    8795 /* check if two variables are in a negated clique */
    8796 if( SCIPisFeasLT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
    8797 {
    8798 clqvars[lastfit + 1] = binvars[j];
    8799
    8800 /* add clique with at least two variables */
    8801 SCIP_CALL( SCIPaddClique(scip, clqvars, values, lastfit + 2, FALSE, &infeasible, &nbdchgs) );
    8802
    8803 if( infeasible )
    8804 {
    8805 *cutoff = TRUE;
    8806 break;
    8807 }
    8808
    8809 *nchgbds += nbdchgs;
    8810
    8811 cliquenonzerosadded += lastfit + 2;
    8812 if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
    8813 break;
    8814
    8815 ++j;
    8816 }
    8817 else
    8818 --lastfit;
    8819 }
    8820
    8821 SCIPfreeBufferArray(scip, &clqvars);
    8822 }
    8823 }
    8824
    8825 SCIPfreeBufferArray(scip, &values);
    8826 }
    8827 }
    8828
    8829 SCIPfreeBufferArray(scip, &binvarvals);
    8830 SCIPfreeBufferArray(scip, &binvars);
    8831
    8832 if( *cutoff )
    8833 return SCIP_OKAY;
    8834 }
    8835
    8836 /* 2. we only check if the constraint is a set packing / partitioning constraint */
    8837
    8838 /* check if all variables are binary, if the coefficients are +1 or -1, and if the right hand side is equal
    8839 * to 1 - number of negative coefficients, or if the left hand side is equal to number of positive coefficients - 1
    8840 */
    8841 nposcoefs = 0;
    8842 nnegcoefs = 0;
    8843 for( i = 0; i < nvars; ++i )
    8844 {
    8845 if( !SCIPvarIsBinary(vars[i]) )
    8846 return SCIP_OKAY;
    8847 else if( SCIPisEQ(scip, vals[i], +1.0) )
    8848 nposcoefs++;
    8849 else if( SCIPisEQ(scip, vals[i], -1.0) )
    8850 nnegcoefs++;
    8851 else
    8852 return SCIP_OKAY;
    8853 }
    8854
    8855 lhsclique = SCIPisEQ(scip, consdata->lhs, (SCIP_Real)nposcoefs - 1.0);
    8856 rhsclique = SCIPisEQ(scip, consdata->rhs, 1.0 - (SCIP_Real)nnegcoefs);
    8857
    8858 if( lhsclique || rhsclique )
    8859 {
    8860 SCIP_Bool* values;
    8861 int nbdchgs;
    8862
    8863 SCIPdebugMsg(scip, "linear constraint <%s>: adding clique with %d vars (%d pos, %d neg)\n",
    8864 SCIPconsGetName(cons), nvars, nposcoefs, nnegcoefs);
    8865 SCIP_CALL( SCIPallocBufferArray(scip, &values, nvars) );
    8866
    8867 for( i = 0; i < nvars; ++i )
    8868 values[i] = (rhsclique == (vals[i] > 0.0));
    8869
    8870 SCIP_CALL( SCIPaddClique(scip, vars, values, nvars, SCIPisEQ(scip, consdata->lhs, consdata->rhs), &infeasible, &nbdchgs) );
    8871
    8872 if( infeasible )
    8873 *cutoff = TRUE;
    8874
    8875 *nchgbds += nbdchgs;
    8876 SCIPfreeBufferArray(scip, &values);
    8877 }
    8878
    8879 return SCIP_OKAY;
    8880}
    8881
    8882/** tightens left and right hand side of constraint due to integrality */
    8883static
    8885 SCIP* scip, /**< SCIP data structure */
    8886 SCIP_CONS* cons, /**< linear constraint */
    8887 int* nchgsides, /**< pointer to count number of side changes */
    8888 SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
    8889 )
    8890{
    8891 SCIP_CONSDATA* consdata;
    8892 SCIP_Real newlhs;
    8893 SCIP_Real newrhs;
    8894 SCIP_Bool chglhs;
    8895 SCIP_Bool chgrhs;
    8896 SCIP_Bool integral;
    8897 int i;
    8898
    8899 assert(scip != NULL);
    8900 assert(cons != NULL);
    8901 assert(nchgsides != NULL);
    8902 assert(infeasible != NULL);
    8903
    8904 consdata = SCIPconsGetData(cons);
    8905 assert(consdata != NULL);
    8906
    8907 *infeasible = FALSE;
    8908
    8909 chglhs = FALSE;
    8910 chgrhs = FALSE;
    8911 newlhs = -SCIPinfinity(scip);
    8912 newrhs = SCIPinfinity(scip);
    8913
    8914 if( !SCIPisIntegral(scip, consdata->lhs) || !SCIPisIntegral(scip, consdata->rhs) )
    8915 {
    8916 integral = TRUE;
    8917 for( i = 0; i < consdata->nvars && integral; ++i )
    8918 integral = SCIPvarIsIntegral(consdata->vars[i]) && SCIPisIntegral(scip, consdata->vals[i]);
    8919 if( integral )
    8920 {
    8921 if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisIntegral(scip, consdata->lhs) )
    8922 {
    8923 newlhs = SCIPfeasCeil(scip, consdata->lhs);
    8924 chglhs = TRUE;
    8925 }
    8926 if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisIntegral(scip, consdata->rhs) )
    8927 {
    8928 newrhs = SCIPfeasFloor(scip, consdata->rhs);
    8929 chgrhs = TRUE;
    8930 }
    8931
    8932 /* check whether rounding would lead to an unsatisfiable constraint */
    8933 if( SCIPisGT(scip, newlhs, newrhs) )
    8934 {
    8935 SCIPdebugMsg(scip, "rounding sides=[%.15g,%.15g] of linear constraint <%s> with integral coefficients and variables only "
    8936 "is infeasible\n", consdata->lhs, consdata->rhs, SCIPconsGetName(cons));
    8937
    8938 *infeasible = TRUE;
    8939 return SCIP_OKAY;
    8940 }
    8941
    8942 SCIPdebugMsg(scip, "linear constraint <%s>: make sides integral: sides=[%.15g,%.15g]\n",
    8943 SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
    8944
    8945 if( chglhs )
    8946 {
    8947 assert(!SCIPisInfinity(scip, -newlhs));
    8948
    8949 SCIP_CALL( chgLhs(scip, cons, newlhs) );
    8950 if( !consdata->upgraded )
    8951 (*nchgsides)++;
    8952 }
    8953 if( chgrhs )
    8954 {
    8955 assert(!SCIPisInfinity(scip, newrhs));
    8956
    8957 SCIP_CALL( chgRhs(scip, cons, newrhs) );
    8958 if( !consdata->upgraded )
    8959 (*nchgsides)++;
    8960 }
    8961 SCIPdebugMsg(scip, "linear constraint <%s>: new integral sides: sides=[%.15g,%.15g]\n",
    8962 SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
    8963 }
    8964 }
    8965
    8966 return SCIP_OKAY;
    8967}
    8968
    8969/** tightens coefficients of binary, integer, and implied integral variables due to activity bounds in presolving:
    8970 * given an inequality lhs <= a*x + ai*xi <= rhs, with a non-continuous variable li <= xi <= ui
    8971 * let minact := min{a*x + ai*xi}, maxact := max{a*x + ai*xi}
    8972 * (i) ai >= 0:
    8973 * if minact + ai >= lhs and maxact - ai <= rhs: (**)
    8974 * - a deviation from the lower/upper bound of xi would make the left/right hand side redundant
    8975 * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
    8976 * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
    8977 * - change coefficients:
    8978 * ai' := max(lhs - minact, maxact - rhs, 0)
    8979 * lhs' := lhs - (ai - ai')*li
    8980 * rhs' := rhs - (ai - ai')*ui
    8981 * (ii) ai < 0:
    8982 * if minact - ai >= lhs and maxact + ai <= rhs: (***)
    8983 * - a deviation from the upper/lower bound of xi would make the left/right hand side redundant
    8984 * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
    8985 * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
    8986 * - change coefficients:
    8987 * ai' := min(rhs - maxact, minact - lhs, 0)
    8988 * lhs' := lhs - (ai - ai')*ui
    8989 * rhs' := rhs - (ai - ai')*li
    8990 *
    8991 * We further try to remove variables from the constraint;
    8992 * Variables which fulfill conditions (**) or (***) are called relevant variables.
    8993 * A deviation of only one from their bound makes the lhs/rhs feasible (i.e., redundant), even if all other
    8994 * variables are set to their "worst" bound. If all variables which are not relevant cannot make the lhs/rhs
    8995 * redundant, even if they are set to their "best" bound, they can be removed from the constraint. E.g., for binary
    8996 * variables and an inequality x_1 +x_2 +10y_1 +10y_2 >= 5, setting either of the y_i to one suffices to fulfill the
    8997 * inequality, whereas the x_i do not contribute to feasibility and can be removed.
    8998 *
    8999 * @todo use also some tightening procedures for (knapsack) constraints with non-integer coefficients, see
    9000 * cons_knapsack.c the following methods detectRedundantVars() and tightenWeights()
    9001 */
    9002static
    9004 SCIP* scip, /**< SCIP data structure */
    9005 SCIP_CONS* cons, /**< linear constraint */
    9006 int* nchgcoefs, /**< pointer to count total number of changed coefficients */
    9007 int* nchgsides /**< pointer to count number of side changes */
    9008 )
    9009{
    9010 SCIP_CONSDATA* consdata;
    9011 SCIP_VAR* var;
    9012 SCIP_Bool* isvarrelevant;
    9013 SCIP_Real minactivity; /* minimal value w.r.t. the variable's local bounds for the constraint's
    9014 * activity, ignoring the coefficients contributing with infinite value */
    9015 SCIP_Real maxactivity; /* maximal value w.r.t. the variable's local bounds for the constraint's
    9016 * activity, ignoring the coefficients contributing with infinite value */
    9017 SCIP_Bool isminacttight; /* are all contributions to the minactivity non-huge or non-contradicting? */
    9018 SCIP_Bool ismaxacttight; /* are all contributions to the maxactivity non-huge or non-contradicting? */
    9019 SCIP_Bool isminsettoinfinity;
    9020 SCIP_Bool ismaxsettoinfinity;
    9021 SCIP_Real minleftactivity; /* minimal activity without relevant variables */
    9022 SCIP_Real maxleftactivity; /* maximal activity without relevant variables */
    9023 SCIP_Real aggrlhs; /* lhs without minimal activity of relevant variables */
    9024 SCIP_Real aggrrhs; /* rhs without maximal activity of relevant variables */
    9025 SCIP_Real lval; /* candidate for new value arising from considering the left hand side */
    9026 SCIP_Real rval; /* candidate for new value arising from considering the left hand side */
    9027 SCIP_Real val;
    9028 SCIP_Real newval;
    9029 SCIP_Real newlhs;
    9030 SCIP_Real newrhs;
    9031 SCIP_Real lb;
    9032 SCIP_Real ub;
    9033 int i;
    9034
    9035 assert(scip != NULL);
    9036 assert(cons != NULL);
    9037 assert(nchgcoefs != NULL);
    9038 assert(nchgsides != NULL);
    9039
    9040 consdata = SCIPconsGetData(cons);
    9041 assert(consdata != NULL);
    9042
    9043 /* allocate relevance flags */
    9044 SCIP_CALL( SCIPallocBufferArray(scip, &isvarrelevant, consdata->nvars) );
    9045
    9046 /* get the minimal and maximal activity of the constraint */
    9047 consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &isminacttight, &ismaxacttight,
    9048 &isminsettoinfinity, &ismaxsettoinfinity);
    9049 assert(( isminsettoinfinity && !SCIPisInfinity(scip, -consdata->lhs) )
    9050 || SCIPisLT(scip, minactivity, consdata->lhs)
    9051 || ( ismaxsettoinfinity && !SCIPisInfinity(scip, consdata->rhs) )
    9052 || SCIPisGT(scip, maxactivity, consdata->rhs));
    9053
    9054 minleftactivity = 0.0;
    9055 maxleftactivity = 0.0;
    9056
    9057 /* try to tighten each coefficient */
    9058 i = 0;
    9059 while( i < consdata->nvars )
    9060 {
    9061 /* get coefficient and variable's bounds */
    9062 var = consdata->vars[i];
    9063 val = consdata->vals[i];
    9064 assert(!SCIPisZero(scip, val));
    9065 lb = SCIPvarGetLbLocal(var);
    9066 ub = SCIPvarGetUbLocal(var);
    9067
    9068 /* check sign of coefficient */
    9069 if( val >= 0.0 )
    9070 {
    9071 /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
    9072 isvarrelevant[i] = SCIPvarIsIntegral(var)
    9073 && SCIPisGE(scip, minactivity + val, consdata->lhs) && SCIPisLE(scip, maxactivity - val, consdata->rhs);
    9074
    9075 if( isvarrelevant[i] )
    9076 {
    9077 /* change coefficients:
    9078 * ai' := max(lhs - minact, maxact - rhs)
    9079 * lhs' := lhs - (ai - ai')*li
    9080 * rhs' := rhs - (ai - ai')*ui
    9081 */
    9082
    9083 lval = consdata->lhs - minactivity;
    9084 rval = maxactivity - consdata->rhs;
    9085
    9086 /* Try to avoid cancellation, if there are only two variables */
    9087 if( consdata->nvars == 2 )
    9088 {
    9089 SCIP_Real otherval;
    9090 otherval = consdata->vals[1-i];
    9091
    9092 if( !SCIPisInfinity(scip, -consdata->lhs) && !isminsettoinfinity )
    9093 {
    9094 lval = consdata->lhs - val*lb;
    9095 lval -= otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
    9096 }
    9097
    9098 if( !SCIPisInfinity(scip, consdata->rhs) && !ismaxsettoinfinity )
    9099 {
    9100 rval = val*ub - consdata->rhs;
    9101 rval += otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
    9102 }
    9103 }
    9104
    9105 newval = MAX3(lval, rval, 0.0);
    9106 assert(SCIPisSumRelLE(scip, newval, val));
    9107
    9108 /* Try to avoid cancellation in computation of lhs/rhs */
    9109 newlhs = consdata->lhs - val * lb;
    9110 newlhs += newval * lb;
    9111 newrhs = consdata->rhs - val * ub;
    9112 newrhs += newval * ub;
    9113
    9114 if( !SCIPisSumRelEQ(scip, newval, val) )
    9115 {
    9116 SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
    9117 SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var), minactivity,
    9118 maxactivity, consdata->lhs, consdata->rhs);
    9119
    9120 /* update the coefficient and the activity bounds */
    9121 if( SCIPisZero(scip, newval) )
    9122 {
    9123 SCIP_CALL( delCoefPos(scip, cons, i) );
    9124 --i;
    9125 }
    9126 else
    9127 {
    9128 SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
    9129 }
    9130 ++(*nchgcoefs);
    9131
    9132 /* get the new minimal and maximal activity of the constraint */
    9133 consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &isminacttight,
    9134 &ismaxacttight, &isminsettoinfinity, &ismaxsettoinfinity);
    9135
    9136 if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
    9137 {
    9138 SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons),
    9139 consdata->lhs, newlhs);
    9140
    9141 SCIP_CALL( chgLhs(scip, cons, newlhs) );
    9142 (*nchgsides)++;
    9143 assert(SCIPisEQ(scip, consdata->lhs, newlhs));
    9144 }
    9145
    9146 if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
    9147 {
    9148 SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons),
    9149 consdata->rhs, newrhs);
    9150
    9151 SCIP_CALL( chgRhs(scip, cons, newrhs) );
    9152 (*nchgsides)++;
    9153 assert(SCIPisEQ(scip, consdata->rhs, newrhs));
    9154 }
    9155 }
    9156 }
    9157 else
    9158 {
    9159 if( !SCIPisInfinity(scip, -minleftactivity) )
    9160 {
    9161 assert(!SCIPisInfinity(scip, val));
    9162 assert(!SCIPisInfinity(scip, lb));
    9163 if( SCIPisInfinity(scip, -lb) )
    9164 minleftactivity = -SCIPinfinity(scip);
    9165 else
    9166 minleftactivity += val * lb;
    9167 }
    9168
    9169 if( !SCIPisInfinity(scip, maxleftactivity) )
    9170 {
    9171 assert(!SCIPisInfinity(scip, val));
    9172 assert(!SCIPisInfinity(scip, -ub));
    9173 if( SCIPisInfinity(scip,ub) )
    9174 maxleftactivity = SCIPinfinity(scip);
    9175 else
    9176 maxleftactivity += val * ub;
    9177 }
    9178 }
    9179 }
    9180 else
    9181 {
    9182 /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
    9183 isvarrelevant[i] = SCIPvarIsIntegral(var)
    9184 && SCIPisGE(scip, minactivity - val, consdata->lhs) && SCIPisLE(scip, maxactivity + val, consdata->rhs);
    9185
    9186 if( isvarrelevant[i] )
    9187 {
    9188 /* change coefficients:
    9189 * ai' := min(rhs - maxact, minact - lhs)
    9190 * lhs' := lhs - (ai - ai')*ui
    9191 * rhs' := rhs - (ai - ai')*li
    9192 */
    9193
    9194 lval = minactivity - consdata->lhs;
    9195 rval = consdata->rhs - maxactivity;
    9196
    9197 /* Try to avoid cancellation, if there are only two variables */
    9198 if( consdata->nvars == 2 )
    9199 {
    9200 SCIP_Real otherval;
    9201 otherval = consdata->vals[1-i];
    9202
    9203 if( !SCIPisInfinity(scip, -consdata->lhs) && !isminsettoinfinity )
    9204 {
    9205 lval = val*ub - consdata->lhs;
    9206 lval += otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
    9207 }
    9208
    9209 if( !SCIPisInfinity(scip, consdata->rhs) && !ismaxsettoinfinity )
    9210 {
    9211 rval = consdata->rhs - val*lb;
    9212 rval -= otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
    9213 }
    9214 }
    9215
    9216 newval = MIN3(lval, rval, 0.0);
    9217 assert(SCIPisSumRelGE(scip, newval, val));
    9218
    9219 /* Try to avoid cancellation in computation of lhs/rhs */
    9220 newlhs = consdata->lhs - val * ub;
    9221 newlhs += newval * ub;
    9222 newrhs = consdata->rhs - val * lb;
    9223 newrhs += newval * lb;
    9224
    9225 if( !SCIPisSumRelEQ(scip, newval, val) )
    9226 {
    9227 SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
    9228 SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var), minactivity,
    9229 maxactivity, consdata->lhs, consdata->rhs);
    9230
    9231 /* update the coefficient and the activity bounds */
    9232 if( SCIPisZero(scip, newval) )
    9233 {
    9234 SCIP_CALL( delCoefPos(scip, cons, i) );
    9235 --i;
    9236 }
    9237 else
    9238 {
    9239 SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
    9240 }
    9241 ++(*nchgcoefs);
    9242
    9243 /* get the new minimal and maximal activity of the constraint */
    9244 consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &isminacttight,
    9245 &ismaxacttight, &isminsettoinfinity, &ismaxsettoinfinity);
    9246
    9247 if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
    9248 {
    9249 SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons),
    9250 consdata->lhs, newlhs);
    9251
    9252 SCIP_CALL( chgLhs(scip, cons, newlhs) );
    9253 (*nchgsides)++;
    9254 assert(SCIPisEQ(scip, consdata->lhs, newlhs));
    9255 }
    9256
    9257 if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
    9258 {
    9259 SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons),
    9260 consdata->rhs, newrhs);
    9261
    9262 SCIP_CALL( chgRhs(scip, cons, newrhs) );
    9263 (*nchgsides)++;
    9264 assert(SCIPisEQ(scip, consdata->rhs, newrhs));
    9265 }
    9266 }
    9267 }
    9268 else
    9269 {
    9270 if( !SCIPisInfinity(scip, -minleftactivity) )
    9271 {
    9272 assert(!SCIPisInfinity(scip, -val));
    9273 assert(!SCIPisInfinity(scip, -ub));
    9274 if( SCIPisInfinity(scip, ub) )
    9275 minleftactivity = -SCIPinfinity(scip);
    9276 else
    9277 minleftactivity += val * ub;
    9278 }
    9279
    9280 if( !SCIPisInfinity(scip, maxleftactivity) )
    9281 {
    9282 assert(!SCIPisInfinity(scip, -val));
    9283 assert(!SCIPisInfinity(scip, lb));
    9284 if( SCIPisInfinity(scip, -lb) )
    9285 maxleftactivity = SCIPinfinity(scip);
    9286 else
    9287 maxleftactivity += val * lb;
    9288 }
    9289 }
    9290 }
    9291
    9292 ++i;
    9293 }
    9294
    9295 SCIPdebugMsg(scip, "minleftactivity = %.15g, rhs = %.15g\n",
    9296 minleftactivity, consdata->rhs);
    9297 SCIPdebugMsg(scip, "maxleftactivity = %.15g, lhs = %.15g\n",
    9298 maxleftactivity, consdata->lhs);
    9299
    9300 /* minleft == \infty ==> minactivity == \infty */
    9301 assert(!SCIPisInfinity(scip, -minleftactivity) || SCIPisInfinity(scip, -minactivity));
    9302 assert(!SCIPisInfinity(scip, maxleftactivity) || SCIPisInfinity(scip, maxactivity));
    9303
    9304 /* if the lhs is finite, we will check in the following whether the not relevant variables can make lhs feasible;
    9305 * this is not valid, if the minactivity is -\infty (aggrlhs would be minus infinity in the following computation)
    9306 * or if huge values contributed to the minactivity, because the minactivity is then just a relaxation
    9307 * (<= the exact minactivity), and we might falsely remove coefficients in the following
    9308 */
    9309 assert(!SCIPisInfinity(scip, minactivity));
    9310 if( !SCIPisInfinity(scip, -consdata->lhs) && (SCIPisInfinity(scip, -minactivity) || !isminacttight) )
    9311 goto TERMINATE;
    9312
    9313 /* if the rhs is finite, we will check in the following whether the not relevant variables can make rhs feasible;
    9314 * this is not valid, if the maxactivity is \infty (aggrrhs would be infinity in the following computation)
    9315 * or if huge values contributed to the maxactivity, because the maxactivity is then just a relaxation
    9316 * (>= the exact maxactivity), and we might falsely remove coefficients in the following
    9317 */
    9318 assert(!SCIPisInfinity(scip, -maxactivity));
    9319 if( !SCIPisInfinity(scip, consdata->rhs) && (SCIPisInfinity(scip, maxactivity) || !ismaxacttight) )
    9320 goto TERMINATE;
    9321
    9322 /* correct lhs and rhs by min/max activity of relevant variables
    9323 * relevant variables are all those where a deviation from the bound makes the lhs/rhs redundant
    9324 */
    9325 aggrlhs = consdata->lhs - minactivity + minleftactivity;
    9326 aggrrhs = consdata->rhs - maxactivity + maxleftactivity;
    9327
    9328 /* check if the constraint contains variables whose coefficient can be removed. The reasoning is the following:
    9329 * Each relevant variable can make the lhs/rhs feasible with a deviation of only one in the bound. If _all_ not
    9330 * relevant variables together cannot make lhs/rhs redundant, they can be removed from the constraint. aggrrhs may
    9331 * contain some near-infinity value, but only if rhs is infinity.
    9332 */
    9333 if( (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasLT(scip, maxleftactivity, aggrlhs))
    9334 && (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasGT(scip, minleftactivity, aggrrhs)) )
    9335 {
    9336 SCIP_Real minleftactivitypart;
    9337 SCIP_Real maxleftactivitypart;
    9338
    9339 assert(!SCIPisInfinity(scip, -consdata->lhs) || !SCIPisInfinity(scip, consdata->rhs));
    9340
    9341 /* remove redundant variables from constraint */
    9342 i = 0;
    9343 while( i < consdata->nvars )
    9344 {
    9345 /* consider redundant variable */
    9346 if( !isvarrelevant[i] )
    9347 {
    9348 /* get coefficient and variable's bounds */
    9349 var = consdata->vars[i];
    9350 val = consdata->vals[i];
    9351 assert(!SCIPisZero(scip, val));
    9352 lb = SCIPvarGetLbLocal(var);
    9353 ub = SCIPvarGetUbLocal(var);
    9354
    9355 SCIPdebugMsg(scip, "val = %g\tlhs = %g\trhs = %g\n", val, consdata->lhs, consdata->rhs);
    9356 SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> from constraint since it is redundant\n",
    9357 SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]));
    9358
    9359 /* check sign of coefficient */
    9360 if( val >= 0.0 )
    9361 {
    9362 minleftactivitypart = val * lb;
    9363 maxleftactivitypart = val * ub;
    9364 }
    9365 else
    9366 {
    9367 minleftactivitypart = val * ub;
    9368 maxleftactivitypart = val * lb;
    9369 }
    9370
    9371 /* remove redundant variable */
    9372 isvarrelevant[i] = isvarrelevant[consdata->nvars - 1];
    9373 SCIP_CALL( delCoefPos(scip, cons, i) );
    9374 --i;
    9375
    9376 /* adjust lhs and right hand side */
    9377 newlhs = consdata->lhs - minleftactivitypart;
    9378 newrhs = consdata->rhs - maxleftactivitypart;
    9379
    9380 if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
    9381 {
    9382 SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons),
    9383 consdata->lhs, newlhs);
    9384
    9385 SCIP_CALL( chgLhs(scip, cons, newlhs) );
    9386 ++(*nchgsides);
    9387 assert(SCIPisEQ(scip, consdata->lhs, newlhs));
    9388 }
    9389
    9390 if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
    9391 {
    9392 SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons),
    9393 consdata->rhs, newrhs);
    9394
    9395 SCIP_CALL( chgRhs(scip, cons, newrhs) );
    9396 ++(*nchgsides);
    9397 assert(SCIPisEQ(scip, consdata->rhs, newrhs));
    9398 }
    9399 }
    9400
    9401 ++i;
    9402 }
    9403 }
    9404
    9405TERMINATE:
    9406 /* free relevance flags */
    9407 SCIPfreeBufferArray(scip, &isvarrelevant);
    9408
    9409 return SCIP_OKAY;
    9410}
    9411
    9412/** processes equality with only one variable by fixing the variable and deleting the constraint */
    9413static
    9415 SCIP* scip, /**< SCIP data structure */
    9416 SCIP_CONS* cons, /**< linear constraint */
    9417 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    9418 int* nfixedvars, /**< pointer to count number of fixed variables */
    9419 int* ndelconss /**< pointer to count number of deleted constraints */
    9420 )
    9421{
    9422 SCIP_CONSDATA* consdata;
    9423 SCIP_VAR* var;
    9424 SCIP_Real val;
    9425 SCIP_Real fixval;
    9426 SCIP_Bool infeasible;
    9427 SCIP_Bool fixed;
    9428
    9429 assert(scip != NULL);
    9430 assert(cons != NULL);
    9431 assert(cutoff != NULL);
    9432 assert(nfixedvars != NULL);
    9433 assert(ndelconss != NULL);
    9434
    9435 consdata = SCIPconsGetData(cons);
    9436 assert(consdata != NULL);
    9437 assert(consdata->nvars == 1);
    9438 assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
    9439
    9440 /* calculate the value to fix the variable to */
    9441 var = consdata->vars[0];
    9442 val = consdata->vals[0];
    9443 assert(!SCIPisZero(scip, val));
    9444 fixval = SCIPselectSimpleValue(consdata->lhs/val - 0.9 * SCIPepsilon(scip),
    9445 consdata->rhs/val + 0.9 * SCIPepsilon(scip), MAXDNOM);
    9446 SCIPdebugMsg(scip, "linear equality <%s>: fix <%s> == %.15g\n",
    9447 SCIPconsGetName(cons), SCIPvarGetName(var), fixval);
    9448
    9449 /* fix variable */
    9450 SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
    9451 if( infeasible )
    9452 {
    9453 SCIPdebugMsg(scip, " -> infeasible fixing\n");
    9454 *cutoff = TRUE;
    9455 return SCIP_OKAY;
    9456 }
    9457 if( fixed )
    9458 (*nfixedvars)++;
    9459
    9460 /* disable constraint */
    9461 SCIP_CALL( SCIPdelCons(scip, cons) );
    9462 if( !consdata->upgraded )
    9463 (*ndelconss)++;
    9464
    9465 return SCIP_OKAY;
    9466}
    9467
    9468/** processes equality with exactly two variables by aggregating one of the variables and deleting the constraint */
    9469static
    9471 SCIP* scip, /**< SCIP data structure */
    9472 SCIP_CONS* cons, /**< linear constraint */
    9473 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    9474 int* naggrvars, /**< pointer to count number of aggregated variables */
    9475 int* ndelconss /**< pointer to count number of deleted constraints */
    9476 )
    9477{
    9478 SCIP_CONSDATA* consdata;
    9479 SCIP_Bool infeasible;
    9480 SCIP_Bool redundant;
    9481 SCIP_Bool aggregated;
    9482
    9483 assert(scip != NULL);
    9484 assert(cons != NULL);
    9485 assert(cutoff != NULL);
    9486 assert(naggrvars != NULL);
    9487 assert(ndelconss != NULL);
    9488
    9489 consdata = SCIPconsGetData(cons);
    9490 assert(consdata != NULL);
    9491 assert(consdata->nvars == 2);
    9492 assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
    9493
    9494 SCIPdebugMsg(scip, "linear constraint <%s>: aggregate %.15g<%s> + %.15g<%s> == %.15g\n",
    9495 SCIPconsGetName(cons), consdata->vals[0], SCIPvarGetName(consdata->vars[0]),
    9496 consdata->vals[1], SCIPvarGetName(consdata->vars[1]), consdata->rhs);
    9497
    9498 /* aggregate the equality */
    9499 SCIP_CALL( SCIPaggregateVars(scip, consdata->vars[0], consdata->vars[1], consdata->vals[0], consdata->vals[1],
    9500 consdata->rhs, &infeasible, &redundant, &aggregated) );
    9501
    9502 /* check for infeasibility of aggregation */
    9503 if( infeasible )
    9504 {
    9505 SCIPdebugMsg(scip, " -> infeasible aggregation\n");
    9506 *cutoff = TRUE;
    9507 return SCIP_OKAY;
    9508 }
    9509
    9510 /* count the aggregation */
    9511 if( aggregated )
    9512 (*naggrvars)++;
    9513
    9514 /* delete the constraint, if it is redundant */
    9515 if( redundant )
    9516 {
    9517 SCIP_CALL( SCIPdelCons(scip, cons) );
    9518
    9519 if( !consdata->upgraded )
    9520 (*ndelconss)++;
    9521 }
    9522
    9523 return SCIP_OKAY;
    9524}
    9525
    9526/** calculates the new lhs and rhs of the constraint after the given variable is aggregated out */
    9527static
    9529 SCIP* scip, /**< SCIP data structure */
    9530 SCIP_CONSDATA* consdata, /**< linear constraint data */
    9531 SCIP_VAR* slackvar, /**< variable to be aggregated out */
    9532 SCIP_Real slackcoef, /**< coefficient of variable in constraint */
    9533 SCIP_Real* newlhs, /**< pointer to store new lhs of constraint */
    9534 SCIP_Real* newrhs /**< pointer to store new rhs of constraint */
    9535 )
    9536{
    9537 SCIP_Real slackvarlb;
    9538 SCIP_Real slackvarub;
    9539
    9540 assert(scip != NULL);
    9541 assert(consdata != NULL);
    9542 assert(newlhs != NULL);
    9543 assert(newrhs != NULL);
    9544 assert(!SCIPisInfinity(scip, -consdata->lhs));
    9545 assert(!SCIPisInfinity(scip, consdata->rhs));
    9546
    9547 slackvarlb = SCIPvarGetLbGlobal(slackvar);
    9548 slackvarub = SCIPvarGetUbGlobal(slackvar);
    9549 if( slackcoef > 0.0 )
    9550 {
    9551 if( SCIPisInfinity(scip, -slackvarlb) )
    9552 *newrhs = SCIPinfinity(scip);
    9553 else
    9554 *newrhs = consdata->rhs - slackcoef * slackvarlb;
    9555 if( SCIPisInfinity(scip, slackvarub) )
    9556 *newlhs = -SCIPinfinity(scip);
    9557 else
    9558 *newlhs = consdata->lhs - slackcoef * slackvarub;
    9559 }
    9560 else
    9561 {
    9562 if( SCIPisInfinity(scip, -slackvarlb) )
    9563 *newlhs = -SCIPinfinity(scip);
    9564 else
    9565 *newlhs = consdata->rhs - slackcoef * slackvarlb;
    9566 if( SCIPisInfinity(scip, slackvarub) )
    9567 *newrhs = SCIPinfinity(scip);
    9568 else
    9569 *newrhs = consdata->lhs - slackcoef * slackvarub;
    9570 }
    9571 assert(SCIPisLE(scip, *newlhs, *newrhs));
    9572}
    9573
    9574/** processes equality with more than two variables by multi-aggregating one of the variables and converting the equality
    9575 * into an inequality; if multi-aggregation is not possible, tries to identify one continuous or integer variable that
    9576 * is implied integral by this constraint
    9577 *
    9578 * @todo Check whether a more clever way of avoiding aggregation of variables containing implied integral variables
    9579 * can help.
    9580 */
    9581static
    9583 SCIP* scip, /**< SCIP data structure */
    9584 SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
    9585 SCIP_CONS* cons, /**< linear constraint */
    9586 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    9587 int* naggrvars, /**< pointer to count number of aggregated variables */
    9588 int* ndelconss, /**< pointer to count number of deleted constraints */
    9589 int* nchgvartypes /**< pointer to count number of changed variable types */
    9590 )
    9591{
    9592 SCIP_CONSDATA* consdata;
    9593 SCIP_VAR** vars;
    9594 SCIP_Real* vals;
    9595 SCIP_VARTYPE bestslacktype;
    9596 SCIP_VARTYPE slacktype;
    9597 SCIP_IMPLINTTYPE impltype;
    9598 SCIP_Real lhs;
    9599 SCIP_Real rhs;
    9600 SCIP_Real bestslackdomrng;
    9601 SCIP_Real minabsval;
    9602 SCIP_Real maxabsval;
    9603 SCIP_Bool bestremovescons;
    9604 SCIP_Bool coefszeroone;
    9605 SCIP_Bool coefsintegral;
    9606 SCIP_Bool varsintegral;
    9607 SCIP_Bool infeasible;
    9608 int maxnlocksstay;
    9609 int maxnlocksremove;
    9610 int bestslackpos;
    9611 int bestnlocks;
    9612 int ncontvars;
    9613 int contvarpos;
    9614 int nintvars;
    9615 int nweakimplvars;
    9616 int nimplvars;
    9617 int intvarpos;
    9618 int v;
    9619
    9620 assert(scip != NULL);
    9621 assert(cons != NULL);
    9622 assert(cutoff != NULL);
    9623 assert(naggrvars != NULL);
    9624
    9625 consdata = SCIPconsGetData(cons);
    9626 assert(consdata != NULL);
    9627 assert(consdata->nvars > 2);
    9628 assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
    9629
    9630 SCIPdebugMsg(scip, "linear constraint <%s>: try to multi-aggregate equality\n", SCIPconsGetName(cons));
    9631
    9632 /* We do not want to increase the total number of non-zeros due to the multi-aggregation.
    9633 * Therefore, we have to restrict the number of locks of a variable that is aggregated out.
    9634 * maxnlocksstay: maximal sum of lock numbers if the constraint does not become redundant after the aggregation
    9635 * maxnlocksremove: maximal sum of lock numbers if the constraint can be deleted after the aggregation
    9636 */
    9637 lhs = consdata->lhs;
    9638 rhs = consdata->rhs;
    9639 maxnlocksstay = 0;
    9640 if( consdata->nvars == 3 )
    9641 {
    9642 /* If the constraint becomes redundant, 3 non-zeros are removed, and we get 1 additional non-zero for each
    9643 * constraint the variable appears in. Thus, the variable must appear in at most 3 other constraints.
    9644 */
    9645 maxnlocksremove = 3;
    9646 }
    9647 else if( consdata->nvars == 4 )
    9648 {
    9649 /* If the constraint becomes redundant, 4 non-zeros are removed, and we get 2 additional non-zeros for each
    9650 * constraint the variable appears in. Thus, the variable must appear in at most 2 other constraints.
    9651 */
    9652 maxnlocksremove = 2;
    9653 }
    9654 else
    9655 {
    9656 /* If the constraint is redundant but has more than 4 variables, we can only accept one other constraint. */
    9657 maxnlocksremove = 1;
    9658 }
    9659
    9660 /* the locks on this constraint can be ignored */
    9661 if( SCIPconsIsChecked(cons) )
    9662 {
    9663 if( !SCIPisInfinity(scip, -lhs) )
    9664 {
    9665 maxnlocksstay++;
    9666 maxnlocksremove++;
    9667 }
    9668 if( !SCIPisInfinity(scip, rhs) )
    9669 {
    9670 maxnlocksstay++;
    9671 maxnlocksremove++;
    9672 }
    9673 }
    9674
    9675 /* look for a slack variable s to convert a*x + s == b into lhs <= a*x <= rhs */
    9676 vars = consdata->vars;
    9677 vals = consdata->vals;
    9678 bestslackpos = -1;
    9679 bestslacktype = SCIP_VARTYPE_BINARY;
    9680 bestnlocks = INT_MAX;
    9681 bestremovescons = FALSE;
    9682 bestslackdomrng = 0.0;
    9683 coefszeroone = TRUE;
    9684 coefsintegral = TRUE;
    9685 varsintegral = TRUE;
    9686 ncontvars = 0;
    9687 contvarpos = -1;
    9688 nintvars = 0;
    9689 nweakimplvars = 0;
    9690 nimplvars = 0;
    9691 intvarpos = -1;
    9692 minabsval = SCIPinfinity(scip);
    9693 maxabsval = -1.0;
    9694 for( v = 0; v < consdata->nvars; ++v )
    9695 {
    9696 SCIP_VAR* var;
    9697 SCIP_Real val;
    9698 SCIP_Real absval;
    9699 SCIP_Real varlb;
    9700 SCIP_Real varub;
    9701 SCIP_Bool iscont;
    9702 int nlocks;
    9703
    9704 assert(vars != NULL);
    9705 assert(vals != NULL);
    9706
    9707 var = vars[v];
    9708 assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= 1); /* because variable is locked in this equality */
    9710 varlb = SCIPvarGetLbGlobal(var);
    9711 varub = SCIPvarGetUbGlobal(var);
    9712
    9713 val = vals[v];
    9714 absval = REALABS(val);
    9715 assert(SCIPisPositive(scip, absval));
    9716
    9717 /* calculate minimal and maximal absolute value */
    9718 if( absval < minabsval )
    9719 minabsval = absval;
    9720 if( absval > maxabsval )
    9721 maxabsval = absval;
    9722
    9723 /** @todo Do not exit here, but continue if we may still detect implied integrality. */
    9724 /* do not try to multi aggregate, when numerical bad */
    9725 if( maxabsval / minabsval > conshdlrdata->maxmultaggrquot )
    9726 return SCIP_OKAY;
    9727
    9728 impltype = SCIPvarGetImplType(var);
    9730 coefszeroone = coefszeroone && SCIPisEQ(scip, absval, 1.0);
    9731 coefsintegral = coefsintegral && SCIPisIntegral(scip, val);
    9732 varsintegral = varsintegral && (slacktype != SCIP_VARTYPE_CONTINUOUS);
    9733 iscont = (slacktype == SCIP_VARTYPE_CONTINUOUS || slacktype == SCIP_DEPRECATED_VARTYPE_IMPLINT);
    9734
    9735 /* update candidates for continuous -> implint and integer -> implint conversion */
    9736 if( slacktype == SCIP_VARTYPE_CONTINUOUS )
    9737 {
    9738 ncontvars++;
    9739 contvarpos = v;
    9740 }
    9741 else if( slacktype == SCIP_DEPRECATED_VARTYPE_IMPLINT )
    9742 {
    9743 ++nimplvars;
    9744 assert(impltype != SCIP_IMPLINTTYPE_NONE);
    9745 if( impltype == SCIP_IMPLINTTYPE_WEAK )
    9746 ++nweakimplvars;
    9747 }
    9748 else if( slacktype == SCIP_VARTYPE_INTEGER )
    9749 {
    9750 nintvars++;
    9751 intvarpos = v;
    9752 }
    9753
    9754 /* check, if variable is already fixed or aggregated */
    9755 if( !SCIPvarIsActive(var) )
    9756 continue;
    9757
    9758 /* check, if variable is used in too many other constraints, even if this constraint could be deleted */
    9760
    9761 if( nlocks > maxnlocksremove )
    9762 continue;
    9763
    9764 /* check, if variable can be used as a slack variable */
    9765 if( (iscont || (coefsintegral && varsintegral && SCIPisEQ(scip, absval, 1.0))) &&
    9766 !SCIPdoNotMultaggrVar(scip, var) )
    9767 {
    9768 SCIP_Bool better;
    9769 SCIP_Bool equal;
    9770 SCIP_Real slackdomrng;
    9771
    9772 if( SCIPisInfinity(scip, varub) || SCIPisInfinity(scip, -varlb) )
    9773 slackdomrng = SCIPinfinity(scip);
    9774 /* we do not want to perform multi-aggregation due to numerics, if the bounds are huge */
    9775 else if( SCIPisHugeValue(scip, varub) || SCIPisHugeValue(scip, -varlb) )
    9776 return SCIP_OKAY;
    9777 else
    9778 {
    9779 slackdomrng = (varub - varlb)*absval;
    9780 assert(!SCIPisInfinity(scip, slackdomrng));
    9781 }
    9782 equal = FALSE;
    9783
    9784 /* continuous > implied > integer > binary */
    9785 better = (slacktype > bestslacktype) || (bestslackpos == -1);
    9786 if( !better && slacktype == bestslacktype )
    9787 {
    9788 better = (nlocks < bestnlocks);
    9789 if( nlocks == bestnlocks && !bestremovescons )
    9790 {
    9791 better = SCIPisGT(scip, slackdomrng, bestslackdomrng);
    9792 equal = !better && SCIPisGE(scip, slackdomrng, bestslackdomrng);
    9793 }
    9794 }
    9795
    9796 if( better || equal )
    9797 {
    9798 SCIP_Real minresactivity;
    9799 SCIP_Real maxresactivity;
    9800 SCIP_Real newlhs;
    9801 SCIP_Real newrhs;
    9802 SCIP_Bool removescons;
    9803 SCIP_Bool ismintight;
    9804 SCIP_Bool ismaxtight;
    9805 SCIP_Bool isminsettoinfinity;
    9806 SCIP_Bool ismaxsettoinfinity;
    9807
    9808 /* check if the constraint becomes redundant after multi-aggregation */
    9809 consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
    9810 &ismintight, &ismaxtight, &isminsettoinfinity, &ismaxsettoinfinity);
    9811
    9812 /* do not perform the multi-aggregation due to numerics, if we have huge contributions in the residual
    9813 * activity
    9814 */
    9815 if( !ismintight || !ismaxtight )
    9816 continue;
    9817
    9818 getNewSidesAfterAggregation(scip, consdata, var, val, &newlhs, &newrhs);
    9819 removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
    9820
    9821 /* check resactivities for reliability */
    9822 if( removescons )
    9823 {
    9824 if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
    9825 consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
    9826
    9827 if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity)
    9828 && SCIPisFeasLE(scip, newlhs, minresactivity))
    9829 consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
    9830
    9831 removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
    9832 }
    9833
    9834 /* if parameter multaggrremove is set to TRUE, only aggregate when this removes constraint */
    9835 if( conshdlrdata->multaggrremove && !removescons )
    9836 continue;
    9837
    9838 /* if the constraint does not become redundant, only accept the variable if it does not appear in
    9839 * other constraints
    9840 */
    9841 if( !removescons && nlocks > maxnlocksstay )
    9842 continue;
    9843
    9844 /* prefer variables that make the constraints redundant
    9845 * unless there is a continuous better slack
    9846 */
    9847 if( !bestremovescons && removescons )
    9848 better = TRUE;
    9849 else if( bestremovescons && !removescons && (bestslacktype > SCIP_VARTYPE_INTEGER || slacktype <= SCIP_VARTYPE_INTEGER) )
    9850 better = FALSE;
    9851 if( better )
    9852 {
    9853 bestslackpos = v;
    9854 bestslacktype = slacktype;
    9855 bestnlocks = nlocks;
    9856 bestslackdomrng = slackdomrng;
    9857 bestremovescons = removescons;
    9858 }
    9859 }
    9860 }
    9861 }
    9862
    9863 /* if all coefficients and variables are integral, the right hand side must also be integral */
    9864 if( coefsintegral && varsintegral && !SCIPisFeasIntegral(scip, consdata->rhs) )
    9865 {
    9866 SCIPdebugMsg(scip, "linear equality <%s> is integer infeasible\n", SCIPconsGetName(cons));
    9868 *cutoff = TRUE;
    9869 return SCIP_OKAY;
    9870 }
    9871
    9872 /* if the slack variable is of integer type, and the constraint itself may take fractional values,
    9873 * we cannot aggregate the variable, because the integrality condition would get lost
    9874 * Similarly, if there are implied integral variables, we cannot aggregate since we might
    9875 * loose the integrality condition for this variable.
    9876 */
    9877 if( bestslackpos >= 0
    9878 && (bestslacktype == SCIP_VARTYPE_CONTINUOUS || bestslacktype == SCIP_DEPRECATED_VARTYPE_IMPLINT
    9879 || (coefsintegral && varsintegral && nimplvars == 0)) )
    9880 {
    9881 SCIP_VAR** aggrvars;
    9882 SCIP_VAR* slackvar;
    9884 SCIP_Real slackcoef;
    9885 SCIP_Real aggrconst;
    9886 SCIP_Real newlhs;
    9887 SCIP_Real newrhs;
    9888 SCIP_Bool aggregated;
    9889
    9890 /* we found a slack variable that only occurs in at most one other constraint:
    9891 * a_1*x_1 + ... + a_k*x_k + a'*s == rhs -> s == rhs - a_1/a'*x_1 - ... - a_k/a'*x_k
    9892 */
    9893 assert(bestslackpos < consdata->nvars);
    9894
    9895 /* do not multi aggregate binary variables */
    9896 if( SCIPvarIsBinary(vars[bestslackpos]) )
    9897 return SCIP_OKAY;
    9898
    9899 /* convert equality into inequality by deleting the slack variable:
    9900 * x + a*s == b, l <= s <= u -> b - a*u <= x <= b - a*l
    9901 */
    9902 slackvar = vars[bestslackpos];
    9903 slackcoef = vals[bestslackpos];
    9904 assert(!SCIPisZero(scip, slackcoef));
    9905 aggrconst = consdata->rhs/slackcoef;
    9906
    9907 /* allocate temporary memory */
    9908 SCIP_CALL( SCIPallocBufferArray(scip, &aggrvars, consdata->nvars - 1) );
    9909 SCIP_CALL( SCIPallocBufferArray(scip, &scalars, consdata->nvars - 1) );
    9910
    9911 /* set up the multi-aggregation */
    9912 SCIPdebugMsg(scip, "linear constraint <%s>: multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(slackvar));
    9913 for( v = 0; v < consdata->nvars - 1; ++v )
    9914 {
    9915 if( v == bestslackpos )
    9916 {
    9917 aggrvars[v] = vars[consdata->nvars - 1];
    9918 scalars[v] = -consdata->vals[consdata->nvars - 1] / slackcoef;
    9919 }
    9920 else
    9921 {
    9922 aggrvars[v] = vars[v];
    9923 scalars[v] = -consdata->vals[v] / slackcoef;
    9924 }
    9925 SCIPdebugMsgPrint(scip, " %+.15g<%s>", scalars[v], SCIPvarGetName(aggrvars[v]));
    9926 }
    9927 SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g], nlocks=%d, maxnlocks=%d, removescons=%u\n",
    9928 aggrconst, SCIPvarGetName(slackvar), SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar),
    9929 bestnlocks, bestremovescons ? maxnlocksremove : maxnlocksstay, bestremovescons);
    9930
    9931 /* perform the multi-aggregation */
    9932 SCIP_CALL( SCIPmultiaggregateVar(scip, slackvar, consdata->nvars - 1, aggrvars, scalars, aggrconst,
    9933 &infeasible, &aggregated) );
    9934
    9935 /* free temporary memory */
    9937 SCIPfreeBufferArray(scip, &aggrvars);
    9938
    9939 /* check for infeasible aggregation */
    9940 if( infeasible )
    9941 {
    9942 SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
    9943 *cutoff = TRUE;
    9944 return SCIP_OKAY;
    9945 }
    9946
    9947 /* check for applied aggregation */
    9948 if( !aggregated )
    9949 {
    9950 SCIPdebugMsg(scip, "linear constraint <%s>: multi-aggregation not applicable\n", SCIPconsGetName(cons));
    9951 return SCIP_OKAY;
    9952 }
    9953
    9954 ++(*naggrvars);
    9955
    9956 getNewSidesAfterAggregation(scip, consdata, slackvar, slackcoef, &newlhs, &newrhs);
    9957 assert(SCIPisLE(scip, newlhs, newrhs));
    9958 SCIP_CALL( chgLhs(scip, cons, newlhs) );
    9959 SCIP_CALL( chgRhs(scip, cons, newrhs) );
    9960 SCIP_CALL( delCoefPos(scip, cons, bestslackpos) );
    9961
    9962 /* delete the constraint if it became redundant */
    9963 if( bestremovescons )
    9964 {
    9965 SCIPdebugMsg(scip, "linear constraint <%s>: redundant after multi-aggregation\n", SCIPconsGetName(cons));
    9966 SCIP_CALL( SCIPdelCons(scip, cons) );
    9967
    9968 if( !consdata->upgraded )
    9969 (*ndelconss)++;
    9970 }
    9971 }
    9972 else if( ncontvars == 1 )
    9973 {
    9974 SCIP_VAR* var;
    9975
    9976 assert(0 <= contvarpos && contvarpos < consdata->nvars);
    9977 var = vars[contvarpos];
    9978 assert(!SCIPvarIsIntegral(var));
    9979
    9980 if( coefsintegral && SCIPisFeasIntegral(scip, consdata->rhs) )
    9981 {
    9982 /* upgrade continuous variable to an implied integral one, if the absolute value of the coefficient is one */
    9983 if( SCIPisEQ(scip, REALABS(vals[contvarpos]), 1.0) )
    9984 {
    9985 /* convert the continuous variable with coefficient 1.0 into an implied integral variable */
    9986 SCIPdebugMsg(scip, "linear constraint <%s>: converting continuous variable <%s> to implied integral variable\n",
    9987 SCIPconsGetName(cons), SCIPvarGetName(var));
    9988 /* if the integrality does not depend on weak implied integrality, the variable becomes strongly implied integral */
    9989 impltype = nweakimplvars == 0 ? SCIP_IMPLINTTYPE_STRONG : SCIP_IMPLINTTYPE_WEAK;
    9990 SCIP_CALL( SCIPchgVarImplType(scip, var, impltype, &infeasible) );
    9991 (*nchgvartypes)++;
    9992 if( infeasible )
    9993 {
    9994 SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
    9995 *cutoff = TRUE;
    9996
    9997 return SCIP_OKAY;
    9998 }
    9999 }
    10000 /* aggregate continuous variable to an implied integral one if the absolute coefficient is unequal to one */
    10001 /* @todo check if the aggregation coefficient should be in some range(, which is not too big) */
    10002 else if( !SCIPdoNotAggr(scip) )
    10003 {
    10004 SCIP_VAR* newvar;
    10005 SCIP_Real absval;
    10006 char newvarname[SCIP_MAXSTRLEN];
    10007 SCIP_Bool redundant;
    10008 SCIP_Bool aggregated;
    10009
    10010 absval = REALABS(vals[contvarpos]);
    10011
    10012 (void) SCIPsnprintf(newvarname, SCIP_MAXSTRLEN, "%s_impl", SCIPvarGetName(var));
    10013
    10014 /* create new implied integral variable for aggregation */
    10015 SCIP_CALL( SCIPcreateVarImpl(scip, &newvar, newvarname, -SCIPinfinity(scip), SCIPinfinity(scip), 0.0,
    10018
    10019 /* add new variable to problem */
    10020 SCIP_CALL( SCIPaddVar(scip, newvar) );
    10021
    10022#ifdef WITH_DEBUG_SOLUTION
    10023 if( SCIPdebugIsMainscip(scip) )
    10024 {
    10025 SCIP_Real varval;
    10026 SCIP_CALL( SCIPdebugGetSolVal(scip, var, &varval) );
    10027 SCIP_CALL( SCIPdebugAddSolVal(scip, newvar, absval * varval) );
    10028 }
    10029#endif
    10030
    10031 /* convert the continuous variable with coefficient 1.0 into an implied integral variable */
    10032 SCIPdebugMsg(scip, "linear constraint <%s>: aggregating continuous variable <%s> to newly created implied integral variable <%s>, aggregation factor = %g\n",
    10033 SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetName(newvar), absval);
    10034
    10035 /* aggregate continuous and implied integral variable */
    10036 SCIP_CALL( SCIPaggregateVars(scip, var, newvar, absval, -1.0, 0.0, &infeasible, &redundant, &aggregated) );
    10037
    10038 if( infeasible )
    10039 {
    10040 SCIPdebugMsg(scip, "infeasible aggregation of variable <%s> to implied integral variable <%s>, domain is empty\n",
    10041 SCIPvarGetName(var), SCIPvarGetName(newvar));
    10042 *cutoff = TRUE;
    10043
    10044 /* release implied integral variable */
    10045 SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
    10046
    10047 return SCIP_OKAY;
    10048 }
    10049
    10050 /* release implied integral variable */
    10051 SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
    10052
    10053 if( aggregated )
    10054 (*naggrvars)++;
    10055 else
    10056 return SCIP_OKAY;
    10057 }
    10058
    10059 /* we do not have any event on vartype changes, so we need to manually force this constraint to be presolved
    10060 * again
    10061 */
    10062 consdata->boundstightened = 0;
    10063 consdata->rangedrowpropagated = 0;
    10064 consdata->presolved = FALSE;
    10065 }
    10066 }
    10067 else if( ncontvars == 0 && nimplvars == 0 && nintvars == 1 && !coefszeroone )
    10068 {
    10069 SCIP_VAR* var;
    10070
    10071 /* this seems to help for rococo instances, but does not for rout (where all coefficients are +/- 1.0)
    10072 * -> we don't convert integers into implints if the row is a 0/1-row
    10073 */
    10074 assert(varsintegral);
    10075 assert(0 <= intvarpos && intvarpos < consdata->nvars);
    10076 var = vars[intvarpos];
    10077 assert(SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER);
    10078
    10079 if( coefsintegral
    10080 && SCIPisEQ(scip, REALABS(vals[intvarpos]), 1.0)
    10081 && SCIPisFeasIntegral(scip, consdata->rhs) )
    10082 {
    10083 /* convert the integer variable with coefficient 1.0 into an implied integral variable */
    10084 SCIPdebugMsg(scip, "linear constraint <%s>: converting integer variable <%s> to implied integral variable\n",
    10085 SCIPconsGetName(cons), SCIPvarGetName(var));
    10087 (*nchgvartypes)++;
    10088 if( infeasible )
    10089 {
    10090 SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
    10091 *cutoff = TRUE;
    10092
    10093 return SCIP_OKAY;
    10094 }
    10095 }
    10096 }
    10097
    10098 return SCIP_OKAY;
    10099}
    10100
    10101/** checks if the given variables and their coefficient are equal (w.r.t. scaling factor) to the objective function */
    10102static
    10104 SCIP* scip, /**< SCIP data structure */
    10105 SCIP_CONSDATA* consdata, /**< linear constraint data */
    10106 SCIP_Real* scale, /**< pointer to store the scaling factor between the constraint and the
    10107 * objective function */
    10108 SCIP_Real* offset /**< pointer to store the offset of the objective function resulting by
    10109 * this constraint */
    10110 )
    10111{
    10112 SCIP_VAR** vars;
    10113 SCIP_VAR* var;
    10114 SCIP_Real objval;
    10115 SCIP_Bool negated;
    10116 int nvars;
    10117 int v;
    10118
    10119 vars = consdata->vars;
    10120 nvars = consdata->nvars;
    10121
    10122 assert(vars != NULL);
    10123
    10124 for( v = 0; v < nvars; ++v )
    10125 {
    10126 negated = FALSE;
    10127 var = vars[v];
    10128 assert(var != NULL);
    10129
    10130 if( SCIPvarIsNegated(var) )
    10131 {
    10132 negated = TRUE;
    10133 var = SCIPvarGetNegatedVar(var);
    10134 assert(var != NULL);
    10135 }
    10136
    10137 objval = SCIPvarGetObj(var);
    10138
    10139 /* if a variable has a zero objective coefficient the linear constraint is not a subset of the objective
    10140 * function
    10141 */
    10142 if( SCIPisZero(scip, objval) )
    10143 return FALSE;
    10144 else
    10145 {
    10146 SCIP_Real val;
    10147
    10148 val = consdata->vals[v];
    10149
    10150 if( negated )
    10151 {
    10152 if( v == 0 )
    10153 {
    10154 /* the first variable defines the scale */
    10155 (*scale) = val / -objval;
    10156
    10157 (*offset) += val;
    10158 }
    10159 else if( SCIPisEQ(scip, -objval * (*scale), val) )
    10160 (*offset) += val;
    10161 else
    10162 return FALSE;
    10163 }
    10164 else if( v == 0 )
    10165 {
    10166 /* the first variable defines the scale */
    10167 (*scale) = val / objval;
    10168 }
    10169 else if( !SCIPisEQ(scip, objval * (*scale), val) )
    10170 return FALSE;
    10171 }
    10172 }
    10173
    10174 return TRUE;
    10175}
    10176
    10177/** check if the linear equality constraint is equal to a subset of the objective function; if so we can remove the
    10178 * objective coefficients and add an objective offset
    10179 */
    10180static
    10182 SCIP* scip, /**< SCIP data structure */
    10183 SCIP_CONS* cons, /**< linear equation constraint */
    10184 SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
    10185 )
    10186{
    10187 SCIP_CONSDATA* consdata;
    10188 SCIP_Real offset;
    10189 SCIP_Real scale;
    10190 SCIP_Bool applicable;
    10191 int nobjvars;
    10192 int nvars;
    10193 int v;
    10194
    10195 assert(scip != NULL);
    10196 assert(cons != NULL);
    10197 assert(conshdlrdata != NULL);
    10198
    10199 consdata = SCIPconsGetData(cons);
    10200 assert(consdata != NULL);
    10201 assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
    10202
    10203 nvars = consdata->nvars;
    10204 nobjvars = SCIPgetNObjVars(scip);
    10205
    10206 /* check if the linear equality constraints does not have more variables than the objective function */
    10207 if( nvars > nobjvars || nvars == 0 )
    10208 return SCIP_OKAY;
    10209
    10210 /* check for allowance of algorithm */
    10211 if( (nvars < nobjvars && !conshdlrdata->detectpartialobjective) ||
    10212 (nvars == nobjvars && (!conshdlrdata->detectcutoffbound || !conshdlrdata->detectlowerbound)) )
    10213 return SCIP_OKAY;
    10214
    10215 offset = consdata->rhs;
    10216 scale = 1.0;
    10217
    10218 /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
    10219 applicable = checkEqualObjective(scip, consdata, &scale, &offset);
    10220
    10221 if( applicable )
    10222 {
    10223 SCIP_VAR** vars;
    10224
    10225 vars = consdata->vars;
    10226 assert(vars != NULL);
    10227
    10228 offset /= scale;
    10229
    10230 SCIPdebugMsg(scip, "linear equality constraint <%s> == %g (offset %g) is a subset of the objective function\n",
    10231 SCIPconsGetName(cons), consdata->rhs, offset);
    10232
    10233 /* make equality a model constraint to ensure optimality in this direction */
    10236
    10237 /* set all objective coefficient to zero */
    10238 for( v = 0; v < nvars; ++v )
    10239 {
    10240 SCIP_CALL( SCIPchgVarObj(scip, vars[v], 0.0) );
    10241 }
    10242
    10243 /* add an objective offset */
    10244 SCIP_CALL( SCIPaddObjoffset(scip, offset) );
    10245 }
    10246
    10247 return SCIP_OKAY;
    10248}
    10249
    10250/** updates the cutoff if the given primal bound (which is implied by the given constraint) is better */
    10251static
    10253 SCIP* scip, /**< SCIP data structure */
    10254 SCIP_CONS* cons, /**< constraint */
    10255 SCIP_Real primalbound /**< feasible primal bound */
    10256 )
    10257{
    10258 SCIP_Real cutoffbound;
    10259
    10260 /* increase the cutoff bound value by an epsilon to ensue that solution with the value of the cutoff bound are still
    10261 * accepted
    10262 */
    10263 cutoffbound = primalbound + SCIPcutoffbounddelta(scip);
    10264
    10265 if( cutoffbound < SCIPgetCutoffbound(scip) )
    10266 {
    10267 SCIPdebugMsg(scip, "update cutoff bound <%g>\n", cutoffbound);
    10268
    10269 SCIP_CALL( SCIPupdateCutoffbound(scip, cutoffbound) );
    10270 }
    10271 else
    10272 {
    10273 SCIP_CONSDATA* consdata;
    10274
    10275 consdata = SCIPconsGetData(cons);
    10276 assert(consdata != NULL);
    10277
    10278 /* we cannot disable the enforcement and propagation on ranged rows, because the cutoffbound could only have
    10279 * resulted from one side
    10280 */
    10281 if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
    10282 {
    10283 /* in case the cutoff bound is worse then the currently known one, we additionally avoid enforcement and
    10284 * propagation
    10285 */
    10288 }
    10289 }
    10290
    10291 return SCIP_OKAY;
    10292}
    10293
    10294/** check if the linear constraint is parallel to objective function; if so update the cutoff bound and avoid that the
    10295 * constraint enters the LP by setting the initial and separated flag to FALSE
    10296 */
    10297static
    10299 SCIP* scip, /**< SCIP data structure */
    10300 SCIP_CONS* cons, /**< linear constraint */
    10301 SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
    10302 )
    10303{
    10304 SCIP_CONSDATA* consdata;
    10305 SCIP_Real offset;
    10306 SCIP_Real scale;
    10307 SCIP_Bool applicable;
    10308 int nobjvars;
    10309 int nvars;
    10310
    10311 assert(scip != NULL);
    10312 assert(cons != NULL);
    10313 assert(conshdlrdata != NULL);
    10314
    10315 consdata = SCIPconsGetData(cons);
    10316 assert(consdata != NULL);
    10317
    10318 /* ignore equalities since these are covered by the method checkPartialObjective() */
    10319 if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
    10320 return SCIP_OKAY;
    10321
    10322 nvars = consdata->nvars;
    10323 nobjvars = SCIPgetNObjVars(scip);
    10324
    10325 /* check if the linear inequality constraints has the same number of variables as the objective function and if the
    10326 * initial and/or separated flag is set to FALSE
    10327 */
    10328 if( nvars != nobjvars || (!SCIPconsIsInitial(cons) && !SCIPconsIsSeparated(cons)) )
    10329 return SCIP_OKAY;
    10330
    10331 offset = 0.0;
    10332 scale = 1.0;
    10333
    10334 /* There are no variables in the objective function and in the constraint. Thus, the constraint is redundant or proves
    10335 * infeasibility. Since we have a pure feasibility problem, we do not want to set a cutoff or lower bound.
    10336 */
    10337 if( nobjvars == 0 )
    10338 return SCIP_OKAY;
    10339
    10340 /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
    10341 applicable = checkEqualObjective(scip, consdata, &scale, &offset);
    10342
    10343 if( applicable )
    10344 {
    10345 SCIP_Bool rhsfinite = !SCIPisInfinity(scip, consdata->rhs);
    10346 SCIP_Bool lhsfinite = !SCIPisInfinity(scip, -consdata->lhs);
    10347
    10348 assert(scale != 0.0);
    10349
    10350 if( scale > 0.0 )
    10351 {
    10352 if( conshdlrdata->detectcutoffbound && rhsfinite )
    10353 {
    10354 SCIP_Real primalbound;
    10355
    10356 primalbound = (consdata->rhs - offset) / scale;
    10357
    10358 SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
    10359 SCIPconsGetName(cons), primalbound);
    10360
    10361 SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
    10362 }
    10363
    10364 if( conshdlrdata->detectlowerbound && lhsfinite )
    10365 {
    10366 SCIP_Real lowerbound;
    10367
    10368 lowerbound = (consdata->lhs - offset) / scale;
    10369
    10370 SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
    10371 SCIPconsGetName(cons), lowerbound);
    10372
    10374 }
    10375
    10376 if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !lhsfinite)) ||
    10377 (conshdlrdata->detectlowerbound && !rhsfinite) )
    10378 {
    10379 /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
    10382 }
    10383 }
    10384 else
    10385 {
    10386 if( conshdlrdata->detectlowerbound && rhsfinite )
    10387 {
    10388 SCIP_Real lowerbound;
    10389
    10390 lowerbound = (consdata->rhs - offset) / scale;
    10391
    10392 SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
    10393 SCIPconsGetName(cons), lowerbound);
    10394
    10396 }
    10397
    10398 if( conshdlrdata->detectcutoffbound && lhsfinite )
    10399 {
    10400 SCIP_Real primalbound;
    10401
    10402 primalbound = (consdata->lhs - offset) / scale;
    10403
    10404 SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
    10405 SCIPconsGetName(cons), primalbound);
    10406
    10407 SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
    10408 }
    10409
    10410 if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !rhsfinite)) ||
    10411 (conshdlrdata->detectlowerbound && !lhsfinite) )
    10412 {
    10413 /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
    10416 }
    10417 }
    10418 }
    10419
    10420 return SCIP_OKAY;
    10421}
    10422
    10423/** converts special equalities */
    10424static
    10426 SCIP* scip, /**< SCIP data structure */
    10427 SCIP_CONS* cons, /**< linear constraint */
    10428 SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
    10429 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    10430 int* nfixedvars, /**< pointer to count number of fixed variables */
    10431 int* naggrvars, /**< pointer to count number of aggregated variables */
    10432 int* ndelconss, /**< pointer to count number of deleted constraints */
    10433 int* nchgvartypes /**< pointer to count number of changed variable types */
    10434 )
    10435{
    10436 SCIP_CONSDATA* consdata;
    10437
    10438 assert(scip != NULL);
    10439 assert(cons != NULL);
    10440 assert(conshdlrdata != NULL);
    10441 assert(cutoff != NULL);
    10442 assert(nfixedvars != NULL);
    10443 assert(naggrvars != NULL);
    10444 assert(ndelconss != NULL);
    10445
    10446 consdata = SCIPconsGetData(cons);
    10447 assert(consdata != NULL);
    10448 assert(consdata->removedfixings);
    10449
    10450 /* do nothing on inequalities */
    10451 if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
    10452 return SCIP_OKAY;
    10453
    10454 /* depending on the number of variables, call a special conversion method */
    10455 if( consdata->nvars == 1 )
    10456 {
    10457 /* fix variable */
    10458 SCIP_CALL( convertUnaryEquality(scip, cons, cutoff, nfixedvars, ndelconss) );
    10459 }
    10460 else if( consdata->nvars == 2 )
    10461 {
    10462 /* aggregate one of the variables */
    10463 SCIP_CALL( convertBinaryEquality(scip, cons, cutoff, naggrvars, ndelconss) );
    10464 }
    10465 else
    10466 {
    10467 /* check if the equality is part of the objective function */
    10468 SCIP_CALL( checkPartialObjective(scip, cons, conshdlrdata) );
    10469
    10470 /* try to multi-aggregate one of the variables */
    10471 SCIP_CALL( convertLongEquality(scip, conshdlrdata, cons, cutoff, naggrvars, ndelconss, nchgvartypes) );
    10472 }
    10473
    10474 return SCIP_OKAY;
    10475}
    10476
    10477/** returns whether the linear sum of all variables/coefficients except the given one divided by the given value is always
    10478 * integral
    10479 */
    10480static
    10482 SCIP* scip, /**< SCIP data structure */
    10483 SCIP_CONSDATA* consdata, /**< linear constraint */
    10484 int pos, /**< position of variable to be left out */
    10485 SCIP_Real val /**< value to divide the coefficients by */
    10486 )
    10487{
    10488 int v;
    10489
    10490 assert(scip != NULL);
    10491 assert(consdata != NULL);
    10492 assert(0 <= pos && pos < consdata->nvars);
    10493
    10494 for( v = 0; v < consdata->nvars; ++v )
    10495 {
    10496 if( v != pos && (!SCIPvarIsIntegral(consdata->vars[v]) || !SCIPisIntegral(scip, consdata->vals[v]/val)) )
    10497 return FALSE;
    10498 }
    10499
    10500 return TRUE;
    10501}
    10502
    10503/** check if \f$lhs/a_i - \sum_{j \neq i} a_j/a_i x_j\f$ is always inside the bounds of \f$x_i\f$,
    10504 * check if \f$rhs/a_i - \sum_{j \neq i} a_j/a_i x_j\f$ is always inside the bounds of \f$x_i\f$
    10505 */
    10506static
    10508 SCIP* scip, /**< SCIP data structure */
    10509 SCIP_Real side, /**< lhs or rhs */
    10510 SCIP_Real val, /**< coefficient */
    10511 SCIP_Real minresactivity, /**< minimal residual activity */
    10512 SCIP_Real maxresactivity, /**< maximal residual activity */
    10513 SCIP_Real* minval, /**< pointer to store calculated minval */
    10514 SCIP_Real* maxval /**< pointer to store calculated maxval */
    10515 )
    10516{
    10517 assert(scip != NULL);
    10518 assert(minval != NULL);
    10519 assert(maxval != NULL);
    10520
    10521 if( val > 0.0 )
    10522 {
    10523 if( SCIPisInfinity(scip, ABS(maxresactivity)) )
    10524 *minval = -maxresactivity;
    10525 else
    10526 *minval = (side - maxresactivity)/val;
    10527
    10528 if( SCIPisInfinity(scip, ABS(minresactivity)) )
    10529 *maxval = -minresactivity;
    10530 else
    10531 *maxval = (side - minresactivity)/val;
    10532 }
    10533 else
    10534 {
    10535 if( SCIPisInfinity(scip, ABS(minresactivity)) )
    10536 *minval = minresactivity;
    10537 else
    10538 *minval = (side - minresactivity)/val;
    10539
    10540 if( SCIPisInfinity(scip, ABS(maxresactivity)) )
    10541 *maxval = maxresactivity;
    10542 else
    10543 *maxval = (side - maxresactivity)/val;
    10544 }
    10545}
    10546
    10547
    10548/** applies dual presolving for variables that are locked only once in a direction, and this locking is due to a
    10549 * linear inequality
    10550 */
    10551static
    10553 SCIP* scip, /**< SCIP data structure */
    10554 SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
    10555 SCIP_CONS* cons, /**< linear constraint */
    10556 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    10557 int* nfixedvars, /**< pointer to count number of fixed variables */
    10558 int* naggrvars, /**< pointer to count number of aggregated variables */
    10559 int* ndelconss, /**< pointer to count number of deleted constraints */
    10560 int* nchgvartypes /**< pointer to count number of changed variable types */
    10561 )
    10562{
    10563 SCIP_CONSDATA* consdata;
    10564 SCIP_Bool lhsexists;
    10565 SCIP_Bool rhsexists;
    10566 SCIP_Bool bestisint;
    10567 SCIP_Bool bestislhs;
    10568 SCIP_Real minabsval;
    10569 SCIP_Real maxabsval;
    10570 int bestpos;
    10571 int i;
    10572 int maxotherlocks;
    10573
    10574 assert(scip != NULL);
    10575 assert(cons != NULL);
    10576 assert(cutoff != NULL);
    10577 assert(nfixedvars != NULL);
    10578 assert(naggrvars != NULL);
    10579 assert(ndelconss != NULL);
    10580
    10581 /* only process checked constraints (for which the locks are increased);
    10582 * otherwise we would have to check for variables with nlocks == 0, and these are already processed by the
    10583 * dualfix presolver
    10584 */
    10585 if( !SCIPconsIsChecked(cons) )
    10586 return SCIP_OKAY;
    10587
    10588 consdata = SCIPconsGetData(cons);
    10589 assert(consdata != NULL);
    10590
    10591 lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
    10592 rhsexists = !SCIPisInfinity(scip, consdata->rhs);
    10593
    10594 /* search for a single-locked variable which can be multi-aggregated; if a valid continuous variable was found, we
    10595 * can use it safely for aggregation and break the search loop
    10596 */
    10597 bestpos = -1;
    10598 bestisint = TRUE;
    10599 bestislhs = FALSE;
    10600
    10601 /* We only want to multi-aggregate variables, if they appear in maximal one additional constraint,
    10602 * everything else would produce fill-in. Exceptions:
    10603 * - If there are only two variables in the constraint from which the multi-aggregation arises, no fill-in will be
    10604 * produced.
    10605 * - If there are three variables in the constraint, multi-aggregation in three additional constraints will remove
    10606 * six nonzeros (three from the constraint and the three entries of the multi-aggregated variable) and add
    10607 * six nonzeros (two variables per substitution).
    10608 * - If there at most four variables in the constraint, multi-aggregation in two additional constraints will remove
    10609 * six nonzeros (four from the constraint and the two entries of the multi-aggregated variable) and add
    10610 * six nonzeros (three variables per substitution). God exists!
    10611 */
    10612 if( consdata->nvars <= 2 )
    10613 maxotherlocks = INT_MAX;
    10614 else if( consdata->nvars == 3 )
    10615 maxotherlocks = 3;
    10616 else if( consdata->nvars == 4 )
    10617 maxotherlocks = 2;
    10618 else
    10619 maxotherlocks = 1;
    10620
    10621 /* if this constraint has both sides, it also provides a lock for the other side and thus we can allow one more lock */
    10622 if( lhsexists && rhsexists && maxotherlocks < INT_MAX )
    10623 maxotherlocks++;
    10624
    10625 minabsval = SCIPinfinity(scip);
    10626 maxabsval = -1.0;
    10627 for( i = 0; i < consdata->nvars && bestisint; ++i )
    10628 {
    10629 SCIP_VAR* var;
    10630 SCIP_Bool isint;
    10631 SCIP_Real val;
    10632 SCIP_Real absval;
    10633 SCIP_Real obj;
    10634 SCIP_Real lb;
    10635 SCIP_Real ub;
    10636 SCIP_Bool agglhs;
    10637 SCIP_Bool aggrhs;
    10638
    10639 val = consdata->vals[i];
    10640 absval = REALABS(val);
    10641
    10642 /* calculate minimal and maximal absolute value */
    10643 if( absval < minabsval )
    10644 minabsval = absval;
    10645 if( absval > maxabsval )
    10646 maxabsval = absval;
    10647
    10648 /* do not try to multi aggregate, when numerical bad */
    10649 if( maxabsval / minabsval > conshdlrdata->maxdualmultaggrquot )
    10650 return SCIP_OKAY;
    10651
    10652 var = consdata->vars[i];
    10653 isint = SCIPvarIsNonimpliedIntegral(var);
    10654
    10655 /* if we already found a candidate, skip integers */
    10656 if( bestpos >= 0 && isint )
    10657 continue;
    10658
    10659 /* better do not multi-aggregate binary variables, since most plugins rely on their binary variables to be either
    10660 * active, fixed, or single-aggregated with another binary variable
    10661 */
    10662 if( SCIPvarIsBinary(var) && consdata->nvars > 2 )
    10663 continue;
    10664
    10665 if ( SCIPdoNotMultaggrVar(scip, var) )
    10666 continue;
    10667
    10668 val = consdata->vals[i];
    10669 obj = SCIPvarGetObj(var);
    10670 lb = SCIPvarGetLbGlobal(var);
    10671 ub = SCIPvarGetUbGlobal(var);
    10672
    10673 /* lhs <= a_0 * x_0 + a_1 * x_1 + ... + a_{n-1} * x_{n-1} <= rhs
    10674 *
    10675 * a_i >= 0, c_i >= 0, lhs exists, nlocksdown(x_i) == 1:
    10676 * - constraint is the only one that forbids fixing the variable to its lower bound
    10677 * - fix x_i to the smallest value for this constraint: x_i := lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
    10678 *
    10679 * a_i <= 0, c_i <= 0, lhs exists, nlocksup(x_i) == 1:
    10680 * - constraint is the only one that forbids fixing the variable to its upper bound
    10681 * - fix x_i to the largest value for this constraint: x_i := lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
    10682 *
    10683 * a_i >= 0, c_i <= 0, rhs exists, nlocksup(x_i) == 1:
    10684 * - constraint is the only one that forbids fixing the variable to its upper bound
    10685 * - fix x_i to the largest value for this constraint: x_i := rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
    10686 *
    10687 * a_i <= 0, c_i >= 0, rhs exists, nlocksdown(x_i) == 1:
    10688 * - constraint is the only one that forbids fixing the variable to its lower bound
    10689 * - fix x_i to the smallest value for this constraint: x_i := rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
    10690 *
    10691 * but: all this is only applicable, if the aggregated value is inside x_i's bounds for all possible values
    10692 * of all x_j
    10693 * furthermore: we only want to apply this, if no fill-in will be produced
    10694 */
    10695 agglhs = lhsexists
    10696 && ((val > 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 1
    10697 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks)
    10698 || (val < 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 1
    10699 && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks));
    10700 aggrhs = rhsexists
    10701 && ((val > 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 1
    10702 && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks)
    10703 || (val < 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 1
    10704 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks));
    10705 if( agglhs || aggrhs )
    10706 {
    10707 SCIP_Real minresactivity;
    10708 SCIP_Real maxresactivity;
    10709 SCIP_Real minval;
    10710 SCIP_Real maxval;
    10711 SCIP_Bool ismintight;
    10712 SCIP_Bool ismaxtight;
    10713 SCIP_Bool isminsettoinfinity;
    10714 SCIP_Bool ismaxsettoinfinity;
    10715
    10716 /* calculate bounds for \sum_{j \neq i} a_j * x_j */
    10717 consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
    10718 &ismintight, &ismaxtight, &isminsettoinfinity, &ismaxsettoinfinity);
    10719 assert(SCIPisLE(scip, minresactivity, maxresactivity));
    10720
    10721 /* We called consdataGetActivityResiduals() saying that we do not need a good relaxation,
    10722 * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
    10723 * This is needed, because we do not want to rely on relaxed finite resactivities.
    10724 */
    10725 assert((ismintight || isminsettoinfinity) && (ismaxtight || ismaxsettoinfinity));
    10726
    10727 if( agglhs )
    10728 {
    10729 /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
    10730 calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
    10731
    10732 assert(SCIPisLE(scip, minval, maxval));
    10733 if( !SCIPisInfinity(scip, -minval) && SCIPisGE(scip, minval, lb)
    10734 && !SCIPisInfinity(scip, maxval) && SCIPisLE(scip, maxval, ub) )
    10735 {
    10736 SCIP_Real oldmaxresactivity;
    10737 SCIP_Real oldminresactivity;
    10738 SCIP_Bool recalculated;
    10739
    10740 recalculated = FALSE;
    10741 oldmaxresactivity = maxresactivity;
    10742 oldminresactivity = minresactivity;
    10743
    10744 /* check minresactivity for reliability */
    10745 if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
    10746 {
    10747 consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
    10748 recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
    10749 isminsettoinfinity = TRUE; /* here it means only that it was even calculated */
    10750 }
    10751
    10752 /* check maxresactivity for reliability */
    10753 if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
    10754 {
    10755 consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
    10756 recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
    10757 ismaxsettoinfinity = TRUE; /* here it means only that it was even calculated */
    10758 }
    10759
    10760 /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
    10761 if( recalculated )
    10762 {
    10763 assert(SCIPisLE(scip, minresactivity, maxresactivity));
    10764
    10765 /* check again if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
    10766 calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
    10767
    10768 assert(SCIPisLE(scip, minval, maxval));
    10769 }
    10770
    10771 if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
    10772 {
    10773 /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
    10774 * in the multi-aggregation
    10775 */
    10776 if( !isint || (SCIPisIntegral(scip, consdata->lhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
    10777 {
    10778 bestpos = i;
    10779 bestisint = isint;
    10780 bestislhs = TRUE;
    10781 continue; /* no need to also look at the right hand side */
    10782 }
    10783 }
    10784 }
    10785 }
    10786
    10787 if( aggrhs )
    10788 {
    10789 /* check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
    10790 calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
    10791
    10792 assert(SCIPisLE(scip,minval,maxval));
    10793 if( !SCIPisInfinity(scip, -minval) && SCIPisGE(scip, minval, lb)
    10794 && !SCIPisInfinity(scip, maxval) && SCIPisLE(scip, maxval, ub) )
    10795 {
    10796 SCIP_Real oldmaxresactivity;
    10797 SCIP_Real oldminresactivity;
    10798 SCIP_Bool recalculated;
    10799
    10800 recalculated = FALSE;
    10801 oldmaxresactivity = maxresactivity;
    10802 oldminresactivity = minresactivity;
    10803
    10804 /* check minresactivity for reliability */
    10805 if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
    10806 {
    10807 consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
    10808 recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
    10809 }
    10810
    10811 /* check maxresactivity for reliability */
    10812 if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
    10813 {
    10814 consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
    10815 recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
    10816 }
    10817
    10818 /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
    10819 if( recalculated )
    10820 {
    10821 /* check again if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
    10822 calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
    10823 assert(SCIPisLE(scip,minval,maxval));
    10824 }
    10825
    10826 if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
    10827 {
    10828 /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
    10829 * in the multi-aggregation
    10830 */
    10831 if( !isint || (SCIPisIntegral(scip, consdata->rhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
    10832 {
    10833 bestpos = i;
    10834 bestisint = isint;
    10835 bestislhs = FALSE;
    10836 }
    10837 }
    10838 }
    10839 }
    10840 }
    10841 }
    10842
    10843 if( bestpos >= 0 )
    10844 {
    10845 SCIP_VAR** aggrvars;
    10846 SCIP_Real* aggrcoefs;
    10847 SCIP_Real aggrconst;
    10848 SCIP_VAR* bestvar;
    10849 SCIP_Real bestval;
    10850 int naggrs;
    10851 int j;
    10852 SCIP_Bool infeasible;
    10853 SCIP_Bool aggregated;
    10854
    10855 assert(!bestislhs || lhsexists);
    10856 assert(bestislhs || rhsexists);
    10857
    10858 bestvar = consdata->vars[bestpos];
    10859 bestval = consdata->vals[bestpos];
    10860 assert(bestisint == SCIPvarIsNonimpliedIntegral(bestvar));
    10861
    10862 /* allocate temporary memory */
    10863 SCIP_CALL( SCIPallocBufferArray(scip, &aggrvars, consdata->nvars-1) );
    10864 SCIP_CALL( SCIPallocBufferArray(scip, &aggrcoefs, consdata->nvars-1) );
    10865
    10866 /* set up the multi-aggregation */
    10868 SCIPdebugMsg(scip, "linear constraint <%s> (dual): multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(bestvar));
    10869 naggrs = 0;
    10870
    10871 for( j = 0; j < consdata->nvars; ++j )
    10872 {
    10873 if( j != bestpos )
    10874 {
    10875 aggrvars[naggrs] = consdata->vars[j];
    10876 aggrcoefs[naggrs] = -consdata->vals[j]/consdata->vals[bestpos];
    10877
    10878 SCIPdebugMsgPrint(scip, " %+.15g<%s>", aggrcoefs[naggrs], SCIPvarGetName(aggrvars[naggrs]));
    10879
    10880 /* do not try to multi aggregate, when numerical bad */
    10881 if( SCIPisZero(scip, aggrcoefs[naggrs]) )
    10882 {
    10883 SCIPdebugMsg(scip, "do not perform multi-aggregation: too large aggregation coefficients\n");
    10884
    10885 /* free temporary memory */
    10886 SCIPfreeBufferArray(scip, &aggrcoefs);
    10887 SCIPfreeBufferArray(scip, &aggrvars);
    10888
    10889 return SCIP_OKAY;
    10890 }
    10891
    10892 if( bestisint )
    10893 {
    10894 /* coefficient must be integral: round it to exact integral value */
    10895 assert(SCIPisIntegral(scip, aggrcoefs[naggrs]));
    10896 aggrcoefs[naggrs] = SCIPfloor(scip, aggrcoefs[naggrs]+0.5);
    10897 }
    10898
    10899 naggrs++;
    10900 }
    10901 }
    10902
    10903 aggrconst = (bestislhs ? consdata->lhs/bestval : consdata->rhs/bestval);
    10904 SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g]\n", aggrconst, SCIPvarGetName(bestvar),
    10905 SCIPvarGetLbGlobal(bestvar), SCIPvarGetUbGlobal(bestvar));
    10906 assert(naggrs == consdata->nvars-1);
    10907
    10908 /* right hand side must be integral: round it to exact integral value */
    10909 if( bestisint )
    10910 {
    10911 assert(SCIPisIntegral(scip, aggrconst));
    10912 aggrconst = SCIPfloor(scip, aggrconst+0.5);
    10913 }
    10914
    10915 aggregated = FALSE;
    10916 infeasible = FALSE;
    10917
    10918 /* perform the multi-aggregation */
    10919 SCIP_CALL( SCIPmultiaggregateVar(scip, bestvar, naggrs, aggrvars, aggrcoefs, aggrconst, &infeasible, &aggregated) );
    10920
    10921 /** @todo handle this case properly with weak and strong implied integrality */
    10922 /* if the multi-aggregated bestvar is enforced but not strongly implied integral, we need to convert implied
    10923 * integral to integer variables because integrality of the multi-aggregated variable must hold
    10924 */
    10925 if( !infeasible && aggregated && SCIPvarGetType(bestvar) != SCIP_VARTYPE_CONTINUOUS && SCIPvarGetImplType(bestvar) != SCIP_IMPLINTTYPE_STRONG )
    10926 {
    10927 SCIP_Bool infeasiblevartypechg = FALSE;
    10928
    10929 for( j = 0; j < naggrs; ++j )
    10930 {
    10931 /* if the multi-aggregation was not infeasible, then setting implied integral to integer should not
    10932 * lead to infeasibility
    10933 */
    10935 {
    10936 if( SCIPvarGetType(aggrvars[j]) == SCIP_VARTYPE_CONTINUOUS )
    10937 {
    10938 SCIP_CALL( SCIPchgVarType(scip, aggrvars[j], SCIP_VARTYPE_INTEGER, &infeasiblevartypechg) );
    10939 assert(!infeasiblevartypechg);
    10940 }
    10941 SCIP_CALL( SCIPchgVarImplType(scip, aggrvars[j], SCIP_IMPLINTTYPE_NONE, &infeasiblevartypechg) );
    10942 assert(!infeasiblevartypechg);
    10943 (*nchgvartypes)++;
    10944 }
    10945 }
    10946 }
    10947
    10948 /* free temporary memory */
    10949 SCIPfreeBufferArray(scip, &aggrcoefs);
    10950 SCIPfreeBufferArray(scip, &aggrvars);
    10951
    10952 /* check for infeasible aggregation */
    10953 if( infeasible )
    10954 {
    10955 SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
    10956 *cutoff = TRUE;
    10957 return SCIP_OKAY;
    10958 }
    10959
    10960 /* delete the constraint, if the aggregation was successful */
    10961 if( aggregated )
    10962 {
    10963 SCIP_CALL( SCIPdelCons(scip, cons) );
    10964
    10965 if( !consdata->upgraded )
    10966 (*ndelconss)++;
    10967 (*naggrvars)++;
    10968 }
    10969 else
    10970 {
    10971 SCIPdebugMsg(scip, "aggregation non successful!\n");
    10972 }
    10973 }
    10974
    10975 return SCIP_OKAY;
    10976}
    10977
    10978#define BINWEIGHT 1
    10979#define INTWEIGHT 4
    10980#define CONTWEIGHT 8
    10981
    10982/** gets weight for variable in a "weighted number of variables" sum */
    10983static
    10985 SCIP_VAR* var /**< variable to get weight for */
    10986 )
    10987{
    10988 if( SCIPvarIsImpliedIntegral(var) )
    10989 return INTWEIGHT;
    10990
    10991 switch( SCIPvarGetType(var) )
    10992 {
    10994 return BINWEIGHT;
    10996 return INTWEIGHT;
    10998 return CONTWEIGHT;
    10999 default:
    11000 SCIPerrorMessage("unknown variable type\n");
    11001 SCIPABORT();
    11002 return 0; /*lint !e527*/
    11003 } /*lint !e788*/
    11004}
    11005
    11006/** tries to aggregate variables in equations a^Tx = lhs
    11007 * in case there are at most two binary variables with an odd coefficient and all other
    11008 * variables are not continuous and have an even coefficient then:
    11009 * - exactly one odd binary variables
    11010 * this binary variables y can be fixed to 0 if the lhs is even and to 1 if the lhs is odd
    11011 * - lhs is odd -> y = 1
    11012 * - lhs is even -> y = 0
    11013 * - exactly two odd binary variables
    11014 * aggregate the two binary variables with odd coefficient
    11015 * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
    11016 * - lhs is even -> both have to take the same value -> var1 - var2 = 0
    11017 */
    11018static
    11020 SCIP* scip, /**< SCIP data structure */
    11021 SCIP_CONS* cons, /**< linear constraint */
    11022 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    11023 int* nfixedvars, /**< pointer to count number of fixed variables */
    11024 int* naggrvars /**< pointer to count number of aggregated variables */
    11025 )
    11026{ /*lint --e{715}*/
    11027 SCIP_CONSDATA* consdata;
    11028 SCIP_Bool success;
    11029
    11030 assert( scip != NULL );
    11031 assert( cons != NULL );
    11032
    11033 consdata = SCIPconsGetData(cons);
    11034 assert( consdata != NULL );
    11035
    11036 /* check if the linear constraint is an equation with integral right hand side */
    11037 if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) || !SCIPisIntegral(scip, consdata->lhs) )
    11038 return SCIP_OKAY;
    11039
    11040 /* try to fix and aggregated variables until nothing is possible anymore */
    11041 do
    11042 {
    11043 int v;
    11044 int nvars;
    11045 SCIP_VAR** vars;
    11046 SCIP_Real* vals;
    11047 SCIP_Real lhs;
    11048 SCIP_Bool lhsodd;
    11049
    11050 SCIP_Bool infeasible;
    11051 SCIP_Bool fixed;
    11052 SCIP_Bool aggregated;
    11053 SCIP_Bool redundant;
    11054
    11055 SCIP_VAR* var1;
    11056 SCIP_VAR* var2;
    11057 int noddvars;
    11058
    11059 success = FALSE;
    11060
    11061 lhs = consdata->lhs;
    11062 vars = consdata->vars;
    11063 vals = consdata->vals;
    11064 nvars = consdata->nvars;
    11065
    11066 assert( !SCIPisInfinity(scip, ABS(lhs)) );
    11067
    11068 var1 = NULL;
    11069 var2 = NULL;
    11070 noddvars = 0;
    11071
    11072 /* search for binary variables with an odd coefficient */
    11073 for( v = 0; v < nvars && noddvars < 3; ++v )
    11074 {
    11075 SCIP_Longint val;
    11076
    11077 /* all coefficients and variables have to be integral */
    11078 if( !SCIPvarIsIntegral(vars[v]) || !SCIPisIntegral(scip, vals[v]) )
    11079 return SCIP_OKAY;
    11080
    11081 val = (SCIP_Longint)SCIPfeasFloor(scip, vals[v]);
    11082 if( val % 2 != 0 )
    11083 {
    11084 /* the odd values have to belong to binary variables */
    11085 if( !SCIPvarIsBinary(vars[v]) )
    11086 return SCIP_OKAY;
    11087
    11088 if( noddvars == 0 )
    11089 var1 = vars[v];
    11090 else
    11091 var2 = vars[v];
    11092
    11093 noddvars++;
    11094 }
    11095 }
    11096
    11097 /* check lhs is odd or even */
    11098 lhsodd = (((SCIP_Longint)SCIPfeasFloor(scip, lhs)) % 2 != 0);
    11099
    11100 if( noddvars == 1 )
    11101 {
    11102 assert( var1 != NULL );
    11103
    11104 SCIPdebugMsg(scip, "linear constraint <%s>: try fixing variable <%s> to <%g>\n",
    11105 SCIPconsGetName(cons), SCIPvarGetName(var1), lhsodd ? 1.0 : 0.0);
    11106
    11107 SCIP_CALL( SCIPfixVar(scip, var1, lhsodd? 1.0 : 0.0, &infeasible, &fixed) );
    11108
    11109 /* check for infeasibility of fixing */
    11110 if( infeasible )
    11111 {
    11112 SCIPdebugMsg(scip, " -> infeasible fixing\n");
    11113 *cutoff = TRUE;
    11114 return SCIP_OKAY;
    11115 }
    11116
    11117 if( fixed )
    11118 {
    11119 SCIPdebugMsg(scip, " -> feasible fixing\n");
    11120 (*nfixedvars)++;
    11121 success = TRUE;
    11122 }
    11123 }
    11124 else if( noddvars == 2 )
    11125 {
    11126 assert( var1 != NULL );
    11127 assert( var2 != NULL );
    11128
    11129 /* aggregate the two variables with odd coefficient
    11130 * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
    11131 * - lhs is even -> both have to take the same value -> var1 - var2 = 0
    11132 */
    11133 SCIPdebugMsg(scip, "linear constraint <%s>: try aggregation of variables <%s> and <%s>\n",
    11134 SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
    11135
    11136 SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, lhsodd ? 1.0 : -1.0,
    11137 lhsodd ? 1.0 : 0.0, &infeasible, &redundant, &aggregated) );
    11138
    11139 /* check for infeasibility of aggregation */
    11140 if( infeasible )
    11141 {
    11142 SCIPdebugMsg(scip, " -> infeasible aggregation\n");
    11143 *cutoff = TRUE;
    11144 return SCIP_OKAY;
    11145 }
    11146
    11147 /* count the aggregation */
    11148 if( aggregated )
    11149 {
    11150 SCIPdebugMsg(scip, " -> feasible aggregation\n");
    11151 (*naggrvars)++;
    11152 success = TRUE;
    11153 }
    11154 }
    11155
    11156 if( success )
    11157 {
    11158 /* apply fixings and aggregation to successfully rerun this presolving step */
    11159 SCIP_CALL( applyFixings(scip, cons, &infeasible) );
    11160
    11161 if( infeasible )
    11162 {
    11163 SCIPdebugMsg(scip, " -> infeasible fixing\n");
    11164 *cutoff = TRUE;
    11165 return SCIP_OKAY;
    11166 }
    11167
    11168 SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
    11169
    11170 if( infeasible )
    11171 {
    11172 SCIPdebugMsg(scip, " -> infeasible normalization\n");
    11173 *cutoff = TRUE;
    11174 return SCIP_OKAY;
    11175 }
    11176 }
    11177 }
    11178 while( success && consdata->nvars >= 1 );
    11179
    11180 return SCIP_OKAY;
    11181}
    11182
    11183
    11184
    11185/** sorting method for constraint data, compares two variables on given indices, continuous variables will be sorted to
    11186 * the end and for all other variables the sortation will be in non-increasing order of their absolute value of the
    11187 * coefficients
    11188 */
    11189static
    11191{ /*lint --e{715}*/
    11192 SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
    11193 SCIP_Real value;
    11194
    11195 assert(consdata != NULL);
    11196 assert(0 <= ind1 && ind1 < consdata->nvars);
    11197 assert(0 <= ind2 && ind2 < consdata->nvars);
    11198
    11199 SCIP_Bool varcont1 = !SCIPvarIsIntegral(consdata->vars[ind1]);
    11200 SCIP_Bool varcont2 = !SCIPvarIsIntegral(consdata->vars[ind2]);
    11201
    11202 if( varcont1 )
    11203 {
    11204 /* continuous variables will be sorted to the back */
    11205 if( varcont1 != varcont2 )
    11206 return +1;
    11207 /* both variables are continuous */
    11208 else
    11209 return 0;
    11210 }
    11211 /* continuous variables will be sorted to the back */
    11212 else if( varcont2 )
    11213 return -1;
    11214
    11215 value = REALABS(consdata->vals[ind2]) - REALABS(consdata->vals[ind1]);
    11216
    11217 /* for all non-continuous variables, the variables are sorted after decreasing absolute coefficients */
    11218 return (value > 0 ? +1 : (value < 0 ? -1 : 0));
    11219}
    11220
    11221/** tries to simplify coefficients in ranged row of the form lhs <= a^Tx <= rhs
    11222 *
    11223 * 1. lhs <= a^Tx <= rhs, x binary, lhs > 0, forall a_i >= lhs, a_i <= rhs, and forall pairs a_i + a_j > rhs,
    11224 * then we can change this constraint to 1^Tx = 1
    11225 */
    11226static
    11228 SCIP* scip, /**< SCIP data structure */
    11229 SCIP_CONS* cons, /**< linear constraint */
    11230 int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
    11231 int* nchgsides /**< pointer to store the amount of changed sides */
    11232 )
    11233{
    11234 SCIP_CONSDATA* consdata;
    11235 SCIP_VAR** vars;
    11236 SCIP_Real* vals;
    11237 SCIP_Real minval;
    11238 SCIP_Real secondminval;
    11239 SCIP_Real maxval;
    11240 SCIP_Real lhs;
    11241 SCIP_Real rhs;
    11242 int nvars;
    11243 int v;
    11244
    11245 /* we must not change a modifiable constraint in any way */
    11246 if( SCIPconsIsModifiable(cons) )
    11247 return SCIP_OKAY;
    11248
    11249 if( SCIPconsIsDeleted(cons) )
    11250 return SCIP_OKAY;
    11251
    11252 consdata = SCIPconsGetData(cons);
    11253 assert(consdata != NULL);
    11254
    11255 nvars = consdata->nvars;
    11256
    11257 /* do not check empty or bound-constraints */
    11258 if( nvars < 2 )
    11259 return SCIP_OKAY;
    11260
    11261 lhs = consdata->lhs;
    11262 rhs = consdata->rhs;
    11263 assert(!SCIPisInfinity(scip, -lhs));
    11264 assert(!SCIPisInfinity(scip, rhs));
    11265 assert(!SCIPisNegative(scip, rhs));
    11266
    11267 /* sides must be positive and different to detect set partition */
    11268 if( !SCIPisPositive(scip, lhs) || !SCIPisLT(scip, lhs, rhs) )
    11269 return SCIP_OKAY;
    11270
    11271 vals = consdata->vals;
    11272 vars = consdata->vars;
    11273 assert(vars != NULL);
    11274 assert(vals != NULL);
    11275
    11276 minval = SCIP_INVALID;
    11277 secondminval = SCIP_INVALID;
    11278 maxval = -SCIP_INVALID;
    11279
    11280 for( v = nvars - 1; v >= 0; --v )
    11281 {
    11282 if( SCIPvarIsBinary(vars[v]) )
    11283 {
    11284 if( minval > vals[v] || minval == SCIP_INVALID ) /*lint !e777*/
    11285 {
    11286 secondminval = minval;
    11287 minval = vals[v];
    11288 }
    11289 else if( secondminval > vals[v] || secondminval == SCIP_INVALID ) /*lint !e777*/
    11290 secondminval = vals[v];
    11291
    11292 if( maxval < vals[v] || maxval == -SCIP_INVALID ) /*lint !e777*/
    11293 maxval = vals[v];
    11294 }
    11295 else
    11296 break;
    11297 }
    11298
    11299 /* check if all variables are binary, we can choose one, and need to choose at most one */
    11300 if( v == -1 && SCIPisGE(scip, minval, lhs) && SCIPisLE(scip, maxval, rhs)
    11301 && SCIPisGT(scip, minval + secondminval, rhs) )
    11302 {
    11303 /* change all coefficients to 1.0 */
    11304 for( v = nvars - 1; v >= 0; --v )
    11305 {
    11306 SCIP_CALL( chgCoefPos(scip, cons, v, 1.0) );
    11307 }
    11308 (*nchgcoefs) += nvars;
    11309
    11310 /* replace old right and left hand side with 1.0 */
    11311 SCIP_CALL( chgRhs(scip, cons, 1.0) );
    11312 SCIP_CALL( chgLhs(scip, cons, 1.0) );
    11313 (*nchgsides) += 2;
    11314 }
    11315
    11316 return SCIP_OKAY;
    11317}
    11318
    11319/** tries to simplify coefficients and delete variables in constraints of the form lhs <= a^Tx <= rhs
    11320 *
    11321 * for both-sided constraints only @see rangedRowSimplify() will be called
    11322 *
    11323 * for one-sided constraints there are several different coefficient reduction steps which will be applied
    11324 *
    11325 * 1. We try to determine parts of the constraint which will not change anything on (in-)feasibility of the constraint
    11326 *
    11327 * e.g. 5x1 + 5x2 + 3z1 <= 8 => 3z1 is redundant if all x are binary and -2 < 3z1 <= 3
    11328 *
    11329 * 2. We try to remove redundant fractional parts in a constraint
    11330 *
    11331 * e.g. 5.2x1 + 5.1x2 + 3x3 <= 8.3 => will be changed to 5x1 + 5x2 + 3x3 <= 8 if all x are binary
    11332 *
    11333 * 3. We are using the greatest common divisor for further reductions
    11334 *
    11335 * e.g. 10x1 + 5y2 + 5x3 + 3x4 <= 15 => will be changed to 2x1 + y2 + x3 + x4 <= 3 if all xi are binary and y2 is
    11336 * integral
    11337 */
    11338static
    11340 SCIP* scip, /**< SCIP data structure */
    11341 SCIP_CONS* cons, /**< linear constraint */
    11342 int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
    11343 int* nchgsides, /**< pointer to store the amount of changed sides */
    11344 SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
    11345 )
    11346{
    11347 SCIP_CONSDATA* consdata;
    11348 SCIP_VAR** vars;
    11349 SCIP_Real* vals;
    11350 int* perm;
    11351 SCIP_Real minactsub;
    11352 SCIP_Real maxactsub;
    11353 SCIP_Real siderest;
    11354 SCIP_Real feastol;
    11355 SCIP_Real newcoef;
    11356 SCIP_Real absval;
    11357 SCIP_Real minact;
    11358 SCIP_Real maxact;
    11359 SCIP_Real side;
    11360 SCIP_Real lhs;
    11361 SCIP_Real rhs;
    11362 SCIP_Real lb;
    11363 SCIP_Real ub;
    11364 SCIP_Longint restcoef;
    11365 SCIP_Longint oldgcd;
    11366 SCIP_Longint rest;
    11367 SCIP_Longint gcd;
    11368 SCIP_Bool isminsettoinfinity;
    11369 SCIP_Bool ismaxsettoinfinity;
    11370 SCIP_Bool ismintight;
    11371 SCIP_Bool ismaxtight;
    11372 SCIP_Bool allcoefintegral;
    11373 SCIP_Bool onlybin;
    11374 SCIP_Bool hasrhs;
    11375 SCIP_Bool haslhs;
    11376 int oldnchgcoefs; /* cppcheck-suppress unassignedVariable */
    11377 int oldnchgsides; /* cppcheck-suppress unassignedVariable */
    11378 int foundbin;
    11379 int candpos;
    11380 int candpos2;
    11381 int offsetv;
    11382 int nvars;
    11383 int v;
    11384 int w;
    11385
    11386 assert(scip != NULL);
    11387 assert(cons != NULL);
    11388 assert(nchgcoefs != NULL);
    11389 assert(nchgsides != NULL);
    11390
    11391 *infeasible = FALSE;
    11392
    11393 /* we must not change a modifiable constraint in any way */
    11394 if( SCIPconsIsModifiable(cons) )
    11395 return SCIP_OKAY;
    11396
    11397 if( SCIPconsIsDeleted(cons) )
    11398 return SCIP_OKAY;
    11399
    11400 consdata = SCIPconsGetData(cons);
    11401 assert(consdata != NULL);
    11402
    11403 nvars = consdata->nvars;
    11404
    11405 /* do not check empty or bound-constraints */
    11406 if( nvars <= 2 )
    11407 return SCIP_OKAY;
    11408
    11409 /* update maximal activity delta if necessary */
    11410 if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
    11412
    11413 assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
    11414 assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
    11415 checkMaxActivityDelta(scip, consdata);
    11416
    11417 /* @todo the following might be too hard, check which steps can be applied and what code must be corrected
    11418 * accordingly
    11419 */
    11420 /* can only work with valid non-infinity activities per variable */
    11421 if( SCIPisInfinity(scip, consdata->maxactdelta) )
    11422 return SCIP_OKAY;
    11423
    11424 /* @todo: change the following: due to vartype changes, the status of the normalization can be wrong, need an event
    11425 * but the eventsystem seems to be full
    11426 */
    11427 consdata->normalized = FALSE;
    11428
    11429 SCIP_CALL( normalizeCons(scip, cons, infeasible) );
    11430 assert(nvars == consdata->nvars);
    11431
    11432 if( *infeasible )
    11433 return SCIP_OKAY;
    11434
    11435 if( !consdata->normalized )
    11436 return SCIP_OKAY;
    11437
    11438 lhs = consdata->lhs;
    11439 rhs = consdata->rhs;
    11440 assert(!SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs));
    11441 assert(!SCIPisNegative(scip, rhs));
    11442
    11443 if( !SCIPisInfinity(scip, -lhs) )
    11444 haslhs = TRUE;
    11445 else
    11446 haslhs = FALSE;
    11447
    11448 if( !SCIPisInfinity(scip, rhs) )
    11449 hasrhs = TRUE;
    11450 else
    11451 hasrhs = FALSE;
    11452
    11453 /* @todo extend both-sided simplification */
    11454 if( haslhs && hasrhs )
    11455 {
    11456 SCIP_CALL( rangedRowSimplify(scip, cons, nchgcoefs, nchgsides ) );
    11457
    11458 return SCIP_OKAY;
    11459 }
    11460 assert(haslhs != hasrhs);
    11461
    11462 /* if we have a normalized inequality (not ranged) the one side should be positive, @see normalizeCons() */
    11463 assert(!hasrhs || !SCIPisNegative(scip, rhs));
    11464 assert(!haslhs || !SCIPisNegative(scip, lhs));
    11465
    11466 /* get temporary memory to store the sorted permutation */
    11467 SCIP_CALL( SCIPallocBufferArray(scip, &perm, nvars) );
    11468
    11469 /* call sorting method, order continuous variables to the end and all other variables after non-increasing absolute
    11470 * value of their coefficients
    11471 */
    11472 SCIPsort(perm, consdataCompSim, (void*)consdata, nvars);
    11473
    11474 /* perform sorting after permutation array */
    11475 permSortConsdata(consdata, perm, nvars);
    11476 consdata->indexsorted = FALSE;
    11477 consdata->coefsorted = FALSE;
    11478
    11479 vars = consdata->vars;
    11480 vals = consdata->vals;
    11481 assert(vars != NULL);
    11482 assert(vals != NULL);
    11483 assert(!consdata->validmaxabsval || SCIPisFeasEQ(scip, consdata->maxabsval, REALABS(vals[0])) || !SCIPvarIsIntegral(vars[nvars - 1]));
    11484
    11485 /* free temporary memory */
    11486 SCIPfreeBufferArray(scip, &perm);
    11487
    11488 /* only check constraints with at least two non continuous variables */
    11489 if( !SCIPvarIsIntegral(vars[1]) )
    11490 return SCIP_OKAY;
    11491
    11492 /* do not process constraints when all coefficients are 1.0 */
    11493 if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) && ((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs))) )
    11494 return SCIP_OKAY;
    11495
    11496 feastol = SCIPfeastol(scip);
    11497
    11498 SCIPdebugMsg(scip, "starting simplification of coefficients\n");
    11500
    11501 /* get global activities */
    11502 consdataGetGlbActivityBounds(scip, consdata, FALSE, &minact, &maxact,
    11503 &ismintight, &ismaxtight, &isminsettoinfinity, &ismaxsettoinfinity);
    11504
    11505 /* cannot work with infinite activities */
    11506 if( isminsettoinfinity || ismaxsettoinfinity )
    11507 return SCIP_OKAY;
    11508
    11509 assert(ismintight);
    11510 assert(ismaxtight);
    11511 assert(maxact > minact);
    11512 assert(!SCIPisInfinity(scip, -minact));
    11513 assert(!SCIPisInfinity(scip, maxact));
    11514
    11515 v = 0;
    11516 offsetv = -1;
    11517 side = haslhs ? lhs : rhs;
    11518 minactsub = minact;
    11519 maxactsub = maxact;
    11520
    11521 /* we now determine coefficients as large as the side of the constraint to retrieve a better reduction where we
    11522 * do not need to look at the large coefficients
    11523 *
    11524 * e.g. all x are binary, z are positive integer
    11525 * c1: +5x1 + 5x2 + 3x3 + 3x4 + x5 >= 5 (x5 is redundant and does not change (in-)feasibility of this constraint)
    11526 * c2: +4x1 + 4x2 + 3x3 + 3x4 + x5 >= 4 (gcd (without the coefficient of x5) after the large coefficients is 3
    11527 * c3: +30x1 + 29x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 30 (gcd (without the coefficient of x2) after the large coefficients is 7
    11528 *
    11529 * can be changed to
    11530 *
    11531 * c1: +6x1 + 6x2 + 3x3 + 3x4 >= 6 (will be changed to c1: +2x1 + 2x2 + x3 + x4 >= 2)
    11532 * c2: +6x1 + 6x2 + 3x3 + 3x4 + 3x5 >= 6 (will be changed to c2: +2x1 + 2x2 + x3 + x4 + x5 >= 2)
    11533 * c3: +28x1 + 28x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 28 (will be changed to c3: +4x1 + 4x2 + 2x3 + 2z1 + x5 + x6 <= 4)
    11534 */
    11535
    11536 /* if the minimal activity is negative and we found more than one variable with a coefficient bigger than the left
    11537 * hand side, we cannot apply the extra reduction step and need to reset v
    11538 *
    11539 * e.g. 7x1 + 7x2 - 4x3 - 4x4 >= 7 => xi = 1 for all i is not a solution, but if we would do a change on the
    11540 * coefficients due to the gcd on the "small" coefficients we would get 8x1 + 8x2 - 4x3 - 4x4 >= 8 were xi = 1
    11541 * for all i is a solution
    11542 *
    11543 * also redundancy of variables would not be correctly determined in such a case
    11544 */
    11545 if( nvars > 2 && SCIPisEQ(scip, vals[0], side) && !SCIPisNegative(scip, minactsub) )
    11546 {
    11547 v = 1;
    11548
    11549 while( v < nvars && SCIPisEQ(scip, side, vals[v]) )
    11550 {
    11551 /* if we have integer variable with "side"-coefficients but also with a lower bound greater than 0 we stop this
    11552 * extra step, which might have worked
    11553 */
    11554 if( SCIPvarGetLbGlobal(vars[v]) > 0.5 )
    11555 {
    11556 v = 0;
    11557 break;
    11558 }
    11559
    11560 ++v;
    11561 }
    11562
    11563 /* easy and quick fix: if all coefficients were equal to the side, we cannot apply further simplifications */
    11564 /* todo find numerically stable normalization conditions to scale this cons to have coefficients almost equal to 1 */
    11565 if( v == nvars )
    11566 return SCIP_OKAY;
    11567
    11568 /* cannot work with continuous variables which have a big coefficient */
    11569 if( v > 0 && !SCIPvarIsIntegral(vars[v - 1]) )
    11570 return SCIP_OKAY;
    11571
    11572 /* big negative coefficient, do not try to use the extra coefficient reduction step */
    11573 if( SCIPisEQ(scip, side, -vals[v]) )
    11574 v = 0;
    11575
    11576 /* all but one variable are processed or the next variable is continuous we cannot perform the extra coefficient
    11577 * reduction
    11578 */
    11579 if( v == nvars - 1 || !SCIPvarIsIntegral(vars[v]) )
    11580 v = 0;
    11581
    11582 if( v > 0 )
    11583 {
    11584 assert(v < nvars);
    11585
    11586 offsetv = v - 1;
    11587
    11588 for( w = 0; w < v; ++w )
    11589 {
    11590 lb = SCIPvarGetLbGlobal(vars[w]);
    11591 ub = SCIPvarGetUbGlobal(vars[w]);
    11592
    11593 assert(vals[w] > 0);
    11594
    11595 /* update residual activities */
    11596 maxactsub -= ub * vals[w];
    11597 minactsub -= lb * vals[w];
    11598 assert(maxactsub > minactsub);
    11599 }
    11600 }
    11601 }
    11602
    11603 /* find and remove redundant variables which do not interact with the (in-)feasibility of this constraint
    11604 *
    11605 * e.g. let all x are binary and y1 is continuous with bounds [-3,1] then we can reduce
    11606 *
    11607 * 15x1 + 15x2 + 7x3 + 3x4 + y1 <= 26
    11608 * to
    11609 * 15x1 + 15x2 <= 26 <=> x1 + x2 <= 1
    11610 */
    11611 if( nvars > 2 && SCIPisIntegral(scip, vals[v]) )
    11612 {
    11613 SCIP_Bool redundant = FALSE;
    11614 SCIP_Bool numericsok;
    11615 SCIP_Bool rredundant;
    11616 SCIP_Bool lredundant;
    11617
    11618 gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
    11619 assert(gcd >= 1);
    11620
    11621 if( v == 0 )
    11622 {
    11623 lb = SCIPvarGetLbGlobal(vars[0]);
    11624 ub = SCIPvarGetUbGlobal(vars[0]);
    11625
    11626 /* update residual activities */
    11627 if( vals[0] > 0 )
    11628 {
    11629 maxactsub -= ub * vals[0];
    11630 minactsub -= lb * vals[0];
    11631 }
    11632 else
    11633 {
    11634 maxactsub -= lb * vals[0];
    11635 minactsub -= ub * vals[0];
    11636 }
    11637 assert(maxactsub > minactsub);
    11638 ++v;
    11639 }
    11640
    11641 siderest = -SCIP_INVALID;
    11642 allcoefintegral = TRUE;
    11643
    11644 /* check if some variables always fit into the given constraint */
    11645 for( ; v < nvars - 1; ++v )
    11646 {
    11647 if( !SCIPvarIsIntegral(vars[v]) )
    11648 break;
    11649
    11650 if( !SCIPisIntegral(scip, vals[v]) )
    11651 {
    11652 allcoefintegral = FALSE;
    11653 break;
    11654 }
    11655
    11656 /* calculate greatest common divisor for all general and binary variables */
    11657 gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
    11658
    11659 if( gcd == 1 )
    11660 break;
    11661
    11662 lb = SCIPvarGetLbGlobal(vars[v]);
    11663 ub = SCIPvarGetUbGlobal(vars[v]);
    11664
    11665 assert(!SCIPisInfinity(scip, -lb));
    11666 assert(!SCIPisInfinity(scip, ub));
    11667
    11668 /* update residual activities */
    11669 if( vals[v] > 0 )
    11670 {
    11671 maxactsub -= ub * vals[v];
    11672 minactsub -= lb * vals[v];
    11673 }
    11674 else
    11675 {
    11676 maxactsub -= lb * vals[v];
    11677 minactsub -= ub * vals[v];
    11678 }
    11679 assert(SCIPisGE(scip, maxactsub, minactsub));
    11680
    11681 if( hasrhs )
    11682 {
    11683 /* determine the remainder of the right hand side and the gcd */
    11684 siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
    11685 }
    11686 else
    11687 {
    11688 /* determine the remainder of the left hand side and the gcd */
    11689 siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
    11690 if( SCIPisZero(scip, siderest) )
    11691 siderest = gcd;
    11692 }
    11693
    11694 rredundant = hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd);
    11695 lredundant = haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd;
    11696
    11697 /* early termination if the activities deceed the gcd */
    11698 if( offsetv == -1 && (rredundant || lredundant) )
    11699 {
    11700 redundant = TRUE;
    11701 break;
    11702 }
    11703 }
    11704 assert(v < nvars || (offsetv >= 0 && gcd > 1));
    11705
    11706 if( !redundant )
    11707 {
    11708 if( hasrhs )
    11709 {
    11710 /* determine the remainder of the right hand side and the gcd */
    11711 siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
    11712 }
    11713 else
    11714 {
    11715 /* determine the remainder of the left hand side and the gcd */
    11716 siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
    11717 if( SCIPisZero(scip, siderest) )
    11718 siderest = gcd;
    11719 }
    11720 }
    11721 else
    11722 ++v;
    11723
    11724 SCIPdebugMsg(scip, "stopped at pos %d (of %d), subactivities [%g, %g], redundant = %u, hasrhs = %u, siderest = %g, gcd = %" SCIP_LONGINT_FORMAT ", offset position for 'side' coefficients = %d\n",
    11725 v, nvars, minactsub, maxactsub, redundant, hasrhs, siderest, gcd, offsetv);
    11726
    11727 /* to avoid inconsistencies due to numerics, check that the full and partial activities have
    11728 * reasonable absolute values */
    11729 numericsok = REALABS(maxact) < MAXACTVAL && REALABS(maxactsub) < MAXACTVAL && REALABS(minact) < MAXACTVAL &&
    11730 REALABS(minactsub) < MAXACTVAL;
    11731
    11732 rredundant = hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd);
    11733 lredundant = haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd;
    11734
    11735 /* check if we can remove redundant variables */
    11736 if( v < nvars && numericsok && (redundant || (offsetv == -1 && (rredundant || lredundant))) )
    11737 {
    11738 SCIP_Real oldcoef;
    11739
    11740 /* double check the redundancy */
    11741#ifndef NDEBUG
    11742 SCIP_Real tmpminactsub = 0.0;
    11743 SCIP_Real tmpmaxactsub = 0.0;
    11744
    11745 /* recompute residual activities */
    11746 for( w = v; w < nvars; ++w )
    11747 {
    11748 lb = SCIPvarGetLbGlobal(vars[w]);
    11749 ub = SCIPvarGetUbGlobal(vars[w]);
    11750
    11751 assert(!SCIPisInfinity(scip, -lb));
    11752 assert(!SCIPisInfinity(scip, ub));
    11753
    11754 /* update residual activities */
    11755 if( vals[w] > 0 )
    11756 {
    11757 tmpmaxactsub += ub * vals[w];
    11758 tmpminactsub += lb * vals[w];
    11759 }
    11760 else
    11761 {
    11762 tmpmaxactsub += lb * vals[w];
    11763 tmpminactsub += ub * vals[w];
    11764 }
    11765 assert(tmpmaxactsub >= tmpminactsub);
    11766 }
    11767
    11768 if( hasrhs )
    11769 {
    11770 assert(offsetv == -1);
    11771
    11772 /* determine the remainder of the right hand side and the gcd */
    11773 siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
    11774 }
    11775 else
    11776 {
    11777 /* determine the remainder of the left hand side and the gcd */
    11778 siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
    11779 if( SCIPisZero(scip, siderest) )
    11780 siderest = gcd;
    11781 }
    11782
    11783 /* is the redundancy really fulfilled */
    11784 assert((hasrhs && SCIPisFeasLE(scip, tmpmaxactsub, siderest) && tmpminactsub > siderest - gcd) ||
    11785 (haslhs && tmpmaxactsub < siderest && SCIPisFeasGE(scip, tmpminactsub, siderest - gcd)));
    11786#endif
    11787
    11788 SCIPdebugMsg(scip, "removing %d last variables from constraint <%s>, because they never change anything on the feasibility of this constraint\n",
    11789 nvars - v, SCIPconsGetName(cons));
    11790
    11791 /* remove redundant variables */
    11792 for( w = nvars - 1; w >= v; --w )
    11793 {
    11794 SCIP_CALL( delCoefPos(scip, cons, w) );
    11795 }
    11796 (*nchgcoefs) += (nvars - v);
    11797
    11798 assert(w >= 0);
    11799
    11800 oldcoef = vals[w];
    11801
    11802 SCIP_CALL( normalizeCons(scip, cons, infeasible) );
    11803 assert(vars == consdata->vars);
    11804 assert(vals == consdata->vals);
    11805 assert(w < consdata->nvars);
    11806
    11807 if( *infeasible )
    11808 return SCIP_OKAY;
    11809
    11810 /* compute new greatest common divisor due to normalization */
    11811 gcd = (SCIP_Longint)(gcd / (oldcoef/vals[w]) + feastol);
    11812 assert(gcd >= 1);
    11813
    11814 /* update side */
    11815 if( hasrhs )
    11816 {
    11817 /* replace old with new right hand side */
    11818 SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
    11819 rhs = consdata->rhs;
    11820 }
    11821 else
    11822 {
    11823 if( SCIPisFeasGT(scip, oldcoef/vals[w], 1.0) )
    11824 {
    11825 SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
    11826 lhs = consdata->lhs;
    11827 }
    11828 else
    11829 assert(offsetv == -1 || SCIPisEQ(scip, vals[offsetv], consdata->lhs));
    11830 }
    11831 ++(*nchgsides);
    11832
    11833 assert(!hasrhs || !SCIPisNegative(scip, rhs));
    11834 assert(!haslhs || !SCIPisNegative(scip, lhs));
    11835
    11836 /* get new constraint data */
    11837 nvars = consdata->nvars;
    11838 assert(nvars > 0);
    11839
    11840 allcoefintegral = TRUE;
    11841
    11842#ifndef NDEBUG
    11843 /* check integrality */
    11844 for( w = offsetv + 1; w < nvars; ++w )
    11845 {
    11846 assert(SCIPisIntegral(scip, vals[w]));
    11847 }
    11848#endif
    11850 }
    11851
    11852 /* try to find a better gcd, when having large coefficients */
    11853 if( offsetv >= 0 && gcd == 1 )
    11854 {
    11855 /* calculate greatest common divisor for all general variables */
    11856 gcd = (SCIP_Longint)(REALABS(vals[nvars - 1]) + feastol);
    11857
    11858 if( gcd > 1 )
    11859 {
    11860 gcd = -1;
    11861 candpos = -1;
    11862
    11863 for( v = nvars - 1; v > offsetv; --v )
    11864 {
    11865 assert(!SCIPisZero(scip, vals[v]));
    11866 if( !SCIPvarIsIntegral(vars[v]) )
    11867 break;
    11868
    11869 if( !SCIPisIntegral(scip, vals[v]) )
    11870 {
    11871 allcoefintegral = FALSE;
    11872 break;
    11873 }
    11874
    11875 oldgcd = gcd;
    11876
    11877 if( gcd == -1 )
    11878 {
    11879 gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
    11880 assert(gcd >= 1);
    11881 }
    11882 else
    11883 {
    11884 /* calculate greatest common divisor for all general and binary variables */
    11885 gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
    11886 }
    11887
    11888 /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
    11889 * can stop searching
    11890 */
    11891 if( gcd == 1 )
    11892 {
    11893 if( !SCIPvarIsBinary(vars[v]) )
    11894 break;
    11895
    11896 /* found candidate */
    11897 if( candpos == -1 )
    11898 {
    11899 gcd = oldgcd;
    11900 candpos = v;
    11901 }
    11902 /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
    11903 else
    11904 break;
    11905 }
    11906 }
    11907 assert(v > offsetv || candpos > offsetv);
    11908 }
    11909 else
    11910 candpos = -1;
    11911 }
    11912 else
    11913 candpos = nvars - 1;
    11914
    11915 /* check last coefficient for integrality */
    11916 if( gcd > 1 && allcoefintegral && !redundant )
    11917 {
    11918 if( !SCIPisIntegral(scip, vals[nvars - 1]) )
    11919 allcoefintegral = FALSE;
    11920 }
    11921
    11922 /* check for further necessary coefficient adjustments */
    11923 if( offsetv >= 0 && gcd > 1 && allcoefintegral )
    11924 {
    11925 assert(offsetv + 1 < nvars);
    11926 assert(0 <= candpos && candpos < nvars);
    11927
    11928 if( SCIPvarIsIntegral(vars[candpos]) )
    11929 {
    11930 SCIP_Bool notchangable = FALSE;
    11931
    11932#ifndef NDEBUG
    11933 /* check integrality */
    11934 for( w = offsetv + 1; w < nvars; ++w )
    11935 {
    11936 assert(SCIPisIntegral(scip, vals[w]));
    11937 }
    11938#endif
    11939
    11940 if( vals[candpos] > 0 && SCIPvarIsBinary(vars[candpos]) &&
    11941 SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) < gcd )
    11942 {
    11943 /* determine the remainder of the side and the gcd */
    11944 if( hasrhs )
    11945 rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
    11946 else
    11947 rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
    11948 assert(rest >= 0);
    11949 assert(rest < gcd);
    11950
    11951 /* determine the remainder of the coefficient candidate and the gcd */
    11952 restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
    11953 assert(restcoef >= 1);
    11954 assert(restcoef < gcd);
    11955
    11956 if( hasrhs )
    11957 {
    11958 /* calculate new coefficient */
    11959 if( restcoef > rest )
    11960 newcoef = vals[candpos] - restcoef + gcd;
    11961 else
    11962 newcoef = vals[candpos] - restcoef;
    11963 }
    11964 else
    11965 {
    11966 /* calculate new coefficient */
    11967 if( rest == 0 || restcoef < rest )
    11968 newcoef = vals[candpos] - restcoef;
    11969 else
    11970 newcoef = vals[candpos] - restcoef + gcd;
    11971 }
    11972
    11973 /* done */
    11974
    11975 /* new coeffcient must not be zero if we would loose the implication that a variable needs to be 0 if
    11976 * another with the big coefficient was set to 1
    11977 */
    11978 if( hasrhs && SCIPisZero(scip, newcoef) )
    11979 {
    11980 notchangable = TRUE;
    11981 }
    11982 else if( SCIPisZero(scip, newcoef) )
    11983 {
    11984 /* delete old redundant coefficient */
    11985 SCIP_CALL( delCoefPos(scip, cons, candpos) );
    11986 ++(*nchgcoefs);
    11987 }
    11988 else
    11989 {
    11990 /* replace old with new coefficient */
    11991 SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
    11992 ++(*nchgcoefs);
    11993 }
    11994 }
    11995 else if( vals[candpos] < 0 || !SCIPvarIsBinary(vars[candpos]) )
    11996 {
    11997 gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol));
    11998 }
    11999
    12000 /* correct side and big coefficients */
    12001 if( (!notchangable && hasrhs && ((!SCIPisFeasIntegral(scip, rhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(rhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd))) ||
    12002 ( haslhs && (!SCIPisFeasIntegral(scip, lhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(lhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd)) )
    12003 {
    12004 if( haslhs )
    12005 {
    12006 newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasCeil(scip, lhs/gcd) * gcd + feastol));
    12007
    12008 SCIP_CALL( chgLhs(scip, cons, newcoef) );
    12009 ++(*nchgsides);
    12010 }
    12011 else
    12012 {
    12013 assert(hasrhs);
    12014 newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasFloor(scip, rhs/gcd) * gcd + feastol));
    12015
    12016 SCIP_CALL( chgRhs(scip, cons, newcoef) );
    12017 ++(*nchgsides);
    12018 }
    12019
    12020 /* correct coefficients up front */
    12021 for( w = offsetv; w >= 0; --w )
    12022 {
    12023 assert(vals[w] > 0);
    12024
    12025 SCIP_CALL( chgCoefPos(scip, cons, w, newcoef) );
    12026 }
    12027 (*nchgcoefs) += (offsetv + 1);
    12028 }
    12029
    12030 if( !notchangable )
    12031 {
    12032 SCIP_CALL( normalizeCons(scip, cons, infeasible) );
    12033 assert(vars == consdata->vars);
    12034 assert(vals == consdata->vals);
    12035
    12036 if( *infeasible )
    12037 return SCIP_OKAY;
    12038
    12039 /* get new constraint data */
    12040 nvars = consdata->nvars;
    12041 assert(nvars >= 2);
    12042
    12044
    12045 lhs = consdata->lhs;
    12046 rhs = consdata->rhs;
    12047 assert(!hasrhs || !SCIPisNegative(scip, rhs));
    12048 assert(!haslhs || !SCIPisNegative(scip, lhs));
    12049 }
    12050 }
    12051 }
    12052 }
    12053
    12054 /* @todo we still can remove continuous variables if they are redundant due to the non-integrality argument */
    12055 /* no continuous variables are left over */
    12056 if( !SCIPvarIsIntegral(vars[nvars - 1]) )
    12057 return SCIP_OKAY;
    12058
    12059 onlybin = TRUE;
    12060 allcoefintegral = TRUE;
    12061 /* check if all variables are of binary type */
    12062 for( v = nvars - 1; v >= 0; --v )
    12063 {
    12064 if( !SCIPvarIsBinary(vars[v]) )
    12065 onlybin = FALSE;
    12066 if( !SCIPisIntegral(scip, vals[v]) )
    12067 allcoefintegral = FALSE;
    12068 }
    12069
    12070 /* check if the non-integrality part of all integral variables is smaller than the non-inegrality part of the right
    12071 * hand side or bigger than the left hand side respectively, so we can make all of them integral
    12072 *
    12073 * @todo there are some steps missing ....
    12074 */
    12075 if( (hasrhs && !SCIPisFeasIntegral(scip, rhs)) || (haslhs && !SCIPisFeasIntegral(scip, lhs)) )
    12076 {
    12077 SCIP_Real val;
    12078 SCIP_Real newval;
    12079 SCIP_Real frac = 0.0;
    12080 SCIP_Bool found = FALSE;
    12081
    12082 if( hasrhs )
    12083 {
    12084 if( allcoefintegral )
    12085 {
    12086 /* replace old with new right hand side */
    12087 SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
    12088 ++(*nchgsides);
    12089 }
    12090 else
    12091 {
    12092 siderest = rhs - SCIPfloor(scip, rhs);
    12093
    12094 /* try to round down all non-integral coefficients */
    12095 for( v = nvars - 1; v >= 0; --v )
    12096 {
    12097 val = vals[v];
    12098
    12099 /* add up all possible fractional parts */
    12100 if( !SCIPisIntegral(scip, val) )
    12101 {
    12102 lb = SCIPvarGetLbGlobal(vars[v]);
    12103 ub = SCIPvarGetUbGlobal(vars[v]);
    12104
    12105 /* at least one bound need to be at zero */
    12106 if( !onlybin && !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
    12107 return SCIP_OKAY;
    12108
    12109 /* swap bounds for 'standard' form */
    12110 if( !SCIPisFeasZero(scip, lb) )
    12111 {
    12112 ub = -lb;
    12113 val *= -1;
    12114 }
    12115
    12116 found = TRUE;
    12117
    12118 frac += (val - SCIPfloor(scip, val)) * ub;
    12119
    12120 /* if we exceed the fractional part of the right hand side, we cannot tighten the coefficients
    12121 *
    12122 * e.g. 1.1x1 + 1.1x2 + 1.4x3 + 1.02x4 <= 2.4, here we cannot floor all fractionals because
    12123 * x3, x4 set to 1 would be infeasible but feasible after flooring
    12124 */
    12125 if( SCIPisGT(scip, frac, siderest) )
    12126 return SCIP_OKAY;
    12127 }
    12128 }
    12129 assert(v == -1);
    12130
    12131 SCIPdebugMsg(scip, "rounding all non-integral coefficients and the right hand side down\n");
    12132
    12133 /* round rhs and coefficients to integral values */
    12134 if( found )
    12135 {
    12136 for( v = nvars - 1; v >= 0; --v )
    12137 {
    12138 val = vals[v];
    12139
    12140 /* add the whole fractional part */
    12141 if( !SCIPisIntegral(scip, val) )
    12142 {
    12143 lb = SCIPvarGetLbGlobal(vars[v]);
    12144
    12145 if( SCIPisFeasZero(scip, lb) )
    12146 newval = SCIPfloor(scip, val);
    12147 else
    12148 newval = SCIPceil(scip, val);
    12149
    12150 if( SCIPisZero(scip, newval) )
    12151 {
    12152 /* delete old redundant coefficient */
    12153 SCIP_CALL( delCoefPos(scip, cons, v) );
    12154 ++(*nchgcoefs);
    12155 }
    12156 else
    12157 {
    12158 /* replace old with new coefficient */
    12159 SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
    12160 ++(*nchgcoefs);
    12161 }
    12162 }
    12163 }
    12164 }
    12165
    12166 /* replace old with new right hand side */
    12167 SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
    12168 ++(*nchgsides);
    12169 }
    12170 }
    12171 else
    12172 {
    12173 if( allcoefintegral )
    12174 {
    12175 /* replace old with new left hand side */
    12176 SCIP_CALL( chgLhs(scip, cons, SCIPceil(scip, lhs)) );
    12177 ++(*nchgsides);
    12178 }
    12179 else
    12180 {
    12181 /* cannot floor left hand side to zero */
    12182 if( SCIPisLT(scip, lhs, 1.0) )
    12183 return SCIP_OKAY;
    12184
    12185 siderest = lhs - SCIPfloor(scip, lhs);
    12186
    12187 /* try to round down all non-integral coefficients */
    12188 for( v = nvars - 1; v >= 0; --v )
    12189 {
    12190 val = vals[v];
    12191
    12192 /* add up all possible fractional parts */
    12193 if( !SCIPisIntegral(scip, val) )
    12194 {
    12195 lb = SCIPvarGetLbGlobal(vars[v]);
    12196 ub = SCIPvarGetUbGlobal(vars[v]);
    12197
    12198 /* at least one bound need to be at zero */
    12199 if( !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
    12200 return SCIP_OKAY;
    12201
    12202 /* swap bounds for 'standard' form */
    12203 if( !SCIPisFeasZero(scip, lb) )
    12204 {
    12205 ub = -lb;
    12206 val *= -1;
    12207 }
    12208
    12209 /* cannot floor to zero */
    12210 if( SCIPisLT(scip, val, 1.0) )
    12211 return SCIP_OKAY;
    12212
    12213 /* the fractional part on each variable need to exceed the fractional part on the left hand side */
    12214 if( SCIPisLT(scip, val - SCIPfloor(scip, val), siderest) )
    12215 return SCIP_OKAY;
    12216
    12217 found = TRUE;
    12218
    12219 frac += (val - SCIPfloor(scip, val)) * ub;
    12220
    12221 /* if we exceed the fractional part of the left hand side plus one by summing up all maximal
    12222 * fractional parts of the variables, we cannot tighten the coefficients
    12223 *
    12224 * e.g. 4.3x1 + 1.3x2 + 1.3x3 + 1.6x4 >= 4.2, here we cannot floor all fractionals because
    12225 * x2-x4 set to 1 would be feasible but not after flooring
    12226 */
    12227 if( SCIPisGE(scip, frac, 1 + siderest) )
    12228 return SCIP_OKAY;
    12229 }
    12230 /* all coefficients need to be integral, otherwise we might do an invalid reduction */
    12231 else
    12232 return SCIP_OKAY;
    12233 }
    12234 assert(v == -1);
    12235
    12236 SCIPdebugMsg(scip, "rounding all non-integral coefficients and the left hand side down\n");
    12237
    12238 /* round lhs and coefficients to integral values */
    12239 if( found )
    12240 {
    12241 for( v = nvars - 1; v >= 0; --v )
    12242 {
    12243 val = vals[v];
    12244
    12245 /* add the whole fractional part */
    12246 if( !SCIPisIntegral(scip, val) )
    12247 {
    12248 lb = SCIPvarGetLbGlobal(vars[v]);
    12249
    12250 if( SCIPisFeasZero(scip, lb) )
    12251 newval = SCIPfloor(scip, val);
    12252 else
    12253 newval = SCIPceil(scip, val);
    12254
    12255 if( SCIPisZero(scip, newval) )
    12256 {
    12257 /* delete old redundant coefficient */
    12258 SCIP_CALL( delCoefPos(scip, cons, v) );
    12259 ++(*nchgcoefs);
    12260 }
    12261 else
    12262 {
    12263 /* replace old with new coefficient */
    12264 SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
    12265 ++(*nchgcoefs);
    12266 }
    12267 }
    12268 }
    12269 }
    12270
    12271 /* replace old with new left hand side */
    12272 SCIP_CALL( chgLhs(scip, cons, SCIPfloor(scip, lhs)) );
    12273 ++(*nchgsides);
    12274 }
    12275 }
    12276
    12277 SCIP_CALL( normalizeCons(scip, cons, infeasible) );
    12278 assert(vars == consdata->vars);
    12279 assert(vals == consdata->vals);
    12280
    12281 if( *infeasible )
    12282 return SCIP_OKAY;
    12283
    12284 rhs = consdata->rhs;
    12285 lhs = consdata->lhs;
    12286
    12287 assert(!hasrhs || !SCIPisNegative(scip, rhs));
    12288 assert(!haslhs || !SCIPisNegative(scip, lhs));
    12289
    12291
    12292 nvars = consdata->nvars;
    12293 if( nvars < 2 )
    12294 return SCIP_OKAY;
    12295
    12296 allcoefintegral = TRUE;
    12297#ifndef NDEBUG
    12298 /* debug check if all coefficients are really integral */
    12299 for( v = nvars - 1; v >= 0; --v )
    12300 assert(SCIPisIntegral(scip, vals[v]));
    12301#endif
    12302 }
    12303
    12304 /* @todo following can also work on non integral coefficients, need more investigation */
    12305 /* only check constraints with integral coefficients on all integral variables */
    12306 if( !allcoefintegral )
    12307 return SCIP_OKAY;
    12308
    12309 /* we want to avoid numerical troubles, therefore we do not change non-integral sides */
    12310 if( (hasrhs && !SCIPisIntegral(scip, rhs)) || (haslhs && !SCIPisIntegral(scip, lhs)) )
    12311 return SCIP_OKAY;
    12312
    12313 /* maximal absolute value of coefficients in constraint is one, so we cannot tighten it further */
    12314 if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) )
    12315 return SCIP_OKAY;
    12316
    12317 /* stop if the last coeffcients is one in absolute value and the variable is not binary */
    12318 if( !SCIPvarIsBinary(vars[nvars - 1]) && SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) )
    12319 return SCIP_OKAY;
    12320
    12321 assert(nvars >= 2);
    12322
    12323 /* start gcd procedure for all variables */
    12324 do
    12325 {
    12326 SCIPdebug( oldnchgcoefs = *nchgcoefs; )
    12327 SCIPdebug( oldnchgsides = *nchgsides; )
    12328
    12329 /* stop if we have two coeffcients which are one in absolute value */
    12330 if( SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) && SCIPisEQ(scip, REALABS(vals[nvars - 2]), 1.0) )
    12331 return SCIP_OKAY;
    12332
    12333 gcd = -1;
    12334
    12335 /* calculate greatest common divisor over all integer variables; note that the onlybin flag needs to be recomputed
    12336 * because coefficients of non-binary variables might have changed to zero */
    12337 if( !onlybin )
    12338 {
    12339 foundbin = -1;
    12340 onlybin = TRUE;
    12341
    12342 for( v = nvars - 1; v >= 0; --v )
    12343 {
    12344 assert(!SCIPisZero(scip, vals[v]));
    12345 assert(SCIPvarIsIntegral(vars[v]));
    12346
    12347 if( SCIPvarIsBinary(vars[v]) )
    12348 {
    12349 if( foundbin == -1 )
    12350 foundbin = v;
    12351 continue;
    12352 }
    12353 else
    12354 onlybin = FALSE;
    12355
    12356 absval = REALABS(vals[v]);
    12357 /* arithmetic precision can lead to the absolute value only being integral up to feasibility tolerance,
    12358 * even though the value itself is feasible up to epsilon, but since we add feastol later, this is enough
    12359 */
    12360 assert(SCIPisFeasIntegral(scip, absval));
    12361
    12362 if( gcd == -1 )
    12363 {
    12364 gcd = (SCIP_Longint)(absval + feastol);
    12365 assert(gcd >= 1);
    12366 }
    12367 else
    12368 {
    12369 /* calculate greatest common divisor for all general variables */
    12370 gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(absval + feastol));
    12371 }
    12372 if( gcd == 1 )
    12373 break;
    12374 }
    12375 }
    12376 else
    12377 foundbin = nvars - 1;
    12378
    12379 /* we need at least one binary variable and a gcd greater than 1 to try to perform further coefficient changes */
    12380 if( gcd == 1 || foundbin == -1)
    12381 return SCIP_OKAY;
    12382
    12383 assert((onlybin && gcd == -1) || (!onlybin && gcd > 1));
    12384
    12385 candpos = -1;
    12386 candpos2 = -1;
    12387
    12388 /* calculate greatest common divisor over all integer and binary variables and determine the candidate where we might
    12389 * change the coefficient
    12390 */
    12391 for( v = foundbin; v >= 0; --v )
    12392 {
    12393 if( onlybin || SCIPvarIsBinary(vars[v]) )
    12394 {
    12395 absval = REALABS(vals[v]);
    12396 /* arithmetic precision can lead to the absolute value only being integral up to feasibility tolerance,
    12397 * even though the value itself is feasible up to epsilon, but since we add feastol later, this is enough
    12398 */
    12399 assert(SCIPisFeasIntegral(scip, absval));
    12400
    12401 oldgcd = gcd;
    12402
    12403 if( gcd == -1 )
    12404 {
    12405 gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
    12406 assert(gcd >= 1);
    12407 }
    12408 else
    12409 {
    12410 /* calculate greatest common divisor for all general and binary variables */
    12411 gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
    12412 }
    12413
    12414 /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
    12415 * can terminate
    12416 */
    12417 if( gcd == 1 )
    12418 {
    12419 /* found candidate */
    12420 if( candpos == -1 )
    12421 {
    12422 gcd = oldgcd;
    12423 candpos = v;
    12424
    12425 /* if we have only binary variables and both first coefficients have a gcd of 1, both are candidates for
    12426 * the coefficient change
    12427 */
    12428 if( onlybin && v == foundbin - 1 )
    12429 candpos2 = foundbin;
    12430 }
    12431 /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
    12432 else
    12433 {
    12434 if( onlybin && candpos == v + 1 && candpos2 == v + 2 )
    12435 {
    12436 assert(candpos2 == nvars - 1);
    12437
    12438 /* take new candidates */
    12439 candpos = candpos2;
    12440
    12441 /* recalculate gcd from scratch */
    12442 gcd = (SCIP_Longint)(REALABS(vals[v+1]) + feastol);
    12443 assert(gcd >= 1);
    12444
    12445 /* calculate greatest common divisor for all general and binary variables */
    12446 gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
    12447 if( gcd == 1 )
    12448 return SCIP_OKAY;
    12449 }
    12450 else
    12451 /* cannot determine a possible coefficient for reduction */
    12452 return SCIP_OKAY;
    12453 }
    12454 }
    12455 }
    12456 }
    12457 assert(gcd >= 2);
    12458
    12459 /* we should have found one coefficient, that led to a gcd of 1, otherwise we could normalize the constraint
    12460 * further
    12461 */
    12462 assert(candpos >= 0 && candpos < nvars);
    12463
    12464 /* all variables and all coefficients are integral, so the side should be too */
    12465 assert((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs)));
    12466
    12467 /* check again, if we have a normalized inequality (not ranged) the one side should be positive,
    12468 * @see normalizeCons()
    12469 */
    12470 assert(!hasrhs || !SCIPisNegative(scip, rhs));
    12471 assert(!haslhs || !SCIPisNegative(scip, lhs));
    12472
    12473 /* determine the remainder of the side and the gcd */
    12474 if( hasrhs )
    12475 rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
    12476 else
    12477 rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
    12478 assert(rest >= 0);
    12479 assert(rest < gcd);
    12480
    12481 /* determine the remainder of the coefficient candidate and the gcd */
    12482 if( vals[candpos] < 0 )
    12483 {
    12484 restcoef = ((SCIP_Longint)(vals[candpos] - feastol)) % gcd;
    12485 assert(restcoef <= -1);
    12486 restcoef += gcd;
    12487 }
    12488 else
    12489 restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
    12490 assert(restcoef >= 1);
    12491 assert(restcoef < gcd);
    12492
    12493 if( hasrhs )
    12494 {
    12495 if( rest > 0 )
    12496 {
    12497 /* replace old with new right hand side */
    12498 SCIP_CALL( chgRhs(scip, cons, rhs - rest) );
    12499 ++(*nchgsides);
    12500 }
    12501
    12502 /* calculate new coefficient */
    12503 if( restcoef > rest )
    12504 newcoef = vals[candpos] - restcoef + gcd;
    12505 else
    12506 newcoef = vals[candpos] - restcoef;
    12507 }
    12508 else
    12509 {
    12510 if( rest > 0 )
    12511 {
    12512 /* replace old with new left hand side */
    12513 SCIP_CALL( chgLhs(scip, cons, lhs - rest + gcd) );
    12514 ++(*nchgsides);
    12515 }
    12516
    12517 /* calculate new coefficient */
    12518 if( rest == 0 || restcoef < rest )
    12519 newcoef = vals[candpos] - restcoef;
    12520 else
    12521 newcoef = vals[candpos] - restcoef + gcd;
    12522 }
    12523 assert(SCIPisZero(scip, newcoef) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(newcoef) + feastol)) == gcd);
    12524
    12525 SCIPdebugMsg(scip, "gcd = %" SCIP_LONGINT_FORMAT ", rest = %" SCIP_LONGINT_FORMAT ", restcoef = %" SCIP_LONGINT_FORMAT "; changing coef of variable <%s> to %g and %s by %" SCIP_LONGINT_FORMAT "\n", gcd, rest, restcoef, SCIPvarGetName(vars[candpos]), newcoef, hasrhs ? "reduced rhs" : "increased lhs", hasrhs ? rest : (rest > 0 ? gcd - rest : 0));
    12526
    12527 if( SCIPisZero(scip, newcoef) )
    12528 {
    12529 /* delete redundant coefficient */
    12530 SCIP_CALL( delCoefPos(scip, cons, candpos) );
    12531 }
    12532 else
    12533 {
    12534 /* replace old with new coefficient */
    12535 SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
    12536 }
    12537 ++(*nchgcoefs);
    12538
    12539 /* now constraint can be normalized, might be directly done by dividing it by the gcd */
    12540 SCIP_CALL( normalizeCons(scip, cons, infeasible) );
    12541 assert(vars == consdata->vars);
    12542 assert(vals == consdata->vals);
    12543
    12544 if( *infeasible )
    12545 return SCIP_OKAY;
    12546
    12548
    12549 rhs = consdata->rhs;
    12550 lhs = consdata->lhs;
    12551 assert(!hasrhs || !SCIPisNegative(scip, rhs));
    12552 assert(!haslhs || !SCIPisNegative(scip, lhs));
    12553
    12554 nvars = consdata->nvars;
    12555
    12556 SCIPdebugMsg(scip, "we did %d coefficient changes and %d side changes on constraint %s when applying one round of the gcd algorithm\n", *nchgcoefs - oldnchgcoefs, *nchgsides - oldnchgsides, SCIPconsGetName(cons));
    12557 }
    12558 while( nvars >= 2 );
    12559
    12560 return SCIP_OKAY;
    12561}
    12562
    12563
    12564/** tries to aggregate an (in)equality and an equality in order to decrease the number of variables in the (in)equality:
    12565 * cons0 := a * cons0 + b * cons1,
    12566 * where a = val1[v] and b = -val0[v] for common variable v which removes most variable weight;
    12567 * for numerical stability, we will only accept integral a and b;
    12568 * the variable weight is a weighted sum over all included variables, where each binary variable weighs BINWEIGHT,
    12569 * each integer or implied integral variable weighs INTWEIGHT and each continuous variable weighs CONTWEIGHT
    12570 */
    12571static
    12573 SCIP* scip, /**< SCIP data structure */
    12574 SCIP_CONS* cons0, /**< (in)equality to modify */
    12575 SCIP_CONS* cons1, /**< equality to use for aggregation of cons0 */
    12576 int* commonidx0, /**< array with indices of variables in cons0, that appear also in cons1 */
    12577 int* commonidx1, /**< array with indices of variables in cons1, that appear also in cons0 */
    12578 int* diffidx0minus1, /**< array with indices of variables in cons0, that don't appear in cons1 */
    12579 int* diffidx1minus0, /**< array with indices of variables in cons1, that don't appear in cons0 */
    12580 int nvarscommon, /**< number of variables, that appear in both constraints */
    12581 int commonidxweight, /**< variable weight sum of common variables */
    12582 int diffidx0minus1weight, /**< variable weight sum of variables in cons0, that don't appear in cons1 */
    12583 int diffidx1minus0weight, /**< variable weight sum of variables in cons1, that don't appear in cons0 */
    12584 SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
    12585 int* nchgcoefs, /**< pointer to count the number of changed coefficients */
    12586 SCIP_Bool* aggregated, /**< pointer to store whether an aggregation was made */
    12587 SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
    12588 )
    12589{
    12590 SCIP_CONSDATA* consdata0;
    12591 SCIP_CONSDATA* consdata1;
    12592 SCIP_Real a;
    12593 SCIP_Real b;
    12594 SCIP_Real aggrcoef;
    12595 SCIP_Real scalarsum;
    12596 SCIP_Real bestscalarsum;
    12597 SCIP_Bool betterscalarsum;
    12598 SCIP_Bool commonvarlindependent; /* indicates whether coefficient vector of common variables in linearly dependent */
    12599 int varweight;
    12600 int nvars;
    12601 int bestvarweight;
    12602 int bestnvars;
    12603 int bestv;
    12604 int v;
    12605 int i;
    12606
    12607 assert(scip != NULL);
    12608 assert(cons0 != NULL);
    12609 assert(cons1 != NULL);
    12610 assert(commonidx0 != NULL);
    12611 assert(commonidx1 != NULL);
    12612 assert(diffidx0minus1 != NULL);
    12613 assert(diffidx1minus0 != NULL);
    12614 assert(nvarscommon >= 1);
    12615 assert(commonidxweight >= nvarscommon);
    12616 assert(nchgcoefs != NULL);
    12617 assert(aggregated != NULL);
    12618
    12619 assert(SCIPconsIsActive(cons0));
    12620 assert(SCIPconsIsActive(cons1));
    12621
    12622 *infeasible = FALSE;
    12623
    12624 SCIPdebugMsg(scip, "try aggregation of <%s> and <%s>\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    12625
    12626 /* cons0 is an (in)equality */
    12627 consdata0 = SCIPconsGetData(cons0);
    12628 assert(consdata0 != NULL);
    12629 assert(consdata0->nvars >= 1);
    12630 assert(SCIPisLE(scip, consdata0->lhs, consdata0->rhs));
    12631 assert(diffidx0minus1weight >= consdata0->nvars - nvarscommon);
    12632
    12633 /* cons1 is an equality */
    12634 consdata1 = SCIPconsGetData(cons1);
    12635 assert(consdata1 != NULL);
    12636 assert(consdata1->nvars >= 1);
    12637 assert(SCIPisEQ(scip, consdata1->lhs, consdata1->rhs));
    12638 assert(diffidx1minus0weight >= consdata1->nvars - nvarscommon);
    12639
    12640 *aggregated = FALSE;
    12641
    12642 /* search for the best common variable such that
    12643 * val1[var] * consdata0 - val0[var] * consdata1
    12644 * has least weighted number of variables
    12645 */
    12646 bestvarweight = commonidxweight + diffidx0minus1weight;
    12647 bestnvars = consdata0->nvars;
    12648 bestv = -1;
    12649 bestscalarsum = 0.0;
    12650 commonvarlindependent = TRUE;
    12651 for( v = 0; v < nvarscommon; ++v )
    12652 {
    12653 assert(consdata0->vars[commonidx0[v]] == consdata1->vars[commonidx1[v]]);
    12654 a = consdata1->vals[commonidx1[v]];
    12655 b = -consdata0->vals[commonidx0[v]];
    12656
    12657 /* only try aggregation, if coefficients are integral (numerical stability) */
    12659 {
    12660 /* count the number of variables in the potential new constraint a * consdata0 + b * consdata1 */
    12661 varweight = diffidx0minus1weight + diffidx1minus0weight;
    12662 nvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
    12663 scalarsum = REALABS(a) + REALABS(b);
    12664 betterscalarsum = (scalarsum < bestscalarsum);
    12665 for( i = 0; i < nvarscommon
    12666 && (varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum)); ++i )
    12667 {
    12668 aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
    12669 if( !SCIPisZero(scip, aggrcoef) )
    12670 {
    12671 varweight += getVarWeight(consdata0->vars[commonidx0[i]]);
    12672 nvars++;
    12673 }
    12674 }
    12675 if( varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum) )
    12676 {
    12677 bestv = v;
    12678 bestvarweight = varweight;
    12679 bestnvars = nvars;
    12680 bestscalarsum = scalarsum;
    12681 }
    12682 }
    12683
    12684 /* update commonvarlindependent flag, if still TRUE:
    12685 * v's common coefficient in cons1 / v's common coefficient in cons0 should be constant, i.e., equal 0's common coefficient in cons1 / 0's common coefficient in cons0
    12686 */
    12687 if( commonvarlindependent && v > 0 )
    12688 commonvarlindependent = SCIPisEQ(scip,
    12689 consdata1->vals[commonidx1[v]] * consdata0->vals[commonidx0[0]],
    12690 consdata1->vals[commonidx1[0]] * consdata0->vals[commonidx0[v]]);
    12691 }
    12692
    12693 /* if better aggregation was found, create new constraint and delete old one */
    12694 if( (bestv != -1 || commonvarlindependent) && SCIPconsGetNUpgradeLocks(cons0) == 0 )
    12695 {
    12696 SCIP_CONS* newcons;
    12697 SCIP_CONSDATA* newconsdata;
    12698 SCIP_VAR** newvars;
    12699 SCIP_Real* newvals;
    12700 SCIP_Real newlhs;
    12701 SCIP_Real newrhs;
    12702 int newnvars;
    12703
    12704 if( bestv != -1 )
    12705 {
    12706 /* choose multipliers such that the multiplier for the (in)equality cons0 is positive */
    12707 if( consdata1->vals[commonidx1[bestv]] > 0.0 )
    12708 {
    12709 a = consdata1->vals[commonidx1[bestv]];
    12710 b = -consdata0->vals[commonidx0[bestv]];
    12711 }
    12712 else
    12713 {
    12714 a = -consdata1->vals[commonidx1[bestv]];
    12715 b = consdata0->vals[commonidx0[bestv]];
    12716 }
    12717 assert(SCIPisIntegral(scip, a));
    12718 assert(SCIPisPositive(scip, a));
    12719 assert(SCIPisIntegral(scip, b));
    12720 assert(!SCIPisZero(scip, b));
    12721 }
    12722 else
    12723 {
    12724 assert(commonvarlindependent);
    12725 if( consdata1->vals[commonidx1[0]] > 0.0 )
    12726 {
    12727 a = consdata1->vals[commonidx1[0]];
    12728 b = -consdata0->vals[commonidx0[0]];
    12729 }
    12730 else
    12731 {
    12732 a = -consdata1->vals[commonidx1[0]];
    12733 b = consdata0->vals[commonidx0[0]];
    12734 }
    12735 assert(SCIPisPositive(scip, a));
    12736 assert(!SCIPisZero(scip, b));
    12737
    12738 /* if a/b is integral, then we can easily choose integer multipliers */
    12739 if( SCIPisIntegral(scip, a/b) )
    12740 {
    12741 if( a/b > 0 )
    12742 {
    12743 a /= b;
    12744 b = 1.0;
    12745 }
    12746 else
    12747 {
    12748 a /= -b;
    12749 b = -1.0;
    12750 }
    12751 }
    12752
    12753 /* setup best* variables that were not setup above because we are in the commonvarlindependent case */
    12754 SCIPdebug( bestvarweight = diffidx0minus1weight + diffidx1minus0weight; )
    12755 bestnvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
    12756 }
    12757
    12758 SCIPdebugMsg(scip, "aggregate linear constraints <%s> := %.15g*<%s> + %.15g*<%s> -> nvars: %d -> %d, weight: %d -> %d\n",
    12759 SCIPconsGetName(cons0), a, SCIPconsGetName(cons0), b, SCIPconsGetName(cons1),
    12760 consdata0->nvars, bestnvars, commonidxweight + diffidx0minus1weight, bestvarweight);
    12761 SCIPdebugPrintCons(scip, cons0, NULL);
    12762 SCIPdebugPrintCons(scip, cons1, NULL);
    12763
    12764 /* get temporary memory for creating the new linear constraint */
    12765 SCIP_CALL( SCIPallocBufferArray(scip, &newvars, bestnvars) );
    12766 SCIP_CALL( SCIPallocBufferArray(scip, &newvals, bestnvars) );
    12767
    12768 /* calculate the common coefficients, if we have not recognized linear dependency */
    12769 newnvars = 0;
    12770 if( !commonvarlindependent )
    12771 {
    12772 for( i = 0; i < nvarscommon; ++i )
    12773 {
    12774 assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
    12775 assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
    12776
    12777 aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
    12778 if( !SCIPisZero(scip, aggrcoef) )
    12779 {
    12780 assert(newnvars < bestnvars);
    12781 newvars[newnvars] = consdata0->vars[commonidx0[i]];
    12782 newvals[newnvars] = aggrcoef;
    12783 newnvars++;
    12784 }
    12785 }
    12786 }
    12787 else
    12788 {
    12789 /* if we recognized linear dependency of the common coefficients, then the aggregation coefficient should be 0.0 for every common variable */
    12790#ifndef NDEBUG
    12791 for( i = 0; i < nvarscommon; ++i )
    12792 {
    12793 assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
    12794 assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
    12795
    12796 aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
    12797 assert(SCIPisZero(scip, aggrcoef));
    12798 }
    12799#endif
    12800 }
    12801
    12802 /* calculate the coefficients appearing in cons0 but not in cons1 */
    12803 for( i = 0; i < consdata0->nvars - nvarscommon; ++i )
    12804 {
    12805 assert(0 <= diffidx0minus1[i] && diffidx0minus1[i] < consdata0->nvars);
    12806
    12807 aggrcoef = a * consdata0->vals[diffidx0minus1[i]];
    12808 assert(!SCIPisZero(scip, aggrcoef));
    12809 assert(newnvars < bestnvars);
    12810 newvars[newnvars] = consdata0->vars[diffidx0minus1[i]];
    12811 newvals[newnvars] = aggrcoef;
    12812 newnvars++;
    12813 }
    12814
    12815 /* calculate the coefficients appearing in cons1 but not in cons0 */
    12816 for( i = 0; i < consdata1->nvars - nvarscommon; ++i )
    12817 {
    12818 assert(0 <= diffidx1minus0[i] && diffidx1minus0[i] < consdata1->nvars);
    12819
    12820 aggrcoef = b * consdata1->vals[diffidx1minus0[i]];
    12821 assert(!SCIPisZero(scip, aggrcoef));
    12822 assert(newnvars < bestnvars);
    12823 newvars[newnvars] = consdata1->vars[diffidx1minus0[i]];
    12824 newvals[newnvars] = aggrcoef;
    12825 newnvars++;
    12826 }
    12827 assert(newnvars == bestnvars);
    12828
    12829 /* calculate the new left and right hand side of the (in)equality */
    12830 assert(!SCIPisInfinity(scip, -consdata1->lhs));
    12831 assert(!SCIPisInfinity(scip, consdata1->rhs));
    12832 if( SCIPisInfinity(scip, -consdata0->lhs) )
    12833 newlhs = -SCIPinfinity(scip);
    12834 else
    12835 newlhs = a * consdata0->lhs + b * consdata1->lhs;
    12836 if( SCIPisInfinity(scip, consdata0->rhs) )
    12837 newrhs = SCIPinfinity(scip);
    12838 else
    12839 newrhs = a * consdata0->rhs + b * consdata1->rhs;
    12840
    12841 /* create the new linear constraint */
    12842 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, SCIPconsGetName(cons0), newnvars, newvars, newvals, newlhs, newrhs,
    12847
    12848 newconsdata = SCIPconsGetData(newcons);
    12849 assert(newconsdata != NULL);
    12850
    12851 /* copy the upgraded flag from the old cons0 to the new constraint */
    12852 newconsdata->upgraded = consdata0->upgraded;
    12853
    12854 SCIP_CALL( normalizeCons(scip, newcons, infeasible) );
    12855
    12856 /* check, if we really want to use the new constraint instead of the old one:
    12857 * use the new one, if the maximum norm doesn't grow too much
    12858 */
    12859 if( !(*infeasible) && consdataGetMaxAbsval(SCIPconsGetData(newcons)) <= maxaggrnormscale * consdataGetMaxAbsval(consdata0) )
    12860 {
    12861 SCIPdebugMsg(scip, " -> aggregated to <%s>\n", SCIPconsGetName(newcons));
    12862 SCIPdebugPrintCons(scip, newcons, NULL);
    12863
    12864 /* update the statistics: we changed all coefficients */
    12865 if( !consdata0->upgraded )
    12866 (*nchgcoefs) += consdata0->nvars + consdata1->nvars - nvarscommon;
    12867 *aggregated = TRUE;
    12868
    12869 /* add the new linear constraint to the problem and delete the old constraint */
    12870 SCIP_CALL( SCIPaddConsUpgrade(scip, cons0, &newcons) );
    12871 SCIP_CALL( SCIPdelCons(scip, cons0) );
    12872 }
    12873 else
    12874 {
    12875 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    12876 }
    12877
    12878 /* free temporary memory */
    12879 SCIPfreeBufferArray(scip, &newvals);
    12880 SCIPfreeBufferArray(scip, &newvars);
    12881 }
    12882
    12883 return SCIP_OKAY;
    12884}
    12885
    12886/** gets the key of the given element */
    12887static
    12888SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
    12889{ /*lint --e{715}*/
    12890 /* the key is the element itself */
    12891 return elem;
    12892}
    12893
    12894/** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables and the
    12895 * coefficients are either equal or negated
    12896 */
    12897static
    12898SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
    12899{
    12900 SCIP* scip;
    12901 SCIP_CONSDATA* consdata1;
    12902 SCIP_CONSDATA* consdata2;
    12903 SCIP_Real minscale;
    12904 SCIP_Real maxscale;
    12905 int i;
    12906
    12907 assert(key1 != NULL);
    12908 assert(key2 != NULL);
    12909 consdata1 = SCIPconsGetData((SCIP_CONS*)key1);
    12910 consdata2 = SCIPconsGetData((SCIP_CONS*)key2);
    12911 assert(consdata1->indexsorted);
    12912 assert(consdata2->indexsorted);
    12913
    12914 scip = (SCIP*)userptr;
    12915 assert(scip != NULL);
    12916
    12917 /* if it is the same constraint we dont need to check anything */
    12918 if( key1 == key2 )
    12919 return TRUE;
    12920
    12921 /* checks trivial case */
    12922 if( consdata1->nvars != consdata2->nvars )
    12923 return FALSE;
    12924
    12925 /* tests if variables are equal */
    12926 for( i = 0; i < consdata1->nvars; ++i )
    12927 {
    12928 if( consdata1->vars[i] != consdata2->vars[i] )
    12929 {
    12930 assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 1 ||
    12931 SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == -1);
    12932 return FALSE;
    12933 }
    12934 assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 0);
    12935 }
    12936
    12937 /* order by maxabsval */
    12938 if( consdataGetMaxAbsval(consdata1) > consdataGetMaxAbsval(consdata2) )
    12939 SCIPswapPointers((void**)&consdata1, (void**)&consdata2);
    12940
    12941 /* initialize extremal scales */
    12942 minscale = SCIPinfinity(scip);
    12943 maxscale = -SCIPinfinity(scip);
    12944
    12945 /* test if coefficient scales are equal */
    12946 for( i = 0; i < consdata1->nvars; ++i )
    12947 {
    12948 SCIP_Real scale = consdata2->vals[i] / consdata1->vals[i];
    12949
    12950 if( minscale > scale )
    12951 {
    12952 minscale = scale;
    12953
    12954 if( SCIPisLT(scip, minscale, maxscale) )
    12955 return FALSE;
    12956 }
    12957
    12958 if( maxscale < scale )
    12959 {
    12960 maxscale = scale;
    12961
    12962 if( SCIPisLT(scip, minscale, maxscale) )
    12963 return FALSE;
    12964 }
    12965 }
    12966
    12967 return TRUE;
    12968}
    12969
    12970/** returns the hash value of the key */
    12971static
    12972SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
    12973{
    12974 SCIP_CONSDATA* consdata;
    12975 int minidx;
    12976 int mididx;
    12977 int maxidx;
    12978#ifndef NDEBUG
    12979 SCIP* scip;
    12980
    12981 scip = (SCIP*)userptr;
    12982 assert(scip != NULL);
    12983#endif
    12984
    12985 assert(key != NULL);
    12986 consdata = SCIPconsGetData((SCIP_CONS*)key);
    12987 assert(consdata != NULL);
    12988 assert(consdata->nvars > 0);
    12989
    12990 assert(consdata->indexsorted);
    12991
    12992 minidx = SCIPvarGetIndex(consdata->vars[0]);
    12993 mididx = SCIPvarGetIndex(consdata->vars[consdata->nvars / 2]);
    12994 maxidx = SCIPvarGetIndex(consdata->vars[consdata->nvars - 1]);
    12995
    12996 /* using only the variable indices as hash, since the values are compared by epsilon */
    12997 return SCIPhashFour(consdata->nvars, minidx, mididx, maxidx);
    12998}
    12999
    13000/** returns the key for deciding which of two parallel constraints should be kept (smaller key should be kept);
    13001 * prefers non-upgraded constraints and as second criterion the constraint with the smallest position
    13002 */
    13003static
    13005 SCIP_CONS* cons /**< linear constraint */
    13006 )
    13007{
    13008 SCIP_CONSDATA* consdata;
    13009
    13010 assert(cons != NULL);
    13011
    13012 consdata = SCIPconsGetData(cons);
    13013 assert(consdata != NULL);
    13014
    13015 return (((unsigned int)consdata->upgraded)<<31) + (unsigned int)SCIPconsGetPos(cons); /*lint !e571*/
    13016}
    13017
    13018/** updates the hashtable such that out of all constraints in the hashtable that are detected
    13019 * to be parallel to *querycons, only one is kept in the hashtable and stored into *querycons,
    13020 * and all others are removed from the hashtable and stored in the given array
    13021 */
    13022static
    13024 SCIP_HASHTABLE* hashtable, /**< hashtable containing linear constraints */
    13025 SCIP_CONS** querycons, /**< pointer to linear constraint used to look for duplicates in the hash table;
    13026 * upon return will contain the constraint that should be kept */
    13027 SCIP_CONS** parallelconss, /**< array to return constraints that are parallel to the given;
    13028 * these constraints where removed from the hashtable */
    13029 int* nparallelconss /**< pointer to return number of parallel constraints */
    13030 )
    13031{
    13032 SCIP_CONS* parallelcons;
    13033 unsigned int querykey;
    13034
    13035 *nparallelconss = 0;
    13036 querykey = getParallelConsKey(*querycons);
    13037
    13038 while( (parallelcons = (SCIP_CONS*)SCIPhashtableRetrieve(hashtable, (void*)(*querycons))) != NULL )
    13039 {
    13040 unsigned int conskey = getParallelConsKey(parallelcons);
    13041
    13042 if( conskey < querykey )
    13043 {
    13044 parallelconss[(*nparallelconss)++] = *querycons;
    13045 *querycons = parallelcons;
    13046 querykey = conskey;
    13047 }
    13048 else
    13049 {
    13050 parallelconss[(*nparallelconss)++] = parallelcons;
    13051 }
    13052
    13053 /* if the constraint that just came out of the hash table is the one that is kept,
    13054 * we do not need to look into the hashtable again, since the invariant is that
    13055 * in the hashtable only pair-wise non-parallel constraints are contained.
    13056 * For the original querycons, however, multiple constraints that compare equal (=parallel)
    13057 * could be contained due to non-transitivity of the equality comparison.
    13058 * Also we can return immediately, since parallelcons is already contained in the
    13059 * hashtable and we do not need to remove and reinsert it.
    13060 */
    13061 if( *querycons == parallelcons )
    13062 return SCIP_OKAY;
    13063
    13064 /* remove parallelcons from the hashtable, since it will be replaced by querycons */
    13065 SCIP_CALL( SCIPhashtableRemove(hashtable, (void*) parallelcons) );
    13066 }
    13067
    13068 /* in debug mode we make sure, that the hashtable cannot contain a constraint that
    13069 * comnpares equal to querycons at this point
    13070 */
    13071#ifndef NDEBUG
    13072 SCIP_CALL_ABORT( SCIPhashtableSafeInsert(hashtable, *querycons) );
    13073#else
    13074 SCIP_CALL( SCIPhashtableInsert(hashtable, *querycons) );
    13075#endif
    13076
    13077 return SCIP_OKAY;
    13078}
    13079
    13080/** compares each constraint with all other constraints for possible redundancy and removes or changes constraint
    13081 * accordingly; in contrast to preprocessConstraintPairs(), it uses a hash table
    13082 */
    13083static
    13085 SCIP* scip, /**< SCIP data structure */
    13086 BMS_BLKMEM* blkmem, /**< block memory */
    13087 SCIP_CONS** conss, /**< constraint set */
    13088 int nconss, /**< number of constraints in constraint set */
    13089 int* firstchange, /**< pointer to store first changed constraint */
    13090 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    13091 int* ndelconss, /**< pointer to count number of deleted constraints */
    13092 int* nchgsides /**< pointer to count number of changed left/right hand sides */
    13093 )
    13094{
    13095 SCIP_HASHTABLE* hashtable;
    13096 SCIP_CONS** parallelconss;
    13097 int nparallelconss;
    13098 int hashtablesize;
    13099 int c;
    13100
    13101 assert(scip != NULL);
    13102 assert(blkmem != NULL);
    13103 assert(conss != NULL);
    13104 assert(firstchange != NULL);
    13105 assert(cutoff != NULL);
    13106 assert(ndelconss != NULL);
    13107 assert(nchgsides != NULL);
    13108
    13109 /* create a hash table for the constraint set */
    13110 hashtablesize = nconss;
    13111 SCIP_CALL( SCIPhashtableCreate(&hashtable, blkmem, hashtablesize,
    13112 hashGetKeyLinearcons, hashKeyEqLinearcons, hashKeyValLinearcons, (void*) scip) );
    13113
    13114 SCIP_CALL( SCIPallocBufferArray(scip, &parallelconss, nconss) );
    13115
    13116 /* check all constraints in the given set for redundancy */
    13117 for( c = 0; c < nconss; ++c )
    13118 {
    13119 SCIP_CONS* cons0;
    13120 SCIP_CONSDATA* consdata0;
    13121
    13122 cons0 = conss[c];
    13123
    13124 if( !SCIPconsIsActive(cons0) || SCIPconsIsModifiable(cons0) )
    13125 continue;
    13126
    13127 /* do not check for parallel constraints if they should not be upgraded */
    13128 if ( SCIPconsGetNUpgradeLocks(cons0) > 0 )
    13129 continue;
    13130
    13131 /* check for interuption */
    13132 if( c % 1000 == 0 && SCIPisStopped(scip) )
    13133 break;
    13134
    13135 /* sorts the constraint */
    13136 consdata0 = SCIPconsGetData(cons0);
    13137 assert(consdata0 != NULL);
    13138 SCIP_CALL( consdataSort(scip, consdata0) );
    13139 assert(consdata0->indexsorted);
    13140
    13141 /* get constraints from current hash table with same variables as cons0 and with coefficients equal
    13142 * to the ones of cons0 when both are scaled such that maxabsval is 1.0 and the coefficient of the
    13143 * first variable is positive
    13144 * Also inserts cons0 into the hashtable.
    13145 */
    13146 SCIP_CALL( retrieveParallelConstraints(hashtable, &cons0, parallelconss, &nparallelconss) );
    13147
    13148 if( nparallelconss != 0 )
    13149 {
    13150 SCIP_Real lhs;
    13151 SCIP_Real rhs;
    13152
    13153 int i;
    13154
    13155 /* cons0 may have been changed in retrieveParallelConstraints() */
    13156 consdata0 = SCIPconsGetData(cons0);
    13157
    13158 lhs = consdata0->lhs;
    13159 rhs = consdata0->rhs;
    13160
    13161 for( i = 0; i < nparallelconss; ++i )
    13162 {
    13163 SCIP_CONS* consdel;
    13164 SCIP_CONSDATA* consdatadel;
    13165 SCIP_Real scale;
    13166
    13167 consdel = parallelconss[i];
    13168 consdatadel = SCIPconsGetData(consdel);
    13169
    13170 /* do not delete constraint if it should not be upgraded */
    13171 if ( SCIPconsGetNUpgradeLocks(consdel) > 0 )
    13172 continue;
    13173
    13174 assert(SCIPconsIsActive(consdel));
    13175 assert(!SCIPconsIsModifiable(consdel));
    13176
    13177 /* constraint found: create a new constraint with same coefficients and best left and right hand side;
    13178 * delete old constraints afterwards
    13179 */
    13180 assert(consdatadel != NULL);
    13181 assert(consdata0->nvars >= 1 && consdata0->nvars == consdatadel->nvars);
    13182
    13183 assert(consdatadel->indexsorted);
    13184 assert(consdata0->vars[0] == consdatadel->vars[0]);
    13185
    13186 scale = consdata0->vals[0] / consdatadel->vals[0];
    13187 assert(scale != 0.0);
    13188
    13189 /* in debug mode, check that all coefficients are equal with respect to epsilon
    13190 * if the constraints are in equilibrium scale
    13191 */
    13192#ifndef NDEBUG
    13193 {
    13194 assert(consdata0->validmaxabsval);
    13195 assert(consdatadel->validmaxabsval);
    13196 int k;
    13197 SCIP_Real scale0 = 1.0 / consdata0->maxabsval;
    13198 SCIP_Real scaledel = COPYSIGN(1.0 / consdatadel->maxabsval, scale);
    13199
    13200 for( k = 0; k < consdata0->nvars; ++k )
    13201 {
    13202 assert(SCIPisEQ(scip, scale0 * consdata0->vals[k], scaledel * consdatadel->vals[k]));
    13203 }
    13204 }
    13205#endif
    13206
    13207 if( scale > 0.0 )
    13208 {
    13209 /* the coefficients of both constraints are parallel with a positive scale */
    13210 SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with equal coefficients into single ranged row\n",
    13211 SCIPconsGetName(cons0), SCIPconsGetName(consdel));
    13212 SCIPdebugPrintCons(scip, cons0, NULL);
    13213 SCIPdebugPrintCons(scip, consdel, NULL);
    13214
    13215 if( ! SCIPisInfinity(scip, -consdatadel->lhs) )
    13216 lhs = MAX(scale * consdatadel->lhs, lhs);
    13217
    13218 if( ! SCIPisInfinity(scip, consdatadel->rhs) )
    13219 rhs = MIN(scale * consdatadel->rhs, rhs);
    13220 }
    13221 else
    13222 {
    13223 /* the coefficients of both rows are negations */
    13224 SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with negated coefficients into single ranged row\n",
    13225 SCIPconsGetName(cons0), SCIPconsGetName(consdel));
    13226 SCIPdebugPrintCons(scip, cons0, NULL);
    13227 SCIPdebugPrintCons(scip, consdel, NULL);
    13228
    13229 if( ! SCIPisInfinity(scip, consdatadel->rhs) )
    13230 lhs = MAX(scale * consdatadel->rhs, lhs);
    13231
    13232 if( ! SCIPisInfinity(scip, -consdatadel->lhs) )
    13233 rhs = MIN(scale * consdatadel->lhs, rhs);
    13234 }
    13235
    13236 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    13237 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, consdel) );
    13238
    13239 /* delete consdel */
    13240 assert( ! consdata0->upgraded || consdatadel->upgraded );
    13241 SCIP_CALL( SCIPdelCons(scip, consdel) );
    13242 if( !consdatadel->upgraded )
    13243 (*ndelconss)++;
    13244 }
    13245
    13246 if( SCIPisFeasLT(scip, rhs, lhs) )
    13247 {
    13248 SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
    13249 *cutoff = TRUE;
    13250 break;
    13251 }
    13252
    13253 /* ensure that lhs <= rhs holds without tolerances as we only allow such rows to enter the LP */
    13254 if( lhs > rhs )
    13255 {
    13256 rhs = (lhs + rhs)/2;
    13257 lhs = rhs;
    13258 }
    13259
    13260 /* update lhs and rhs of cons0 */
    13261 SCIP_CALL( chgLhs(scip, cons0, lhs) );
    13262 SCIP_CALL( chgRhs(scip, cons0, rhs) );
    13263
    13264 /* update the first changed constraint to begin the next aggregation round with */
    13265 if( consdata0->changed && SCIPconsGetPos(cons0) < *firstchange )
    13266 *firstchange = SCIPconsGetPos(cons0);
    13267
    13268 assert(SCIPconsIsActive(cons0));
    13269 }
    13270 }
    13271#ifdef SCIP_MORE_DEBUG
    13272 SCIPinfoMessage(scip, NULL, "linear pairwise comparison hashtable statistics:\n");
    13274#endif
    13275
    13276 SCIPfreeBufferArray(scip, &parallelconss);
    13277
    13278 /* free hash table */
    13279 SCIPhashtableFree(&hashtable);
    13280
    13281 return SCIP_OKAY;
    13282}
    13283
    13284/** compares constraint with all prior constraints for possible redundancy or aggregation,
    13285 * and removes or changes constraint accordingly
    13286 */
    13287static
    13289 SCIP* scip, /**< SCIP data structure */
    13290 SCIP_CONS** conss, /**< constraint set */
    13291 int firstchange, /**< first constraint that changed since last pair preprocessing round */
    13292 int chkind, /**< index of constraint to check against all prior indices upto startind */
    13293 SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
    13294 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    13295 int* ndelconss, /**< pointer to count number of deleted constraints */
    13296 int* nchgsides, /**< pointer to count number of changed left/right hand sides */
    13297 int* nchgcoefs /**< pointer to count number of changed coefficients */
    13298 )
    13299{
    13300 SCIP_CONS* cons0;
    13301 SCIP_CONSDATA* consdata0;
    13302 int* commonidx0;
    13303 int* commonidx1;
    13304 int* diffidx0minus1;
    13305 int* diffidx1minus0;
    13306 uint64_t possignature0;
    13307 uint64_t negsignature0;
    13308 SCIP_Bool cons0changed;
    13309 SCIP_Bool cons0isequality;
    13310 int diffidx1minus0size;
    13311 int c;
    13312 SCIP_Real cons0lhs;
    13313 SCIP_Real cons0rhs;
    13314 SCIP_Bool cons0upgraded;
    13315
    13316 assert(scip != NULL);
    13317 assert(conss != NULL);
    13318 assert(firstchange <= chkind);
    13319 assert(cutoff != NULL);
    13320 assert(ndelconss != NULL);
    13321 assert(nchgsides != NULL);
    13322 assert(nchgcoefs != NULL);
    13323
    13324 /* get the constraint to be checked against all prior constraints */
    13325 cons0 = conss[chkind];
    13326 assert(cons0 != NULL);
    13327 assert(SCIPconsIsActive(cons0));
    13328 assert(!SCIPconsIsModifiable(cons0));
    13329
    13330 consdata0 = SCIPconsGetData(cons0);
    13331 assert(consdata0 != NULL);
    13332 assert(consdata0->nvars >= 1);
    13333 cons0isequality = SCIPisEQ(scip, consdata0->lhs, consdata0->rhs);
    13334
    13335 /* sort the constraint */
    13336 SCIP_CALL( consdataSort(scip, consdata0) );
    13337
    13338 /* calculate bit signatures of cons0 for potentially positive and negative coefficients */
    13339 consdataCalcSignatures(consdata0);
    13340 possignature0 = consdata0->possignature;
    13341 negsignature0 = consdata0->negsignature;
    13342
    13343 /* get temporary memory for indices of common variables */
    13344 SCIP_CALL( SCIPallocBufferArray(scip, &commonidx0, consdata0->nvars) );
    13345 SCIP_CALL( SCIPallocBufferArray(scip, &commonidx1, consdata0->nvars) );
    13346 SCIP_CALL( SCIPallocBufferArray(scip, &diffidx0minus1, consdata0->nvars) );
    13347 SCIP_CALL( SCIPallocBufferArray(scip, &diffidx1minus0, consdata0->nvars) );
    13348 diffidx1minus0size = consdata0->nvars;
    13349
    13350 cons0lhs = consdata0->lhs;
    13351 cons0rhs = consdata0->rhs;
    13352 cons0upgraded = consdata0->upgraded;
    13353
    13354 /* check constraint against all prior constraints */
    13355 cons0changed = consdata0->changed;
    13356 consdata0->changed = FALSE;
    13357 for( c = (cons0changed ? 0 : firstchange); c < chkind && !(*cutoff) && conss[chkind] != NULL; ++c )
    13358 {
    13359 SCIP_CONS* cons1;
    13360 SCIP_CONSDATA* consdata1;
    13361 uint64_t possignature1;
    13362 uint64_t negsignature1;
    13363 SCIP_Bool cons0dominateslhs;
    13364 SCIP_Bool cons1dominateslhs;
    13365 SCIP_Bool cons0dominatesrhs;
    13366 SCIP_Bool cons1dominatesrhs;
    13367 SCIP_Bool cons1isequality;
    13368 SCIP_Bool coefsequal;
    13369 SCIP_Bool coefsnegated;
    13370 SCIP_Bool tryaggregation;
    13371 int nvarscommon;
    13372 int nvars0minus1;
    13373 int nvars1minus0;
    13374 int commonidxweight;
    13375 int diffidx0minus1weight;
    13376 int diffidx1minus0weight;
    13377 int v0;
    13378 int v1;
    13379
    13380 assert(cons0lhs == consdata0->lhs); /*lint !e777*/
    13381 assert(cons0rhs == consdata0->rhs); /*lint !e777*/
    13382 assert(cons0upgraded == consdata0->upgraded);
    13383
    13384 cons1 = conss[c];
    13385
    13386 /* cons1 has become inactive during presolving of constraint pairs */
    13387 if( cons1 == NULL )
    13388 continue;
    13389
    13390 assert(SCIPconsIsActive(cons0) && !SCIPconsIsModifiable(cons0));
    13391 assert(SCIPconsIsActive(cons1) && !SCIPconsIsModifiable(cons1));
    13392
    13393 consdata1 = SCIPconsGetData(cons1);
    13394 assert(consdata1 != NULL);
    13395
    13396 /* SCIPdebugMsg(scip, "preprocess linear constraint pair <%s>[chgd:%d, upgd:%d] and <%s>[chgd:%d, upgd:%d]\n",
    13397 SCIPconsGetName(cons0), cons0changed, cons0upgraded,
    13398 SCIPconsGetName(cons1), consdata1->changed, consdata1->upgraded); */
    13399
    13400 /* if both constraints didn't change since last pair processing, we can ignore the pair */
    13401 if( !cons0changed && !consdata1->changed )
    13402 continue;
    13403
    13404 /* if both constraints are already upgraded, skip the pair;
    13405 * because changes on these constraints cannot be applied to the instance anymore */
    13406 if( cons0upgraded && consdata1->upgraded )
    13407 continue;
    13408
    13409 assert(consdata1->nvars >= 1);
    13410
    13411 /* sort the constraint */
    13412 SCIP_CALL( consdataSort(scip, consdata1) );
    13413
    13414 /* calculate bit signatures of cons1 for potentially positive and negative coefficients */
    13415 consdataCalcSignatures(consdata1);
    13416 possignature1 = consdata1->possignature;
    13417 negsignature1 = consdata1->negsignature;
    13418
    13419 /* the signatures give a quick test to check for domination and equality of coefficients */
    13420 coefsequal = (possignature0 == possignature1) && (negsignature0 == negsignature1);
    13421 coefsnegated = (possignature0 == negsignature1) && (negsignature0 == possignature1);
    13422 cons0dominateslhs = SCIPisGE(scip, cons0lhs, consdata1->lhs)
    13423 && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
    13424 && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
    13425 cons1dominateslhs = SCIPisGE(scip, consdata1->lhs, cons0lhs)
    13426 && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
    13427 && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
    13428 cons0dominatesrhs = SCIPisLE(scip, cons0rhs, consdata1->rhs)
    13429 && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
    13430 && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
    13431 cons1dominatesrhs = SCIPisLE(scip, consdata1->rhs, cons0rhs)
    13432 && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
    13433 && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
    13434 cons1isequality = SCIPisEQ(scip, consdata1->lhs, consdata1->rhs);
    13435 tryaggregation = (cons0isequality || cons1isequality) && (maxaggrnormscale > 0.0);
    13436 if( !cons0dominateslhs && !cons1dominateslhs && !cons0dominatesrhs && !cons1dominatesrhs
    13437 && !coefsequal && !coefsnegated && !tryaggregation )
    13438 continue;
    13439
    13440 /* make sure, we have enough memory for the index set of V_1 \ V_0 */
    13441 if( tryaggregation && consdata1->nvars > diffidx1minus0size )
    13442 {
    13443 SCIP_CALL( SCIPreallocBufferArray(scip, &diffidx1minus0, consdata1->nvars) );
    13444 diffidx1minus0size = consdata1->nvars;
    13445 }
    13446
    13447 /* check consdata0 against consdata1:
    13448 * - if lhs0 >= lhs1 and for each variable v and each solution value x_v val0[v]*x_v <= val1[v]*x_v,
    13449 * consdata0 dominates consdata1 w.r.t. left hand side
    13450 * - if rhs0 <= rhs1 and for each variable v and each solution value x_v val0[v]*x_v >= val1[v]*x_v,
    13451 * consdata0 dominates consdata1 w.r.t. right hand side
    13452 * - if val0[v] == -val1[v] for all variables v, the two inequalities can be replaced by a single
    13453 * ranged row (or equality)
    13454 * - if at least one constraint is an equality, count the weighted number of common variables W_c
    13455 * and the weighted number of variable in the difference sets W_0 = w(V_0 \ V_1), W_1 = w(V_1 \ V_0),
    13456 * where the weight of each variable depends on its type, such that aggregations in order to remove the
    13457 * number of continuous and integer variables are preferred:
    13458 * - if W_c > W_1, try to aggregate consdata0 := a * consdata0 + b * consdata1 in order to decrease the
    13459 * variable weight in consdata0, where a = +/- val1[v] and b = -/+ val0[v] for common v which leads to
    13460 * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
    13461 * to be positive to not switch the sense of the (in)equality cons0
    13462 * - if W_c > W_0, try to aggregate consdata1 := a * consdata1 + b * consdata0 in order to decrease the
    13463 * variable weight in consdata1, where a = +/- val0[v] and b = -/+ val1[v] for common v which leads to
    13464 * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
    13465 * to be positive to not switch the sense of the (in)equality cons1
    13466 */
    13467
    13468 /* check consdata0 against consdata1 for redundancy, or ranged row accumulation */
    13469 nvarscommon = 0;
    13470 commonidxweight = 0;
    13471 nvars0minus1 = 0;
    13472 diffidx0minus1weight = 0;
    13473 nvars1minus0 = 0;
    13474 diffidx1minus0weight = 0;
    13475 v0 = 0;
    13476 v1 = 0;
    13477 while( (v0 < consdata0->nvars || v1 < consdata1->nvars)
    13478 && (cons0dominateslhs || cons1dominateslhs || cons0dominatesrhs || cons1dominatesrhs
    13479 || coefsequal || coefsnegated || tryaggregation) )
    13480 {
    13481 SCIP_VAR* var;
    13482 SCIP_Real val0;
    13483 SCIP_Real val1;
    13484 int varcmp;
    13485
    13486 /* test, if variable appears in only one or in both constraints */
    13487 if( v0 < consdata0->nvars && v1 < consdata1->nvars )
    13488 varcmp = SCIPvarCompare(consdata0->vars[v0], consdata1->vars[v1]);
    13489 else if( v0 < consdata0->nvars )
    13490 varcmp = -1;
    13491 else
    13492 varcmp = +1;
    13493
    13494 switch( varcmp )
    13495 {
    13496 case -1:
    13497 /* variable doesn't appear in consdata1 */
    13498 var = consdata0->vars[v0];
    13499 val0 = consdata0->vals[v0];
    13500 val1 = 0.0;
    13501 if( tryaggregation )
    13502 {
    13503 diffidx0minus1[nvars0minus1] = v0;
    13504 nvars0minus1++;
    13505 diffidx0minus1weight += getVarWeight(var);
    13506 }
    13507 v0++;
    13508 coefsequal = FALSE;
    13509 coefsnegated = FALSE;
    13510 break;
    13511
    13512 case +1:
    13513 /* variable doesn't appear in consdata0 */
    13514 var = consdata1->vars[v1];
    13515 val0 = 0.0;
    13516 val1 = consdata1->vals[v1];
    13517 if( tryaggregation )
    13518 {
    13519 diffidx1minus0[nvars1minus0] = v1;
    13520 nvars1minus0++;
    13521 diffidx1minus0weight += getVarWeight(var);
    13522 }
    13523 v1++;
    13524 coefsequal = FALSE;
    13525 coefsnegated = FALSE;
    13526 break;
    13527
    13528 case 0:
    13529 /* variable appears in both constraints */
    13530 assert(consdata0->vars[v0] == consdata1->vars[v1]);
    13531 var = consdata0->vars[v0];
    13532 val0 = consdata0->vals[v0];
    13533 val1 = consdata1->vals[v1];
    13534 if( tryaggregation )
    13535 {
    13536 commonidx0[nvarscommon] = v0;
    13537 commonidx1[nvarscommon] = v1;
    13538 nvarscommon++;
    13539 commonidxweight += getVarWeight(var);
    13540 }
    13541 v0++;
    13542 v1++;
    13543 coefsequal = coefsequal && (SCIPisEQ(scip, val0, val1));
    13544 coefsnegated = coefsnegated && (SCIPisEQ(scip, val0, -val1));
    13545 break;
    13546
    13547 default:
    13548 SCIPerrorMessage("invalid comparison result\n");
    13549 SCIPABORT();
    13550 var = NULL;
    13551 val0 = 0.0;
    13552 val1 = 0.0;
    13553 }
    13554 assert(var != NULL);
    13555
    13556 /* update domination criteria w.r.t. the coefficient and the variable's bounds */
    13557 if( SCIPisGT(scip, val0, val1) )
    13558 {
    13560 {
    13561 cons0dominatesrhs = FALSE;
    13562 cons1dominateslhs = FALSE;
    13563 }
    13565 {
    13566 cons0dominateslhs = FALSE;
    13567 cons1dominatesrhs = FALSE;
    13568 }
    13569 }
    13570 else if( SCIPisLT(scip, val0, val1) )
    13571 {
    13573 {
    13574 cons0dominateslhs = FALSE;
    13575 cons1dominatesrhs = FALSE;
    13576 }
    13578 {
    13579 cons0dominatesrhs = FALSE;
    13580 cons1dominateslhs = FALSE;
    13581 }
    13582 }
    13583 }
    13584
    13585 /* check for disaggregated ranged rows */
    13586 if( coefsequal || coefsnegated )
    13587 {
    13588 SCIP_CONS* consstay;
    13589 SCIP_CONS* consdel;
    13590#ifndef NDEBUG
    13591 SCIP_CONSDATA* consdatastay;
    13592#endif
    13593 SCIP_CONSDATA* consdatadel;
    13594 SCIP_Real lhs;
    13595 SCIP_Real rhs;
    13596 int consinddel;
    13597
    13598 /* the coefficients in both rows are either equal or negated: create a new constraint with same coefficients and
    13599 * best left and right hand sides; delete the old constraints afterwards
    13600 */
    13601 SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with %s coefficients into single ranged row\n",
    13602 SCIPconsGetName(cons0), SCIPconsGetName(cons1), coefsequal ? "equal" : "negated");
    13603 SCIPdebugPrintCons(scip, cons0, NULL);
    13604 SCIPdebugPrintCons(scip, cons1, NULL);
    13605
    13606 if( coefsequal )
    13607 {
    13608 /* the coefficients of both rows are equal */
    13609 lhs = MAX(consdata0->lhs, consdata1->lhs);
    13610 rhs = MIN(consdata0->rhs, consdata1->rhs);
    13611 }
    13612 else
    13613 {
    13614 /* the coefficients of both rows are negations */
    13615 lhs = MAX(consdata0->lhs, -consdata1->rhs);
    13616 rhs = MIN(consdata0->rhs, -consdata1->lhs);
    13617 }
    13618 if( SCIPisFeasLT(scip, rhs, lhs) )
    13619 {
    13620 SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
    13621 *cutoff = TRUE;
    13622 break;
    13623 }
    13624
    13625 /* check which constraint has to stay;
    13626 * changes applied to an upgraded constraint will not be considered in the instance */
    13627 if( consdata0->upgraded )
    13628 {
    13629 assert(!consdata1->upgraded);
    13630 consstay = cons1;
    13631#ifndef NDEBUG
    13632 consdatastay = consdata1;
    13633#endif
    13634
    13635 consdel = cons0;
    13636 consdatadel = consdata0;
    13637 consinddel = chkind;
    13638 }
    13639 else
    13640 {
    13641 consstay = cons0;
    13642#ifndef NDEBUG
    13643 consdatastay = consdata0;
    13644#endif
    13645
    13646 consdel = cons1;
    13647 consdatadel = consdata1;
    13648 consinddel = c;
    13649 }
    13650
    13651 /* update the sides of consstay */
    13652 SCIP_CALL( chgLhs(scip, consstay, lhs) );
    13653 SCIP_CALL( chgRhs(scip, consstay, rhs) );
    13654 if( !consdata0->upgraded )
    13655 {
    13656 assert(consstay == cons0);
    13657 cons0lhs = consdata0->lhs;
    13658 cons0rhs = consdata0->rhs;
    13659 }
    13660
    13661 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    13662 SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
    13663
    13664 assert( !consdatastay->upgraded );
    13665 /* delete consdel */
    13666 SCIP_CALL( SCIPdelCons(scip, consdel) );
    13667 conss[consinddel] = NULL;
    13668 if( !consdatadel->upgraded )
    13669 (*ndelconss)++;
    13670 continue;
    13671 }
    13672
    13673 /* check for domination: remove dominated sides, but don't touch equalities as long as they are not totally
    13674 * redundant
    13675 */
    13676 if( cons1dominateslhs && (!cons0isequality || cons1dominatesrhs || SCIPisInfinity(scip, consdata0->rhs) ) )
    13677 {
    13678 /* left hand side is dominated by consdata1: delete left hand side of consdata0 */
    13679 SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
    13680 SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    13681 SCIPdebugPrintCons(scip, cons0, NULL);
    13682 SCIPdebugPrintCons(scip, cons1, NULL);
    13683
    13684 /* check for infeasibility */
    13685 if( SCIPisFeasGT(scip, consdata1->lhs, consdata0->rhs) )
    13686 {
    13687 SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    13688 *cutoff = TRUE;
    13689 break;
    13690 }
    13691
    13692 /* remove redundant left hand side */
    13693 if( !SCIPisInfinity(scip, -consdata0->lhs) )
    13694 {
    13695 SCIP_CALL( chgLhs(scip, cons0, -SCIPinfinity(scip)) );
    13696 cons0lhs = consdata0->lhs;
    13697 cons0isequality = FALSE;
    13698 if( !consdata0->upgraded )
    13699 {
    13700 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    13701 SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
    13702
    13703 (*nchgsides)++;
    13704 }
    13705 }
    13706 }
    13707 else if( cons0dominateslhs && (!cons1isequality || cons0dominatesrhs || SCIPisInfinity(scip, consdata1->rhs)) )
    13708 {
    13709 /* left hand side is dominated by consdata0: delete left hand side of consdata1 */
    13710 SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
    13711 SCIPconsGetName(cons1), SCIPconsGetName(cons0));
    13712 SCIPdebugPrintCons(scip, cons1, NULL);
    13713 SCIPdebugPrintCons(scip, cons0, NULL);
    13714
    13715 /* check for infeasibility */
    13716 if( SCIPisFeasGT(scip, consdata0->lhs, consdata1->rhs) )
    13717 {
    13718 SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    13719 *cutoff = TRUE;
    13720 break;
    13721 }
    13722
    13723 /* remove redundant left hand side */
    13724 if( !SCIPisInfinity(scip, -consdata1->lhs) )
    13725 {
    13726 SCIP_CALL( chgLhs(scip, cons1, -SCIPinfinity(scip)) );
    13727 cons1isequality = FALSE;
    13728 if( !consdata1->upgraded )
    13729 {
    13730 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    13731 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
    13732
    13733 (*nchgsides)++;
    13734 }
    13735 }
    13736 }
    13737 if( cons1dominatesrhs && (!cons0isequality || cons1dominateslhs || SCIPisInfinity(scip, -consdata0->lhs)) )
    13738 {
    13739 /* right hand side is dominated by consdata1: delete right hand side of consdata0 */
    13740 SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
    13741 SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    13742 SCIPdebugPrintCons(scip, cons0, NULL);
    13743 SCIPdebugPrintCons(scip, cons1, NULL);
    13744
    13745 /* check for infeasibility */
    13746 if( SCIPisFeasLT(scip, consdata1->rhs, consdata0->lhs) )
    13747 {
    13748 SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    13749 *cutoff = TRUE;
    13750 break;
    13751 }
    13752
    13753 /* remove redundant right hand side */
    13754 if( !SCIPisInfinity(scip, consdata0->rhs) )
    13755 {
    13756 SCIP_CALL( chgRhs(scip, cons0, SCIPinfinity(scip)) );
    13757 cons0rhs = consdata0->rhs;
    13758 cons0isequality = FALSE;
    13759 if( !consdata0->upgraded )
    13760 {
    13761 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    13762 SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
    13763
    13764 (*nchgsides)++;
    13765 }
    13766 }
    13767 }
    13768 else if( cons0dominatesrhs && (!cons1isequality || cons0dominateslhs || SCIPisInfinity(scip, -consdata1->lhs)) )
    13769 {
    13770 /* right hand side is dominated by consdata0: delete right hand side of consdata1 */
    13771 SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
    13772 SCIPconsGetName(cons1), SCIPconsGetName(cons0));
    13773 SCIPdebugPrintCons(scip, cons1, NULL);
    13774 SCIPdebugPrintCons(scip, cons0, NULL);
    13775
    13776 /* check for infeasibility */
    13777 if( SCIPisFeasLT(scip, consdata0->rhs, consdata1->lhs) )
    13778 {
    13779 SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
    13780 *cutoff = TRUE;
    13781 break;
    13782 }
    13783
    13784 /* remove redundant right hand side */
    13785 if( !SCIPisInfinity(scip, consdata1->rhs) )
    13786 {
    13787 SCIP_CALL( chgRhs(scip, cons1, SCIPinfinity(scip)) );
    13788 cons1isequality = FALSE;
    13789 if( !consdata1->upgraded )
    13790 {
    13791 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    13792 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
    13793
    13794 (*nchgsides)++;
    13795 }
    13796 }
    13797 }
    13798
    13799 /* check for now redundant constraints */
    13800 if( SCIPisInfinity(scip, -consdata0->lhs) && SCIPisInfinity(scip, consdata0->rhs) )
    13801 {
    13802 /* consdata0 became redundant */
    13803 SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons0));
    13804 SCIP_CALL( SCIPdelCons(scip, cons0) );
    13805 conss[chkind] = NULL;
    13806 if( !consdata0->upgraded )
    13807 {
    13808 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    13809 SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
    13810
    13811 (*ndelconss)++;
    13812 }
    13813 continue;
    13814 }
    13815 if( SCIPisInfinity(scip, -consdata1->lhs) && SCIPisInfinity(scip, consdata1->rhs) )
    13816 {
    13817 /* consdata1 became redundant */
    13818 SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons1));
    13819 SCIP_CALL( SCIPdelCons(scip, cons1) );
    13820 conss[c] = NULL;
    13821 if( !consdata1->upgraded )
    13822 {
    13823 /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
    13824 SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
    13825
    13826 (*ndelconss)++;
    13827 }
    13828 continue;
    13829 }
    13830
    13831 /* check, if we want to aggregate an (in)equality with an equality:
    13832 * consdata0 := a * consdata0 + b * consdata1 or consdata1 := a * consdata1 + b * consdata0
    13833 */
    13834 if( tryaggregation )
    13835 {
    13836 SCIP_Bool aggregated;
    13837
    13838 assert(consdata0->nvars == nvarscommon + nvars0minus1);
    13839 assert(consdata1->nvars == nvarscommon + nvars1minus0);
    13840
    13841 aggregated = FALSE;
    13842 if( cons1isequality && !consdata0->upgraded && commonidxweight > diffidx1minus0weight )
    13843 {
    13844 /* W_c > W_1: try to aggregate consdata0 := a * consdata0 + b * consdata1 */
    13845 SCIP_CALL( aggregateConstraints(scip, cons0, cons1, commonidx0, commonidx1, diffidx0minus1, diffidx1minus0,
    13846 nvarscommon, commonidxweight, diffidx0minus1weight, diffidx1minus0weight, maxaggrnormscale,
    13847 nchgcoefs, &aggregated, cutoff) );
    13848
    13849 if( *cutoff )
    13850 break;
    13851
    13852 /* update array of active constraints */
    13853 if( aggregated )
    13854 {
    13855 assert(!SCIPconsIsActive(cons0));
    13856 assert(SCIPconsIsActive(cons1));
    13857 conss[chkind] = NULL;
    13858 }
    13859 }
    13860 if( !aggregated && cons0isequality && !consdata1->upgraded && commonidxweight > diffidx0minus1weight )
    13861 {
    13862 /* W_c > W_0: try to aggregate consdata1 := a * consdata1 + b * consdata0 */
    13863 SCIP_CALL( aggregateConstraints(scip, cons1, cons0, commonidx1, commonidx0, diffidx1minus0, diffidx0minus1,
    13864 nvarscommon, commonidxweight, diffidx1minus0weight, diffidx0minus1weight, maxaggrnormscale,
    13865 nchgcoefs, &aggregated, cutoff) );
    13866
    13867 if( *cutoff )
    13868 break;
    13869
    13870 /* update array of active constraints */
    13871 if( aggregated )
    13872 {
    13873 assert(!SCIPconsIsActive(cons1));
    13874 assert(SCIPconsIsActive(cons0));
    13875 conss[c] = NULL;
    13876 }
    13877 }
    13878 }
    13879 }
    13880
    13881 /* free temporary memory */
    13882 SCIPfreeBufferArray(scip, &diffidx1minus0);
    13883 SCIPfreeBufferArray(scip, &diffidx0minus1);
    13884 SCIPfreeBufferArray(scip, &commonidx1);
    13885 SCIPfreeBufferArray(scip, &commonidx0);
    13886
    13887 return SCIP_OKAY;
    13888}
    13889
    13890/** do stuffing presolving on a single constraint */
    13891static
    13893 SCIP* scip, /**< SCIP data structure */
    13894 SCIP_CONS* cons, /**< linear constraint */
    13895 SCIP_Bool singletonstuffing, /**< should stuffing of singleton continuous variables be performed? */
    13896 SCIP_Bool singlevarstuffing, /**< should single variable stuffing be performed, which tries to fulfill
    13897 * constraints using the cheapest variable? */
    13898 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    13899 int* nfixedvars, /**< pointer to count the total number of fixed variables */
    13900 int* nchgbds /**< pointer to count the total number of tightened bounds */
    13901 )
    13902{
    13903 SCIP_CONSDATA* consdata;
    13904 SCIP_Real* ratios;
    13905 int* varpos;
    13906 SCIP_Bool* swapped;
    13907 SCIP_VAR** vars;
    13908 SCIP_Real* vals;
    13909 SCIP_VAR* var;
    13910 SCIP_Real lb;
    13911 SCIP_Real ub;
    13912 SCIP_Real minactivity;
    13913 SCIP_Real maxactivity;
    13914 SCIP_Real maxcondactivity;
    13915 SCIP_Real mincondactivity;
    13916 SCIP_Real rhs;
    13917 SCIP_Real val;
    13918 SCIP_Real obj;
    13919 SCIP_Real factor;
    13920 SCIP_Bool isminacttight;
    13921 SCIP_Bool ismaxacttight;
    13922 SCIP_Bool isminsettoinfinity;
    13923 SCIP_Bool ismaxsettoinfinity;
    13924 SCIP_Bool tryfixing;
    13925 int nsingletons;
    13926 int idx;
    13927 int v;
    13928 int nvars;
    13929
    13930 assert(scip != NULL);
    13931 assert(cons != NULL);
    13932 assert(nfixedvars != NULL);
    13933
    13934 consdata = SCIPconsGetData(cons);
    13935
    13936 /* we only want to run for inequalities */
    13937 if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->lhs) )
    13938 return SCIP_OKAY;
    13939
    13940 if( singlevarstuffing )
    13941 {
    13942 consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &isminacttight, &ismaxacttight,
    13943 &isminsettoinfinity, &ismaxsettoinfinity);
    13944 }
    13945 else
    13946 {
    13947 minactivity = SCIP_INVALID;
    13948 maxactivity = SCIP_INVALID;
    13949 isminsettoinfinity = FALSE;
    13950 ismaxsettoinfinity = FALSE;
    13951 }
    13952
    13953 /* we want to have a <= constraint, if the rhs is infinite, we implicitly multiply the constraint by -1,
    13954 * the new maxactivity is minus the old minactivity then
    13955 */
    13956 if( SCIPisInfinity(scip, consdata->rhs) )
    13957 {
    13958 rhs = -consdata->lhs;
    13959 factor = -1.0;
    13960 maxactivity = -minactivity;
    13961 ismaxsettoinfinity = isminsettoinfinity;
    13962 }
    13963 else
    13964 {
    13965 assert(SCIPisInfinity(scip, -consdata->lhs));
    13966 rhs = consdata->rhs;
    13967 factor = 1.0;
    13968 }
    13969
    13970 nvars = consdata->nvars;
    13971 vars = consdata->vars;
    13972 vals = consdata->vals;
    13973
    13974 /* check for continuous singletons */
    13975 if( singletonstuffing )
    13976 {
    13977 for( v = 0; v < nvars; ++v )
    13978 {
    13979 var = vars[v];
    13980
    13981 if( !SCIPvarIsIntegral(var)
    13983 break;
    13984 }
    13985 }
    13986 else
    13987 /* we don't want to go into the next block */
    13988 v = nvars;
    13989
    13990 /* a singleton was found -> perform singleton variable stuffing */
    13991 if( v < nvars )
    13992 {
    13993 assert(singletonstuffing);
    13994
    13995 SCIP_CALL( SCIPallocBufferArray(scip, &varpos, nvars) );
    13996 SCIP_CALL( SCIPallocBufferArray(scip, &ratios, nvars) );
    13997 SCIP_CALL( SCIPallocBufferArray(scip, &swapped, nvars) );
    13998
    13999 tryfixing = TRUE;
    14000 nsingletons = 0;
    14001 mincondactivity = 0.0;
    14002 maxcondactivity = 0.0;
    14003
    14004 for( v = 0; v < nvars; ++v )
    14005 {
    14006 var = vars[v];
    14007 lb = SCIPvarGetLbGlobal(var);
    14008 ub = SCIPvarGetUbGlobal(var);
    14009 obj = SCIPvarGetObj(var);
    14010 val = factor * vals[v];
    14011
    14012 assert(!SCIPisZero(scip, val));
    14013
    14014 /* the variable is a singleton and continuous */
    14015 if( !SCIPvarIsIntegral(var)
    14017 {
    14018 if( SCIPisNegative(scip, obj) && val > 0 )
    14019 {
    14020 /* case 1: obj < 0 and coef > 0 */
    14021 if( SCIPisInfinity(scip, -lb) )
    14022 {
    14023 tryfixing = FALSE;
    14024 break;
    14025 }
    14026
    14027 maxcondactivity += val * lb;
    14028 mincondactivity += val * lb;
    14029 swapped[v] = FALSE;
    14030 ratios[nsingletons] = obj / val;
    14031 varpos[nsingletons] = v;
    14032 nsingletons++;
    14033 }
    14034 else if( SCIPisPositive(scip, obj) && val < 0 )
    14035 {
    14036 /* case 2: obj > 0 and coef < 0 */
    14037 if( SCIPisInfinity(scip, ub) )
    14038 {
    14039 tryfixing = FALSE;
    14040 break;
    14041 }
    14042 /* multiply column by (-1) to become case 1.
    14043 * now bounds are swapped: ub := -lb, lb := -ub
    14044 */
    14045
    14046 maxcondactivity += val * ub;
    14047 mincondactivity += val * ub;
    14048 swapped[v] = TRUE;
    14049 ratios[nsingletons] = obj / val;
    14050 varpos[nsingletons] = v;
    14051 nsingletons++;
    14052 }
    14053 else if( val > 0 )
    14054 {
    14055 /* case 3: obj >= 0 and coef >= 0 is handled by duality fixing.
    14056 * we only consider the lower bound for the constants
    14057 */
    14058 assert(!SCIPisNegative(scip, obj));
    14059
    14060 if( SCIPisInfinity(scip, -lb) )
    14061 {
    14062 /* maybe unbounded */
    14063 tryfixing = FALSE;
    14064 break;
    14065 }
    14066
    14067 maxcondactivity += val * lb;
    14068 mincondactivity += val * lb;
    14069 }
    14070 else
    14071 {
    14072 /* case 4: obj <= 0 and coef <= 0 is also handled by duality fixing.
    14073 * we only consider the upper bound for the constants
    14074 */
    14075 assert(!SCIPisPositive(scip, obj));
    14076 assert(val < 0);
    14077
    14078 if( SCIPisInfinity(scip, ub) )
    14079 {
    14080 /* maybe unbounded */
    14081 tryfixing = FALSE;
    14082 break;
    14083 }
    14084
    14085 maxcondactivity += val * ub;
    14086 mincondactivity += val * ub;
    14087 }
    14088 }
    14089 else
    14090 {
    14091 /* consider contribution of discrete variables, non-singleton
    14092 * continuous variables and variables with more than one lock
    14093 */
    14094 if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
    14095 {
    14096 tryfixing = FALSE;
    14097 break;
    14098 }
    14099
    14100 if( val > 0 )
    14101 {
    14102 maxcondactivity += val * ub;
    14103 mincondactivity += val * lb;
    14104 }
    14105 else
    14106 {
    14107 maxcondactivity += val * lb;
    14108 mincondactivity += val * ub;
    14109 }
    14110 }
    14111 }
    14112 if( tryfixing && nsingletons > 0 && (SCIPisGT(scip, rhs, maxcondactivity) || SCIPisLE(scip, rhs, mincondactivity)) )
    14113 {
    14114 SCIP_Real delta;
    14115 SCIP_Bool tightened;
    14116#ifdef SCIP_DEBUG
    14117 int oldnfixedvars = *nfixedvars;
    14118#endif
    14119
    14120 SCIPsortRealInt(ratios, varpos, nsingletons);
    14121
    14122 /* verify which singleton continuous variables can be fixed */
    14123 for( v = 0; v < nsingletons; ++v )
    14124 {
    14125 idx = varpos[v];
    14126 var = vars[idx];
    14127 val = factor * vals[idx];
    14128 lb = SCIPvarGetLbGlobal(var);
    14129 ub = SCIPvarGetUbGlobal(var);
    14130
    14131 assert(val > 0 || SCIPisPositive(scip, SCIPvarGetObj(var)));
    14132 assert((val < 0) == swapped[idx]);
    14133 val = REALABS(val);
    14134
    14135 /* stop fixing if variable bounds are not finite */
    14136 if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
    14137 break;
    14138
    14141 assert(!SCIPvarIsIntegral(var));
    14142
    14143 /* calculate the change in the row activities if this variable changes
    14144 * its value from its worst to its best bound
    14145 */
    14146 if( swapped[idx] )
    14147 delta = -(lb - ub) * val;
    14148 else
    14149 delta = (ub - lb) * val;
    14150
    14151 assert(!SCIPisNegative(scip, delta));
    14152
    14153 if( SCIPisLE(scip, delta, rhs - maxcondactivity) )
    14154 {
    14155 if( swapped[idx] )
    14156 {
    14157 SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
    14158 SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
    14159 }
    14160 else
    14161 {
    14162 SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
    14163 SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
    14164 }
    14165
    14166 if( *cutoff )
    14167 break;
    14168 if( tightened )
    14169 {
    14170 (*nfixedvars)++;
    14171 }
    14172 }
    14173 /* @note: we could in theory tighten the bound of the first singleton variable which does not fall into the above case,
    14174 * since it cannot be fully fixed. However, this is not needed and should be done by activity-based bound tightening
    14175 * anyway after all other continuous singleton columns were fixed; doing it here may introduce numerical
    14176 * troubles in case of large bounds.
    14177 */
    14178 else if( SCIPisLE(scip, rhs, mincondactivity) )
    14179 {
    14180 if( swapped[idx] )
    14181 {
    14182 SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
    14183 SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
    14184 }
    14185 else
    14186 {
    14187 SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
    14188 SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
    14189 }
    14190
    14191 if( *cutoff )
    14192 break;
    14193 if( tightened )
    14194 {
    14195 (*nfixedvars)++;
    14196 }
    14197 }
    14198
    14199 maxcondactivity += delta;
    14200 mincondactivity += delta;
    14201 }
    14202
    14203#ifdef SCIP_DEBUG
    14204 if( *nfixedvars - oldnfixedvars > 0 )
    14205 {
    14206 SCIPdebugMsg(scip, "### stuffing fixed %d variables\n", *nfixedvars - oldnfixedvars);
    14207 }
    14208#endif
    14209 }
    14210
    14211 SCIPfreeBufferArray(scip, &swapped);
    14212 SCIPfreeBufferArray(scip, &ratios);
    14213 SCIPfreeBufferArray(scip, &varpos);
    14214 }
    14215
    14216 /* perform single-variable stuffing:
    14217 * for a linear inequality
    14218 * a_1 x_1 + a_2 x_2 + ... + a_n x_n <= b
    14219 * with a_i > 0 and objective coefficients c_i < 0,
    14220 * setting all variables to their upper bound (giving us the maximal activity of the constraint) is worst w.r.t.
    14221 * feasibility of the constraint. On the other hand, this gives the best objective function contribution of the
    14222 * variables contained in the constraint. The maximal activity should be larger than the rhs, otherwise the constraint
    14223 * is redundant.
    14224 * Now we are searching for a variable x_k with maximal ratio c_k / a_k (note that all these ratios are negative), so
    14225 * that by reducing the value of this variable we reduce the activity of the constraint while having the smallest
    14226 * objective deterioration per activity unit. If x_k has no downlocks, is continuous, and can be reduced enough to
    14227 * render the constraint feasible, and ALL other variables have only the one uplock installed by the current constraint,
    14228 * we can reduce the upper bound of x_k such that the maxactivity equals the rhs and fix all other variables to their
    14229 * upper bound.
    14230 * Note that the others variables may have downlocks from other constraints, which we do not need to care
    14231 * about since we are setting them to the highest possible value. Also, they may be integer or binary, because the
    14232 * computed ratio is still a lower bound on the change in the objective caused by reducing those variable to reach
    14233 * constraint feasibility. On the other hand, uplocks on x_k from other constraint do no interfer with the method.
    14234 * With a slight adjustment, the procedure even works for integral x_k. If (maxactivity - rhs)/val is integral,
    14235 * the variable gets an integral value in order to fulfill the constraint tightly, and we can just apply the procedure.
    14236 * If (maxactivity - rhs)/val is fractional, we need to check, if overfulfilling the constraint by setting x_k to
    14237 * ceil((maxactivity - rhs)/val) is still better than setting x_k to ceil((maxactivity - rhs)/val) - 1 and
    14238 * filling the remaining gap in the constraint with the next-best variable. For this, we check that
    14239 * c_k * ceil((maxactivity - rhs)/val) is still better than
    14240 * c_k * floor((maxactivity - rhs)/val) + c_j * ((maxactivity - rhs) - (floor((maxactivity - rhs)/val) * val))/a_j.
    14241 * In this case, the upper bound of x_k is decreased to ub_k - ceil(maxactivity - rhs).
    14242 * If there are variables with a_i < 0 and c_i > 0, they are negated to obtain the above form, variables with same
    14243 * sign of coefficients in constraint and objective prevent the use of this method.
    14244 */
    14245 if( singlevarstuffing && !ismaxsettoinfinity )
    14246 {
    14247 SCIP_Real bestratio = -SCIPinfinity(scip);
    14248 SCIP_Real secondbestratio = -SCIPinfinity(scip);
    14249 SCIP_Real ratio;
    14250 int bestindex = -1;
    14251 int bestuplocks = 0;
    14252 int bestdownlocks = 1;
    14253 int downlocks;
    14254 int uplocks;
    14255 SCIPdebug( int oldnfixedvars = *nfixedvars; )
    14256 SCIPdebug( int oldnchgbds = *nchgbds; )
    14257
    14258 /* loop over all variables to identify the best and second-best ratio */
    14259 for( v = 0; v < nvars; ++v )
    14260 {
    14261 var = vars[v];
    14262 obj = SCIPvarGetObj(var);
    14263 val = factor * vals[v];
    14264
    14265 assert(!SCIPisZero(scip, val));
    14266
    14267 ratio = obj / val;
    14268
    14269 /* if both objective and constraint push the variable to the same direction, we can do nothing here */
    14270 if( !SCIPisNegative(scip, ratio) )
    14271 {
    14272 bestindex = -1;
    14273 break;
    14274 }
    14275
    14276 if( val > 0 )
    14277 {
    14280 }
    14281 else
    14282 {
    14285 }
    14286
    14287 /* better ratio, update best candidate
    14288 * @todo use some tolerance
    14289 * @todo check size of domain and updated ratio for integer variables already?
    14290 */
    14291 if( ratio > bestratio || ( downlocks == 0 && ratio == bestratio && ( bestdownlocks > 0 /*lint !e777*/
    14292 || ( !SCIPvarIsIntegral(var) && SCIPvarIsIntegral(vars[bestindex]) ) ) ) )
    14293 {
    14294 /* best index becomes second-best*/
    14295 if( bestindex != -1 )
    14296 {
    14297 /* second-best index must not have more than 1 uplock */
    14298 if( bestuplocks > 1 )
    14299 {
    14300 bestindex = -1;
    14301 break;
    14302 }
    14303 else
    14304 {
    14305 secondbestratio = bestratio;
    14306 }
    14307 }
    14308 bestdownlocks = downlocks;
    14309 bestuplocks = uplocks;
    14310 bestratio = ratio;
    14311 bestindex = v;
    14312
    14313 /* if this variable is the best in the end, we cannot do reductions since it has a downlocks,
    14314 * if it is not the best, it has too many uplocks -> not applicable
    14315 */
    14316 if( bestdownlocks > 0 && bestuplocks > 1 )
    14317 {
    14318 bestindex = -1;
    14319 break;
    14320 }
    14321 }
    14322 else
    14323 {
    14324 /* non-best index must not have more than 1 uplock */
    14325 if( uplocks > 1 )
    14326 {
    14327 bestindex = -1;
    14328 break;
    14329 }
    14330 /* update second-best ratio */
    14331 if( ratio > secondbestratio )
    14332 {
    14333 secondbestratio = ratio;
    14334 }
    14335 }
    14336 }
    14337
    14338 /* check if we can apply single variable stuffing */
    14339 if( bestindex != -1 && bestdownlocks == 0 )
    14340 {
    14341 SCIP_Bool tightened = FALSE;
    14342 SCIP_Real bounddelta;
    14343
    14344 var = vars[bestindex];
    14345 obj = SCIPvarGetObj(var);
    14346 val = factor * vals[bestindex];
    14347 lb = SCIPvarGetLbGlobal(var);
    14348 ub = SCIPvarGetUbGlobal(var);
    14349 tryfixing = TRUE;
    14350
    14351 if( val < 0 )
    14352 {
    14353 assert(!SCIPisNegative(scip, obj));
    14354
    14355 /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
    14356 if( SCIPvarIsIntegral(var) && !SCIPisIntegral(scip, (maxactivity - rhs) / val) )
    14357 {
    14358 SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/-val);
    14359 SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * -val);
    14360 assert(SCIPisPositive(scip, activitydelta));
    14361
    14362 tryfixing = SCIPisLE(scip, obj, -activitydelta * secondbestratio);
    14363
    14364 bounddelta = SCIPceil(scip, (maxactivity - rhs)/-val);
    14365 assert(SCIPisPositive(scip, bounddelta));
    14366 }
    14367 else
    14368 bounddelta = (maxactivity - rhs)/-val;
    14369
    14370 tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
    14371
    14372 if( tryfixing )
    14373 {
    14375
    14376 if( SCIPisEQ(scip, lb + bounddelta, ub) )
    14377 {
    14378 SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), lb + bounddelta);
    14379 SCIP_CALL( SCIPfixVar(scip, var, lb + bounddelta, cutoff, &tightened) );
    14380 }
    14381 else
    14382 {
    14383 SCIPdebugMsg(scip, "tighten the lower bound of <%s> from %g to %g (ub=%g)\n", SCIPvarGetName(var), lb, lb + bounddelta, ub);
    14384 SCIP_CALL( SCIPtightenVarLb(scip, var, lb + bounddelta, FALSE, cutoff, &tightened) );
    14385 }
    14386 }
    14387 }
    14388 else
    14389 {
    14390 assert(!SCIPisPositive(scip, obj));
    14391
    14392 /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
    14393 if( SCIPvarIsIntegral(var) && !SCIPisIntegral(scip, (maxactivity - rhs) / val) )
    14394 {
    14395 SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/val);
    14396 SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * val);
    14397 assert(SCIPisPositive(scip, activitydelta));
    14398
    14399 tryfixing = SCIPisLE(scip, -obj, activitydelta * secondbestratio);
    14400
    14401 bounddelta = SCIPceil(scip, (maxactivity - rhs)/val);
    14402 assert(SCIPisPositive(scip, bounddelta));
    14403 }
    14404 else
    14405 bounddelta = (maxactivity - rhs)/val;
    14406
    14407 tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
    14408
    14409 if( tryfixing )
    14410 {
    14412
    14413 if( SCIPisEQ(scip, ub - bounddelta, lb) )
    14414 {
    14415 SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), ub - bounddelta);
    14416 SCIP_CALL( SCIPfixVar(scip, var, ub - bounddelta, cutoff, &tightened) );
    14417 }
    14418 else
    14419 {
    14420 SCIPdebugMsg(scip, "tighten the upper bound of <%s> from %g to %g (lb=%g)\n", SCIPvarGetName(var), ub, ub - bounddelta, lb);
    14421 SCIP_CALL( SCIPtightenVarUb(scip, var, ub - bounddelta, FALSE, cutoff, &tightened) );
    14422 }
    14423 }
    14424 }
    14425
    14426 if( *cutoff )
    14427 return SCIP_OKAY;
    14428 if( tightened )
    14429 {
    14431 ++(*nfixedvars);
    14432 else
    14433 ++(*nchgbds);
    14434
    14435 SCIPdebugMsg(scip, "cons <%s>: %g <=\n", SCIPconsGetName(cons), factor > 0 ? consdata->lhs : -consdata->rhs);
    14436 for( v = 0; v < nvars; ++v )
    14437 {
    14438 SCIPdebugMsg(scip, "%+g <%s>([%g,%g],%g,[%d,%d],%s)\n", factor * vals[v], SCIPvarGetName(vars[v]),
    14439 SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), SCIPvarGetObj(vars[v]),
    14442 SCIPvarIsIntegral(vars[v]) ? "I" : "C");
    14443 }
    14444 SCIPdebugMsg(scip, "<= %g\n", factor > 0 ? consdata->rhs : -consdata->lhs);
    14445
    14446 for( v = 0; v < nvars; ++v )
    14447 {
    14448 if( v == bestindex )
    14449 continue;
    14450
    14451 if( factor * vals[v] < 0 )
    14452 {
    14453 assert(SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL) == 1);
    14454 SCIPdebugMsg(scip, "fix <%s> to its lower bound (%g)\n",
    14455 SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]));
    14456 SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetLbGlobal(vars[v]), cutoff, &tightened) );
    14457 }
    14458 else
    14459 {
    14460 assert(SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL) == 1);
    14461 SCIPdebugMsg(scip, "fix <%s> to its upper bound (%g)\n",
    14462 SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]));
    14463 SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetUbGlobal(vars[v]), cutoff, &tightened) );
    14464 }
    14465
    14466 if( *cutoff )
    14467 return SCIP_OKAY;
    14468 if( tightened )
    14469 ++(*nfixedvars);
    14470 }
    14471 SCIPdebug( SCIPdebugMsg(scip, "### new stuffing fixed %d vars, tightened %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds); )
    14472 }
    14473 }
    14474 }
    14475
    14476 return SCIP_OKAY;
    14477}
    14478
    14479/** applies full dual presolving on variables that only appear in linear constraints */
    14480static
    14482 SCIP* scip, /**< SCIP data structure */
    14483 SCIP_CONS** conss, /**< constraint set */
    14484 int nconss, /**< number of constraints */
    14485 SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
    14486 int* nchgbds, /**< pointer to count the number of bound changes */
    14487 int* nchgvartypes /**< pointer to count the number of variable type changes */
    14488 )
    14489{
    14490 SCIP_Real* redlb;
    14491 SCIP_Real* redub;
    14492 int* nlocksdown;
    14493 int* nlocksup;
    14494 SCIP_Bool* isimplint;
    14495 SCIP_VAR** origvars;
    14496 SCIP_VAR** vars;
    14497 SCIP_VAR** conscontvars;
    14498 int nvars;
    14499 int nbinvars;
    14500 int nintvars;
    14501 int ncontvars;
    14502 int v;
    14503 int c;
    14504
    14505 /* we calculate redundancy bounds with the following meaning:
    14506 * redlb[v] == k : if x_v >= k, we can always round x_v down to x_v == k without violating any constraint
    14507 * redub[v] == k : if x_v <= k, we can always round x_v up to x_v == k without violating any constraint
    14508 * then:
    14509 * c_v >= 0 : x_v <= redlb[v] is feasible due to optimality
    14510 * c_v <= 0 : x_v >= redub[v] is feasible due to optimality
    14511 */
    14512
    14513 /* Additionally, we detect continuous variables that are implied integral.
    14514 * A continuous variable j is implied integral if it only has only +/-1 coefficients,
    14515 * and all constraints (including the bounds as trivial constraints) in which:
    14516 * c_j > 0: the variable is down-locked,
    14517 * c_j < 0: the variable is up-locked,
    14518 * c_j = 0: the variable appears
    14519 * have, apart from j, only integer variables with integral coefficients and integral sides.
    14520 * This is because then, the value of the variable is either determined by one of its bounds or
    14521 * by one of these constraints, and in all cases, the value of the variable is integral.
    14522 */
    14523
    14524 assert(scip != NULL);
    14525 assert(nconss == 0 || conss != NULL);
    14526 assert(nchgbds != NULL);
    14527 assert(!SCIPinProbing(scip));
    14528
    14529 /* get active variables */
    14530 nvars = SCIPgetNVars(scip);
    14531 origvars = SCIPgetVars(scip);
    14532
    14533 /* if the problem is a pure binary program, nothing can be achieved by full dual presolve */
    14534 nbinvars = SCIPgetNBinVars(scip);
    14535 if( nbinvars == nvars )
    14536 return SCIP_OKAY;
    14537
    14538 /* get number of continuous variables */
    14539 ncontvars = SCIPgetNContVars(scip);
    14540 nintvars = nvars - ncontvars;
    14541
    14542 /* copy the variable array since this array might change during the curse of this algorithm */
    14543 nvars = nvars - nbinvars;
    14544 SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &(origvars[nbinvars]), nvars) );
    14545
    14546 /* allocate temporary memory */
    14547 SCIP_CALL( SCIPallocBufferArray(scip, &redlb, nvars) );
    14548 SCIP_CALL( SCIPallocBufferArray(scip, &redub, nvars) );
    14549 SCIP_CALL( SCIPallocBufferArray(scip, &nlocksdown, nvars) );
    14550 SCIP_CALL( SCIPallocBufferArray(scip, &nlocksup, nvars) );
    14551 SCIP_CALL( SCIPallocBufferArray(scip, &isimplint, ncontvars) );
    14552 SCIP_CALL( SCIPallocBufferArray(scip, &conscontvars, ncontvars) );
    14553
    14554 /* initialize redundancy bounds */
    14555 for( v = 0; v < nvars; ++v )
    14556 {
    14557 assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY || SCIPvarIsImpliedIntegral(vars[v]));
    14558 redlb[v] = SCIPvarGetLbGlobal(vars[v]);
    14559 redub[v] = SCIPvarGetUbGlobal(vars[v]);
    14560 }
    14561 BMSclearMemoryArray(nlocksdown, nvars);
    14562 BMSclearMemoryArray(nlocksup, nvars);
    14563
    14564 /* Initialize isimplint array: variable may be implied integral if rounded to their best bound they are integral
    14565 * we better not use SCIPisFeasIntegral() in these checks.
    14566 */
    14567 for( v = 0; v < ncontvars; v++ )
    14568 {
    14569 SCIP_VAR* var;
    14570 SCIP_Real obj;
    14571 SCIP_Real lb;
    14572 SCIP_Real ub;
    14573
    14574 var = vars[v + nintvars - nbinvars];
    14575 assert(!SCIPvarIsIntegral(var));
    14576
    14577 lb = SCIPvarGetLbGlobal(var);
    14578 ub = SCIPvarGetUbGlobal(var);
    14579
    14580 obj = SCIPvarGetObj(var);
    14581 if( SCIPisZero(scip, obj) )
    14582 isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb)) && (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
    14583 else
    14584 {
    14585 if( SCIPisPositive(scip, obj) )
    14586 isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb));
    14587 else
    14588 {
    14589 assert(SCIPisNegative(scip, obj));
    14590 isimplint[v] = (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
    14591 }
    14592 }
    14593 }
    14594
    14595 /* scan all constraints */
    14596 for( c = 0; c < nconss; ++c )
    14597 {
    14598 /* we only need to consider constraints that have been locked (i.e., checked constraints or constraints that are
    14599 * part of checked disjunctions)
    14600 */
    14601 if( SCIPconsIsLocked(conss[c]) )
    14602 {
    14603 SCIP_CONSDATA* consdata;
    14604 SCIP_Bool lhsexists;
    14605 SCIP_Bool rhsexists;
    14606 SCIP_Bool hasimpliedpotential;
    14607 SCIP_Bool integralcoefs;
    14608 int nlockspos;
    14609 int contvarpos;
    14610 int nconscontvars;
    14611 int i;
    14612
    14613 consdata = SCIPconsGetData(conss[c]);
    14614 assert(consdata != NULL);
    14615
    14616 /* get number of times the constraint was locked */
    14617 nlockspos = SCIPconsGetNLocksPos(conss[c]);
    14618
    14619 /* we do not want to include constraints with locked negation (this would be too weird) */
    14620 if( SCIPconsGetNLocksNeg(conss[c]) > 0 )
    14621 {
    14622 /* mark all non-implied continuous variables */
    14623 for( i = 0; i < consdata->nvars; ++i )
    14624 {
    14625 SCIP_VAR* var;
    14626
    14627 var = consdata->vars[i];
    14628 if( !SCIPvarIsIntegral(var) )
    14629 {
    14630 int contv;
    14631 contv = SCIPvarGetProbindex(var) - nintvars;
    14632 assert(0 <= contv && contv < ncontvars); /* variable should be active due to applyFixings() */
    14633 isimplint[contv] = FALSE;
    14634 }
    14635 }
    14636 continue;
    14637 }
    14638
    14639 /* check for existing sides */
    14640 lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
    14641 rhsexists = !SCIPisInfinity(scip, consdata->rhs);
    14642
    14643 /* count locks and update redundancy bounds */
    14644 contvarpos = -1;
    14645 nconscontvars = 0;
    14646 hasimpliedpotential = FALSE;
    14647 integralcoefs = !SCIPconsIsModifiable(conss[c]);
    14648
    14649 for( i = 0; i < consdata->nvars; ++i )
    14650 {
    14651 SCIP_VAR* var;
    14652 SCIP_Real val;
    14653 SCIP_Real minresactivity;
    14654 SCIP_Real maxresactivity;
    14655 SCIP_Real newredlb;
    14656 SCIP_Real newredub;
    14657 SCIP_Bool ismintight;
    14658 SCIP_Bool ismaxtight;
    14659 SCIP_Bool isminsettoinfinity;
    14660 SCIP_Bool ismaxsettoinfinity;
    14661 int arrayindex;
    14662
    14663 var = consdata->vars[i];
    14664 assert(var != NULL);
    14665 val = consdata->vals[i];
    14666 assert(!SCIPisZero(scip, val));
    14667
    14668 /* check if still all integer variables have integral coefficients */
    14669 if( SCIPvarIsIntegral(var) )
    14670 integralcoefs = integralcoefs && SCIPisIntegral(scip, val);
    14671
    14672 /* we do not need to process binary variables */
    14673 if( SCIPvarIsBinary(var) )
    14674 continue;
    14675
    14676 if( SCIPconsIsModifiable(conss[c]) )
    14677 {
    14678 minresactivity = -SCIPinfinity(scip);
    14679 maxresactivity = SCIPinfinity(scip);
    14680 isminsettoinfinity = TRUE;
    14681 ismaxsettoinfinity = TRUE;
    14682 }
    14683 else
    14684 {
    14685 /* calculate residual activity bounds if variable would be fixed to zero */
    14686 consdataGetGlbActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
    14687 &ismintight, &ismaxtight, &isminsettoinfinity, &ismaxsettoinfinity);
    14688
    14689 /* We called consdataGetGlbActivityResiduals() saying that we do not need a good relaxation,
    14690 * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
    14691 * This is needed, because we do not want to rely on relaxed finite resactivities.
    14692 */
    14693 assert((ismintight || isminsettoinfinity) && (ismaxtight || ismaxsettoinfinity));
    14694
    14695 /* check minresactivity for reliability */
    14696 if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
    14697 consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, TRUE);
    14698
    14699 /* check maxresactivity for reliability */
    14700 if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
    14701 consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, TRUE);
    14702 }
    14703
    14704 arrayindex = SCIPvarGetProbindex(var) - nbinvars;
    14705
    14706 assert(0 <= arrayindex && arrayindex < nvars); /* variable should be active due to applyFixings() */
    14707
    14708 newredlb = redlb[arrayindex];
    14709 newredub = redub[arrayindex];
    14710 if( val > 0.0 )
    14711 {
    14712 if( lhsexists )
    14713 {
    14714 /* lhs <= d*x + a*y, d > 0 -> redundant in y if x >= (lhs - min{a*y})/d */
    14715 nlocksdown[arrayindex] += nlockspos;
    14716 newredlb = (isminsettoinfinity ? SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
    14717 }
    14718 if( rhsexists )
    14719 {
    14720 /* d*x + a*y <= rhs, d > 0 -> redundant in y if x <= (rhs - max{a*y})/d */
    14721 nlocksup[arrayindex] += nlockspos;
    14722 newredub = (ismaxsettoinfinity ? -SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
    14723 }
    14724 }
    14725 else
    14726 {
    14727 if( lhsexists )
    14728 {
    14729 /* lhs <= d*x + a*y, d < 0 -> redundant in y if x <= (lhs - min{a*y})/d */
    14730 nlocksup[arrayindex] += nlockspos;
    14731 newredub = (isminsettoinfinity ? -SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
    14732 }
    14733 if( rhsexists )
    14734 {
    14735 /* d*x + a*y <= rhs, d < 0 -> redundant in y if x >= (rhs - max{a*y})/d */
    14736 nlocksdown[arrayindex] += nlockspos;
    14737 newredlb = (ismaxsettoinfinity ? SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
    14738 }
    14739 }
    14740
    14741 /* if the variable is integer, we have to round the value to the next integral value */
    14742 if( SCIPvarIsIntegral(var) )
    14743 {
    14744 if( !SCIPisInfinity(scip, newredlb) )
    14745 newredlb = SCIPceil(scip, newredlb);
    14746 if( !SCIPisInfinity(scip, -newredub) )
    14747 newredub = SCIPfloor(scip, newredub);
    14748 }
    14749
    14750 /* update redundancy bounds */
    14751 redlb[arrayindex] = MAX(redlb[arrayindex], newredlb);
    14752 redub[arrayindex] = MIN(redub[arrayindex], newredub);
    14753
    14754 /* collect the continuous variables of the constraint */
    14755 if( !SCIPvarIsIntegral(var) )
    14756 {
    14757 int contv;
    14758
    14759 assert(nconscontvars < ncontvars);
    14760 contvarpos = i;
    14761 conscontvars[nconscontvars] = var;
    14762 nconscontvars++;
    14763
    14764 contv = SCIPvarGetProbindex(var) - nintvars;
    14765 assert(0 <= contv && contv < ncontvars);
    14766 hasimpliedpotential = hasimpliedpotential || isimplint[contv];
    14767 }
    14768 }
    14769
    14770 /* update implied integrality status of continuous variables */
    14771 if( hasimpliedpotential )
    14772 {
    14773 if( nconscontvars > 1 || !integralcoefs )
    14774 {
    14775 /* there is more than one continuous variable or the integer variables have fractional coefficients:
    14776 * none of the continuous variables is implied integral
    14777 */
    14778 for( i = 0; i < nconscontvars; i++ )
    14779 {
    14780 int contv;
    14781 contv = SCIPvarGetProbindex(conscontvars[i]) - nintvars;
    14782 assert(0 <= contv && contv < ncontvars);
    14783 isimplint[contv] = FALSE;
    14784 }
    14785 }
    14786 else
    14787 {
    14788 SCIP_VAR* var;
    14789 SCIP_Real val;
    14790 SCIP_Real absval;
    14791 int contv;
    14792
    14793 /* there is exactly one continuous variable and the integer variables have integral coefficients:
    14794 * this is the interesting case, and we have to check whether the coefficient is +/-1 and the corresponding
    14795 * side(s) of the constraint is integral
    14796 */
    14797 assert(nconscontvars == 1);
    14798 assert(0 <= contvarpos && contvarpos < consdata->nvars);
    14799 var = consdata->vars[contvarpos];
    14800 val = consdata->vals[contvarpos];
    14801 contv = SCIPvarGetProbindex(var) - nintvars;
    14802 assert(0 <= contv && contv < ncontvars);
    14803 assert(isimplint[contv]);
    14804
    14805 absval = REALABS(val);
    14806 if( !SCIPisEQ(scip, absval, 1.0) )
    14807 isimplint[contv] = FALSE;
    14808 else
    14809 {
    14810 SCIP_Real obj;
    14811
    14812 obj = SCIPvarGetObj(var);
    14813 if( obj * val >= 0.0 && lhsexists )
    14814 {
    14815 /* the variable may be blocked by the constraint's left hand side */
    14816 isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->lhs);
    14817 }
    14818 if( obj * val <= 0.0 && rhsexists )
    14819 {
    14820 /* the variable may be blocked by the constraint's left hand side */
    14821 isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->rhs);
    14822 }
    14823 }
    14824 }
    14825 }
    14826 }
    14827 }
    14828
    14829 /* check if any bounds can be tightened due to optimality */
    14830 for( v = 0; v < nvars; ++v )
    14831 {
    14832 SCIP_VAR* var;
    14833 SCIP_Real obj;
    14834 SCIP_Bool infeasible;
    14835 SCIP_Bool tightened;
    14836
    14837 assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY || SCIPvarIsImpliedIntegral(vars[v]));
    14838 assert(SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL) >= nlocksdown[v]);
    14839 assert(SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL) >= nlocksup[v]);
    14840
    14841 var = vars[v];
    14842 obj = SCIPvarGetObj(var);
    14843 if( !SCIPisPositive(scip, -obj) )
    14844 {
    14845 /* making the variable as small as possible does not increase the objective:
    14846 * check if all down locks of the variables are due to linear constraints;
    14847 * if variable is cost neutral and only upper bounded non-positively or negative largest bound to make
    14848 * constraints redundant is huge, we better do nothing for numerical reasons
    14849 */
    14851 && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlocksdown[v]
    14852 && !SCIPisHugeValue(scip, -redlb[v])
    14853 && redlb[v] < SCIPvarGetUbGlobal(var) )
    14854 {
    14855 SCIP_Real ub;
    14856
    14857 /* if x_v >= redlb[v], we can always round x_v down to x_v == redlb[v] without violating any constraint
    14858 * -> tighten upper bound to x_v <= redlb[v]
    14859 */
    14860 SCIPdebugMsg(scip, "variable <%s> only locked down in linear constraints: dual presolve <%s>[%.15g,%.15g] <= %.15g\n",
    14862 redlb[v]);
    14863 SCIP_CALL( SCIPtightenVarUb(scip, var, redlb[v], FALSE, &infeasible, &tightened) );
    14864 assert(!infeasible);
    14865
    14866 ub = SCIPvarGetUbGlobal(var);
    14867 redub[v] = MIN(redub[v], ub);
    14868 if( tightened )
    14869 (*nchgbds)++;
    14870 }
    14871 }
    14872 if( !SCIPisPositive(scip, obj) )
    14873 {
    14874 /* making the variable as large as possible does not increase the objective:
    14875 * check if all up locks of the variables are due to linear constraints;
    14876 * if variable is cost neutral and only lower bounded non-negatively or positive smallest bound to make
    14877 * constraints redundant is huge, we better do nothing for numerical reasons
    14878 */
    14880 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlocksup[v]
    14881 && !SCIPisHugeValue(scip, redub[v])
    14882 && redub[v] > SCIPvarGetLbGlobal(var) )
    14883 {
    14884 SCIP_Real lb;
    14885
    14886 /* if x_v <= redub[v], we can always round x_v up to x_v == redub[v] without violating any constraint
    14887 * -> tighten lower bound to x_v >= redub[v]
    14888 */
    14889 SCIPdebugMsg(scip, "variable <%s> only locked up in linear constraints: dual presolve <%s>[%.15g,%.15g] >= %.15g\n",
    14891 redub[v]);
    14892 SCIP_CALL( SCIPtightenVarLb(scip, var, redub[v], FALSE, &infeasible, &tightened) );
    14893 assert(!infeasible);
    14894
    14895 lb = SCIPvarGetLbGlobal(var);
    14896 redlb[v] = MAX(redlb[v], lb);
    14897 if( tightened )
    14898 (*nchgbds)++;
    14899 }
    14900 }
    14901 }
    14902
    14903 /* @TODO: improve range names */
    14904 /* declare continuous variables implied integral */
    14905 for( v = nintvars - nbinvars; v < nvars; ++v )
    14906 {
    14907 SCIP_VAR* var;
    14908 SCIP_Bool infeasible;
    14909
    14910 var = vars[v];
    14911 assert(var != NULL);
    14912
    14913 assert(!SCIPvarIsIntegral(var));
    14914 assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= nlocksdown[v]);
    14915 assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= nlocksup[v]);
    14916 assert(0 <= v - nintvars + nbinvars && v - nintvars + nbinvars < ncontvars);
    14917
    14918 /* @TODO: relax lock conditions */
    14919 /* we can only conclude implied integrality if the variable appears in no other constraint */
    14920 if( isimplint[v - nintvars + nbinvars]
    14921 && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlocksdown[v]
    14922 && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlocksup[v] )
    14923 {
    14924 /* since we locally copied the variable array we can change the variable type immediately */
    14925 assert(!SCIPvarIsIntegral(var));
    14927 (*nchgvartypes)++;
    14928 if( infeasible )
    14929 {
    14930 SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
    14931 *cutoff = TRUE;
    14932
    14933 break;
    14934 }
    14935
    14936 SCIPdebugMsg(scip, "dual presolve: declare continuous variable <%s>[%g,%g] implied integral\n",
    14938 }
    14939 }
    14940
    14941 /* free temporary memory */
    14942 SCIPfreeBufferArray(scip, &conscontvars);
    14943 SCIPfreeBufferArray(scip, &isimplint);
    14944 SCIPfreeBufferArray(scip, &nlocksup);
    14945 SCIPfreeBufferArray(scip, &nlocksdown);
    14946 SCIPfreeBufferArray(scip, &redub);
    14947 SCIPfreeBufferArray(scip, &redlb);
    14948
    14949 SCIPfreeBufferArray(scip, &vars);
    14950
    14951 return SCIP_OKAY;
    14952}
    14953
    14954/** helper function to enforce constraints */
    14955static
    14957 SCIP* scip, /**< SCIP data structure */
    14958 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    14959 SCIP_CONS** conss, /**< constraints to process */
    14960 int nconss, /**< number of constraints */
    14961 int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
    14962 SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
    14963 SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
    14964 )
    14965{
    14966 SCIP_CONSHDLRDATA* conshdlrdata;
    14967 SCIP_Bool checkrelmaxabs;
    14968 SCIP_Bool violated;
    14969 SCIP_Bool cutoff = FALSE;
    14970 int c;
    14971
    14972 assert(scip != NULL);
    14973 assert(conshdlr != NULL);
    14974 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    14975 assert(result != NULL);
    14976
    14977 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    14978 assert(conshdlrdata != NULL);
    14979
    14980 checkrelmaxabs = conshdlrdata->checkrelmaxabs;
    14981
    14982 SCIPdebugMsg(scip, "Enforcement method of linear constraints for %s solution\n", sol == NULL ? "LP" : "relaxation");
    14983
    14984 /* check for violated constraints
    14985 * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
    14986 */
    14987 *result = SCIP_FEASIBLE;
    14988
    14989 /* check all useful linear constraints for feasibility */
    14990 for( c = 0; c < nusefulconss; ++c )
    14991 {
    14992 SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
    14993
    14994 if( violated )
    14995 {
    14996 /* insert LP row as cut */
    14997 SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
    14998 if ( cutoff )
    14999 *result = SCIP_CUTOFF;
    15000 else
    15001 *result = SCIP_SEPARATED;
    15002 }
    15003 }
    15004
    15005 /* check all obsolete linear constraints for feasibility */
    15006 for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
    15007 {
    15008 SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
    15009
    15010 if( violated )
    15011 {
    15012 /* insert LP row as cut */
    15013 SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
    15014 if ( cutoff )
    15015 *result = SCIP_CUTOFF;
    15016 else
    15017 *result = SCIP_SEPARATED;
    15018 }
    15019 }
    15020
    15021 SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
    15022
    15023 return SCIP_OKAY;
    15024}
    15025
    15026/** adds symmetry information of constraint to a symmetry detection graph */
    15027static
    15029 SCIP* scip, /**< SCIP pointer */
    15030 SYM_SYMTYPE symtype, /**< type of symmetries that need to be added */
    15031 SCIP_CONS* cons, /**< constraint */
    15032 SYM_GRAPH* graph, /**< symmetry detection graph */
    15033 SCIP_Bool* success /**< pointer to store whether symmetry information could be added */
    15034 )
    15035{
    15036 SCIP_CONSDATA* consdata;
    15037 SCIP_VAR** vars;
    15038 SCIP_Real* vals;
    15039 SCIP_Real constant = 0.0;
    15040 SCIP_Real lhs;
    15041 SCIP_Real rhs;
    15042 int nlocvars;
    15043 int nvars;
    15044 int i;
    15045
    15046 assert(scip != NULL);
    15047 assert(cons != NULL);
    15048 assert(graph != NULL);
    15049 assert(success != NULL);
    15050
    15051 consdata = SCIPconsGetData(cons);
    15052 assert(consdata != NULL);
    15053
    15054 /* get active variables of the constraint */
    15055 nvars = SCIPgetNVars(scip);
    15056 nlocvars = consdata->nvars;
    15057
    15058 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
    15059 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
    15060
    15061 for( i = 0; i < nlocvars; ++i )
    15062 {
    15063 vars[i] = consdata->vars[i];
    15064 vals[i] = consdata->vals[i];
    15065 }
    15066
    15067 SCIP_CALL( SCIPgetSymActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant, SCIPisTransformed(scip)) );
    15068 lhs = consdata->lhs - constant;
    15069 rhs = consdata->rhs - constant;
    15070
    15071 /* if rhs is infinite, normalize rhs to be finite to make sure that different encodings
    15072 * of the same constraint are rated as equal
    15073 */
    15074 if ( SCIPisInfinity(scip, rhs) )
    15075 {
    15076 SCIP_Real tmp;
    15077 assert(!SCIPisInfinity(scip, -lhs));
    15078
    15079 for( i = 0; i < nlocvars; ++i )
    15080 vals[i] *= -1;
    15081 tmp = rhs;
    15082 rhs = -lhs;
    15083 lhs = -tmp;
    15084 }
    15085
    15086 SCIP_CALL( SCIPextendPermsymDetectionGraphLinear(scip, graph, vars, vals, nlocvars,
    15087 cons, lhs, rhs, success) );
    15088
    15089 SCIPfreeBufferArray(scip, &vals);
    15090 SCIPfreeBufferArray(scip, &vars);
    15091
    15092 return SCIP_OKAY;
    15093}
    15094
    15095/*
    15096 * Callback methods of constraint handler
    15097 */
    15098
    15099/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    15100static
    15101SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
    15102{ /*lint --e{715}*/
    15103 assert(scip != NULL);
    15104 assert(conshdlr != NULL);
    15105 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    15106
    15107 /* call inclusion method of constraint handler */
    15109
    15110 *valid = TRUE;
    15111
    15112 return SCIP_OKAY;
    15113}
    15114
    15115/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
    15116static
    15117SCIP_DECL_CONSFREE(consFreeLinear)
    15118{ /*lint --e{715}*/
    15119 SCIP_CONSHDLRDATA* conshdlrdata;
    15120
    15121 assert(scip != NULL);
    15122 assert(conshdlr != NULL);
    15123 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    15124
    15125 /* free constraint handler data */
    15126 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    15127 assert(conshdlrdata != NULL);
    15128
    15129 conshdlrdataFree(scip, &conshdlrdata);
    15130
    15131 SCIPconshdlrSetData(conshdlr, NULL);
    15132
    15133 return SCIP_OKAY;
    15134}
    15135
    15136
    15137/** initialization method of constraint handler (called after problem was transformed) */
    15138static
    15139SCIP_DECL_CONSINIT(consInitLinear)
    15140{
    15141 SCIP_CONSHDLRDATA* conshdlrdata;
    15142 int c;
    15143
    15144 assert(scip != NULL);
    15145
    15146 /* check for event handler */
    15147 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    15148 assert(conshdlrdata != NULL);
    15149 assert(conshdlrdata->eventhdlr != NULL);
    15150 assert(nconss == 0 || conss != NULL);
    15151
    15152 conshdlrdata->naddconss = 0;
    15153
    15154 /* catch events for the constraints */
    15155 for( c = 0; c < nconss; ++c )
    15156 {
    15157 /* catch all events */
    15158 SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
    15159 }
    15160
    15161 return SCIP_OKAY;
    15162}
    15163
    15164
    15165/** deinitialization method of constraint handler (called before transformed problem is freed) */
    15166static
    15167SCIP_DECL_CONSEXIT(consExitLinear)
    15168{
    15169 SCIP_CONSHDLRDATA* conshdlrdata;
    15170 int c;
    15171
    15172 assert(scip != NULL);
    15173
    15174 /* check for event handler */
    15175 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    15176 assert(conshdlrdata != NULL);
    15177 assert(conshdlrdata->eventhdlr != NULL);
    15178
    15179 /* drop events for the constraints */
    15180 for( c = nconss - 1; c >= 0; --c )
    15181 {
    15182 SCIP_CONSDATA* consdata;
    15183
    15184 consdata = SCIPconsGetData(conss[c]);
    15185 assert(consdata != NULL);
    15186
    15187 if( consdata->eventdata != NULL )
    15188 {
    15189 /* drop all events */
    15190 SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
    15191 assert(consdata->eventdata == NULL);
    15192 }
    15193 }
    15194
    15195 return SCIP_OKAY;
    15196}
    15197
    15198/** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
    15199static
    15201 SCIP* scip, /**< SCIP data structure */
    15202 SCIP_Real lhs, /**< left hand side */
    15203 SCIP_Real rhs /**< right hand side */
    15204 )
    15205{
    15206 assert(scip != NULL);
    15207
    15208 return !(SCIPisEQ(scip, lhs, rhs) || SCIPisInfinity(scip, -lhs) || SCIPisInfinity(scip, rhs) );
    15209}
    15210
    15211/** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
    15212static
    15214 SCIP* scip, /**< SCIP data structure */
    15215 SCIP_Real x /**< value */
    15216 )
    15217{
    15218 assert(scip != NULL);
    15219
    15220 return (!SCIPisInfinity(scip, x) && !SCIPisNegative(scip, x) && SCIPisIntegral(scip, x));
    15221}
    15222
    15223/** performs linear constraint type classification as used for MIPLIB
    15224 *
    15225 * iterates through all linear constraints and stores relevant statistics in the linear constraint statistics \p linconsstats.
    15226 *
    15227 * @note only constraints are iterated that belong to the linear constraint handler. If the problem has been presolved already,
    15228 * constraints that were upgraded to more special types such as, e.g., varbound constraints, will not be shown correctly anymore.
    15229 * Similarly, if specialized constraints were created through the API, these are currently not present.
    15230 */
    15232 SCIP* scip, /**< SCIP data structure */
    15233 SCIP_LINCONSSTATS* linconsstats /**< linear constraint type classification */
    15234 )
    15235{
    15236 int c;
    15237 SCIP_CONSHDLR* conshdlr;
    15238 SCIP_CONS** conss;
    15239 int nconss;
    15240
    15241 assert(scip != NULL);
    15242 assert(linconsstats != NULL);
    15243 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    15244 assert(conshdlr != NULL);
    15245
    15247 {
    15248 conss = SCIPgetConss(scip);
    15249 nconss = SCIPgetNConss(scip);
    15250 }
    15251 else
    15252 {
    15253 conss = SCIPconshdlrGetConss(conshdlr);
    15254 nconss = SCIPconshdlrGetNConss(conshdlr);
    15255 }
    15256
    15257 /* reset linear constraint type classification */
    15258 SCIPlinConsStatsReset(linconsstats);
    15259
    15260 /* loop through all constraints */
    15261 for( c = 0; c < nconss; c++ )
    15262 {
    15263 SCIP_CONS* cons;
    15264 SCIP_CONSDATA* consdata;
    15265 SCIP_Real lhs;
    15266 SCIP_Real rhs;
    15267 int i;
    15268
    15269 /* get constraint */
    15270 cons = conss[c];
    15271 assert(cons != NULL);
    15272
    15273 /* skip constraints that are not handled by the constraint handler */
    15274 if( SCIPconsGetHdlr(cons) != conshdlr )
    15275 continue;
    15276
    15277 /* get constraint data */
    15278 consdata = SCIPconsGetData(cons);
    15279 assert(consdata != NULL);
    15280 rhs = consdata->rhs;
    15281 lhs = consdata->lhs;
    15282
    15283 /* merge multiples and delete variables with zero coefficient */
    15284 SCIP_CALL( mergeMultiples(scip, cons) );
    15285 for( i = 0; i < consdata->nvars; i++ )
    15286 {
    15287 assert(!SCIPisZero(scip, consdata->vals[i]));
    15288 }
    15289
    15290 /* is constraint of type SCIP_CONSTYPE_EMPTY? */
    15291 if( consdata->nvars == 0 )
    15292 {
    15293 SCIPdebugMsg(scip, "classified as EMPTY: ");
    15296
    15297 continue;
    15298 }
    15299
    15300 /* is constraint of type SCIP_CONSTYPE_FREE? */
    15301 if( SCIPisInfinity(scip, rhs) && SCIPisInfinity(scip, -lhs) )
    15302 {
    15303 SCIPdebugMsg(scip, "classified as FREE: ");
    15306
    15307 continue;
    15308 }
    15309
    15310 /* is constraint of type SCIP_CONSTYPE_SINGLETON? */
    15311 if( consdata->nvars == 1 )
    15312 {
    15313 SCIPdebugMsg(scip, "classified as SINGLETON: ");
    15316
    15317 continue;
    15318 }
    15319
    15320 /* is constraint of type SCIP_CONSTYPE_AGGREGATION? */
    15321 if( consdata->nvars == 2 && SCIPisEQ(scip, lhs, rhs) )
    15322 {
    15323 SCIPdebugMsg(scip, "classified as AGGREGATION: ");
    15326
    15327 continue;
    15328 }
    15329
    15330 /* is constraint of type SCIP_CONSTYPE_{VARBOUND,PRECEDENCE}? */
    15331 if( consdata->nvars == 2 )
    15332 {
    15333 /* precedence constraints have same variable type and same absolute coefficient with opposite sign */
    15334 if( SCIPvarGetType(consdata->vars[0]) == SCIPvarGetType(consdata->vars[1])
    15335 && SCIPisEQ(scip, consdata->vals[0], -consdata->vals[1]) )
    15336 {
    15337 SCIPdebugMsg(scip, "classified as PRECEDENCE: ");
    15340
    15341 continue;
    15342 }
    15343 /* varbound constraints have otherwise a binary variable */
    15344 else if( SCIPvarGetType(consdata->vars[0]) == SCIP_VARTYPE_BINARY
    15345 || SCIPvarGetType(consdata->vars[1]) == SCIP_VARTYPE_BINARY )
    15346 {
    15347 SCIPdebugMsg(scip, "classified as VARBOUND: ");
    15350
    15351 continue;
    15352 }
    15353 }
    15354
    15355 /* is constraint of type SCIP_CONSTYPE_{SETPARTITION, SETPACKING, SETCOVERING, CARDINALITY, INVKNAPSACK}? */
    15356 {
    15357 SCIP_Real scale;
    15358 SCIP_Real b;
    15359 SCIP_Bool unmatched;
    15360 int nnegbinvars;
    15361
    15362 unmatched = FALSE;
    15363 nnegbinvars = 0;
    15364
    15365 scale = REALABS(consdata->vals[0]);
    15366
    15367 /* scan through variables and detect if all variables are binary and have a coefficient +/-1 */
    15368 for( i = 0; i < consdata->nvars && !unmatched; i++ )
    15369 {
    15370 unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
    15371 unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
    15372 unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
    15373 unmatched = unmatched || !SCIPisEQ(scip, REALABS(consdata->vals[i]), scale);
    15374
    15375 if( consdata->vals[i] < 0.0 )
    15376 nnegbinvars++;
    15377 }
    15378
    15379 if( !unmatched )
    15380 {
    15381 if( SCIPisEQ(scip, lhs, rhs) )
    15382 {
    15383 b = rhs/scale + nnegbinvars;
    15384 if( SCIPisEQ(scip, 1.0, b) )
    15385 {
    15386 SCIPdebugMsg(scip, "classified as SETPARTITION: ");
    15389
    15390 continue;
    15391 }
    15392 else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
    15393 {
    15394 SCIPdebugMsg(scip, "classified as CARDINALITY: ");
    15397
    15398 continue;
    15399 }
    15400 }
    15401
    15402 /* compute right hand side divided by scale */
    15403 if( !SCIPisInfinity(scip, rhs) )
    15404 b = rhs/scale + nnegbinvars;
    15405 else
    15406 b = SCIPinfinity(scip);
    15407
    15408 if( SCIPisEQ(scip, 1.0, b) )
    15409 {
    15410 SCIPdebugMsg(scip, "classified as SETPACKING: ");
    15413
    15414 /* relax right hand side to prevent further classifications */
    15415 rhs = SCIPinfinity(scip);
    15416 }
    15417 else if( !SCIPisInfinity(scip, b) && SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
    15418 {
    15419 SCIPdebugMsg(scip, "classified as INVKNAPSACK: ");
    15421
    15423
    15424 /* relax right hand side to prevent further classifications */
    15425 rhs = SCIPinfinity(scip);
    15426 }
    15427
    15428 if( !SCIPisInfinity(scip, lhs) )
    15429 b = lhs/scale + nnegbinvars;
    15430 else
    15431 b = SCIPinfinity(scip);
    15432
    15433 if( SCIPisEQ(scip, 1.0, b) )
    15434 {
    15435 SCIPdebugMsg(scip, "classified as SETCOVERING: ");
    15438
    15439 /* relax left hand side to prevent further classifications */
    15440 lhs = -SCIPinfinity(scip);
    15441 }
    15442
    15443 /* if both sides are infinite at this point, no further classification is necessary for this constraint */
    15444 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
    15445 continue;
    15446 }
    15447 }
    15448
    15449 /* is constraint of type SCIP_CONSTYPE_{EQKNAPSACK, BINPACKING, KNAPSACK}? */
    15450 /* @todo If coefficients or rhs are not integral, we currently do not check
    15451 * if the constraint could be scaled (finitely), such that they are.
    15452 */
    15453 {
    15454 SCIP_Real b;
    15455 SCIP_Bool unmatched;
    15456
    15457 b = rhs;
    15458 unmatched = FALSE;
    15459 for( i = 0; i < consdata->nvars && !unmatched; i++ )
    15460 {
    15461 unmatched = unmatched || !SCIPvarIsIntegral(consdata->vars[i]);
    15462 unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
    15463 unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
    15464 unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
    15465
    15466 if( SCIPisNegative(scip, consdata->vals[i]) )
    15467 b -= consdata->vals[i];
    15468 }
    15469 unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
    15470
    15471 if( !unmatched )
    15472 {
    15473 if( SCIPisEQ(scip, lhs, rhs) )
    15474 {
    15475 SCIPdebugMsg(scip, "classified as EQKNAPSACK: ");
    15477
    15479
    15480 continue;
    15481 }
    15482 else
    15483 {
    15484 SCIP_Bool matched;
    15485
    15486 matched = FALSE;
    15487 for( i = 0; i < consdata->nvars && !matched; i++ )
    15488 {
    15489 matched = matched || SCIPisEQ(scip, b, REALABS(consdata->vals[i]));
    15490 }
    15491
    15492 SCIPdebugMsg(scip, "classified as %s: ", matched ? "BINPACKING" : "KNAPSACK");
    15495 }
    15496
    15497 /* check if finite left hand side allows for a second classification, relax already used right hand side */
    15498 if( SCIPisInfinity(scip, -lhs) )
    15499 continue;
    15500 else
    15501 rhs = SCIPinfinity(scip);
    15502 }
    15503 }
    15504
    15505 /* is constraint of type SCIP_CONSTYPE_{INTKNAPSACK}? */
    15506 {
    15507 SCIP_Real b;
    15508 SCIP_Bool unmatched;
    15509
    15510 unmatched = FALSE;
    15511
    15512 b = rhs;
    15513 unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
    15514
    15515 for( i = 0; i < consdata->nvars && !unmatched; i++ )
    15516 {
    15517 unmatched = unmatched || !SCIPvarIsIntegral(consdata->vars[i]);
    15518 unmatched = unmatched || SCIPisNegative(scip, SCIPvarGetLbGlobal(consdata->vars[i]));
    15519 unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
    15520 unmatched = unmatched || SCIPisNegative(scip, consdata->vals[i]);
    15521 }
    15522
    15523 if( !unmatched )
    15524 {
    15525 SCIPdebugMsg(scip, "classified as INTKNAPSACK: ");
    15528
    15529 /* check if finite left hand side allows for a second classification, relax already used right hand side */
    15530 if( SCIPisInfinity(scip, -lhs) )
    15531 continue;
    15532 else
    15533 rhs = SCIPinfinity(scip);
    15534 }
    15535 }
    15536
    15537 /* is constraint of type SCIP_CONSTYPE_{MIXEDBINARY}? */
    15538 {
    15539 SCIP_Bool unmatched;
    15540
    15541 unmatched = FALSE;
    15542 for( i = 0; i < consdata->nvars && !unmatched; i++ )
    15543 {
    15544 if( SCIPvarIsIntegral(consdata->vars[i])
    15545 && ( SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0)
    15546 || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0) ) )
    15547 unmatched = TRUE;
    15548 }
    15549
    15550 if( !unmatched )
    15551 {
    15552 SCIPdebugMsg(scip, "classified as MIXEDBINARY (%d): ", isRangedRow(scip, lhs, rhs) ? 2 : 1);
    15555
    15556 continue;
    15557 }
    15558 }
    15559
    15560 /* no special structure detected */
    15561 SCIPdebugMsg(scip, "classified as GENERAL: ");
    15563 SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_GENERAL, isRangedRow(scip, lhs, rhs) ? 2 : 1);
    15564 }
    15565
    15566 return SCIP_OKAY;
    15567}
    15568
    15569
    15570/** presolving deinitialization method of constraint handler (called after presolving has been finished) */
    15571static
    15572SCIP_DECL_CONSEXITPRE(consExitpreLinear)
    15573{ /*lint --e{715}*/
    15574 int c;
    15575#ifdef SCIP_STATISTIC
    15576 SCIP_CONSHDLRDATA* conshdlrdata;
    15577 int ngoodconss;
    15578 int nallconss;
    15579#endif
    15580
    15581 /* delete all linear constraints that were upgraded to a more specific constraint type;
    15582 * make sure, only active variables remain in the remaining constraints
    15583 */
    15584 assert(scip != NULL);
    15585
    15586#ifdef SCIP_STATISTIC
    15587 /* count number of well behaved linear constraints */
    15588 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    15589 assert(conshdlrdata != NULL);
    15590
    15591 ngoodconss = 0;
    15592 nallconss = 0;
    15593
    15594 for( c = 0; c < nconss; ++c )
    15595 {
    15596 SCIP_CONSDATA* consdata;
    15597
    15598 if( SCIPconsIsDeleted(conss[c]) )
    15599 continue;
    15600
    15601 consdata = SCIPconsGetData(conss[c]);
    15602 assert(consdata != NULL);
    15603
    15604 if( consdata->upgraded )
    15605 continue;
    15606
    15607 nallconss++;
    15608
    15610
    15611 if( SCIPisLT(scip, consdata->maxactdelta, conshdlrdata->maxeasyactivitydelta) )
    15612 ngoodconss++;
    15613 }
    15614 if( nallconss )
    15615 {
    15616 SCIPstatisticMessage("below threshold: %d / %d ratio= %g\n", ngoodconss, nallconss, (100.0 * ngoodconss / nallconss));
    15617 }
    15618#endif
    15619
    15620 for( c = 0; c < nconss; ++c )
    15621 {
    15622 SCIP_CONSDATA* consdata;
    15623
    15624 if( SCIPconsIsDeleted(conss[c]) )
    15625 continue;
    15626
    15627 consdata = SCIPconsGetData(conss[c]);
    15628 assert(consdata != NULL);
    15629
    15630 if( consdata->upgraded )
    15631 {
    15632 /* this is no problem reduction, because the upgraded constraint was added to the problem before, and the
    15633 * (redundant) linear constraint was only kept in order to support presolving the the linear constraint handler
    15634 */
    15635 SCIP_CALL( SCIPdelCons(scip, conss[c]) );
    15636 }
    15637 else
    15638 {
    15639 /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
    15640 SCIP_CALL( applyFixings(scip, conss[c], NULL) );
    15641 }
    15642 }
    15643
    15644 return SCIP_OKAY;
    15645}
    15646
    15647/** solving process initialization method of constraint handler */
    15648static
    15649SCIP_DECL_CONSINITSOL(consInitsolLinear)
    15650{ /*lint --e{715}*/
    15651 /* add nlrow representation to NLP, if NLP had been constructed */
    15653 {
    15654 int c;
    15655 for( c = 0; c < nconss; ++c )
    15656 {
    15657 SCIP_CALL( addNlrow(scip, conss[c]) );
    15658 }
    15659 }
    15660
    15661 return SCIP_OKAY;
    15662}
    15663
    15664/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
    15665static
    15666SCIP_DECL_CONSEXITSOL(consExitsolLinear)
    15667{ /*lint --e{715}*/
    15668 int c;
    15669
    15670 assert(scip != NULL);
    15671
    15672 /* release the rows and nlrows of all constraints */
    15673 for( c = 0; c < nconss; ++c )
    15674 {
    15675 SCIP_CONSDATA* consdata;
    15676
    15677 consdata = SCIPconsGetData(conss[c]);
    15678 assert(consdata != NULL);
    15679
    15680 if( consdata->row != NULL )
    15681 {
    15682 SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
    15683 }
    15684
    15685 if( consdata->nlrow != NULL )
    15686 {
    15687 SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow) );
    15688 }
    15689 }
    15690
    15691 /* if this is a restart, convert cutpool rows into linear constraints */
    15692 if( restart )
    15693 {
    15694 int ncutsadded;
    15695
    15696 ncutsadded = 0;
    15697
    15698 /* create out of all active cuts in cutpool linear constraints */
    15699 SCIP_CALL( SCIPconvertCutsToConss(scip, NULL, NULL, TRUE, &ncutsadded) );
    15700
    15701 if( ncutsadded > 0 )
    15702 {
    15704 "(restart) converted %d cuts from the global cut pool into linear constraints\n", ncutsadded);
    15705 /* an extra blank line should be printed separately since the buffer message handler only handles up to one
    15706 * line correctly
    15707 */
    15709 }
    15710 }
    15711
    15712 return SCIP_OKAY;
    15713}
    15714
    15715
    15716/** constraint activation notification method of constraint handler */
    15717static
    15718SCIP_DECL_CONSACTIVE(consActiveLinear)
    15719{ /*lint --e{715}*/
    15720 assert(cons != NULL);
    15721
    15723 {
    15724 SCIP_CALL( addNlrow(scip, cons) );
    15725 }
    15726
    15727 return SCIP_OKAY;
    15728}
    15729
    15730/** constraint deactivation notification method of constraint handler */
    15731static
    15732SCIP_DECL_CONSDEACTIVE(consDeactiveLinear)
    15733{ /*lint --e{715}*/
    15734 SCIP_CONSDATA* consdata;
    15735
    15736 assert(scip != NULL);
    15737 assert(conshdlr != NULL);
    15738 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    15739 assert(cons != NULL );
    15740
    15741 /* get constraint data */
    15742 consdata = SCIPconsGetData(cons);
    15743 assert(consdata != NULL);
    15744
    15745 if( SCIPconsIsDeleted(cons) )
    15746 {
    15747 SCIP_CONSHDLRDATA* conshdlrdata;
    15748
    15749 /* check for event handler */
    15750 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    15751 assert(conshdlrdata != NULL);
    15752 assert(conshdlrdata->eventhdlr != NULL);
    15753
    15754 /* free event data */
    15755 if( consdata->eventdata != NULL )
    15756 {
    15757 /* drop bound change events of variables */
    15758 SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    15759 }
    15760 assert(consdata->eventdata == NULL);
    15761 }
    15762
    15763 /* remove row from NLP, if still in solving
    15764 * if we are in exitsolve, the whole NLP will be freed anyway
    15765 */
    15766 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && consdata->nlrow != NULL )
    15767 {
    15768 SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow) );
    15769 }
    15770
    15771 return SCIP_OKAY;
    15772}
    15773
    15774
    15775/** frees specific constraint data */
    15776static
    15777SCIP_DECL_CONSDELETE(consDeleteLinear)
    15778{ /*lint --e{715}*/
    15779 assert(scip != NULL);
    15780 assert(conshdlr != NULL);
    15781 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    15782
    15783 if( (*consdata)->eventdata != NULL )
    15784 {
    15785 SCIP_CONSHDLRDATA* conshdlrdata;
    15786
    15787 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    15788 assert(conshdlrdata != NULL);
    15789
    15790 /* drop all events */
    15791 SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    15792 assert((*consdata)->eventdata == NULL);
    15793 }
    15794
    15795 /* free linear constraint */
    15796 SCIP_CALL( consdataFree(scip, consdata) );
    15797
    15798 return SCIP_OKAY;
    15799}
    15800
    15801
    15802/** transforms constraint data into data belonging to the transformed problem */
    15803static
    15804SCIP_DECL_CONSTRANS(consTransLinear)
    15805{ /*lint --e{715}*/
    15806 SCIP_CONSDATA* sourcedata;
    15807 SCIP_CONSDATA* targetdata;
    15808
    15809 /*debugMsg(scip, "Trans method of linear constraints\n");*/
    15810
    15811 assert(scip != NULL);
    15812 assert(conshdlr != NULL);
    15813 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    15815 assert(sourcecons != NULL);
    15816 assert(targetcons != NULL);
    15817
    15818 sourcedata = SCIPconsGetData(sourcecons);
    15819 assert(sourcedata != NULL);
    15820 assert(sourcedata->row == NULL); /* in original problem, there cannot be LP rows */
    15821
    15822 /* create linear constraint data for target constraint */
    15823 SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs,
    15824 sourcedata->rhs) );
    15825
    15826#ifndef NDEBUG
    15827 /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
    15828 if( SCIPconsIsEnforced(sourcecons) || SCIPconsIsChecked(sourcecons) )
    15829 {
    15830 int n;
    15831 for(n = targetdata->nvars - 1; n >= 0; --n )
    15832 assert(!SCIPvarIsRelaxationOnly(targetdata->vars[n]));
    15833 }
    15834#endif
    15835
    15836 /* create target constraint */
    15837 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
    15838 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    15839 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
    15840 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
    15841 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
    15842
    15843 return SCIP_OKAY;
    15844}
    15845
    15846
    15847/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
    15848static
    15849SCIP_DECL_CONSINITLP(consInitlpLinear)
    15850{ /*lint --e{715}*/
    15851 int c;
    15852
    15853 assert(scip != NULL);
    15854 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    15855
    15856 *infeasible = FALSE;
    15857
    15858 for( c = 0; c < nconss && !(*infeasible); ++c )
    15859 {
    15860 assert(SCIPconsIsInitial(conss[c]));
    15861 SCIP_CALL( addRelaxation(scip, conss[c], infeasible) );
    15862 }
    15863
    15864 return SCIP_OKAY;
    15865}
    15866
    15867
    15868/** separation method of constraint handler for LP solutions */
    15869static
    15870SCIP_DECL_CONSSEPALP(consSepalpLinear)
    15871{ /*lint --e{715}*/
    15872 SCIP_CONSHDLRDATA* conshdlrdata;
    15873 SCIP_Real loclowerbound;
    15874 SCIP_Real glblowerbound;
    15875 SCIP_Real cutoffbound;
    15876 SCIP_Real maxbound;
    15877 SCIP_Bool separatecards;
    15878 SCIP_Bool cutoff;
    15879 int c;
    15880 int depth;
    15881 int nrounds;
    15882 int maxsepacuts;
    15883 int ncuts;
    15884
    15885 assert(scip != NULL);
    15886 assert(conshdlr != NULL);
    15887 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    15888 assert(result != NULL);
    15889
    15890 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    15891 assert(conshdlrdata != NULL);
    15892 depth = SCIPgetDepth(scip);
    15893 nrounds = SCIPgetNSepaRounds(scip);
    15894
    15895 /*debugMsg(scip, "Sepa method of linear constraints\n");*/
    15896
    15897 *result = SCIP_DIDNOTRUN;
    15898
    15899 /* only call the separator a given number of times at each node */
    15900 if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
    15901 || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
    15902 return SCIP_OKAY;
    15903
    15904 /* get the maximal number of cuts allowed in a separation round */
    15905 maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
    15906
    15907 /* check if we want to produce knapsack cardinality cuts at this node */
    15908 loclowerbound = SCIPgetLocalLowerbound(scip);
    15909 glblowerbound = SCIPgetLowerbound(scip);
    15910 cutoffbound = SCIPgetCutoffbound(scip);
    15911 maxbound = glblowerbound + conshdlrdata->maxcardbounddist * (cutoffbound - glblowerbound);
    15912 separatecards = SCIPisLE(scip, loclowerbound, maxbound);
    15913 separatecards = separatecards && (SCIPgetNLPBranchCands(scip) > 0);
    15914
    15915 *result = SCIP_DIDNOTFIND;
    15916 ncuts = 0;
    15917 cutoff = FALSE;
    15918
    15919 /* check all useful linear constraints for feasibility */
    15920 for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
    15921 {
    15922 /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
    15923 SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, separatecards, conshdlrdata->separateall, &ncuts, &cutoff) );
    15924 }
    15925
    15926 /* adjust return value */
    15927 if( cutoff )
    15928 *result = SCIP_CUTOFF;
    15929 else if( ncuts > 0 )
    15930 *result = SCIP_SEPARATED;
    15931
    15932 /* combine linear constraints to get more cuts */
    15933 /**@todo further cuts of linear constraints */
    15934
    15935 return SCIP_OKAY;
    15936}
    15937
    15938
    15939/** separation method of constraint handler for arbitrary primal solutions */
    15940static
    15941SCIP_DECL_CONSSEPASOL(consSepasolLinear)
    15942{ /*lint --e{715}*/
    15943 SCIP_CONSHDLRDATA* conshdlrdata;
    15944 int c;
    15945 int depth;
    15946 int nrounds;
    15947 int maxsepacuts;
    15948 int ncuts;
    15949 SCIP_Bool cutoff;
    15950
    15951 assert(scip != NULL);
    15952 assert(conshdlr != NULL);
    15953 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    15954 assert(result != NULL);
    15955
    15956 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    15957 assert(conshdlrdata != NULL);
    15958 depth = SCIPgetDepth(scip);
    15959 nrounds = SCIPgetNSepaRounds(scip);
    15960
    15961 /*debugMsg(scip, "Sepa method of linear constraints\n");*/
    15962
    15963 *result = SCIP_DIDNOTRUN;
    15964
    15965 /* only call the separator a given number of times at each node */
    15966 if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
    15967 || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
    15968 return SCIP_OKAY;
    15969
    15970 /* get the maximal number of cuts allowed in a separation round */
    15971 maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
    15972
    15973 *result = SCIP_DIDNOTFIND;
    15974 ncuts = 0;
    15975 cutoff = FALSE;
    15976
    15977 /* check all useful linear constraints for feasibility */
    15978 for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
    15979 {
    15980 /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
    15981 SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, TRUE, conshdlrdata->separateall, &ncuts, &cutoff) );
    15982 }
    15983
    15984 /* adjust return value */
    15985 if( cutoff )
    15986 *result = SCIP_CUTOFF;
    15987 else if( ncuts > 0 )
    15988 *result = SCIP_SEPARATED;
    15989
    15990 /* combine linear constraints to get more cuts */
    15991 /**@todo further cuts of linear constraints */
    15992
    15993 return SCIP_OKAY;
    15994}
    15995
    15996
    15997/** constraint enforcing method of constraint handler for LP solutions */
    15998static
    15999SCIP_DECL_CONSENFOLP(consEnfolpLinear)
    16000{ /*lint --e{715}*/
    16001 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
    16002
    16003 return SCIP_OKAY;
    16004}
    16005
    16006/** constraint enforcing method of constraint handler for relaxation solutions */
    16007static
    16008SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
    16009{ /*lint --e{715}*/
    16010 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
    16011
    16012 return SCIP_OKAY;
    16013}
    16014
    16015/** constraint enforcing method of constraint handler for pseudo solutions */
    16016static
    16017SCIP_DECL_CONSENFOPS(consEnfopsLinear)
    16018{ /*lint --e{715}*/
    16019 SCIP_CONSHDLRDATA* conshdlrdata;
    16020 SCIP_Bool checkrelmaxabs;
    16021 SCIP_Bool violated;
    16022 int c;
    16023
    16024 assert(scip != NULL);
    16025 assert(conshdlr != NULL);
    16026 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    16027 assert(result != NULL);
    16028
    16029 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    16030 assert(conshdlrdata != NULL);
    16031
    16032 checkrelmaxabs = conshdlrdata->checkrelmaxabs;
    16033
    16034 SCIPdebugMsg(scip, "Enfops method of linear constraints\n");
    16035
    16036 /* if the solution is infeasible anyway due to objective value, skip the enforcement */
    16037 if( objinfeasible )
    16038 {
    16039 SCIPdebugMsg(scip, "-> pseudo solution is objective infeasible, return.\n");
    16040
    16041 *result = SCIP_DIDNOTRUN;
    16042 return SCIP_OKAY;
    16043 }
    16044
    16045 /* check all linear constraints for feasibility */
    16046 violated = FALSE;
    16047 for( c = 0; c < nconss && !violated; ++c )
    16048 {
    16049 SCIP_CALL( checkCons(scip, conss[c], NULL, TRUE, checkrelmaxabs, &violated) );
    16050 }
    16051
    16052 if( violated )
    16053 *result = SCIP_INFEASIBLE;
    16054 else
    16055 *result = SCIP_FEASIBLE;
    16056
    16057 SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
    16058
    16059 return SCIP_OKAY;
    16060}
    16061
    16062
    16063/** feasibility check method of constraint handler for integral solutions */
    16064static
    16065SCIP_DECL_CONSCHECK(consCheckLinear)
    16066{ /*lint --e{715}*/
    16067 SCIP_CONSHDLRDATA* conshdlrdata;
    16068 SCIP_Bool checkrelmaxabs;
    16069 int c;
    16070
    16071 assert(scip != NULL);
    16072 assert(conshdlr != NULL);
    16073 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    16074 assert(result != NULL);
    16075
    16076 *result = SCIP_FEASIBLE;
    16077
    16078 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    16079 assert(conshdlrdata != NULL);
    16080
    16081 checkrelmaxabs = conshdlrdata->checkrelmaxabs;
    16082
    16083 /*debugMsg(scip, "Check method of linear constraints\n");*/
    16084
    16085 /* check all linear constraints for feasibility */
    16086 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
    16087 {
    16088 SCIP_Bool violated = FALSE;
    16089 SCIP_CALL( checkCons(scip, conss[c], sol, checklprows, checkrelmaxabs, &violated) );
    16090
    16091 if( violated )
    16092 {
    16093 *result = SCIP_INFEASIBLE;
    16094
    16095 if( printreason )
    16096 {
    16097 SCIP_CONSDATA* consdata;
    16098 SCIP_Real activity;
    16099
    16100 consdata = SCIPconsGetData(conss[c]);
    16101 assert( consdata != NULL);
    16102
    16103 activity = consdataGetActivity(scip, consdata, sol);
    16104
    16105 SCIP_CALL( consPrintConsSol(scip, conss[c], sol, NULL ) );
    16106 SCIPinfoMessage(scip, NULL, ";\n");
    16107
    16108 if( activity == SCIP_INVALID || SCIPisInfinity(scip, ABS(activity)) ) /*lint !e777*/
    16109 SCIPinfoMessage(scip, NULL, "activity invalid due to infinity contributions\n");
    16110 else if( SCIPisFeasLT(scip, activity, consdata->lhs) )
    16111 SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", consdata->lhs - activity);
    16112 else if( SCIPisFeasGT(scip, activity, consdata->rhs) )
    16113 SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - consdata->rhs);
    16114 }
    16115 }
    16116 }
    16117
    16118 return SCIP_OKAY;
    16119}
    16120
    16121
    16122/** domain propagation method of constraint handler */
    16123static
    16124SCIP_DECL_CONSPROP(consPropLinear)
    16125{ /*lint --e{715}*/
    16126 SCIP_CONSHDLRDATA* conshdlrdata;
    16127 SCIP_Bool rangedrowpropagation = FALSE;
    16128 SCIP_Bool tightenbounds;
    16129 SCIP_Bool cutoff;
    16130
    16131 int nchgbds;
    16132 int i;
    16133
    16134 assert(scip != NULL);
    16135 assert(conshdlr != NULL);
    16136 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    16137 assert(result != NULL);
    16138
    16139 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    16140 assert(conshdlrdata != NULL);
    16141
    16142 /*debugMsg(scip, "Prop method of linear constraints\n");*/
    16143
    16144 /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
    16145 if( SCIPinProbing(scip) )
    16146 tightenbounds = TRUE;
    16147 else
    16148 {
    16149 int depth;
    16150 int propfreq;
    16151 int tightenboundsfreq;
    16152 int rangedrowfreq;
    16153
    16154 depth = SCIPgetDepth(scip);
    16155 propfreq = SCIPconshdlrGetPropFreq(conshdlr);
    16156 tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
    16157 tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
    16158 && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
    16159
    16160 /* check if we want to do ranged row propagation */
    16161 rangedrowpropagation = conshdlrdata->rangedrowpropagation;
    16162 rangedrowpropagation = rangedrowpropagation && !SCIPinRepropagation(scip);
    16163 rangedrowpropagation = rangedrowpropagation && (depth <= conshdlrdata->rangedrowmaxdepth);
    16164 rangedrowfreq = propfreq * conshdlrdata->rangedrowfreq;
    16165 rangedrowpropagation = rangedrowpropagation && (conshdlrdata->rangedrowfreq >= 0)
    16166 && ((rangedrowfreq == 0 && depth == 0) || (rangedrowfreq >= 1 && (depth % rangedrowfreq == 0)));
    16167 }
    16168
    16169 cutoff = FALSE;
    16170 nchgbds = 0;
    16171
    16172 /* process constraints marked for propagation */
    16173 for( i = 0; i < nmarkedconss && !cutoff; i++ )
    16174 {
    16176 SCIP_CALL( propagateCons(scip, conss[i], tightenbounds, rangedrowpropagation,
    16177 conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, &nchgbds) );
    16178 }
    16179
    16180 /* adjust result code */
    16181 if( cutoff )
    16182 *result = SCIP_CUTOFF;
    16183 else if( nchgbds > 0 )
    16184 *result = SCIP_REDUCEDDOM;
    16185 else
    16186 *result = SCIP_DIDNOTFIND;
    16187
    16188 return SCIP_OKAY;
    16189}
    16190
    16191
    16192#define MAXCONSPRESOLROUNDS 10
    16193/** presolving method of constraint handler */
    16194static
    16195SCIP_DECL_CONSPRESOL(consPresolLinear)
    16196{ /*lint --e{715}*/
    16197 SCIP_CONSHDLRDATA* conshdlrdata;
    16198 SCIP_CONS* cons;
    16199 SCIP_CONSDATA* consdata;
    16200 SCIP_Real minactivity;
    16201 SCIP_Real maxactivity;
    16202 SCIP_Bool isminacttight;
    16203 SCIP_Bool ismaxacttight;
    16204 SCIP_Bool isminsettoinfinity;
    16205 SCIP_Bool ismaxsettoinfinity;
    16206 SCIP_Bool cutoff;
    16207 int oldnfixedvars;
    16208 int oldnaggrvars;
    16209 int oldnchgbds;
    16210 int oldndelconss;
    16211 int oldnupgdconss;
    16212 int oldnchgcoefs;
    16213 int oldnchgsides;
    16214 int firstchange;
    16215 int firstupgradetry;
    16216 int c;
    16217
    16218 assert(scip != NULL);
    16219 assert(conshdlr != NULL);
    16220 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
    16221 assert(result != NULL);
    16222
    16223 /*debugMsg(scip, "Presol method of linear constraints\n");*/
    16224
    16225 /* remember old preprocessing counters */
    16226 cutoff = FALSE;
    16227 oldnfixedvars = *nfixedvars;
    16228 oldnaggrvars = *naggrvars;
    16229 oldnchgbds = *nchgbds;
    16230 oldndelconss = *ndelconss;
    16231 oldnupgdconss = *nupgdconss;
    16232 oldnchgcoefs = *nchgcoefs;
    16233 oldnchgsides = *nchgsides;
    16234
    16235 /* get constraint handler data */
    16236 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    16237 assert(conshdlrdata != NULL);
    16238
    16239 /* process single constraints */
    16240 firstchange = INT_MAX;
    16241 firstupgradetry = INT_MAX;
    16242 for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
    16243 {
    16244 int npresolrounds;
    16245 SCIP_Bool infeasible;
    16246
    16247 infeasible = FALSE;
    16248
    16249 cons = conss[c];
    16250 assert(SCIPconsIsActive(cons));
    16251 consdata = SCIPconsGetData(cons);
    16252 assert(consdata != NULL);
    16253
    16254 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
    16255 if( SCIPisEQ(scip, consdata->rhs, consdata->lhs) )
    16256 {
    16257 consdata->lhs = consdata->rhs;
    16258 assert(consdata->row == NULL);
    16259 }
    16260
    16261 if( consdata->eventdata == NULL )
    16262 {
    16263 /* catch bound change events of variables */
    16264 SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
    16265 assert(consdata->eventdata != NULL);
    16266 }
    16267
    16268 /* constraint should not be already presolved in the initial round */
    16269 assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || SCIPconsIsMarkedPropagate(cons));
    16270 assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || consdata->boundstightened == 0);
    16271 assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->presolved);
    16272 assert(!SCIPconsIsMarkedPropagate(cons) || !consdata->presolved);
    16273
    16274 /* incorporate fixings and aggregations in constraint */
    16275 SCIP_CALL( applyFixings(scip, cons, &infeasible) );
    16276
    16277 if( infeasible )
    16278 {
    16279 SCIPdebugMsg(scip, " -> infeasible fixing\n");
    16280 cutoff = TRUE;
    16281 break;
    16282 }
    16283
    16284 assert(consdata->removedfixings);
    16285
    16286 /* we can only presolve linear constraints, that are not modifiable */
    16287 if( SCIPconsIsModifiable(cons) )
    16288 continue;
    16289
    16290 /* remember the first changed constraint to begin the next aggregation round with */
    16291 if( firstchange == INT_MAX && consdata->changed )
    16292 firstchange = c;
    16293
    16294 /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
    16295 if( firstupgradetry == INT_MAX && !consdata->upgradetried )
    16296 firstupgradetry = c;
    16297
    16298 /* check, if constraint is already preprocessed */
    16299 if( consdata->presolved )
    16300 continue;
    16301
    16302 assert(SCIPconsIsActive(cons));
    16303
    16304 SCIPdebugMsg(scip, "presolving linear constraint <%s>\n", SCIPconsGetName(cons));
    16306
    16307 /* apply presolving as long as possible on the single constraint (however, abort after a certain number of rounds
    16308 * to avoid nearly infinite cycling due to very small bound changes)
    16309 */
    16310 npresolrounds = 0;
    16311 while( !consdata->presolved && npresolrounds < MAXCONSPRESOLROUNDS && !SCIPisStopped(scip) )
    16312 {
    16313 assert(!cutoff);
    16314 npresolrounds++;
    16315
    16316 /* mark constraint being presolved and propagated */
    16317 consdata->presolved = TRUE;
    16319
    16320 SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
    16321
    16322 if( infeasible )
    16323 {
    16324 SCIPdebugMsg(scip, " -> infeasible normalization\n");
    16325 cutoff = TRUE;
    16326 break;
    16327 }
    16328
    16329 /* tighten left and right hand side due to integrality */
    16330 SCIP_CALL( tightenSides(scip, cons, nchgsides, &infeasible) );
    16331
    16332 if( infeasible )
    16333 {
    16334 SCIPdebugMsg(scip, " -> infeasibility detected during tightening sides\n");
    16335 cutoff = TRUE;
    16336 break;
    16337 }
    16338
    16339 /* check bounds */
    16340 if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
    16341 {
    16342 SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
    16343 SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
    16344 cutoff = TRUE;
    16345 break;
    16346 }
    16347
    16348 /* tighten variable's bounds */
    16349 SCIP_CALL( tightenBounds(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, nchgbds) );
    16350 if( cutoff )
    16351 break;
    16352
    16353 /* check for fixed variables */
    16354 SCIP_CALL( fixVariables(scip, cons, &cutoff, nfixedvars) );
    16355 if( cutoff )
    16356 break;
    16357
    16358 /* if the maximal coefficient is large, recompute the activities before infeasibility and redundancy checks */
    16359 if( ( consdata->validmaxabsval && consdata->maxabsval > MAXVALRECOMP )
    16360 || ( consdata->validminabsval && consdata->minabsval < MINVALRECOMP ) )
    16361 {
    16364 }
    16365
    16366 /* get activity bounds */
    16367 consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &isminacttight, &ismaxacttight,
    16368 &isminsettoinfinity, &ismaxsettoinfinity);
    16369
    16370 /* check constraint for infeasibility and redundancy */
    16371 if( SCIPisFeasGT(scip, minactivity, consdata->rhs) || SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
    16372 {
    16373 SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
    16374 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
    16375 cutoff = TRUE;
    16376 break;
    16377 }
    16378 else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
    16379 {
    16380 SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
    16381 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
    16382 SCIP_CALL( SCIPdelCons(scip, cons) );
    16383 assert(!SCIPconsIsActive(cons));
    16384
    16385 if( !consdata->upgraded )
    16386 (*ndelconss)++;
    16387 break;
    16388 }
    16389 else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisGE(scip, minactivity, consdata->lhs) )
    16390 {
    16391 SCIPdebugMsg(scip, "linear constraint <%s> left hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
    16392 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
    16393 SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
    16394 if( !consdata->upgraded )
    16395 (*nchgsides)++;
    16396 }
    16397 else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
    16398 {
    16399 SCIPdebugMsg(scip, "linear constraint <%s> right hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
    16400 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
    16402 if( !consdata->upgraded )
    16403 (*nchgsides)++;
    16404 }
    16405
    16406 /* handle empty constraint */
    16407 if( consdata->nvars == 0 )
    16408 {
    16409 if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
    16410 {
    16411 SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
    16412 SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
    16413 cutoff = TRUE;
    16414 }
    16415 else
    16416 {
    16417 SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
    16418 SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
    16419 SCIP_CALL( SCIPdelCons(scip, cons) );
    16420 assert(!SCIPconsIsActive(cons));
    16421
    16422 if( !consdata->upgraded )
    16423 (*ndelconss)++;
    16424 }
    16425 break;
    16426 }
    16427
    16428 /* reduce big-M coefficients, that make the constraint redundant if the variable is on a bound */
    16429 SCIP_CALL( consdataTightenCoefs(scip, cons, nchgcoefs, nchgsides) );
    16430
    16431 /* try to simplify inequalities */
    16432 if( conshdlrdata->simplifyinequalities )
    16433 {
    16434 SCIP_CALL( simplifyInequalities(scip, cons, nchgcoefs, nchgsides, &cutoff) );
    16435
    16436 if( cutoff )
    16437 break;
    16438 }
    16439
    16440 /* aggregation variable in equations */
    16441 if( conshdlrdata->aggregatevariables )
    16442 {
    16443 SCIP_CALL( aggregateVariables(scip, cons, &cutoff, nfixedvars, naggrvars) );
    16444 if( cutoff )
    16445 break;
    16446 }
    16447 }
    16448
    16449 if( !cutoff && !SCIPisStopped(scip) )
    16450 {
    16451 /* perform ranged row propagation */
    16452 if( conshdlrdata->rangedrowpropagation )
    16453 {
    16454 int lastnfixedvars;
    16455
    16456 lastnfixedvars = *nfixedvars;
    16457
    16458 SCIP_CALL( rangedRowPropagation(scip, cons, &cutoff, nfixedvars, nchgbds, naddconss) );
    16459 if( !cutoff )
    16460 {
    16461 if( lastnfixedvars < *nfixedvars )
    16462 {
    16463 SCIP_CALL( applyFixings(scip, cons, &cutoff) );
    16464 }
    16465 }
    16466 }
    16467
    16468 /* extract cliques from constraint */
    16469 if( conshdlrdata->extractcliques && !cutoff && SCIPconsIsActive(cons) )
    16470 {
    16471 SCIP_CALL( extractCliques(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars,
    16472 nfixedvars, nchgbds, &cutoff) );
    16473
    16474 /* check if the constraint got redundant or infeasible */
    16475 if( !cutoff && SCIPconsIsActive(cons) && consdata->nvars == 0 )
    16476 {
    16477 if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
    16478 {
    16479 SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
    16480 SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
    16481 cutoff = TRUE;
    16482 }
    16483 else
    16484 {
    16485 SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
    16486 SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
    16487 SCIP_CALL( SCIPdelCons(scip, cons) );
    16488 assert(!SCIPconsIsActive(cons));
    16489
    16490 if( !consdata->upgraded )
    16491 (*ndelconss)++;
    16492 }
    16493 }
    16494 }
    16495
    16496 /* convert special equalities */
    16497 if( !cutoff && SCIPconsIsActive(cons) )
    16498 {
    16499 SCIP_CALL( convertEquality(scip, cons, conshdlrdata, &cutoff, nfixedvars, naggrvars, ndelconss, nchgvartypes) );
    16500 }
    16501
    16502 /* apply dual presolving for variables that appear in only one constraint */
    16503 if( !cutoff && SCIPconsIsActive(cons) && conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) )
    16504 {
    16505 SCIP_CALL( dualPresolve(scip, conshdlrdata, cons, &cutoff, nfixedvars, naggrvars, ndelconss, nchgvartypes) );
    16506 }
    16507
    16508 /* check if an inequality is parallel to the objective function */
    16509 if( !cutoff && SCIPconsIsActive(cons) )
    16510 {
    16511 SCIP_CALL( checkParallelObjective(scip, cons, conshdlrdata) );
    16512 }
    16513
    16514 /* remember the first changed constraint to begin the next aggregation round with */
    16515 if( firstchange == INT_MAX && consdata->changed )
    16516 firstchange = c;
    16517
    16518 /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
    16519 if( firstupgradetry == INT_MAX && !consdata->upgradetried )
    16520 firstupgradetry = c;
    16521 }
    16522
    16523 /* singleton column stuffing */
    16524 if( !cutoff && SCIPconsIsActive(cons) && SCIPconsIsChecked(cons) &&
    16525 (conshdlrdata->singletonstuffing || conshdlrdata->singlevarstuffing) && SCIPallowStrongDualReds(scip) )
    16526 {
    16527 SCIP_CALL( presolStuffing(scip, cons, conshdlrdata->singletonstuffing,
    16528 conshdlrdata->singlevarstuffing, &cutoff, nfixedvars, nchgbds) );
    16529
    16530 /* handle empty constraint */
    16531 if( consdata->nvars == 0 )
    16532 {
    16533 if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
    16534 {
    16535 SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
    16536 SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
    16537 cutoff = TRUE;
    16538 }
    16539 else
    16540 {
    16541 SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
    16542 SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
    16543 SCIP_CALL( SCIPdelCons(scip, cons) );
    16544 assert(!SCIPconsIsActive(cons));
    16545
    16546 if( !consdata->upgraded )
    16547 (*ndelconss)++;
    16548 }
    16549 break;
    16550 }
    16551 }
    16552 }
    16553
    16554 /* process pairs of constraints: check them for redundancy and try to aggregate them;
    16555 * only apply this expensive procedure in exhaustive presolving timing
    16556 */
    16557 if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && (conshdlrdata->presolusehashing || conshdlrdata->presolpairwise) && !SCIPisStopped(scip) )
    16558 {
    16559 assert(firstchange >= 0);
    16560
    16561 if( firstchange < nconss && conshdlrdata->presolusehashing )
    16562 {
    16563 /* detect redundant constraints; fast version with hash table instead of pairwise comparison */
    16564 SCIP_CALL( detectRedundantConstraints(scip, SCIPblkmem(scip), conss, nconss, &firstchange, &cutoff,
    16565 ndelconss, nchgsides) );
    16566 }
    16567
    16568 if( firstchange < nconss && conshdlrdata->presolpairwise )
    16569 {
    16570 SCIP_CONS** usefulconss;
    16571 int nusefulconss;
    16572 int firstchangenew;
    16573 SCIP_Longint npaircomparisons;
    16574
    16575 npaircomparisons = 0;
    16576 oldndelconss = *ndelconss;
    16577 oldnchgsides = *nchgsides;
    16578 oldnchgcoefs = *nchgcoefs;
    16579
    16580 /* allocate temporary memory */
    16581 SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, nconss) );
    16582
    16583 nusefulconss = 0;
    16584 firstchangenew = -1;
    16585 for( c = 0; c < nconss; ++c )
    16586 {
    16587 /* update firstchange */
    16588 if( c == firstchange )
    16589 firstchangenew = nusefulconss;
    16590
    16591 /* ignore inactive and modifiable constraints */
    16592 if( !SCIPconsIsActive(conss[c]) || SCIPconsIsModifiable(conss[c]) )
    16593 continue;
    16594
    16595 usefulconss[nusefulconss] = conss[c];
    16596 ++nusefulconss;
    16597 }
    16598 firstchange = firstchangenew;
    16599 assert(firstchangenew >= 0 && firstchangenew <= nusefulconss);
    16600
    16601 for( c = firstchange; c < nusefulconss && !cutoff && !SCIPisStopped(scip); ++c )
    16602 {
    16603 /* constraint has become inactive or modifiable during pairwise presolving */
    16604 if( usefulconss[c] == NULL )
    16605 continue;
    16606
    16607 npaircomparisons += (SCIPconsGetData(conss[c])->changed) ? c : (c - firstchange); /*lint !e776*/
    16608
    16609 assert(SCIPconsIsActive(usefulconss[c]) && !SCIPconsIsModifiable(usefulconss[c]));
    16610 SCIP_CALL( preprocessConstraintPairs(scip, usefulconss, firstchange, c, conshdlrdata->maxaggrnormscale,
    16611 &cutoff, ndelconss, nchgsides, nchgcoefs) );
    16612
    16613 if( npaircomparisons > conshdlrdata->nmincomparisons )
    16614 {
    16615 assert(npaircomparisons > 0);
    16616 if( ((*ndelconss - oldndelconss) + (*nchgsides - oldnchgsides)/2.0 + (*nchgcoefs - oldnchgcoefs)/10.0) / ((SCIP_Real) npaircomparisons) < conshdlrdata->mingainpernmincomp )
    16617 break;
    16618 oldndelconss = *ndelconss;
    16619 oldnchgsides = *nchgsides;
    16620 oldnchgcoefs = *nchgcoefs;
    16621 npaircomparisons = 0;
    16622 }
    16623 }
    16624 /* free temporary memory */
    16625 SCIPfreeBufferArray(scip, &usefulconss);
    16626 }
    16627 }
    16628
    16629 /* before upgrading, check whether we can apply some additional dual presolving, because a variable only appears
    16630 * in linear constraints and we therefore have full information about it
    16631 */
    16632 if( !cutoff && firstupgradetry < nconss
    16633 && *nfixedvars == oldnfixedvars && *naggrvars == oldnaggrvars && *nchgbds == oldnchgbds && *ndelconss == oldndelconss
    16634 && *nupgdconss == oldnupgdconss && *nchgcoefs == oldnchgcoefs && *nchgsides == oldnchgsides
    16635 )
    16636 {
    16637 if( conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) && !SCIPisStopped(scip) )
    16638 {
    16639 SCIP_CALL( fullDualPresolve(scip, conss, nconss, &cutoff, nchgbds, nchgvartypes) );
    16640 }
    16641 }
    16642
    16643 /* try to upgrade constraints into a more specific constraint type;
    16644 * only upgrade constraints, if no reductions were found in this round (otherwise, the linear constraint handler
    16645 * may find additional reductions before giving control away to other (less intelligent?) constraint handlers)
    16646 */
    16647 if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && SCIPisPresolveFinished(scip) )
    16648 {
    16649 for( c = firstupgradetry; c < nconss && !SCIPisStopped(scip); ++c )
    16650 {
    16651 cons = conss[c];
    16652
    16653 /* don't upgrade modifiable constraints */
    16654 if( SCIPconsIsModifiable(cons) )
    16655 continue;
    16656
    16657 consdata = SCIPconsGetData(cons);
    16658 assert(consdata != NULL);
    16659
    16660 /* only upgrade completely presolved constraints, that changed since the last upgrading call */
    16661 if( consdata->upgradetried )
    16662 continue;
    16663 /* @todo force that upgrade will be performed later? */
    16664 if( !consdata->presolved )
    16665 continue;
    16666
    16667 consdata->upgradetried = TRUE;
    16668 if( SCIPconsIsActive(cons) )
    16669 {
    16670 SCIP_CONS* upgdcons;
    16671
    16672 SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
    16673 if( upgdcons != NULL )
    16674 {
    16675 /* add the upgraded constraint to the problem */
    16676 SCIP_CALL( SCIPaddConsUpgrade(scip, cons, &upgdcons) );
    16677 ++(*nupgdconss);
    16678
    16679 /* mark the linear constraint being upgraded and to be removed after presolving;
    16680 * don't delete it directly, because it may help to preprocess other linear constraints
    16681 */
    16682 assert(!consdata->upgraded);
    16683 consdata->upgraded = TRUE;
    16684
    16685 /* delete upgraded inequalities immediately;
    16686 * delete upgraded equalities, if we don't need it anymore for aggregation and redundancy checking
    16687 */
    16688 if( SCIPisLT(scip, consdata->lhs, consdata->rhs)
    16689 || !conshdlrdata->presolpairwise
    16690 || (conshdlrdata->maxaggrnormscale == 0.0) )
    16691 {
    16692 SCIP_CALL( SCIPdelCons(scip, cons) );
    16693 }
    16694 }
    16695 }
    16696 }
    16697 }
    16698
    16699 /* return the correct result code */
    16700 if( cutoff )
    16701 *result = SCIP_CUTOFF;
    16702 else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds || *ndelconss > oldndelconss
    16703 || *nupgdconss > oldnupgdconss || *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides )
    16704 *result = SCIP_SUCCESS;
    16705 else
    16706 *result = SCIP_DIDNOTFIND;
    16707
    16708 return SCIP_OKAY;
    16709}
    16710
    16711
    16712/** propagation conflict resolving method of constraint handler */
    16713static
    16714SCIP_DECL_CONSRESPROP(consRespropLinear)
    16715{ /*lint --e{715}*/
    16716 assert(scip != NULL);
    16717 assert(cons != NULL);
    16718 assert(result != NULL);
    16719
    16720 SCIP_CALL( resolvePropagation(scip, cons, infervar, intToInferInfo(inferinfo), boundtype, bdchgidx, result) );
    16721
    16722 return SCIP_OKAY;
    16723}
    16724
    16725
    16726/** variable rounding lock method of constraint handler */
    16727static
    16728SCIP_DECL_CONSLOCK(consLockLinear)
    16729{ /*lint --e{715}*/
    16730 SCIP_CONSDATA* consdata;
    16731 SCIP_Bool haslhs;
    16732 SCIP_Bool hasrhs;
    16733 int i;
    16734
    16735 assert(scip != NULL);
    16736 assert(cons != NULL);
    16737 consdata = SCIPconsGetData(cons);
    16738 assert(consdata != NULL);
    16739
    16740 haslhs = !SCIPisInfinity(scip, -consdata->lhs);
    16741 hasrhs = !SCIPisInfinity(scip, consdata->rhs);
    16742
    16743 /* update rounding locks of every single variable */
    16744 for( i = 0; i < consdata->nvars; ++i )
    16745 {
    16746 if( SCIPisPositive(scip, consdata->vals[i]) )
    16747 {
    16748 if( haslhs )
    16749 {
    16750 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
    16751 }
    16752 if( hasrhs )
    16753 {
    16754 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
    16755 }
    16756 }
    16757 else
    16758 {
    16759 if( haslhs )
    16760 {
    16761 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
    16762 }
    16763 if( hasrhs )
    16764 {
    16765 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
    16766 }
    16767 }
    16768 }
    16769
    16770 return SCIP_OKAY;
    16771}
    16772
    16773
    16774/** variable deletion method of constraint handler */
    16775static
    16776SCIP_DECL_CONSDELVARS(consDelvarsLinear)
    16777{
    16778 assert(scip != NULL);
    16779 assert(conshdlr != NULL);
    16780 assert(conss != NULL || nconss == 0);
    16781
    16782 if( nconss > 0 )
    16783 {
    16784 SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
    16785 }
    16786
    16787 return SCIP_OKAY;
    16788}
    16789
    16790/** constraint display method of constraint handler */
    16791static
    16792SCIP_DECL_CONSPRINT(consPrintLinear)
    16793{ /*lint --e{715}*/
    16794 assert(scip != NULL);
    16795 assert(conshdlr != NULL);
    16796 assert(cons != NULL);
    16797
    16799
    16800 return SCIP_OKAY;
    16801}
    16802
    16803/** constraint copying method of constraint handler */
    16804static
    16805SCIP_DECL_CONSCOPY(consCopyLinear)
    16806{ /*lint --e{715}*/
    16807 SCIP_VAR** sourcevars;
    16808 SCIP_Real* sourcecoefs;
    16809 const char* consname;
    16810 int nvars;
    16811
    16812 assert(scip != NULL);
    16813 assert(sourcescip != NULL);
    16814 assert(sourcecons != NULL);
    16815
    16816 /* get variables and coefficients of the source constraint */
    16817 sourcevars = SCIPgetVarsLinear(sourcescip, sourcecons);
    16818 sourcecoefs = SCIPgetValsLinear(sourcescip, sourcecons);
    16819 nvars = SCIPgetNVarsLinear(sourcescip, sourcecons);
    16820
    16821 if( name != NULL )
    16822 consname = name;
    16823 else
    16824 consname = SCIPconsGetName(sourcecons);
    16825
    16826 SCIP_CALL( SCIPcopyConsLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
    16827 SCIPgetLhsLinear(sourcescip, sourcecons), SCIPgetRhsLinear(sourcescip, sourcecons), varmap, consmap,
    16828 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
    16829 assert(cons != NULL || *valid == FALSE);
    16830
    16831 /* @todo should also the checkabsolute flag of the constraint be copied? */
    16832
    16833 return SCIP_OKAY;
    16834}
    16835
    16836/** find operators '<=', '==', '>=', [free] in input string and return those places
    16837 *
    16838 * There should only be one operator, except for ranged rows for which exactly two operators '<=' must be present.
    16839 */
    16840static
    16842 const char* str, /**< null terminated input string */
    16843 char** firstoperator, /**< pointer to store the string starting at the first operator */
    16844 char** secondoperator, /**< pointer to store the string starting at the second operator */
    16845 SCIP_Bool* success /**< pointer to store if the line contains a valid operator order */
    16846 )
    16847{
    16848 char* curr;
    16849
    16850 assert(str != NULL);
    16851 assert(firstoperator != NULL);
    16852 assert(secondoperator != NULL);
    16853
    16854 *firstoperator = NULL;
    16855 *secondoperator = NULL;
    16856
    16857 curr = (char*)str;
    16858 *success = TRUE;
    16859
    16860 /* loop over the input string to find all operators */
    16861 while( *curr && *success )
    16862 {
    16863 SCIP_Bool found = FALSE;
    16864 int increment = 1;
    16865
    16866 /* try if we found a possible operator */
    16867 switch( *curr )
    16868 {
    16869 case '<':
    16870 case '=':
    16871 case '>':
    16872
    16873 /* check if the two characters curr[0,1] form an operator together */
    16874 if( curr[1] == '=' )
    16875 {
    16876 found = TRUE;
    16877
    16878 /* update increment to continue after this operator */
    16879 increment = 2;
    16880 }
    16881 break;
    16882 case '[':
    16883 if( strncmp(curr, "[free]", 6) == 0 )
    16884 {
    16885 found = TRUE;
    16886
    16887 /* update increment to continue after this operator */
    16888 increment = 6;
    16889 }
    16890 break;
    16891 default:
    16892 break;
    16893 }
    16894
    16895 /* assign the found operator to the first or second pointer and check for violations of the linear constraint grammar */
    16896 if( found )
    16897 {
    16898 if( *firstoperator == NULL )
    16899 {
    16900 *firstoperator = curr;
    16901 }
    16902 else
    16903 {
    16904 if( *secondoperator != NULL )
    16905 {
    16906 SCIPerrorMessage("Found more than two operators in line %s\n", str);
    16907 *success = FALSE;
    16908 }
    16909 else if( strncmp(*firstoperator, "<=", 2) != 0 )
    16910 {
    16911 SCIPerrorMessage("Two operators in line that is not a ranged row: %s", str);
    16912 *success = FALSE;
    16913 }
    16914 else if( strncmp(curr, "<=", 2) != 0 )
    16915 {
    16916 SCIPerrorMessage("Bad second operator, expected ranged row specification: %s", str);
    16917 *success = FALSE;
    16918 }
    16919
    16920 *secondoperator = curr;
    16921 }
    16922 }
    16923
    16924 curr += increment;
    16925 }
    16926
    16927 /* check if we did find at least one operator */
    16928 if( *success )
    16929 {
    16930 if( *firstoperator == NULL )
    16931 {
    16932 SCIPerrorMessage("Could not find any operator in line %s\n", str);
    16933 *success = FALSE;
    16934 }
    16935 }
    16936}
    16937
    16938/** constraint parsing method of constraint handler */
    16939static
    16940SCIP_DECL_CONSPARSE(consParseLinear)
    16941{ /*lint --e{715}*/
    16942 SCIP_VAR** vars;
    16943 SCIP_Real* coefs = NULL;
    16944 int nvars;
    16945 int coefssize = 100;
    16946 int requsize;
    16947 SCIP_Real lhs;
    16948 SCIP_Real rhs;
    16949 char* endptr;
    16950 char* firstop;
    16951 char* secondop;
    16952 SCIP_Bool operatorsuccess;
    16953 char* lhsstrptr = NULL;
    16954 char* rhsstrptr = NULL;
    16955 char* varstrptr = (char*)str;
    16956
    16957 assert(scip != NULL);
    16958 assert(success != NULL);
    16959 assert(str != NULL);
    16960 assert(name != NULL);
    16961 assert(cons != NULL);
    16962
    16963 *success = FALSE;
    16964
    16965 /* return of string empty */
    16966 if( !(*str) )
    16967 return SCIP_OKAY;
    16968
    16969 /* set left and right hand side to their default values */
    16970 lhs = -SCIPinfinity(scip);
    16971 rhs = SCIPinfinity(scip);
    16972
    16973 /* ignore whitespace */
    16974 SCIP_CALL( SCIPskipSpace((char**)&str) );
    16975
    16976 /* find operators in the line first, all other remaining parsing depends on occurence of the operators '<=', '>=', '==',
    16977 * and the special word [free]
    16978 */
    16979 findOperators(str, &firstop, &secondop, &operatorsuccess);
    16980
    16981 /* if the grammar is not valid for parsing a linear constraint, return */
    16982 if( ! operatorsuccess )
    16983 return SCIP_OKAY;
    16984 assert(firstop != NULL);
    16985
    16986 /* assign the strings for parsing the left hand side, right hand side, and the linear variable sum */
    16987 switch( *firstop )
    16988 {
    16989 case '<':
    16990 assert(firstop[1] == '=');
    16991 /* we have ranged row lhs <= a_1 x_1 + ... + a_n x_n <= rhs */
    16992 if( secondop != NULL )
    16993 {
    16994 assert(secondop[0] == '<' && secondop[1] == '=');
    16995 lhsstrptr = (char *)str;
    16996 varstrptr = firstop + 2;
    16997 rhsstrptr = secondop + 2;
    16998 }
    16999 else
    17000 {
    17001 /* we have an inequality with infinite left hand side a_1 x_1 + ... + a_n x_n <= rhs */
    17002 lhsstrptr = NULL;
    17003 varstrptr = (char *)str;
    17004 rhsstrptr = firstop + 2;
    17005 }
    17006 break;
    17007 case '>':
    17008 assert(firstop[1] == '=');
    17009 assert(secondop == NULL);
    17010 /* we have a_1 x_1 + ... + a_n x_n >= lhs */
    17011 lhsstrptr = firstop + 2;
    17012 break;
    17013 case '=':
    17014 assert(firstop[1] == '=');
    17015 assert(secondop == NULL);
    17016 /* we have a_1 x_1 + ... + a_n x_n == lhs (rhs) */
    17017 rhsstrptr = firstop + 2;
    17018 lhsstrptr = firstop + 2;
    17019 break;
    17020 case '[':
    17021 assert(strncmp(firstop, "[free]", 6) == 0);
    17022 assert(secondop == NULL);
    17023 /* nothing to assign in case of a free a_1 x_1 + ... + a_n x_n [free] */
    17024 break;
    17025 default:
    17026 /* it should not be possible that a different character appears in that position */
    17027 SCIPerrorMessage("Parsing has wrong operator character '%c', should be one of <=>[", *firstop);
    17028 return SCIP_READERROR;
    17029 }
    17030
    17031 /* parse left hand side, if necessary */
    17032 if( lhsstrptr != NULL )
    17033 {
    17034 if( ! SCIPparseReal(scip, lhsstrptr, &lhs, &endptr) )
    17035 {
    17036 SCIPerrorMessage("error parsing left hand side number from <%s>\n", lhsstrptr);
    17037 return SCIP_OKAY;
    17038 }
    17039
    17040 /* in case of an equation, assign the left also to the right hand side */
    17041 if( rhsstrptr == lhsstrptr )
    17042 rhs = lhs;
    17043 }
    17044
    17045 /* parse right hand side, if different from left hand side */
    17046 if( rhsstrptr != NULL && rhsstrptr != lhsstrptr )
    17047 {
    17048 if( ! SCIPparseReal(scip, rhsstrptr, &rhs, &endptr) )
    17049 {
    17050 SCIPerrorMessage("error parsing right hand side number from <%s>\n", lhsstrptr);
    17051 return SCIP_OKAY;
    17052 }
    17053 }
    17054
    17055 /* initialize buffers for storing the variables and coefficients */
    17056 SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
    17057 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, coefssize) );
    17058
    17059 assert(varstrptr != NULL);
    17060
    17061 /* parse linear sum to get variables and coefficients */
    17062 SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
    17063
    17064 if( *success && requsize > coefssize )
    17065 {
    17066 /* realloc buffers and try again */
    17067 coefssize = requsize;
    17068 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, coefssize) );
    17069 SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, coefssize) );
    17070
    17071 SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
    17072 assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
    17073 }
    17074
    17075 if( !*success )
    17076 {
    17077 SCIPerrorMessage("no luck in parsing linear sum '%s'\n", varstrptr);
    17078 }
    17079 else
    17080 {
    17081 SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
    17082 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    17083 }
    17084
    17085 SCIPfreeBufferArray(scip, &coefs);
    17086 SCIPfreeBufferArray(scip, &vars);
    17087
    17088 return SCIP_OKAY;
    17089}
    17090
    17091
    17092/** constraint method of constraint handler which returns the variables (if possible) */
    17093static
    17094SCIP_DECL_CONSGETVARS(consGetVarsLinear)
    17095{ /*lint --e{715}*/
    17096 SCIP_CONSDATA* consdata;
    17097
    17098 consdata = SCIPconsGetData(cons);
    17099 assert(consdata != NULL);
    17100
    17101 if( varssize < consdata->nvars )
    17102 (*success) = FALSE;
    17103 else
    17104 {
    17105 assert(vars != NULL);
    17106
    17107 BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
    17108 (*success) = TRUE;
    17109 }
    17110
    17111 return SCIP_OKAY;
    17112}
    17113
    17114/**! [Callback for the number of variables]*/
    17115/** constraint method of constraint handler which returns the number of variables (if possible) */
    17116static
    17117SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
    17118{ /*lint --e{715}*/
    17119 SCIP_CONSDATA* consdata;
    17120
    17121 consdata = SCIPconsGetData(cons);
    17122 assert(consdata != NULL);
    17123
    17124 (*nvars) = consdata->nvars;
    17125 (*success) = TRUE;
    17126
    17127 return SCIP_OKAY;
    17128}
    17129/**! [Callback for the number of variables]*/
    17130
    17131/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
    17132static
    17133SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphLinear)
    17134{ /*lint --e{715}*/
    17135 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_PERM, cons, graph, success) );
    17136
    17137 return SCIP_OKAY;
    17138}
    17139
    17140/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
    17141static
    17142SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphLinear)
    17143{ /*lint --e{715}*/
    17144 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_SIGNPERM, cons, graph, success) );
    17145
    17146 return SCIP_OKAY;
    17147}
    17148
    17149/*
    17150 * Callback methods of event handler
    17151 */
    17152
    17153/** execution method of event handler */
    17154static
    17155SCIP_DECL_EVENTEXEC(eventExecLinear)
    17156{ /*lint --e{715}*/
    17157 SCIP_CONS* cons;
    17158 SCIP_CONSDATA* consdata;
    17159 SCIP_VAR* var;
    17160 SCIP_EVENTTYPE eventtype;
    17161
    17162 assert(scip != NULL);
    17163 assert(eventhdlr != NULL);
    17164 assert(eventdata != NULL);
    17165 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    17166 assert(event != NULL);
    17167
    17168 cons = eventdata->cons;
    17169 assert(cons != NULL);
    17170 consdata = SCIPconsGetData(cons);
    17171 assert(consdata != NULL);
    17172
    17173 /* we can skip events droped for deleted constraints */
    17174 if( SCIPconsIsDeleted(cons) )
    17175 return SCIP_OKAY;
    17176
    17177 eventtype = SCIPeventGetType(event);
    17178 var = SCIPeventGetVar(event);
    17179
    17181 {
    17182 SCIP_Real oldbound;
    17183 SCIP_Real newbound;
    17184 SCIP_Real val;
    17185 int varpos;
    17186
    17187 varpos = eventdata->varpos;
    17188 assert(0 <= varpos && varpos < consdata->nvars);
    17189 oldbound = SCIPeventGetOldbound(event);
    17190 newbound = SCIPeventGetNewbound(event);
    17191 assert(var != NULL);
    17192 assert(consdata->vars[varpos] == var);
    17193 val = consdata->vals[varpos];
    17194
    17195 /* we only need to update the activities if the constraint is active,
    17196 * otherwise we mark them to be invalid
    17197 */
    17198 if( SCIPconsIsActive(cons) )
    17199 {
    17200 /* update the activity values */
    17202 consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, val, TRUE);
    17203 else
    17204 {
    17205 assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != SCIP_EVENTTYPE_DISABLED);
    17206 consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, val, TRUE);
    17207 }
    17208 }
    17209 else
    17211
    17212 consdata->presolved = FALSE;
    17213 consdata->rangedrowpropagated = 0;
    17214
    17215 /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
    17217 {
    17219
    17220 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
    17221 if( consdata->maxactdeltavar == var )
    17222 {
    17223 consdata->maxactdelta = SCIP_INVALID;
    17224 consdata->maxactdeltavar = NULL;
    17225 }
    17226
    17227 /* check whether bound tightening might now be successful */
    17228 if( consdata->boundstightened > 0)
    17229 {
    17230 switch( eventtype )
    17231 {
    17233 if( (val > 0.0 ? !SCIPisInfinity(scip, consdata->rhs) : !SCIPisInfinity(scip, -consdata->lhs)) )
    17234 consdata->boundstightened = 0;
    17235 break;
    17237 if( (val > 0.0 ? !SCIPisInfinity(scip, -consdata->lhs) : !SCIPisInfinity(scip, consdata->rhs)) )
    17238 consdata->boundstightened = 0;
    17239 break;
    17240 default:
    17241 SCIPerrorMessage("invalid event type %" SCIP_EVENTTYPE_FORMAT "\n", eventtype);
    17242 return SCIP_INVALIDDATA;
    17243 }
    17244 }
    17245 }
    17246 /* update maximal activity delta if a bound was relaxed */
    17247 else if( !SCIPisInfinity(scip, consdata->maxactdelta) )
    17248 {
    17249 SCIP_Real lb;
    17250 SCIP_Real ub;
    17251 SCIP_Real domain;
    17252 SCIP_Real delta;
    17253
    17255
    17256 lb = SCIPvarGetLbLocal(var);
    17257 ub = SCIPvarGetUbLocal(var);
    17258
    17259 domain = ub - lb;
    17260 delta = REALABS(val) * domain;
    17261
    17262 if( delta > consdata->maxactdelta )
    17263 {
    17264 consdata->maxactdelta = delta;
    17265 consdata->maxactdeltavar = var;
    17266 }
    17267 }
    17268 }
    17269 else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != SCIP_EVENTTYPE_DISABLED )
    17270 {
    17271 /* we want to remove the fixed variable */
    17272 consdata->presolved = FALSE;
    17273 consdata->removedfixings = FALSE;
    17274 consdata->rangedrowpropagated = 0;
    17275
    17276 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
    17277 if( consdata->maxactdeltavar == var )
    17278 {
    17279 consdata->maxactdelta = SCIP_INVALID;
    17280 consdata->maxactdeltavar = NULL;
    17281 }
    17282 }
    17283 else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != SCIP_EVENTTYPE_DISABLED )
    17284 {
    17285 /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
    17288 consdata->presolved = FALSE;
    17289 }
    17290 else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != SCIP_EVENTTYPE_DISABLED )
    17291 {
    17292 SCIP_Real oldbound;
    17293 SCIP_Real newbound;
    17294 SCIP_Real val;
    17295 int varpos;
    17296
    17297 varpos = eventdata->varpos;
    17298 assert(0 <= varpos && varpos < consdata->nvars);
    17299 oldbound = SCIPeventGetOldbound(event);
    17300 newbound = SCIPeventGetNewbound(event);
    17301 assert(var != NULL);
    17302 assert(consdata->vars[varpos] == var);
    17303 val = consdata->vals[varpos];
    17304
    17305 consdata->rangedrowpropagated = 0;
    17306
    17307 /* update the activity values */
    17309 consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, val, TRUE);
    17310 else
    17311 {
    17312 assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != SCIP_EVENTTYPE_DISABLED);
    17313 consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, val, TRUE);
    17314 }
    17315
    17316 /* if the variable is binary but not fixed it had to become binary due to this global change */
    17318 {
    17320 consdata->indexsorted = FALSE;
    17321 else
    17322 consdata->coefsorted = FALSE;
    17323 }
    17324 }
    17325 else if( (eventtype & SCIP_EVENTTYPE_TYPECHANGED) != SCIP_EVENTTYPE_DISABLED )
    17326 {
    17328
    17329 /* for presolving it only matters if a variable becomes integral */
    17330 consdata->presolved = (consdata->presolved && (SCIPeventGetOldtype(event) != SCIP_VARTYPE_CONTINUOUS || SCIPvarIsImpliedIntegral(var)));
    17331
    17332 /* the ordering is preserved if the variable remains binary */
    17333 consdata->indexsorted = (consdata->indexsorted && SCIPvarIsBinary(var) && (SCIPeventGetOldtype(event) != SCIP_VARTYPE_CONTINUOUS || SCIPvarIsImpliedIntegral(var)));
    17334 }
    17336 {
    17338
    17339 /* for presolving it only matters if a variable becomes integral */
    17340 consdata->presolved = (consdata->presolved && (SCIPeventGetOldImpltype(event) != SCIP_IMPLINTTYPE_NONE || SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS));
    17341
    17342 /* the ordering is preserved if the variable remains binary */
    17343 consdata->indexsorted = (consdata->indexsorted && SCIPvarIsBinary(var) && (SCIPeventGetOldImpltype(event) != SCIP_IMPLINTTYPE_NONE || SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS));
    17344 }
    17345 else
    17346 {
    17347 assert((eventtype & SCIP_EVENTTYPE_VARDELETED) != SCIP_EVENTTYPE_DISABLED);
    17348 consdata->varsdeleted = TRUE;
    17349 }
    17350
    17351 return SCIP_OKAY;
    17352}
    17353
    17354
    17355/*
    17356 * Callback methods of conflict handler
    17357 */
    17358
    17359/** conflict processing method of conflict handler (called when conflict was found) */
    17360static
    17361SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
    17362{ /*lint --e{715}*/
    17363 SCIP_VAR** vars;
    17364 SCIP_Real* vals;
    17365 SCIP_Real lhs;
    17366 int i;
    17367
    17368 assert(scip != NULL);
    17369 assert(conflicthdlr != NULL);
    17370 assert(strcmp(SCIPconflicthdlrGetName(conflicthdlr), CONFLICTHDLR_NAME) == 0);
    17371 assert(bdchginfos != NULL || nbdchginfos == 0);
    17372 assert(result != NULL);
    17373
    17374 /* don't process already resolved conflicts */
    17375 if( resolved )
    17376 {
    17377 *result = SCIP_DIDNOTRUN;
    17378 return SCIP_OKAY;
    17379 }
    17380
    17381 *result = SCIP_DIDNOTFIND;
    17382
    17383 /* create array of variables and coefficients: sum_{i \in P} x_i - sum_{i \in N} x_i >= 1 - |N| */
    17384 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
    17385 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nbdchginfos) );
    17386 lhs = 1.0;
    17387 for( i = 0; i < nbdchginfos; ++i )
    17388 {
    17389 assert(bdchginfos != NULL);
    17390
    17391 vars[i] = SCIPbdchginfoGetVar(bdchginfos[i]);
    17392
    17393 /* we can only treat binary variables */
    17394 /**@todo extend linear conflict constraints to some non-binary cases */
    17395 if( !SCIPvarIsBinary(vars[i]) )
    17396 break;
    17397
    17398 /* check whether the variable is fixed to zero (P) or one (N) in the conflict set */
    17399 if( SCIPbdchginfoGetNewbound(bdchginfos[i]) < 0.5 )
    17400 vals[i] = 1.0;
    17401 else
    17402 {
    17403 vals[i] = -1.0;
    17404 lhs -= 1.0;
    17405 }
    17406 }
    17407
    17408 if( i == nbdchginfos )
    17409 {
    17410 SCIP_CONS* cons;
    17411 SCIP_CONS* upgdcons;
    17412 char consname[SCIP_MAXSTRLEN];
    17413
    17414 /* create a constraint out of the conflict set */
    17416 SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, nbdchginfos, vars, vals, lhs, SCIPinfinity(scip),
    17417 FALSE, separate, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
    17418
    17419 /* try to automatically convert a linear constraint into a more specific and more specialized constraint */
    17420 SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
    17421 if( upgdcons != NULL )
    17422 {
    17423 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    17424 cons = upgdcons;
    17425 }
    17426
    17427 /* add conflict to SCIP */
    17428 SCIP_CALL( SCIPaddConflict(scip, node, &cons, validnode, conftype, cutoffinvolved) );
    17429
    17430 *result = SCIP_CONSADDED;
    17431 }
    17432
    17433 /* free temporary memory */
    17434 SCIPfreeBufferArray(scip, &vals);
    17435 SCIPfreeBufferArray(scip, &vars);
    17436
    17437 return SCIP_OKAY;
    17438}
    17439
    17440
    17441/*
    17442 * Nonlinear constraint upgrading
    17443 */
    17444
    17445/** tries to upgrade a nonlinear constraint into a linear constraint */
    17446static
    17447SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
    17448{
    17449 SCIP_CONSDATA* consdata;
    17450 SCIP_EXPR* expr;
    17451 SCIP_Real lhs;
    17452 SCIP_Real rhs;
    17453 int i;
    17454
    17455 assert(nupgdconss != NULL);
    17456 assert(upgdconss != NULL);
    17457 assert(upgdconsssize > 0);
    17458
    17459 expr = SCIPgetExprNonlinear(cons);
    17460 assert(expr != NULL);
    17461
    17462 /* not a linear constraint if the expression is not a sum
    17463 * (unless the expression is a variable or a constant or a constant*variable, but these are simplified away in cons_nonlinear)
    17464 */
    17465 if( !SCIPisExprSum(scip, expr) )
    17466 return SCIP_OKAY;
    17467
    17468 /* if at least one child is not a variable, then not a linear constraint */
    17469 for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
    17470 if( !SCIPisExprVar(scip, SCIPexprGetChildren(expr)[i]) )
    17471 return SCIP_OKAY;
    17472
    17473 /* consider constant part of the sum expression */
    17476
    17477 SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
    17478 0, NULL, NULL, lhs, rhs,
    17482 SCIPconsIsStickingAtNode(cons)) );
    17483 assert(upgdconss[0] != NULL);
    17484
    17485 consdata = SCIPconsGetData(upgdconss[0]);
    17486
    17487 /* add linear terms */
    17489 for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
    17490 {
    17492 }
    17493
    17494 /* check violation of this linear constraint with absolute tolerances, to be consistent with the original nonlinear constraint */
    17495 consdata->checkabsolute = TRUE;
    17496
    17497 *nupgdconss = 1;
    17498
    17499 SCIPdebugMsg(scip, "created linear constraint:\n");
    17500 SCIPdebugPrintCons(scip, upgdconss[0], NULL);
    17501
    17502 return SCIP_OKAY;
    17503} /*lint !e715*/
    17504
    17505/*
    17506 * constraint specific interface methods
    17507 */
    17508
    17509/** creates the handler for linear constraints and includes it in SCIP */
    17511 SCIP* scip /**< SCIP data structure */
    17512 )
    17513{
    17514 SCIP_CONSHDLRDATA* conshdlrdata;
    17515 SCIP_CONSHDLR* conshdlr;
    17516 SCIP_EVENTHDLR* eventhdlr;
    17517 SCIP_CONFLICTHDLR* conflicthdlr;
    17518
    17519 assert(scip != NULL);
    17520
    17521 /* create event handler for bound change events */
    17523 eventExecLinear, NULL) );
    17524
    17525 /* create conflict handler for linear constraints */
    17527 conflictExecLinear, NULL) );
    17528
    17529 /* create constraint handler data */
    17530 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
    17531
    17532 /* include constraint handler */
    17535 consEnfolpLinear, consEnfopsLinear, consCheckLinear, consLockLinear,
    17536 conshdlrdata) );
    17537
    17538 assert(conshdlr != NULL);
    17539
    17540 /* set non-fundamental callbacks via specific setter functions */
    17541 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinear, consCopyLinear) );
    17542 SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveLinear) );
    17543 SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveLinear) );
    17544 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinear) );
    17545 SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsLinear) );
    17546 SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitLinear) );
    17547 SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreLinear) );
    17548 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolLinear) );
    17549 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinear) );
    17550 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinear) );
    17551 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinear) );
    17552 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinear) );
    17553 SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitLinear) );
    17554 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinear) );
    17555 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinear) );
    17557 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinear) );
    17560 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinear) );
    17561 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinear, consSepasolLinear, CONSHDLR_SEPAFREQ,
    17563 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinear) );
    17564 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxLinear) );
    17565 SCIP_CALL( SCIPsetConshdlrGetPermsymGraph(scip, conshdlr, consGetPermsymGraphLinear) );
    17566 SCIP_CALL( SCIPsetConshdlrGetSignedPermsymGraph(scip, conshdlr, consGetSignedPermsymGraphLinear) );
    17567
    17568 if( SCIPfindConshdlr(scip, "nonlinear") != NULL )
    17569 {
    17570 /* include the linear constraint upgrade in the nonlinear constraint handler */
    17572 }
    17573
    17574 /* add linear constraint handler parameters */
    17576 "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
    17577 "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
    17578 &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
    17580 "constraints/" CONSHDLR_NAME "/maxrounds",
    17581 "maximal number of separation rounds per node (-1: unlimited)",
    17582 &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
    17584 "constraints/" CONSHDLR_NAME "/maxroundsroot",
    17585 "maximal number of separation rounds per node in the root node (-1: unlimited)",
    17586 &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
    17588 "constraints/" CONSHDLR_NAME "/maxsepacuts",
    17589 "maximal number of cuts separated per separation round",
    17590 &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
    17592 "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
    17593 "maximal number of cuts separated per separation round in the root node",
    17594 &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
    17596 "constraints/" CONSHDLR_NAME "/presolpairwise",
    17597 "should pairwise constraint comparison be performed in presolving?",
    17598 &conshdlrdata->presolpairwise, TRUE, DEFAULT_PRESOLPAIRWISE, NULL, NULL) );
    17600 "constraints/" CONSHDLR_NAME "/presolusehashing",
    17601 "should hash table be used for detecting redundant constraints in advance",
    17602 &conshdlrdata->presolusehashing, TRUE, DEFAULT_PRESOLUSEHASHING, NULL, NULL) );
    17604 "constraints/" CONSHDLR_NAME "/nmincomparisons",
    17605 "number for minimal pairwise presolve comparisons",
    17606 &conshdlrdata->nmincomparisons, TRUE, DEFAULT_NMINCOMPARISONS, 1, INT_MAX, NULL, NULL) );
    17608 "constraints/" CONSHDLR_NAME "/mingainpernmincomparisons",
    17609 "minimal gain per minimal pairwise presolve comparisons to repeat pairwise comparison round",
    17610 &conshdlrdata->mingainpernmincomp, TRUE, DEFAULT_MINGAINPERNMINCOMP, 0.0, 1.0, NULL, NULL) );
    17612 "constraints/" CONSHDLR_NAME "/maxaggrnormscale",
    17613 "maximal allowed relative gain in maximum norm for constraint aggregation (0.0: disable constraint aggregation)",
    17614 &conshdlrdata->maxaggrnormscale, TRUE, DEFAULT_MAXAGGRNORMSCALE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    17616 "constraints/" CONSHDLR_NAME "/maxeasyactivitydelta",
    17617 "maximum activity delta to run easy propagation on linear constraint (faster, but numerically less stable)",
    17618 &conshdlrdata->maxeasyactivitydelta, TRUE, DEFAULT_MAXEASYACTIVITYDELTA, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    17620 "constraints/" CONSHDLR_NAME "/maxcardbounddist",
    17621 "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for separating knapsack cardinality cuts",
    17622 &conshdlrdata->maxcardbounddist, TRUE, DEFAULT_MAXCARDBOUNDDIST, 0.0, 1.0, NULL, NULL) );
    17624 "constraints/" CONSHDLR_NAME "/separateall",
    17625 "should all constraints be subject to cardinality cut generation instead of only the ones with non-zero dual value?",
    17626 &conshdlrdata->separateall, FALSE, DEFAULT_SEPARATEALL, NULL, NULL) );
    17628 "constraints/" CONSHDLR_NAME "/aggregatevariables",
    17629 "should presolving search for aggregations in equations",
    17630 &conshdlrdata->aggregatevariables, TRUE, DEFAULT_AGGREGATEVARIABLES, NULL, NULL) );
    17632 "constraints/" CONSHDLR_NAME "/simplifyinequalities",
    17633 "should presolving try to simplify inequalities",
    17634 &conshdlrdata->simplifyinequalities, TRUE, DEFAULT_SIMPLIFYINEQUALITIES, NULL, NULL) );
    17636 "constraints/" CONSHDLR_NAME "/dualpresolving",
    17637 "should dual presolving steps be performed?",
    17638 &conshdlrdata->dualpresolving, TRUE, DEFAULT_DUALPRESOLVING, NULL, NULL) );
    17640 "constraints/" CONSHDLR_NAME "/singletonstuffing",
    17641 "should stuffing of singleton continuous variables be performed?",
    17642 &conshdlrdata->singletonstuffing, TRUE, DEFAULT_SINGLETONSTUFFING, NULL, NULL) );
    17644 "constraints/" CONSHDLR_NAME "/singlevarstuffing",
    17645 "should single variable stuffing be performed, which tries to fulfill constraints using the cheapest variable?",
    17646 &conshdlrdata->singlevarstuffing, TRUE, DEFAULT_SINGLEVARSTUFFING, NULL, NULL) );
    17648 "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
    17649 &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
    17651 "constraints/" CONSHDLR_NAME "/checkrelmaxabs",
    17652 "should the violation for a constraint with side 0.0 be checked relative to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)?",
    17653 &conshdlrdata->checkrelmaxabs, TRUE, DEFAULT_CHECKRELMAXABS, NULL, NULL) );
    17655 "constraints/" CONSHDLR_NAME "/detectcutoffbound",
    17656 "should presolving try to detect constraints parallel to the objective function defining an upper bound and prevent these constraints from entering the LP?",
    17657 &conshdlrdata->detectcutoffbound, TRUE, DEFAULT_DETECTCUTOFFBOUND, NULL, NULL) );
    17659 "constraints/" CONSHDLR_NAME "/detectlowerbound",
    17660 "should presolving try to detect constraints parallel to the objective function defining a lower bound and prevent these constraints from entering the LP?",
    17661 &conshdlrdata->detectlowerbound, TRUE, DEFAULT_DETECTLOWERBOUND, NULL, NULL) );
    17663 "constraints/" CONSHDLR_NAME "/detectpartialobjective",
    17664 "should presolving try to detect subsets of constraints parallel to the objective function?",
    17665 &conshdlrdata->detectpartialobjective, TRUE, DEFAULT_DETECTPARTIALOBJECTIVE, NULL, NULL) );
    17667 "constraints/" CONSHDLR_NAME "/rangedrowpropagation",
    17668 "should presolving and propagation try to improve bounds, detect infeasibility, and extract sub-constraints from ranged rows and equations?",
    17669 &conshdlrdata->rangedrowpropagation, TRUE, DEFAULT_RANGEDROWPROPAGATION, NULL, NULL) );
    17671 "constraints/" CONSHDLR_NAME "/rangedrowartcons",
    17672 "should presolving and propagation extract sub-constraints from ranged rows and equations?",
    17673 &conshdlrdata->rangedrowartcons, TRUE, DEFAULT_RANGEDROWARTCONS, NULL, NULL) );
    17675 "constraints/" CONSHDLR_NAME "/rangedrowmaxdepth",
    17676 "maximum depth to apply ranged row propagation",
    17677 &conshdlrdata->rangedrowmaxdepth, TRUE, DEFAULT_RANGEDROWMAXDEPTH, 0, INT_MAX, NULL, NULL) );
    17679 "constraints/" CONSHDLR_NAME "/rangedrowfreq",
    17680 "frequency for applying ranged row propagation",
    17681 &conshdlrdata->rangedrowfreq, TRUE, DEFAULT_RANGEDROWFREQ, 1, SCIP_MAXTREEDEPTH, NULL, NULL) );
    17683 "constraints/" CONSHDLR_NAME "/multaggrremove",
    17684 "should multi-aggregations only be performed if the constraint can be removed afterwards?",
    17685 &conshdlrdata->multaggrremove, TRUE, DEFAULT_MULTAGGRREMOVE, NULL, NULL) );
    17687 "constraints/" CONSHDLR_NAME "/maxmultaggrquot",
    17688 "maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation",
    17689 &conshdlrdata->maxmultaggrquot, TRUE, DEFAULT_MAXMULTAGGRQUOT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
    17691 "constraints/" CONSHDLR_NAME "/maxdualmultaggrquot",
    17692 "maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation",
    17693 &conshdlrdata->maxdualmultaggrquot, TRUE, DEFAULT_MAXDUALMULTAGGRQUOT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
    17695 "constraints/" CONSHDLR_NAME "/extractcliques",
    17696 "should Cliques be extracted?",
    17697 &conshdlrdata->extractcliques, TRUE, DEFAULT_EXTRACTCLIQUES, NULL, NULL) );
    17698
    17699 return SCIP_OKAY;
    17700}
    17701
    17702/** includes a linear constraint update method into the linear constraint handler */
    17704 SCIP* scip, /**< SCIP data structure */
    17705 SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
    17706 int priority, /**< priority of upgrading method */
    17707 const char* conshdlrname /**< name of the constraint handler */
    17708 )
    17709{
    17710 SCIP_CONSHDLR* conshdlr;
    17711 SCIP_CONSHDLRDATA* conshdlrdata;
    17712 SCIP_LINCONSUPGRADE* linconsupgrade;
    17714 char paramdesc[SCIP_MAXSTRLEN];
    17715
    17716 assert(scip != NULL);
    17717 assert(linconsupgd != NULL);
    17718 assert(conshdlrname != NULL );
    17719
    17720 /* find the linear constraint handler */
    17721 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    17722 if( conshdlr == NULL )
    17723 {
    17724 SCIPerrorMessage("linear constraint handler not found\n");
    17725 return SCIP_PLUGINNOTFOUND;
    17726 }
    17727
    17728 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    17729 assert(conshdlrdata != NULL);
    17730
    17731 /* check if linear constraint update method already exists in constraint handler data */
    17732 if( !conshdlrdataHasUpgrade(scip, conshdlrdata, linconsupgd, conshdlrname) )
    17733 {
    17734 /* create a linear constraint upgrade data object */
    17735 SCIP_CALL( linconsupgradeCreate(scip, &linconsupgrade, linconsupgd, priority) );
    17736
    17737 /* insert linear constraint update method into constraint handler data */
    17738 SCIP_CALL( conshdlrdataIncludeUpgrade(scip, conshdlrdata, linconsupgrade) );
    17739
    17740 /* adds parameter to turn on and off the upgrading step */
    17741 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/linear/upgrade/%s", conshdlrname);
    17742 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "enable linear upgrading for constraint handler <%s>", conshdlrname);
    17744 paramname, paramdesc,
    17745 &linconsupgrade->active, FALSE, TRUE, NULL, NULL) );
    17746 }
    17747
    17748 return SCIP_OKAY;
    17749}
    17750
    17751/** creates and captures a linear constraint
    17752 *
    17753 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    17754 */
    17756 SCIP* scip, /**< SCIP data structure */
    17757 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    17758 const char* name, /**< name of constraint */
    17759 int nvars, /**< number of nonzeros in the constraint */
    17760 SCIP_VAR** vars, /**< array with variables of constraint entries */
    17761 SCIP_Real* vals, /**< array with coefficients of constraint entries */
    17762 SCIP_Real lhs, /**< left hand side of constraint */
    17763 SCIP_Real rhs, /**< right hand side of constraint */
    17764 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    17765 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    17766 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    17767 * Usually set to TRUE. */
    17768 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    17769 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    17770 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    17771 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    17772 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    17773 * Usually set to TRUE. */
    17774 SCIP_Bool local, /**< is constraint only valid locally?
    17775 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    17776 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
    17777 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
    17778 * adds coefficients to this constraint. */
    17779 SCIP_Bool dynamic, /**< is constraint subject to aging?
    17780 * Usually set to FALSE. Set to TRUE for own cuts which
    17781 * are separated as constraints. */
    17782 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    17783 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    17784 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    17785 * if it may be moved to a more global node?
    17786 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    17787 )
    17788{
    17789 SCIP_CONSHDLR* conshdlr;
    17790 SCIP_CONSDATA* consdata;
    17791 int i;
    17792
    17793 assert(scip != NULL);
    17794 assert(cons != NULL);
    17795
    17796 /* find the linear constraint handler */
    17797 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    17798 if( conshdlr == NULL )
    17799 {
    17800 SCIPerrorMessage("linear constraint handler not found\n");
    17801 return SCIP_PLUGINNOTFOUND;
    17802 }
    17803
    17804 /* terminate if a coefficient is infinite */
    17805 assert(SCIPisFinite(lhs));
    17806 assert(SCIPisFinite(rhs));
    17807 for( i = 0; i < nvars; ++i )
    17808 {
    17809 assert(SCIPisFinite(vals[i]));
    17810 if( SCIPisInfinity(scip, REALABS(vals[i])) )
    17811 {
    17812 SCIPerrorMessage("coefficient of variable <%s> in constraint <%s> is infinite,"
    17813 " consider adjusting the infinity threshold\n", SCIPvarGetName(vars[i]), name);
    17814 SCIPABORT();
    17815 return SCIP_INVALIDDATA;
    17816 }
    17817 }
    17818
    17819 /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
    17820 * constraint after presolving we have to ensure that it holds active variables
    17821 */
    17822 if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE && nvars > 0 )
    17823 {
    17824 SCIP_VAR** consvars;
    17825 SCIP_Real* consvals;
    17826 SCIP_Real constant = 0.0;
    17827 int nconsvars;
    17828 int requiredsize;
    17829
    17830 nconsvars = nvars;
    17831 SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
    17832 SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
    17833
    17834 /* get active variables for new constraint */
    17835 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize) );
    17836
    17837 /* if space was not enough we need to resize the buffers */
    17838 if( requiredsize > nconsvars )
    17839 {
    17840 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
    17841 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
    17842
    17843 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize) );
    17844 }
    17845 assert(requiredsize == nconsvars);
    17846
    17847 /* adjust sides and check that we do not subtract infinity values */
    17848 if( SCIPisInfinity(scip, REALABS(constant)) )
    17849 {
    17850 SCIPfreeBufferArray(scip, &consvals);
    17851 SCIPfreeBufferArray(scip, &consvars);
    17852 SCIPerrorMessage("while creating constraint <%s> inactive variables lead to an infinite constant\n", name);
    17853 SCIPABORT();
    17854 return SCIP_INVALIDDATA;
    17855 }
    17856 else
    17857 {
    17858 if( !SCIPisInfinity(scip, REALABS(lhs)) )
    17859 lhs -= constant;
    17860 if( !SCIPisInfinity(scip, REALABS(rhs)) )
    17861 rhs -= constant;
    17862
    17863 if( SCIPisInfinity(scip, -lhs) )
    17864 lhs = -SCIPinfinity(scip);
    17865 else if( SCIPisInfinity(scip, lhs) )
    17866 lhs = SCIPinfinity(scip);
    17867
    17868 if( SCIPisInfinity(scip, rhs) )
    17869 rhs = SCIPinfinity(scip);
    17870 else if( SCIPisInfinity(scip, -rhs) )
    17871 rhs = -SCIPinfinity(scip);
    17872 }
    17873
    17874 /* create constraint data */
    17875 SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
    17876
    17877 SCIPfreeBufferArray(scip, &consvals);
    17878 SCIPfreeBufferArray(scip, &consvars);
    17879 }
    17880 else
    17881 {
    17882 /* create constraint data */
    17883 SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
    17884 }
    17885 assert(consdata != NULL);
    17886
    17887#ifndef NDEBUG
    17888 /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
    17889 if( check || enforce )
    17890 {
    17891 int n;
    17892 for(n = consdata->nvars - 1; n >= 0; --n )
    17893 assert(!SCIPvarIsRelaxationOnly(consdata->vars[n]));
    17894 }
    17895#endif
    17896
    17897 /* create constraint */
    17898 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
    17899 local, modifiable, dynamic, removable, stickingatnode) );
    17900
    17901 return SCIP_OKAY;
    17902}
    17903
    17904/** creates and captures a linear constraint
    17905 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
    17906 * method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
    17907 *
    17908 * @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
    17909 *
    17910 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    17911 */
    17913 SCIP* scip, /**< SCIP data structure */
    17914 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    17915 const char* name, /**< name of constraint */
    17916 int nvars, /**< number of nonzeros in the constraint */
    17917 SCIP_VAR** vars, /**< array with variables of constraint entries */
    17918 SCIP_Real* vals, /**< array with coefficients of constraint entries */
    17919 SCIP_Real lhs, /**< left hand side of constraint */
    17920 SCIP_Real rhs /**< right hand side of constraint */
    17921 )
    17922{
    17923 assert(scip != NULL);
    17924
    17925 SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
    17927
    17928 return SCIP_OKAY;
    17929}
    17930
    17931/** creates by copying and captures a linear constraint */
    17933 SCIP* scip, /**< target SCIP data structure */
    17934 SCIP_CONS** cons, /**< pointer to store the created target constraint */
    17935 SCIP* sourcescip, /**< source SCIP data structure */
    17936 const char* name, /**< name of constraint */
    17937 int nvars, /**< number of variables in source variable array */
    17938 SCIP_VAR** sourcevars, /**< source variables of the linear constraints */
    17939 SCIP_Real* sourcecoefs, /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
    17940 SCIP_Real lhs, /**< left hand side of the linear constraint */
    17941 SCIP_Real rhs, /**< right hand side of the linear constraint */
    17942 SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
    17943 * variables of the target SCIP */
    17944 SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
    17945 * target constraints */
    17946 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
    17947 SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
    17948 SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
    17949 SCIP_Bool check, /**< should the constraint be checked for feasibility? */
    17950 SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
    17951 SCIP_Bool local, /**< is constraint only valid locally? */
    17952 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
    17953 SCIP_Bool dynamic, /**< is constraint subject to aging? */
    17954 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
    17955 SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
    17956 * if it may be moved to a more global node? */
    17957 SCIP_Bool global, /**< create a global or a local copy? */
    17958 SCIP_Bool* valid /**< pointer to store if the copying was valid */
    17959 )
    17960{
    17961 SCIP_VAR** vars;
    17962 SCIP_Real* coefs;
    17963
    17964 SCIP_Real constant;
    17965 int requiredsize;
    17966 int v;
    17967 SCIP_Bool success;
    17968
    17969 if( SCIPisGT(scip, lhs, rhs) )
    17970 {
    17971 *valid = FALSE;
    17972 return SCIP_OKAY;
    17973 }
    17974
    17975 (*valid) = TRUE;
    17976
    17977 if( nvars == 0 )
    17978 {
    17979 SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
    17980 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    17981 return SCIP_OKAY;
    17982 }
    17983
    17984 /* duplicate variable array */
    17985 SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, sourcevars, nvars) );
    17986
    17987 /* duplicate coefficient array */
    17988 if( sourcecoefs != NULL )
    17989 {
    17990 SCIP_CALL( SCIPduplicateBufferArray(scip, &coefs, sourcecoefs, nvars) );
    17991 }
    17992 else
    17993 {
    17994 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
    17995 for( v = 0; v < nvars; ++v )
    17996 coefs[v] = 1.0;
    17997 }
    17998
    17999 constant = 0.0;
    18000
    18001 /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
    18002 * the target SCIP
    18003 */
    18004 if( !SCIPvarIsOriginal(vars[0]) )
    18005 {
    18006 SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize) );
    18007
    18008 if( requiredsize > nvars )
    18009 {
    18010 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
    18011 SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
    18012
    18013 SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize) );
    18014 }
    18015 assert(requiredsize == nvars);
    18016 }
    18017 else
    18018 {
    18019 for( v = 0; v < nvars; ++v )
    18020 {
    18021 assert(SCIPvarIsOriginal(vars[v]));
    18022 SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
    18023 assert(vars[v] != NULL);
    18024 }
    18025 }
    18026
    18027 success = TRUE;
    18028 /* map variables of the source constraint to variables of the target SCIP */
    18029 for( v = 0; v < nvars && success; ++v )
    18030 {
    18031 SCIP_VAR* var;
    18032 var = vars[v];
    18033
    18034 /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
    18035 assert(!SCIPvarIsRelaxationOnly(var) || (!check && !enforce));
    18036
    18037 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, &success) );
    18038 assert(!(success) || vars[v] != NULL);
    18039 }
    18040
    18041 /* only create the target constraint, if all variables could be copied */
    18042 if( success )
    18043 {
    18044 if( !SCIPisInfinity(scip, -lhs) )
    18045 lhs -= constant;
    18046
    18047 if( !SCIPisInfinity(scip, rhs) )
    18048 rhs -= constant;
    18049
    18050 SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
    18051 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
    18052 }
    18053 else
    18054 *valid = FALSE;
    18055
    18056 /* free buffer array */
    18057 SCIPfreeBufferArray(scip, &coefs);
    18058 SCIPfreeBufferArray(scip, &vars);
    18059
    18060 return SCIP_OKAY;
    18061}
    18062
    18063/** adds coefficient to linear constraint (if it is not zero) */
    18065 SCIP* scip, /**< SCIP data structure */
    18066 SCIP_CONS* cons, /**< constraint data */
    18067 SCIP_VAR* var, /**< variable of constraint entry */
    18068 SCIP_Real val /**< coefficient of constraint entry */
    18069 )
    18070{
    18071 assert(scip != NULL);
    18072 assert(cons != NULL);
    18073 assert(var != NULL);
    18074
    18075 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18076 {
    18077 SCIPerrorMessage("constraint is not linear\n");
    18078 return SCIP_INVALIDDATA;
    18079 }
    18080
    18081 /* terminate if coefficient is infinite */
    18082 assert(SCIPisFinite(val));
    18083 if( SCIPisInfinity(scip, REALABS(val)) )
    18084 {
    18085 SCIPerrorMessage("coefficient of variable <%s> in constraint <%s> is infinite,"
    18086 " consider adjusting the infinity threshold\n", SCIPvarGetName(var), SCIPconsGetName(cons));
    18087 SCIPABORT();
    18088 return SCIP_INVALIDDATA;
    18089 }
    18090
    18091 /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
    18092 * constraint after presolving we have to ensure that it holds active variables
    18093 */
    18095 {
    18096 SCIP_CONSDATA* consdata;
    18097 SCIP_VAR** consvars;
    18098 SCIP_Real* consvals;
    18099 SCIP_Real constant = 0.0;
    18100 SCIP_Real rhs;
    18101 SCIP_Real lhs;
    18102 int nconsvars;
    18103 int requiredsize;
    18104 int v;
    18105
    18106 nconsvars = 1;
    18107 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
    18108 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
    18109 consvars[0] = var;
    18110 consvals[0] = val;
    18111
    18112 /* get active variables for new constraint */
    18113 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize) );
    18114
    18115 /* if space was not enough we need to resize the buffers */
    18116 if( requiredsize > nconsvars )
    18117 {
    18118 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
    18119 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
    18120
    18121 SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize) );
    18122 }
    18123 assert(requiredsize == nconsvars);
    18124
    18125 consdata = SCIPconsGetData(cons);
    18126 assert(consdata != NULL);
    18127
    18128 lhs = consdata->lhs;
    18129 rhs = consdata->rhs;
    18130
    18131 /* adjust sides and check that we do not subtract infinity values */
    18132 /* constant is infinite */
    18133 if( SCIPisInfinity(scip, REALABS(constant)) )
    18134 {
    18135 if( constant < 0.0 )
    18136 {
    18137 if( SCIPisInfinity(scip, lhs) )
    18138 {
    18139 SCIPfreeBufferArray(scip, &consvals);
    18140 SCIPfreeBufferArray(scip, &consvars);
    18141
    18142 SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
    18143
    18144 SCIPABORT();
    18145 return SCIP_INVALIDDATA; /*lint !e527*/
    18146 }
    18147 if( SCIPisInfinity(scip, rhs) )
    18148 {
    18149 SCIPfreeBufferArray(scip, &consvals);
    18150 SCIPfreeBufferArray(scip, &consvars);
    18151
    18152 SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
    18153
    18154 SCIPABORT();
    18155 return SCIP_INVALIDDATA; /*lint !e527*/
    18156 }
    18157
    18158 lhs = -SCIPinfinity(scip);
    18159 rhs = -SCIPinfinity(scip);
    18160 }
    18161 else
    18162 {
    18163 if( SCIPisInfinity(scip, -lhs) )
    18164 {
    18165 SCIPfreeBufferArray(scip, &consvals);
    18166 SCIPfreeBufferArray(scip, &consvars);
    18167
    18168 SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
    18169
    18170 SCIPABORT();
    18171 return SCIP_INVALIDDATA; /*lint !e527*/
    18172 }
    18173 if( SCIPisInfinity(scip, -rhs) )
    18174 {
    18175 SCIPfreeBufferArray(scip, &consvals);
    18176 SCIPfreeBufferArray(scip, &consvars);
    18177
    18178 SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
    18179
    18180 SCIPABORT();
    18181 return SCIP_INVALIDDATA; /*lint !e527*/
    18182 }
    18183
    18184 lhs = SCIPinfinity(scip);
    18185 rhs = SCIPinfinity(scip);
    18186 }
    18187 }
    18188 /* constant is not infinite */
    18189 else
    18190 {
    18191 if( !SCIPisInfinity(scip, REALABS(lhs)) )
    18192 lhs -= constant;
    18193 if( !SCIPisInfinity(scip, REALABS(rhs)) )
    18194 rhs -= constant;
    18195
    18196 if( SCIPisInfinity(scip, -lhs) )
    18197 lhs = -SCIPinfinity(scip);
    18198 else if( SCIPisInfinity(scip, lhs) )
    18199 lhs = SCIPinfinity(scip);
    18200
    18201 if( SCIPisInfinity(scip, rhs) )
    18202 rhs = SCIPinfinity(scip);
    18203 else if( SCIPisInfinity(scip, -rhs) )
    18204 rhs = -SCIPinfinity(scip);
    18205 }
    18206
    18207 /* add all active variables to constraint */
    18208 for( v = nconsvars - 1; v >= 0; --v )
    18209 {
    18210 if( !SCIPisZero(scip, consvals[v]) )
    18211 {
    18212 SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
    18213 }
    18214 }
    18215
    18216 /* update left and right hand sides */
    18217 SCIP_CALL( chgLhs(scip, cons, lhs) );
    18218 SCIP_CALL( chgRhs(scip, cons, rhs) );
    18219
    18220 SCIPfreeBufferArray(scip, &consvals);
    18221 SCIPfreeBufferArray(scip, &consvars);
    18222 }
    18223 else if( !SCIPisZero(scip, val) )
    18224 {
    18225 SCIP_CALL( addCoef(scip, cons, var, val) );
    18226 }
    18227
    18228 return SCIP_OKAY;
    18229}
    18230
    18231/** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
    18232 * not yet contained in the constraint
    18233 *
    18234 * @note This method may only be called during problem creation stage for an original constraint and variable.
    18235 *
    18236 * @note This method requires linear time to search for occurences of the variable in the constraint data.
    18237 */
    18239 SCIP* scip, /**< SCIP data structure */
    18240 SCIP_CONS* cons, /**< constraint data */
    18241 SCIP_VAR* var, /**< variable of constraint entry */
    18242 SCIP_Real val /**< new coefficient of constraint entry */
    18243 )
    18244{
    18245 SCIP_CONSDATA* consdata;
    18246 SCIP_VAR** vars;
    18247 SCIP_Bool found;
    18248 int i;
    18249
    18250 assert(scip != NULL);
    18251 assert(cons != NULL);
    18252 assert(var != NULL);
    18253
    18254 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18255 {
    18256 SCIPerrorMessage("constraint is not linear\n");
    18257 return SCIP_INVALIDDATA;
    18258 }
    18259
    18261 {
    18262 SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
    18263 return SCIP_INVALIDDATA;
    18264 }
    18265
    18266 consdata = SCIPconsGetData(cons);
    18267 assert(consdata != NULL);
    18268
    18269 vars = consdata->vars;
    18270 found = FALSE;
    18271 i = 0;
    18272 while( i < consdata->nvars )
    18273 {
    18274 if( vars[i] == var )
    18275 {
    18276 if( found || SCIPisZero(scip, val) )
    18277 {
    18278 SCIP_CALL( delCoefPos(scip, cons, i) );
    18279
    18280 /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
    18281 i--;
    18282 }
    18283 else
    18284 {
    18285 SCIP_CALL( chgCoefPos(scip, cons, i, val) );
    18286 }
    18287 found = TRUE;
    18288 }
    18289 i++;
    18290 }
    18291
    18292 if( !found )
    18293 {
    18294 SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
    18295 }
    18296
    18297 return SCIP_OKAY;
    18298}
    18299
    18300/** deletes variable from linear constraint
    18301 *
    18302 * @note This method may only be called during problem creation stage for an original constraint and variable.
    18303 *
    18304 * @note This method requires linear time to search for occurences of the variable in the constraint data.
    18305 */
    18307 SCIP* scip, /**< SCIP data structure */
    18308 SCIP_CONS* cons, /**< constraint data */
    18309 SCIP_VAR* var /**< variable of constraint entry */
    18310 )
    18311{
    18312 assert(scip != NULL);
    18313 assert(cons != NULL);
    18314 assert(var != NULL);
    18315
    18316 SCIP_CALL( SCIPchgCoefLinear(scip, cons, var, 0.0) );
    18317
    18318 return SCIP_OKAY;
    18319}
    18320
    18321/** gets left hand side of linear constraint */
    18323 SCIP* scip, /**< SCIP data structure */
    18324 SCIP_CONS* cons /**< constraint data */
    18325 )
    18326{
    18327 SCIP_CONSDATA* consdata;
    18328
    18329 assert(scip != NULL);
    18330 assert(cons != NULL);
    18331
    18332 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18333 {
    18334 SCIPerrorMessage("constraint is not linear\n");
    18335 SCIPABORT();
    18336 return SCIP_INVALID; /*lint !e527*/
    18337 }
    18338
    18339 consdata = SCIPconsGetData(cons);
    18340 assert(consdata != NULL);
    18341
    18342 return consdata->lhs;
    18343}
    18344
    18345/** gets right hand side of linear constraint */
    18347 SCIP* scip, /**< SCIP data structure */
    18348 SCIP_CONS* cons /**< constraint data */
    18349 )
    18350{
    18351 SCIP_CONSDATA* consdata;
    18352
    18353 assert(scip != NULL);
    18354 assert(cons != NULL);
    18355
    18356 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18357 {
    18358 SCIPerrorMessage("constraint is not linear\n");
    18359 SCIPABORT();
    18360 return SCIP_INVALID; /*lint !e527*/
    18361 }
    18362
    18363 consdata = SCIPconsGetData(cons);
    18364 assert(consdata != NULL);
    18365
    18366 return consdata->rhs;
    18367}
    18368
    18369/** changes left hand side of linear constraint */
    18371 SCIP* scip, /**< SCIP data structure */
    18372 SCIP_CONS* cons, /**< constraint data */
    18373 SCIP_Real lhs /**< new left hand side */
    18374 )
    18375{
    18376 assert(scip != NULL);
    18377 assert(cons != NULL);
    18378
    18379 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18380 {
    18381 SCIPerrorMessage("constraint is not linear\n");
    18382 return SCIP_INVALIDDATA;
    18383 }
    18384
    18385 SCIP_CALL( chgLhs(scip, cons, lhs) );
    18386
    18387 return SCIP_OKAY;
    18388}
    18389
    18390/** changes right hand side of linear constraint */
    18392 SCIP* scip, /**< SCIP data structure */
    18393 SCIP_CONS* cons, /**< constraint data */
    18394 SCIP_Real rhs /**< new right hand side */
    18395 )
    18396{
    18397 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18398 {
    18399 SCIPerrorMessage("constraint is not linear\n");
    18400 return SCIP_INVALIDDATA;
    18401 }
    18402
    18403 SCIP_CALL( chgRhs(scip, cons, rhs) );
    18404
    18405 return SCIP_OKAY;
    18406}
    18407
    18408/** gets the number of variables in the linear constraint */
    18410 SCIP* scip, /**< SCIP data structure */
    18411 SCIP_CONS* cons /**< constraint data */
    18412 )
    18413{
    18414 SCIP_CONSDATA* consdata;
    18415
    18416 assert(scip != NULL);
    18417 assert(cons != NULL);
    18418
    18419 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18420 {
    18421 SCIPerrorMessage("constraint is not linear\n");
    18422 SCIPABORT();
    18423 return -1; /*lint !e527*/
    18424 }
    18425
    18426 consdata = SCIPconsGetData(cons);
    18427 assert(consdata != NULL);
    18428
    18429 return consdata->nvars;
    18430}
    18431
    18432/** gets the array of variables in the linear constraint; the user must not modify this array! */
    18434 SCIP* scip, /**< SCIP data structure */
    18435 SCIP_CONS* cons /**< constraint data */
    18436 )
    18437{
    18438 SCIP_CONSDATA* consdata;
    18439
    18440 assert(scip != NULL);
    18441 assert(cons != NULL);
    18442
    18443 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18444 {
    18445 SCIPerrorMessage("constraint is not linear\n");
    18446 SCIPABORT();
    18447 return NULL; /*lint !e527*/
    18448 }
    18449
    18450 consdata = SCIPconsGetData(cons);
    18451 assert(consdata != NULL);
    18452
    18453 return consdata->vars;
    18454}
    18455
    18456/** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
    18458 SCIP* scip, /**< SCIP data structure */
    18459 SCIP_CONS* cons /**< constraint data */
    18460 )
    18461{
    18462 SCIP_CONSDATA* consdata;
    18463
    18464 assert(scip != NULL);
    18465 assert(cons != NULL);
    18466
    18467 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18468 {
    18469 SCIPerrorMessage("constraint is not linear\n");
    18470 SCIPABORT();
    18471 return NULL; /*lint !e527*/
    18472 }
    18473
    18474 consdata = SCIPconsGetData(cons);
    18475 assert(consdata != NULL);
    18476
    18477 return consdata->vals;
    18478}
    18479
    18480/** gets the activity of the linear constraint in the given solution
    18481 *
    18482 * @note if the solution contains values at infinity, this method will return SCIP_INVALID in case the activity
    18483 * comprises positive and negative infinity contributions
    18484 */
    18486 SCIP* scip, /**< SCIP data structure */
    18487 SCIP_CONS* cons, /**< constraint data */
    18488 SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
    18489 )
    18490{
    18491 SCIP_CONSDATA* consdata;
    18492
    18493 assert(scip != NULL);
    18494 assert(cons != NULL);
    18495
    18496 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18497 {
    18498 SCIPerrorMessage("constraint is not linear\n");
    18499 SCIPABORT();
    18500 return SCIP_INVALID; /*lint !e527*/
    18501 }
    18502
    18503 consdata = SCIPconsGetData(cons);
    18504 assert(consdata != NULL);
    18505
    18506 if( consdata->row != NULL )
    18507 return SCIPgetRowSolActivity(scip, consdata->row, sol);
    18508 else
    18509 return consdataGetActivity(scip, consdata, sol);
    18510}
    18511
    18512/** gets the feasibility of the linear constraint in the given solution */
    18514 SCIP* scip, /**< SCIP data structure */
    18515 SCIP_CONS* cons, /**< constraint data */
    18516 SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
    18517 )
    18518{
    18519 SCIP_CONSDATA* consdata;
    18520
    18521 assert(scip != NULL);
    18522 assert(cons != NULL);
    18523
    18524 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18525 {
    18526 SCIPerrorMessage("constraint is not linear\n");
    18527 SCIPABORT();
    18528 return SCIP_INVALID; /*lint !e527*/
    18529 }
    18530
    18531 consdata = SCIPconsGetData(cons);
    18532 assert(consdata != NULL);
    18533
    18534 if( consdata->row != NULL )
    18535 return SCIPgetRowSolFeasibility(scip, consdata->row, sol);
    18536 else
    18537 return consdataGetFeasibility(scip, consdata, sol);
    18538}
    18539
    18540/** gets the dual solution of the linear constraint in the current LP */
    18542 SCIP* scip, /**< SCIP data structure */
    18543 SCIP_CONS* cons /**< constraint data */
    18544 )
    18545{
    18546 SCIP_CONSDATA* consdata;
    18547
    18548 assert(scip != NULL);
    18549 assert(cons != NULL);
    18550 assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
    18551
    18552 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18553 {
    18554 SCIPerrorMessage("constraint is not linear\n");
    18555 SCIPABORT();
    18556 return SCIP_INVALID; /*lint !e527*/
    18557 }
    18558
    18559 consdata = SCIPconsGetData(cons);
    18560 assert(consdata != NULL);
    18561
    18562 if( consdata->row != NULL )
    18563 return SCIProwGetDualsol(consdata->row);
    18564 else
    18565 return 0.0;
    18566}
    18567
    18568/** gets the dual Farkas value of the linear constraint in the current infeasible LP */
    18570 SCIP* scip, /**< SCIP data structure */
    18571 SCIP_CONS* cons /**< constraint data */
    18572 )
    18573{
    18574 SCIP_CONSDATA* consdata;
    18575
    18576 assert(scip != NULL);
    18577 assert(cons != NULL);
    18578 assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
    18579
    18580 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18581 {
    18582 SCIPerrorMessage("constraint is not linear\n");
    18583 SCIPABORT();
    18584 return SCIP_INVALID; /*lint !e527*/
    18585 }
    18586
    18587 consdata = SCIPconsGetData(cons);
    18588 assert(consdata != NULL);
    18589
    18590 if( consdata->row != NULL )
    18591 return SCIProwGetDualfarkas(consdata->row);
    18592 else
    18593 return 0.0;
    18594}
    18595
    18596/** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
    18597 * the user must not modify the row!
    18598 */
    18600 SCIP* scip, /**< SCIP data structure */
    18601 SCIP_CONS* cons /**< constraint data */
    18602 )
    18603{
    18604 SCIP_CONSDATA* consdata;
    18605
    18606 assert(scip != NULL);
    18607 assert(cons != NULL);
    18608
    18609 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18610 {
    18611 SCIPerrorMessage("constraint is not linear\n");
    18612 SCIPABORT();
    18613 return NULL; /*lint !e527*/
    18614 }
    18615
    18616 consdata = SCIPconsGetData(cons);
    18617 assert(consdata != NULL);
    18618
    18619 return consdata->row;
    18620}
    18621
    18622/** creates and returns the row of the given linear constraint */
    18624 SCIP* scip, /**< SCIP data structure */
    18625 SCIP_CONS* cons /**< constraint data */
    18626 )
    18627{
    18628 SCIP_CONSDATA* consdata;
    18629
    18630 assert(scip != NULL);
    18631 assert(cons != NULL);
    18632
    18633 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
    18634 {
    18635 SCIPerrorMessage("constraint is not linear\n");
    18636 SCIPABORT();
    18637 return SCIP_ERROR; /*lint !e527*/
    18638 }
    18639
    18640 consdata = SCIPconsGetData(cons);
    18641 assert(consdata != NULL);
    18642
    18643 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, cons, SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
    18645
    18646 SCIP_CALL( SCIPaddVarsToRow(scip, consdata->row, consdata->nvars, consdata->vars, consdata->vals) ) ;
    18647
    18648 return SCIP_OKAY;
    18649}
    18650
    18651/** tries to automatically convert a linear constraint into a more specific and more specialized constraint */
    18653 SCIP* scip, /**< SCIP data structure */
    18654 SCIP_CONS* cons, /**< source constraint to try to convert */
    18655 SCIP_CONS** upgdcons /**< pointer to store upgraded constraint, or NULL if not successful */
    18656 )
    18657{
    18658 SCIP_CONSHDLR* conshdlr;
    18659 SCIP_CONSHDLRDATA* conshdlrdata;
    18660 SCIP_CONSDATA* consdata;
    18661 SCIP_VAR* var;
    18662 SCIP_Real val;
    18663 SCIP_Real lb;
    18664 SCIP_Real ub;
    18665 SCIP_Real poscoeffsum;
    18666 SCIP_Real negcoeffsum;
    18667 SCIP_Bool infeasible;
    18668 SCIP_Bool integral;
    18669 int nchgsides = 0;
    18670 int nposbin;
    18671 int nnegbin;
    18672 int nposint;
    18673 int nnegint;
    18674 int nposimpl;
    18675 int nnegimpl;
    18676 int nposimplbin;
    18677 int nnegimplbin;
    18678 int nposcont;
    18679 int nnegcont;
    18680 int ncoeffspone;
    18681 int ncoeffsnone;
    18682 int ncoeffspint;
    18683 int ncoeffsnint;
    18684 int ncoeffspfrac;
    18685 int ncoeffsnfrac;
    18686 int i;
    18687
    18688 assert(scip != NULL);
    18689 assert(cons != NULL);
    18690 assert(upgdcons != NULL);
    18691
    18692 *upgdcons = NULL;
    18693
    18694 /* we cannot upgrade a modifiable linear constraint, since we don't know what additional coefficients to expect */
    18695 if( SCIPconsIsModifiable(cons) )
    18696 return SCIP_OKAY;
    18697
    18698 /* check for upgradability */
    18699 if( SCIPconsGetNUpgradeLocks(cons) > 0 )
    18700 return SCIP_OKAY;
    18701
    18702 /* get the constraint handler and check, if it's really a linear constraint */
    18703 conshdlr = SCIPconsGetHdlr(cons);
    18704 if( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) != 0 )
    18705 {
    18706 SCIPerrorMessage("constraint is not linear\n");
    18707 return SCIP_INVALIDDATA;
    18708 }
    18709
    18710 /* get constraint handler data and constraint data */
    18711 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    18712 assert(conshdlrdata != NULL);
    18713 consdata = SCIPconsGetData(cons);
    18714 assert(consdata != NULL);
    18715
    18716 /* check, if the constraint was already upgraded and will be deleted anyway after preprocessing */
    18717 if( consdata->upgraded )
    18718 return SCIP_OKAY;
    18719
    18720 /* check, if the constraint is already stored as LP row */
    18721 if( consdata->row != NULL )
    18722 {
    18723 if( SCIProwIsInLP(consdata->row) )
    18724 {
    18725 SCIPerrorMessage("cannot upgrade linear constraint that is already stored as row in the LP\n");
    18726 return SCIP_INVALIDDATA;
    18727 }
    18728 else
    18729 {
    18730 SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
    18731 }
    18732 }
    18733
    18734 SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
    18735
    18736 /* normalizeCons() can only detect infeasibility when scaling with the gcd. in that case, the scaling was
    18737 * skipped and we hope that the infeasibility gets detected later again.
    18738 *
    18739 * TODO: do we want to try to upgrade the constraint anyway?
    18740 *
    18741 * TODO: this needs to be fixed on master by changing the API and passing a pointer to whether the constraint is
    18742 * proven to be infeasible.
    18743 */
    18744 if( infeasible ) /*lint !e774*/
    18745 return SCIP_OKAY;
    18746
    18747 /* tighten sides */
    18748 SCIP_CALL( tightenSides(scip, cons, &nchgsides, &infeasible) );
    18749
    18750 if( infeasible ) /*lint !e774*/
    18751 return SCIP_OKAY;
    18752
    18753 /*
    18754 * calculate some statistics on linear constraint
    18755 */
    18756
    18757 nposbin = 0;
    18758 nnegbin = 0;
    18759 nposint = 0;
    18760 nnegint = 0;
    18761 nposimpl = 0;
    18762 nnegimpl = 0;
    18763 nposimplbin = 0;
    18764 nnegimplbin = 0;
    18765 nposcont = 0;
    18766 nnegcont = 0;
    18767 ncoeffspone = 0;
    18768 ncoeffsnone = 0;
    18769 ncoeffspint = 0;
    18770 ncoeffsnint = 0;
    18771 ncoeffspfrac = 0;
    18772 ncoeffsnfrac = 0;
    18773 integral = TRUE;
    18774 poscoeffsum = 0.0;
    18775 negcoeffsum = 0.0;
    18776
    18777 for( i = 0; i < consdata->nvars; ++i )
    18778 {
    18779 var = consdata->vars[i];
    18780 val = consdata->vals[i];
    18781 lb = SCIPvarGetLbLocal(var);
    18782 ub = SCIPvarGetUbLocal(var);
    18783 assert(!SCIPisZero(scip, val));
    18784
    18785 if( SCIPvarIsImpliedIntegral(var) )
    18786 {
    18787 if( SCIPvarIsBinary(var) )
    18788 {
    18789 if( val >= 0.0 )
    18790 ++nposimplbin;
    18791 else
    18792 ++nnegimplbin;
    18793 }
    18794 if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
    18795 integral = integral && SCIPisIntegral(scip, val);
    18796 if( val >= 0.0 )
    18797 ++nposimpl;
    18798 else
    18799 ++nnegimpl;
    18800 }
    18801 else
    18802 {
    18803 switch( SCIPvarGetType(var) )
    18804 {
    18806 if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
    18807 integral = integral && SCIPisIntegral(scip, val);
    18808 if( val >= 0.0 )
    18809 ++nposbin;
    18810 else
    18811 ++nnegbin;
    18812 break;
    18814 if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
    18815 integral = integral && SCIPisIntegral(scip, val);
    18816 if( val >= 0.0 )
    18817 ++nposint;
    18818 else
    18819 ++nnegint;
    18820 break;
    18822 integral = integral && SCIPisEQ(scip, lb, ub) && SCIPisIntegral(scip, val * lb);
    18823 if( val >= 0.0 )
    18824 ++nposcont;
    18825 else
    18826 ++nnegcont;
    18827 break;
    18828 default:
    18829 SCIPerrorMessage("unknown variable type\n");
    18830 return SCIP_INVALIDDATA;
    18831 } /*lint !e788*/
    18832 }
    18833
    18834 if( SCIPisEQ(scip, val, 1.0) )
    18835 ncoeffspone++;
    18836 else if( SCIPisEQ(scip, val, -1.0) )
    18837 ncoeffsnone++;
    18838 else if( SCIPisIntegral(scip, val) )
    18839 {
    18840 if( SCIPisPositive(scip, val) )
    18841 ncoeffspint++;
    18842 else
    18843 ncoeffsnint++;
    18844 }
    18845 else
    18846 {
    18847 if( SCIPisPositive(scip, val) )
    18848 ncoeffspfrac++;
    18849 else
    18850 ncoeffsnfrac++;
    18851 }
    18852 if( SCIPisPositive(scip, val) )
    18853 poscoeffsum += val;
    18854 else
    18855 negcoeffsum += val;
    18856 }
    18857
    18858 /*
    18859 * call the upgrading methods
    18860 */
    18861
    18862 SCIPdebugMsg(scip, "upgrading linear constraint <%s> (%d upgrade methods):\n",
    18863 SCIPconsGetName(cons), conshdlrdata->nlinconsupgrades);
    18864 SCIPdebugMsg(scip, " +bin=%d -bin=%d +int=%d -int=%d +impl=%d -impl=%d +cont=%d -cont=%d +1=%d -1=%d +I=%d -I=%d +F=%d -F=%d possum=%.15g negsum=%.15g integral=%u\n",
    18865 nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposcont, nnegcont,
    18866 ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
    18867 poscoeffsum, negcoeffsum, integral);
    18868
    18869 /* try all upgrading methods in priority order in case the upgrading step is enable */
    18870 for( i = 0; i < conshdlrdata->nlinconsupgrades && *upgdcons == NULL; ++i )
    18871 {
    18872 if( conshdlrdata->linconsupgrades[i]->active )
    18873 {
    18874 SCIP_CALL( conshdlrdata->linconsupgrades[i]->linconsupgd(scip, cons, consdata->nvars,
    18875 consdata->vars, consdata->vals, consdata->lhs, consdata->rhs,
    18876 nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposimplbin, nnegimplbin, nposcont, nnegcont,
    18877 ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
    18878 poscoeffsum, negcoeffsum, integral,
    18879 upgdcons) );
    18880 }
    18881 }
    18882
    18883#ifdef SCIP_DEBUG
    18884 if( *upgdcons != NULL )
    18885 {
    18887 SCIPdebugMsg(scip, " -> upgraded to constraint type <%s>\n", SCIPconshdlrGetName(SCIPconsGetHdlr(*upgdcons)));
    18888 SCIPdebugPrintCons(scip, *upgdcons, NULL);
    18889 }
    18890#endif
    18891
    18892 return SCIP_OKAY; /*lint !e438*/
    18893}
    18894
    18895/** cleans up (multi-)aggregations and fixings from linear constraints */
    18897 SCIP* scip, /**< SCIP data structure */
    18898 SCIP_Bool onlychecked, /**< should only checked constraints be cleaned up? */
    18899 SCIP_Bool* infeasible, /**< pointer to return whether the problem was detected to be infeasible */
    18900 int* ndelconss /**< pointer to count number of deleted constraints */
    18901 )
    18902{
    18903 SCIP_CONSHDLR* conshdlr;
    18904 SCIP_CONS** conss;
    18905 int nconss;
    18906 int i;
    18907
    18908 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    18909 if( conshdlr == NULL )
    18910 return SCIP_OKAY;
    18911
    18912 assert(infeasible != NULL);
    18913 *infeasible = FALSE;
    18914
    18915 nconss = onlychecked ? SCIPconshdlrGetNCheckConss(conshdlr) : SCIPconshdlrGetNActiveConss(conshdlr);
    18916 conss = onlychecked ? SCIPconshdlrGetCheckConss(conshdlr) : SCIPconshdlrGetConss(conshdlr);
    18917
    18918 /* loop backwards since then deleted constraints do not interfere with the loop */
    18919 for( i = nconss - 1; i >= 0; --i )
    18920 {
    18921 SCIP_CALL( applyFixings(scip, conss[i], infeasible) );
    18922
    18923 if( *infeasible )
    18924 break;
    18925
    18926 if( SCIPconsGetData(conss[i])->nvars >= 1 )
    18927 continue;
    18928
    18929 SCIP_CALL( SCIPdelCons(scip, conss[i]) );
    18930 ++(*ndelconss);
    18931 }
    18932
    18933 return SCIP_OKAY;
    18934}
    static long bound
    SCIP_VAR * w
    Definition: circlepacking.c:67
    SCIP_VAR * a
    Definition: circlepacking.c:66
    SCIP_VAR ** b
    Definition: circlepacking.c:65
    SCIP_VAR ** x
    Definition: circlepacking.c:63
    enum Proprule PROPRULE
    Definition: cons_and.c:173
    Proprule
    Definition: cons_and.c:166
    struct InferInfo INFERINFO
    Constraint handler for knapsack constraints of the form , x binary and .
    #define MAX_CLIQUE_NONZEROS_PER_CONS
    Definition: cons_linear.c:7844
    enum Proprule PROPRULE
    Definition: cons_linear.c:354
    static SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
    static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    Definition: cons_linear.c:3662
    #define DEFAULT_AGGREGATEVARIABLES
    Definition: cons_linear.c:141
    static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
    Definition: cons_linear.c:1097
    #define DEFAULT_NMINCOMPARISONS
    Definition: cons_linear.c:126
    #define DEFAULT_MULTAGGRREMOVE
    Definition: cons_linear.c:160
    #define DEFAULT_DUALPRESOLVING
    Definition: cons_linear.c:143
    #define DEFAULT_EXTRACTCLIQUES
    Definition: cons_linear.c:164
    static void permSortConsdata(SCIP_CONSDATA *consdata, int *perm, int nvars)
    Definition: cons_linear.c:3261
    #define CONSHDLR_NEEDSCONS
    Definition: cons_linear.c:107
    static void consdataRecomputeMaxActivityDelta(SCIP *scip, SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:1542
    #define CONSHDLR_SEPAFREQ
    Definition: cons_linear.c:100
    static SCIP_RETCODE checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checklprows, SCIP_Bool checkrelmaxabs, SCIP_Bool *violated)
    Definition: cons_linear.c:7155
    static SCIP_RETCODE addRelaxation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff)
    Definition: cons_linear.c:7439
    #define CONFLICTHDLR_PRIORITY
    Definition: cons_linear.c:117
    static void consdataGetReliableResidualActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *cancelvar, SCIP_Real *resactivity, SCIP_Bool isminresact, SCIP_Bool useglobalbounds)
    Definition: cons_linear.c:2580
    static SCIP_DECL_EVENTEXEC(eventExecLinear)
    static SCIP_RETCODE convertEquality(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss, int *nchgvartypes)
    static SCIP_Bool checkEqualObjective(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real *scale, SCIP_Real *offset)
    #define CONFLICTHDLR_NAME
    Definition: cons_linear.c:115
    #define MAXDNOM
    Definition: cons_linear.c:166
    static SCIP_RETCODE conshdlrdataIncludeUpgrade(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_LINCONSUPGRADE *linconsupgrade)
    Definition: cons_linear.c:618
    static SCIP_RETCODE extractCliques(SCIP *scip, SCIP_CONS *cons, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, int *nfixedvars, int *nchgbds, SCIP_Bool *cutoff)
    Definition: cons_linear.c:7911
    static SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
    #define CONSHDLR_CHECKPRIORITY
    Definition: cons_linear.c:99
    #define CONSHDLR_DESC
    Definition: cons_linear.c:96
    static SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
    static SCIP_DECL_CONSGETVARS(consGetVarsLinear)
    static SCIP_RETCODE createRow(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_linear.c:7415
    static SCIP_DECL_SORTINDCOMP(consdataCompVar)
    Definition: cons_linear.c:3152
    static int getVarWeight(SCIP_VAR *var)
    static SCIP_RETCODE convertBinaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
    Definition: cons_linear.c:9470
    static void consdataRecomputeMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:1307
    static SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
    static SCIP_DECL_CONSPRESOL(consPresolLinear)
    static SCIP_RETCODE addConflictFixedVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_BDCHGIDX *bdchgidx, int inferpos)
    Definition: cons_linear.c:4980
    static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
    static SCIP_DECL_CONSFREE(consFreeLinear)
    #define DEFAULT_DETECTCUTOFFBOUND
    Definition: cons_linear.c:147
    static SCIP_RETCODE tightenVarLb(SCIP *scip, SCIP_CONS *cons, int pos, PROPRULE proprule, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
    Definition: cons_linear.c:5310
    static SCIP_RETCODE fullDualPresolve(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool *cutoff, int *nchgbds, int *nchgvartypes)
    static SCIP_RETCODE convertLongEquality(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss, int *nchgvartypes)
    Definition: cons_linear.c:9582
    static SCIP_DECL_CONSINITLP(consInitlpLinear)
    #define CONSHDLR_PROP_TIMING
    Definition: cons_linear.c:110
    static SCIP_Real consdataComputePseudoActivity(SCIP *scip, SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:1254
    static SCIP_DECL_CONSPARSE(consParseLinear)
    static SCIP_RETCODE conshdlrdataEnsureLinconsupgradesSize(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, int num)
    Definition: cons_linear.c:447
    static SCIP_DECL_CONSENFOLP(consEnfolpLinear)
    static SCIP_RETCODE retrieveParallelConstraints(SCIP_HASHTABLE *hashtable, SCIP_CONS **querycons, SCIP_CONS **parallelconss, int *nparallelconss)
    #define CONFLICTHDLR_DESC
    Definition: cons_linear.c:116
    static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
    Definition: cons_linear.c:566
    static void calculateMinvalAndMaxval(SCIP *scip, SCIP_Real side, SCIP_Real val, SCIP_Real minresactivity, SCIP_Real maxresactivity, SCIP_Real *minval, SCIP_Real *maxval)
    static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    Definition: cons_linear.c:650
    static void consdataRecomputeGlbMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:1361
    static SCIP_DECL_CONSDELVARS(consDelvarsLinear)
    static void consdataUpdateActivitiesUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub, SCIP_Real val, SCIP_Bool checkreliability)
    Definition: cons_linear.c:2021
    static SCIP_RETCODE tightenSides(SCIP *scip, SCIP_CONS *cons, int *nchgsides, SCIP_Bool *infeasible)
    Definition: cons_linear.c:8884
    static void consdataUpdateActivitiesGlbLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real val, SCIP_Bool checkreliability)
    Definition: cons_linear.c:2046
    static void consdataUpdateActivitiesLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real val, SCIP_Bool checkreliability)
    Definition: cons_linear.c:1996
    #define CONSHDLR_MAXPREROUNDS
    Definition: cons_linear.c:104
    static SCIP_Bool conshdlrdataHasUpgrade(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_DECL_LINCONSUPGD((*linconsupgd)), const char *conshdlrname)
    Definition: cons_linear.c:588
    static SCIP_RETCODE chgCoefPos(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Real newval)
    Definition: cons_linear.c:3908
    static void consdataRecomputeMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:1334
    static SCIP_RETCODE linconsupgradeCreate(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority)
    Definition: cons_linear.c:507
    #define DEFAULT_PRESOLPAIRWISE
    Definition: cons_linear.c:124
    #define DEFAULT_MAXAGGRNORMSCALE
    Definition: cons_linear.c:133
    static SCIP_RETCODE performVarDeletions(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss)
    Definition: cons_linear.c:4091
    #define checkMaxActivityDelta(scip, consdata)
    Definition: cons_linear.c:1537
    static SCIP_DECL_CONSTRANS(consTransLinear)
    #define CONSHDLR_SEPAPRIORITY
    Definition: cons_linear.c:97
    static SCIP_Bool isFiniteNonnegativeIntegral(SCIP *scip, SCIP_Real x)
    #define DEFAULT_SINGLETONSTUFFING
    Definition: cons_linear.c:144
    #define DEFAULT_MAXROUNDSROOT
    Definition: cons_linear.c:121
    static void consdataUpdateSignatures(SCIP_CONSDATA *consdata, int pos)
    Definition: cons_linear.c:3107
    #define MINVALRECOMP
    Definition: cons_linear.c:176
    #define DEFAULT_MAXCARDBOUNDDIST
    Definition: cons_linear.c:137
    #define DEFAULT_MAXEASYACTIVITYDELTA
    Definition: cons_linear.c:135
    static SCIP_DECL_CONSEXIT(consExitLinear)
    static SCIP_RETCODE scaleCons(SCIP *scip, SCIP_CONS *cons, SCIP_Real scalar)
    Definition: cons_linear.c:3998
    static int inferInfoGetPos(INFERINFO inferinfo)
    Definition: cons_linear.c:404
    static SCIP_DECL_CONSPRINT(consPrintLinear)
    static SCIP_RETCODE detectRedundantConstraints(SCIP *scip, BMS_BLKMEM *blkmem, SCIP_CONS **conss, int nconss, int *firstchange, SCIP_Bool *cutoff, int *ndelconss, int *nchgsides)
    #define DEFAULT_CHECKRELMAXABS
    Definition: cons_linear.c:131
    #define DEFAULT_MAXDUALMULTAGGRQUOT
    Definition: cons_linear.c:163
    static void linconsupgradeFree(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade)
    Definition: cons_linear.c:528
    static SCIP_RETCODE aggregateConstraints(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1, int *commonidx0, int *commonidx1, int *diffidx0minus1, int *diffidx1minus0, int nvarscommon, int commonidxweight, int diffidx0minus1weight, int diffidx1minus0weight, SCIP_Real maxaggrnormscale, int *nchgcoefs, SCIP_Bool *aggregated, SCIP_Bool *infeasible)
    static SCIP_DECL_CONSENFOPS(consEnfopsLinear)
    static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons, SCIP_Bool reasonisrhs)
    Definition: cons_linear.c:5189
    static SCIP_RETCODE rangedRowPropagation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds, int *naddconss)
    Definition: cons_linear.c:5714
    static INFERINFO intToInferInfo(int i)
    Definition: cons_linear.c:373
    static SCIP_RETCODE mergeMultiples(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_linear.c:4470
    static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_SOL *sol, SCIP_Bool separatecards, SCIP_Bool separateall, int *ncuts, SCIP_Bool *cutoff)
    Definition: cons_linear.c:7538
    static SCIP_RETCODE addSymmetryInformation(SCIP *scip, SYM_SYMTYPE symtype, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
    static void consdataGetActivityBounds(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Bool goodrelax, SCIP_Real *minactivity, SCIP_Real *maxactivity, SCIP_Bool *ismintight, SCIP_Bool *ismaxtight, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
    Definition: cons_linear.c:2533
    static void consdataCheckNonbinvar(SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:1468
    static SCIP_RETCODE chgLhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
    Definition: cons_linear.c:3404
    static SCIP_DECL_CONSEXITSOL(consExitsolLinear)
    #define DEFAULT_SORTVARS
    Definition: cons_linear.c:129
    #define DEFAULT_MAXMULTAGGRQUOT
    Definition: cons_linear.c:162
    static void consdataUpdateActivitiesGlbUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldub, SCIP_Real newub, SCIP_Real val, SCIP_Bool checkreliability)
    Definition: cons_linear.c:2069
    static SCIP_RETCODE consCatchEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
    Definition: cons_linear.c:717
    static void consdataCalcMinAbsval(SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:1439
    static SCIP_RETCODE addConflictBounds(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_BDCHGIDX *bdchgidx, int inferpos, SCIP_Bool reasonisrhs)
    Definition: cons_linear.c:4798
    #define MAXCONSPRESOLROUNDS
    static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
    Definition: cons_linear.c:472
    #define MAXACTVAL
    Definition: cons_linear.c:171
    #define NONLINCONSUPGD_PRIORITY
    Definition: cons_linear.c:179
    #define DEFAULT_MAXSEPACUTSROOT
    Definition: cons_linear.c:123
    @ PROPRULE_1_RANGEDROW
    Definition: cons_linear.c:350
    @ PROPRULE_1_LHS
    Definition: cons_linear.c:348
    @ PROPRULE_INVALID
    Definition: cons_linear.c:352
    @ PROPRULE_1_RHS
    Definition: cons_linear.c:346
    static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_CONS *cons, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
    Definition: cons_linear.c:6977
    static void consdataCalcMaxAbsval(SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:1415
    #define DEFAULT_RANGEDROWPROPAGATION
    Definition: cons_linear.c:155
    static SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphLinear)
    static SCIP_DECL_CONSEXITPRE(consExitpreLinear)
    static SCIP_RETCODE consDropAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
    Definition: cons_linear.c:824
    static SCIP_DECL_CONSDEACTIVE(consDeactiveLinear)
    #define DEFAULT_PRESOLUSEHASHING
    Definition: cons_linear.c:125
    static SCIP_Real consdataGetActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
    Definition: cons_linear.c:3020
    static SCIP_RETCODE consdataTightenCoefs(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
    Definition: cons_linear.c:9003
    static SCIP_RETCODE normalizeCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
    Definition: cons_linear.c:4150
    static SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphLinear)
    static SCIP_RETCODE presolStuffing(SCIP *scip, SCIP_CONS *cons, SCIP_Bool singletonstuffing, SCIP_Bool singlevarstuffing, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds)
    static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    Definition: cons_linear.c:683
    static void consdataCalcSignatures(SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:3132
    static SCIP_RETCODE addConflictReasonVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR *var, SCIP_Real bound)
    Definition: cons_linear.c:5045
    static SCIP_DECL_CONSINIT(consInitLinear)
    #define DEFAULT_RANGEDROWFREQ
    Definition: cons_linear.c:158
    static SCIP_DECL_CONSDELETE(consDeleteLinear)
    static SCIP_RETCODE propagateCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool tightenbounds, SCIP_Bool rangedrowpropagation, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
    Definition: cons_linear.c:7628
    static SCIP_RETCODE updateCutoffbound(SCIP *scip, SCIP_CONS *cons, SCIP_Real primalbound)
    static void consdataUpdateDelCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
    Definition: cons_linear.c:2168
    #define DEFAULT_RANGEDROWARTCONS
    Definition: cons_linear.c:156
    static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, int pos)
    Definition: cons_linear.c:3795
    #define MAXSCALEDCOEFINTEGER
    Definition: cons_linear.c:168
    static void consdataUpdateAddCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
    Definition: cons_linear.c:2092
    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 *istight, SCIP_Bool *issettoinfinity)
    Definition: cons_linear.c:2345
    static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
    Definition: cons_linear.c:855
    static SCIP_DECL_CONSACTIVE(consActiveLinear)
    #define BINWEIGHT
    static SCIP_RETCODE chgRhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
    Definition: cons_linear.c:3532
    static SCIP_DECL_CONSCHECK(consCheckLinear)
    #define DEFAULT_SIMPLIFYINEQUALITIES
    Definition: cons_linear.c:142
    static SCIP_DECL_CONSSEPALP(consSepalpLinear)
    #define CONSHDLR_PROPFREQ
    Definition: cons_linear.c:101
    static SCIP_RETCODE tightenVarBoundsEasy(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
    Definition: cons_linear.c:5379
    static void consdataUpdateActivities(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_Real val, SCIP_BOUNDTYPE boundtype, SCIP_Bool global, SCIP_Bool checkreliability)
    Definition: cons_linear.c:1604
    static unsigned int getParallelConsKey(SCIP_CONS *cons)
    #define CONTWEIGHT
    static SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
    static SCIP_RETCODE fixVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars)
    Definition: cons_linear.c:7776
    #define CONSHDLR_PRESOLTIMING
    Definition: cons_linear.c:109
    #define DEFAULT_DETECTPARTIALOBJECTIVE
    Definition: cons_linear.c:153
    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)
    Definition: cons_linear.c:1056
    static SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
    #define DEFAULT_MAXSEPACUTS
    Definition: cons_linear.c:122
    static void consdataGetActivityResiduals(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool goodrelax, SCIP_Real *minresactivity, SCIP_Real *maxresactivity, SCIP_Bool *ismintight, SCIP_Bool *ismaxtight, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
    Definition: cons_linear.c:2661
    static SCIP_Real consdataGetMaxAbsval(SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:2249
    static SCIP_DECL_CONSINITSOL(consInitsolLinear)
    static SCIP_DECL_CONSRESPROP(consRespropLinear)
    static SCIP_RETCODE addNlrow(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_linear.c:7502
    static SCIP_RETCODE consPrintConsSol(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, FILE *file)
    Definition: cons_linear.c:1136
    #define CONSHDLR_EAGERFREQ
    Definition: cons_linear.c:102
    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 *istight, SCIP_Bool *issettoinfinity)
    Definition: cons_linear.c:2440
    #define DEFAULT_TIGHTENBOUNDSFREQ
    Definition: cons_linear.c:119
    static void getNewSidesAfterAggregation(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *slackvar, SCIP_Real slackcoef, SCIP_Real *newlhs, SCIP_Real *newrhs)
    Definition: cons_linear.c:9528
    static SCIP_RETCODE convertUnaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *ndelconss)
    Definition: cons_linear.c:9414
    static SCIP_DECL_CONSSEPASOL(consSepasolLinear)
    static void consdataUpdateChgCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldval, SCIP_Real newval, SCIP_Bool checkreliability)
    Definition: cons_linear.c:2233
    #define EVENTHDLR_DESC
    Definition: cons_linear.c:113
    static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
    Definition: cons_linear.c:542
    static void consdataRecomputeGlbMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:1388
    static SCIP_DECL_CONSPROP(consPropLinear)
    static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
    Definition: cons_linear.c:4533
    static SCIP_DECL_CONSLOCK(consLockLinear)
    static void consdataCalcActivities(SCIP *scip, SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:2283
    #define DEFAULT_MAXROUNDS
    Definition: cons_linear.c:120
    static void consdataGetGlbActivityResiduals(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool goodrelax, SCIP_Real *minresactivity, SCIP_Real *maxresactivity, SCIP_Bool *ismintight, SCIP_Bool *ismaxtight, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
    Definition: cons_linear.c:2870
    #define CONSHDLR_ENFOPRIORITY
    Definition: cons_linear.c:98
    static SCIP_RETCODE tightenVarUb(SCIP *scip, SCIP_CONS *cons, int pos, PROPRULE proprule, SCIP_Real newub, SCIP_Real oldub, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
    Definition: cons_linear.c:5241
    static int getInferInt(PROPRULE proprule, int pos)
    Definition: cons_linear.c:432
    static int inferInfoGetProprule(INFERINFO inferinfo)
    Definition: cons_linear.c:395
    static SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
    static SCIP_RETCODE dualPresolve(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss, int *nchgvartypes)
    #define DEFAULT_MINGAINPERNMINCOMP
    Definition: cons_linear.c:127
    static SCIP_Real consdataGetFeasibility(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
    Definition: cons_linear.c:3086
    static SCIP_RETCODE rangedRowSimplify(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
    static SCIP_RETCODE aggregateVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars)
    #define CONSHDLR_DELAYSEPA
    Definition: cons_linear.c:105
    static SCIP_DECL_CONSCOPY(consCopyLinear)
    #define MAXSCALEDCOEF
    Definition: cons_linear.c:167
    static void consdataInvalidateActivities(SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:1208
    #define DEFAULT_RANGEDROWMAXDEPTH
    Definition: cons_linear.c:157
    static SCIP_RETCODE analyzeConflictRangedRow(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int nvars, SCIP_VAR *var, SCIP_Real bound)
    Definition: cons_linear.c:5656
    static SCIP_RETCODE consDropEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
    Definition: cons_linear.c:757
    static SCIP_RETCODE tightenVarBounds(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
    Definition: cons_linear.c:6697
    static SCIP_Real consdataGetMinAbsval(SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:2265
    #define CONSHDLR_NAME
    Definition: cons_linear.c:95
    static SCIP_Bool consdataIsResidualIntegral(SCIP *scip, SCIP_CONSDATA *consdata, int pos, SCIP_Real val)
    static int inferInfoToInt(INFERINFO inferinfo)
    Definition: cons_linear.c:386
    static SCIP_RETCODE preprocessConstraintPairs(SCIP *scip, SCIP_CONS **conss, int firstchange, int chkind, SCIP_Real maxaggrnormscale, SCIP_Bool *cutoff, int *ndelconss, int *nchgsides, int *nchgcoefs)
    static SCIP_RETCODE consdataSort(SCIP *scip, SCIP_CONSDATA *consdata)
    Definition: cons_linear.c:3337
    #define DEFAULT_SINGLEVARSTUFFING
    Definition: cons_linear.c:145
    #define EVENTHDLR_NAME
    Definition: cons_linear.c:112
    #define INTWEIGHT
    static SCIP_RETCODE checkParallelObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
    static SCIP_RETCODE simplifyInequalities(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides, SCIP_Bool *infeasible)
    static SCIP_RETCODE consCatchAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
    Definition: cons_linear.c:792
    static SCIP_RETCODE resolvePropagation(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, INFERINFO inferinfo, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_RESULT *result)
    Definition: cons_linear.c:5096
    static SCIP_Bool isRangedRow(SCIP *scip, SCIP_Real lhs, SCIP_Real rhs)
    #define DEFAULT_DETECTLOWERBOUND
    Definition: cons_linear.c:150
    static SCIP_RETCODE checkPartialObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
    #define MAXVALRECOMP
    Definition: cons_linear.c:175
    #define CONSHDLR_DELAYPROP
    Definition: cons_linear.c:106
    static void consdataGetGlbActivityBounds(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Bool goodrelax, SCIP_Real *glbminactivity, SCIP_Real *glbmaxactivity, SCIP_Bool *ismintight, SCIP_Bool *ismaxtight, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
    Definition: cons_linear.c:2810
    static SCIP_Bool canTightenBounds(SCIP_CONS *cons)
    Definition: cons_linear.c:5213
    #define DEFAULT_SEPARATEALL
    Definition: cons_linear.c:139
    static void findOperators(const char *str, char **firstoperator, char **secondoperator, SCIP_Bool *success)
    static INFERINFO getInferInfo(PROPRULE proprule, int pos)
    Definition: cons_linear.c:413
    #define MAXTIGHTENROUNDS
    Definition: cons_linear.c:6973
    Constraint handler for linear constraints in their most general form, .
    constraint handler for nonlinear constraints specified by algebraic expressions
    defines macros for basic operations in double-double arithmetic giving roughly twice the precision of...
    #define QUAD_MEMBER(x)
    Definition: dbldblarith.h:48
    #define SCIPquadprecSumQD(r, a, b)
    Definition: dbldblarith.h:62
    #define QUAD_ASSIGN(a, constant)
    Definition: dbldblarith.h:51
    #define QUAD(x)
    Definition: dbldblarith.h:47
    #define QUAD_ASSIGN_Q(a, b)
    Definition: dbldblarith.h:52
    #define QUAD_TO_DBL(x)
    Definition: dbldblarith.h:49
    methods for debugging
    #define SCIPdebugGetSolVal(scip, var, val)
    Definition: debug.h:312
    #define SCIPdebugAddSolVal(scip, var, val)
    Definition: debug.h:311
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define COPYSIGN
    Definition: def.h:239
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_MAXTREEDEPTH
    Definition: def.h:297
    #define SCIP_REAL_MAX
    Definition: def.h:158
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define MAX3(x, y, z)
    Definition: def.h:228
    #define SCIP_Real
    Definition: def.h:156
    #define ABS(x)
    Definition: def.h:216
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define MIN3(x, y, z)
    Definition: def.h:232
    #define SCIPABORT()
    Definition: def.h:327
    #define REALABS(x)
    Definition: def.h:182
    #define EPSGT(x, y, eps)
    Definition: def.h:186
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPcreateRowLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetDualsolLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPincludeLinconsUpgrade(SCIP *scip, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority, const char *conshdlrname)
    SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPupgradeConsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **upgdcons)
    SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
    SCIP_RETCODE SCIPcleanupConssLinear(SCIP *scip, SCIP_Bool onlychecked, SCIP_Bool *infeasible, int *ndelconss)
    SCIP_RETCODE SCIPincludeConsUpgradeNonlinear(SCIP *scip, SCIP_DECL_NONLINCONSUPGD((*nlconsupgd)), int priority, SCIP_Bool active, const char *conshdlrname)
    SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_ROW * SCIPgetRowLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
    SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
    SCIP_RETCODE SCIPseparateRelaxedKnapsack(SCIP *scip, SCIP_CONS *cons, SCIP_SEPA *sepa, int nknapvars, SCIP_VAR **knapvars, SCIP_Real *knapvals, SCIP_Real valscale, SCIP_Real rhs, SCIP_SOL *sol, SCIP_Bool *cutoff, int *ncuts)
    SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
    SCIP_Real SCIPgetDualfarkasLinear(SCIP *scip, SCIP_CONS *cons)
    #define SCIP_DECL_LINCONSUPGD(x)
    Definition: cons_linear.h:120
    SCIP_RETCODE SCIPcopyConsLinear(SCIP *scip, SCIP_CONS **cons, SCIP *sourcescip, const char *name, int nvars, SCIP_VAR **sourcevars, SCIP_Real *sourcecoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool global, SCIP_Bool *valid)
    SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
    SCIP_Real SCIPgetFeasibilityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
    SCIP_RETCODE SCIPclassifyConstraintTypesLinear(SCIP *scip, SCIP_LINCONSSTATS *linconsstats)
    SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
    SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
    SCIP_RETCODE SCIPchgCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    SCIP_RETCODE SCIPdelCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
    SCIP_RETCODE SCIPincludeConshdlrLinear(SCIP *scip)
    SCIP_RETCODE SCIPconvertCutsToConss(SCIP *scip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
    Definition: scip_copy.c:2051
    SCIP_Bool SCIPisConsCompressionEnabled(SCIP *scip)
    Definition: scip_copy.c:662
    SCIP_RETCODE SCIPgetVarCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR *sourcevar, SCIP_VAR **targetvar, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *success)
    Definition: scip_copy.c:713
    SCIP_Bool SCIPisTransformed(SCIP *scip)
    Definition: scip_general.c:647
    SCIP_Bool SCIPisPresolveFinished(SCIP *scip)
    Definition: scip_general.c:668
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:759
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    int SCIPgetNObjVars(SCIP *scip)
    Definition: scip_prob.c:2616
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    SCIP_RETCODE SCIPaddConsUpgrade(SCIP *scip, SCIP_CONS *oldcons, SCIP_CONS **newcons)
    Definition: scip_prob.c:3368
    int SCIPgetNContVars(SCIP *scip)
    Definition: scip_prob.c:2569
    SCIP_CONS ** SCIPgetConss(SCIP *scip)
    Definition: scip_prob.c:3666
    SCIP_RETCODE SCIPaddObjoffset(SCIP *scip, SCIP_Real addval)
    Definition: scip_prob.c:1443
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3420
    int SCIPgetNConss(SCIP *scip)
    Definition: scip_prob.c:3620
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
    Definition: misc.c:2348
    #define SCIPhashFour(a, b, c, d)
    Definition: pub_misc.h:573
    SCIP_RETCODE SCIPhashtableSafeInsert(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2567
    SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
    Definition: misc.c:2298
    void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
    Definition: misc.c:2596
    void SCIPhashtablePrintStatistics(SCIP_HASHTABLE *hashtable, SCIP_MESSAGEHDLR *messagehdlr)
    Definition: misc.c:2792
    SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2665
    SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2535
    #define SCIPhashSignature64(a)
    Definition: pub_misc.h:566
    SCIP_RETCODE SCIPupdateLocalLowerbound(SCIP *scip, SCIP_Real newbound)
    Definition: scip_prob.c:4289
    SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:4067
    SCIP_Real SCIPgetLocalLowerbound(SCIP *scip)
    Definition: scip_prob.c:4178
    SCIP_RETCODE SCIPaddConflict(SCIP *scip, SCIP_NODE *node, SCIP_CONS **cons, SCIP_NODE *validnode, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
    Definition: scip_prob.c:3806
    SCIP_RETCODE SCIPaddConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_NODE *validnode)
    Definition: scip_prob.c:3986
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsgPrint
    Definition: scip_message.h:79
    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_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
    Definition: misc.c:9197
    SCIP_Longint SCIPcalcSmaComMul(SCIP_Longint val1, SCIP_Longint val2)
    Definition: misc.c:9449
    SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
    Definition: misc.c:10041
    SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *numerator, SCIP_Longint *denominator)
    Definition: misc.c:9470
    SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
    Definition: misc.c:11162
    SCIP_RETCODE 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 SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:139
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
    Definition: scip_param.c:269
    void SCIPswapPointers(void **pointer1, void **pointer2)
    Definition: misc.c:10511
    int SCIPgetNLPBranchCands(SCIP *scip)
    Definition: scip_branch.c:436
    SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
    SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
    SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
    const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
    SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
    SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
    SCIP_RETCODE SCIPincludeConflicthdlrBasic(SCIP *scip, SCIP_CONFLICTHDLR **conflicthdlrptr, const char *name, const char *desc, int priority, SCIP_DECL_CONFLICTEXEC((*conflictexec)), SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
    int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4798
    SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
    Definition: scip_cons.c:808
    void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: cons.c:4346
    SCIP_CONS ** SCIPconshdlrGetCheckConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4755
    SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
    Definition: scip_cons.c:540
    SCIP_RETCODE 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
    SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
    Definition: scip_cons.c:693
    SCIP_RETCODE SCIPsetConshdlrGetPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETPERMSYMGRAPH((*consgetpermsymgraph)))
    Definition: scip_cons.c:900
    SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
    Definition: scip_cons.c:578
    SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
    Definition: scip_cons.c:372
    SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
    Definition: scip_cons.c:323
    int SCIPconshdlrGetPropFreq(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:5282
    int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4778
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXIT((*consexit)))
    Definition: scip_cons.c:420
    SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
    Definition: scip_cons.c:516
    SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
    Definition: scip_cons.c:347
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_RETCODE SCIPsetConshdlrGetSignedPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH((*consgetsignedpermsymgraph)))
    Definition: scip_cons.c:924
    SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
    Definition: scip_cons.c:468
    SCIP_RETCODE 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_RETCODE SCIPsetConshdlrInitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITSOL((*consinitsol)))
    Definition: scip_cons.c:444
    SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4336
    SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
    Definition: scip_cons.c:601
    SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
    Definition: scip_cons.c:647
    int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4812
    SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
    Definition: scip_cons.c:854
    SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4735
    SCIP_RETCODE SCIPsetConshdlrActive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSACTIVE((*consactive)))
    Definition: scip_cons.c:670
    SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
    Definition: scip_cons.c:785
    SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
    Definition: cons.c:8419
    int SCIPconsGetPos(SCIP_CONS *cons)
    Definition: cons.c:8399
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8648
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8558
    SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
    Definition: scip_cons.c:2536
    int SCIPconsGetNUpgradeLocks(SCIP_CONS *cons)
    Definition: cons.c:8841
    SCIP_RETCODE SCIPsetConsSeparated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool separate)
    Definition: scip_cons.c:1296
    SCIP_Bool SCIPconsIsMarkedPropagate(SCIP_CONS *cons)
    Definition: cons.c:8598
    SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
    Definition: cons.c:8688
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8588
    SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
    Definition: cons.c:8518
    SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
    Definition: cons.c:8698
    int SCIPconsGetNLocksPos(SCIP_CONS *cons)
    Definition: cons.c:8738
    SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
    Definition: scip_cons.c:1271
    SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
    Definition: scip_cons.c:1321
    SCIP_Bool SCIPconsIsLockedType(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
    Definition: cons.c:8782
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8578
    SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:2042
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8450
    SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: scip_cons.c:997
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8608
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8628
    int SCIPconsGetNLocksNeg(SCIP_CONS *cons)
    Definition: cons.c:8748
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    SCIP_Bool SCIPconsIsLocked(SCIP_CONS *cons)
    Definition: cons.c:8728
    SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1812
    SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:2014
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8638
    SCIP_RETCODE SCIPupdateConsFlags(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1)
    Definition: scip_cons.c:1524
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8668
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_RETCODE SCIPsetConsPropagated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool propagate)
    Definition: scip_cons.c:1371
    SCIP_RETCODE SCIPsetConsChecked(SCIP *scip, SCIP_CONS *cons, SCIP_Bool check)
    Definition: scip_cons.c:1346
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8568
    SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1784
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8658
    SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
    Definition: scip_cut.c:225
    SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: scip_event.c:111
    const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:396
    SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
    Definition: event.c:1194
    SCIP_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_IMPLINTTYPE SCIPeventGetOldImpltype(SCIP_EVENT *event)
    Definition: event.c:1496
    SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
    Definition: event.c:1415
    SCIP_VARTYPE SCIPeventGetOldtype(SCIP_EVENT *event)
    Definition: event.c:1462
    int SCIPexprGetNChildren(SCIP_EXPR *expr)
    Definition: expr.c:3872
    SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1479
    SCIP_Real * SCIPgetCoefsExprSum(SCIP_EXPR *expr)
    Definition: expr_sum.c:1554
    SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1457
    SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
    Definition: expr.c:3882
    SCIP_Real SCIPgetConstantExprSum(SCIP_EXPR *expr)
    Definition: expr_sum.c:1569
    SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
    Definition: expr_var.c:424
    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
    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 SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    SCIP_RETCODE SCIPdelNlRow(SCIP *scip, SCIP_NLROW *nlrow)
    Definition: scip_nlp.c:424
    SCIP_RETCODE SCIPaddNlRow(SCIP *scip, SCIP_NLROW *nlrow)
    Definition: scip_nlp.c:396
    SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
    Definition: scip_nlp.c:110
    SCIP_RETCODE SCIPreleaseNlRow(SCIP *scip, SCIP_NLROW **nlrow)
    Definition: scip_nlp.c:1058
    SCIP_Bool SCIPnlrowIsInNLP(SCIP_NLROW *nlrow)
    Definition: nlp.c:1953
    SCIP_RETCODE SCIPcreateNlRow(SCIP *scip, SCIP_NLROW **nlrow, const char *name, SCIP_Real constant, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_EXPRCURV curvature)
    Definition: scip_nlp.c:954
    SCIP_Bool SCIPinProbing(SCIP *scip)
    Definition: scip_probing.c:98
    void SCIPlinConsStatsIncTypeCount(SCIP_LINCONSSTATS *linconsstats, SCIP_LINCONSTYPE linconstype, int increment)
    Definition: cons.c:8283
    void SCIPlinConsStatsReset(SCIP_LINCONSSTATS *linconsstats)
    Definition: cons.c:8251
    SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
    Definition: lp.c:17805
    SCIP_RETCODE SCIPchgRowLhs(SCIP *scip, SCIP_ROW *row, SCIP_Real lhs)
    Definition: scip_lp.c:1529
    SCIP_RETCODE SCIPcreateEmptyRowCons(SCIP *scip, SCIP_ROW **row, SCIP_CONS *cons, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
    Definition: scip_lp.c:1398
    SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_lp.c:1646
    SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
    Definition: scip_lp.c:2176
    SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
    Definition: scip_lp.c:2131
    SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
    Definition: scip_lp.c:1508
    SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
    Definition: lp.c:17719
    SCIP_RETCODE SCIPchgRowRhs(SCIP *scip, SCIP_ROW *row, SCIP_Real rhs)
    Definition: scip_lp.c:1553
    SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
    Definition: lp.c:17917
    SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
    Definition: scip_lp.c:1672
    SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
    Definition: lp.c:17706
    SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
    Definition: scip_lp.c:2108
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    void SCIPupdateSolLPConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
    Definition: scip_sol.c:469
    SCIP_RETCODE SCIPupdateCutoffbound(SCIP *scip, SCIP_Real cutoffbound)
    int SCIPgetNSepaRounds(SCIP *scip)
    SCIP_Real SCIPgetLowerbound(SCIP *scip)
    int SCIPgetNRuns(SCIP *scip)
    SCIP_Real SCIPgetCutoffbound(SCIP *scip)
    SCIP_Longint SCIPgetNConflictConssApplied(SCIP *scip)
    SCIP_Bool SCIPisUbBetter(SCIP *scip, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
    SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisSumRelLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisSumRelEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLbBetter(SCIP *scip, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
    SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeasFloor(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_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeastol(SCIP *scip)
    SCIP_Real SCIPgetHugeValue(SCIP *scip)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisSumRelGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisScalingIntegral(SCIP *scip, SCIP_Real val, SCIP_Real scalar)
    SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPcutoffbounddelta(SCIP *scip)
    SCIP_Bool SCIPisUpdateUnreliable(SCIP *scip, SCIP_Real newvalue, SCIP_Real oldvalue)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPepsilon(SCIP *scip)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisSumGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPparseReal(SCIP *scip, const char *str, SCIP_Real *value, char **endptr)
    SCIP_Bool SCIPinRepropagation(SCIP *scip)
    Definition: scip_tree.c:146
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_Bool SCIPvarIsInitial(SCIP_VAR *var)
    Definition: var.c:23514
    SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6401
    SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18320
    SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
    Definition: var.c:23534
    SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5210
    SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
    Definition: var.c:23843
    SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23868
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8882
    SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
    Definition: scip_var.c:2119
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4386
    SCIP_Bool SCIPdoNotAggr(SCIP *scip)
    Definition: scip_var.c:10909
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23498
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:10942
    SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
    Definition: var.c:23430
    SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
    Definition: scip_var.c:10550
    SCIP_RETCODE SCIPinferVarUbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:7069
    SCIP_Bool SCIPvarIsNonimpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23506
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_RETCODE SCIPchgVarImplType(SCIP *scip, SCIP_VAR *var, SCIP_IMPLINTTYPE impltype, SCIP_Bool *infeasible)
    Definition: scip_var.c:10218
    SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6651
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: scip_var.c:2499
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23652
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
    Definition: scip_var.c:5296
    SCIP_RETCODE SCIPcreateVarImpl(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_IMPLINTTYPE impltype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
    Definition: scip_var.c:225
    SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2872
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23662
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPmultiaggregateVar(SCIP *scip, SCIP_VAR *var, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
    Definition: scip_var.c:10834
    SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24929
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
    Definition: scip_var.c:5634
    SCIP_Real SCIPvarGetBestBoundLocal(SCIP_VAR *var)
    Definition: var.c:24312
    SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
    Definition: scip_var.c:899
    SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
    Definition: scip_var.c:2378
    SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
    Definition: scip_var.c:5570
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
    Definition: scip_var.c:10113
    SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:2332
    SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
    Definition: var.c:23806
    int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
    Definition: var.c:23794
    SCIP_RETCODE SCIPaddVarImplication(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool *infeasible, int *nbdchgs)
    Definition: scip_var.c:8740
    SCIP_Bool SCIPvarIsRemovable(SCIP_VAR *var)
    Definition: var.c:23524
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
    Definition: var.c:23443
    SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
    Definition: var.c:23600
    SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
    Definition: var.c:23417
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
    Definition: scip_var.c:10318
    SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6964
    SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2736
    SCIP_IMPLINTTYPE SCIPvarGetImplType(SCIP_VAR *var)
    Definition: var.c:23463
    int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
    Definition: var.c:17274
    SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
    Definition: scip_var.c:361
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
    Definition: scip_var.c:474
    SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
    Definition: var.c:24919
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4328
    SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
    Definition: scip_var.c:2078
    SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
    Definition: scip_var.c:10984
    SCIP_RETCODE SCIPinferVarFixCons(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6895
    SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
    Definition: var.c:23818
    void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
    void SCIPsortRealInt(SCIP_Real *realarray, int *intarray, int len)
    void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
    Definition: misc.c:5581
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    SCIP_RETCODE SCIPskipSpace(char **s)
    Definition: misc.c:10816
    SCIP_RETCODE SCIPgetSymActiveVariables(SCIP *scip, SYM_SYMTYPE symtype, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
    SCIP_RETCODE SCIPextendPermsymDetectionGraphLinear(SCIP *scip, SYM_GRAPH *graph, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_CONS *cons, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool *success)
    static const SCIP_Real scalars[]
    Definition: lp.c:5959
    static const char * paramname[]
    Definition: lpi_msk.c:5172
    memory allocation routines
    #define BMScopyMemoryArray(ptr, source, num)
    Definition: memory.h:134
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
    Definition: message.c:618
    SCIP_Longint denominator(Rational &r)
    SCIP_Longint numerator(Rational &r)
    public methods for conflict analysis handlers
    public methods for managing constraints
    public methods for managing events
    public functions to work with algebraic expressions
    public methods for LP management
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPstatisticMessage
    Definition: pub_message.h:123
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugPrintCons(x, y, z)
    Definition: pub_message.h:102
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    public data structures and miscellaneous methods
    #define SCIPisFinite(x)
    Definition: pub_misc.h:82
    methods for sorting joint arrays of various types
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for conflict handler plugins and conflict analysis
    public methods for constraint handler plugins and constraints
    public methods for problem copies
    public methods for cuts and aggregation rows
    public methods for event handler plugins and event handlers
    general public methods
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for the probing mode
    public methods for solutions
    public methods for querying solving statistics
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1221
    SCIP_DECL_LINCONSUPGD((*linconsupgd))
    structs for symmetry computations
    methods for dealing with symmetry detection graphs
    @ SCIP_CONFTYPE_PROPAGATION
    Definition: type_conflict.h:62
    struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
    Definition: type_cons.h:64
    @ SCIP_LINCONSTYPE_BINPACKING
    Definition: type_cons.h:85
    @ SCIP_LINCONSTYPE_VARBOUND
    Definition: type_cons.h:78
    @ SCIP_LINCONSTYPE_EMPTY
    Definition: type_cons.h:73
    @ SCIP_LINCONSTYPE_INVKNAPSACK
    Definition: type_cons.h:83
    @ SCIP_LINCONSTYPE_PRECEDENCE
    Definition: type_cons.h:77
    @ SCIP_LINCONSTYPE_AGGREGATION
    Definition: type_cons.h:76
    @ SCIP_LINCONSTYPE_MIXEDBINARY
    Definition: type_cons.h:88
    @ SCIP_LINCONSTYPE_SINGLETON
    Definition: type_cons.h:75
    @ SCIP_LINCONSTYPE_SETCOVERING
    Definition: type_cons.h:81
    @ SCIP_LINCONSTYPE_EQKNAPSACK
    Definition: type_cons.h:84
    @ SCIP_LINCONSTYPE_FREE
    Definition: type_cons.h:74
    @ SCIP_LINCONSTYPE_KNAPSACK
    Definition: type_cons.h:86
    @ SCIP_LINCONSTYPE_SETPARTITION
    Definition: type_cons.h:79
    @ SCIP_LINCONSTYPE_INTKNAPSACK
    Definition: type_cons.h:87
    @ SCIP_LINCONSTYPE_SETPACKING
    Definition: type_cons.h:80
    @ SCIP_LINCONSTYPE_GENERAL
    Definition: type_cons.h:89
    @ SCIP_LINCONSTYPE_CARDINALITY
    Definition: type_cons.h:82
    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_IMPLTYPECHANGED
    Definition: type_event.h:87
    #define SCIP_EVENTTYPE_DISABLED
    Definition: type_event.h:67
    #define SCIP_EVENTTYPE_BOUNDTIGHTENED
    Definition: type_event.h:125
    #define SCIP_EVENTTYPE_LBTIGHTENED
    Definition: type_event.h:77
    @ SCIP_EXPRCURV_LINEAR
    Definition: type_expr.h:65
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_VERBLEVEL_HIGH
    Definition: type_message.h:61
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_FEASIBLE
    Definition: type_result.h:45
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_INFEASIBLE
    Definition: type_result.h:46
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_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_ERROR
    Definition: type_retcode.h:43
    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_SOLVING
    Definition: type_set.h:53
    @ SCIP_STAGE_TRANSFORMING
    Definition: type_set.h:46
    @ SCIP_STAGE_PRESOLVED
    Definition: type_set.h:51
    enum SYM_Symtype SYM_SYMTYPE
    Definition: type_symmetry.h:64
    @ SYM_SYMTYPE_SIGNPERM
    Definition: type_symmetry.h:62
    @ SYM_SYMTYPE_PERM
    Definition: type_symmetry.h:61
    #define SCIP_PRESOLTIMING_EXHAUSTIVE
    Definition: type_timing.h:54
    #define NLOCKTYPES
    Definition: type_var.h:138
    enum SCIP_ImplintType SCIP_IMPLINTTYPE
    Definition: type_var.h:117
    @ SCIP_IMPLINTTYPE_NONE
    Definition: type_var.h:90
    @ SCIP_IMPLINTTYPE_STRONG
    Definition: type_var.h:106
    @ SCIP_IMPLINTTYPE_WEAK
    Definition: type_var.h:91
    #define SCIP_DEPRECATED_VARTYPE_IMPLINT
    Definition: type_var.h:79
    @ SCIP_VARTYPE_INTEGER
    Definition: type_var.h:65
    @ 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
    enum SCIP_Varstatus SCIP_VARSTATUS
    Definition: type_var.h:59