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-2016 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file cons_linear.c
17  * @brief Constraint handler for linear constraints in their most general form, \f$lhs <= a^T x <= rhs\f$.
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  * @author Marc Pfetsch
21  * @author Kati Wolter
22  * @author Michael Winkler
23  * @author Gerald Gamrath
24  * @author Domenico Salvagnin
25  *
26  * Linear constraints are separated with a high priority, because they are easy
27  * to separate. Instead of using the global cut pool, the same effect can be
28  * implemented by adding linear constraints to the root node, such that they are
29  * separated each time, the linear constraints are separated. A constraint
30  * handler, which generates linear constraints in this way should have a lower
31  * separation priority than the linear constraint handler, and it should have a
32  * separation frequency that is a multiple of the frequency of the linear
33  * constraint handler. In this way, it can be avoided to separate the same cut
34  * twice, because if a separation run of the handler is always preceded by a
35  * separation of the linear constraints, the priorily added constraints are
36  * always satisfied.
37  *
38  * Linear constraints are enforced and checked with a very low priority. Checking
39  * of (many) linear constraints is much more involved than checking the solution
40  * values for integrality. Because we are separating the linear constraints quite
41  * often, it is only necessary to enforce them for integral solutions. A constraint
42  * handler which generates pool cuts in its enforcing method should have an
43  * enforcing priority smaller than that of the linear constraint handler to avoid
44  * regenerating constraints which already exist.
45  */
46 
47 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
48 
49 #include <assert.h>
50 #include <string.h>
51 #include <limits.h>
52 #include <ctype.h>
53 
54 #include "scip/cons_linear.h"
55 #include "scip/cons_knapsack.h"
56 #include "scip/cons_quadratic.h"
57 #include "scip/cons_nonlinear.h"
58 #include "scip/pub_misc.h"
59 #include "scip/debug.h"
60 
61 #define CONSHDLR_NAME "linear"
62 #define CONSHDLR_DESC "linear constraints of the form lhs <= a^T x <= rhs"
63 #define CONSHDLR_SEPAPRIORITY +100000 /**< priority of the constraint handler for separation */
64 #define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
65 #define CONSHDLR_CHECKPRIORITY -1000000 /**< priority of the constraint handler for checking feasibility */
66 #define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
67 #define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
68 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
69  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
70 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
71 #define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
72 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
73 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
74 
75 #define CONSHDLR_PRESOLTIMING (SCIP_PRESOLTIMING_FAST | SCIP_PRESOLTIMING_EXHAUSTIVE) /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
76 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
77 
78 #define EVENTHDLR_NAME "linear"
79 #define EVENTHDLR_DESC "bound change event handler for linear constraints"
80 
81 #define CONFLICTHDLR_NAME "linear"
82 #define CONFLICTHDLR_DESC "conflict handler creating linear constraints"
83 #define CONFLICTHDLR_PRIORITY -1000000
84 
85 #define DEFAULT_TIGHTENBOUNDSFREQ 1 /**< multiplier on propagation frequency, how often the bounds are tightened */
86 #define DEFAULT_MAXROUNDS 5 /**< maximal number of separation rounds per node (-1: unlimited) */
87 #define DEFAULT_MAXROUNDSROOT -1 /**< maximal number of separation rounds in the root node (-1: unlimited) */
88 #define DEFAULT_MAXSEPACUTS 50 /**< maximal number of cuts separated per separation round */
89 #define DEFAULT_MAXSEPACUTSROOT 200 /**< maximal number of cuts separated per separation round in root node */
90 #define DEFAULT_PRESOLPAIRWISE TRUE /**< should pairwise constraint comparison be performed in presolving? */
91 #define DEFAULT_PRESOLUSEHASHING TRUE /**< should hash table be used for detecting redundant constraints in advance */
92 #define DEFAULT_NMINCOMPARISONS 200000 /**< number for minimal pairwise presolving comparisons */
93 #define DEFAULT_MINGAINPERNMINCOMP 1e-06 /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise
94  * comparison round */
95 #define DEFAULT_SORTVARS TRUE /**< should variables be sorted after presolve w.r.t their coefficient absolute for faster
96  * propagation? */
97 #define DEFAULT_CHECKRELMAXABS FALSE /**< should the violation for a constraint with side 0.0 be checked relative
98  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
99 #define DEFAULT_MAXAGGRNORMSCALE 0.0 /**< maximal allowed relative gain in maximum norm for constraint aggregation
100  * (0.0: disable constraint aggregation) */
101 #define DEFAULT_MAXEASYACTIVITYDELTA 1e6 /**< maximum activity delta to run easy propagation on linear constraint
102  * (faster, but numerically less stable) */
103 #define DEFAULT_MAXCARDBOUNDDIST 0.0 /**< maximal relative distance from current node's dual bound to primal bound compared
104  * to best node's dual bound for separating knapsack cardinality cuts */
105 #define DEFAULT_SEPARATEALL FALSE /**< should all constraints be subject to cardinality cut generation instead of only
106  * the ones with non-zero dual value? */
107 #define DEFAULT_AGGREGATEVARIABLES TRUE /**< should presolving search for redundant variables in equations */
108 #define DEFAULT_SIMPLIFYINEQUALITIES TRUE /**< should presolving try to simplify inequalities */
109 #define DEFAULT_DUALPRESOLVING TRUE /**< should dual presolving steps be performed? */
110 #define DEFAULT_DETECTCUTOFFBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
111  * function defining an upper bound and prevent these constraints from
112  * entering the LP */
113 #define DEFAULT_DETECTLOWERBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
114  * function defining a lower bound and prevent these constraints from
115  * entering the LP */
116 #define DEFAULT_DETECTPARTIALOBJECTIVE TRUE/**< should presolving try to detect subsets of constraints parallel to the
117  * objective function */
118 #define DEFAULT_RANGEDROWPROPAGATION TRUE /**< should we perform ranged row propagation */
119 #define DEFAULT_RANGEDROWARTCONS TRUE /**< should presolving and propagation extract sub-constraints from ranged rows and equations? */
120 #define DEFAULT_RANGEDROWMAXDEPTH INT_MAX /**< maximum depth to apply ranged row propagation */
121 #define DEFAULT_RANGEDROWFREQ 1 /**< frequency for applying ranged row propagation */
122 
123 #define DEFAULT_MULTAGGRREMOVE FALSE /**< should multi-aggregations only be performed if the constraint can be
124  * removed afterwards? */
125 
126 #define MAXDNOM 10000LL /**< maximal denominator for simple rational fixed values */
127 #define MAXSCALEDCOEF 1e+03 /**< maximal coefficient value after scaling */
128 #define MAXSCALEDCOEFINTEGER 1e+05 /**< maximal coefficient value after scaling if all variables are of integral
129  * type
130  */
132 #define HASHSIZE_LINEARCONS 131101 /**< minimal size of hash table in linear constraint tables */
134 #define QUADCONSUPGD_PRIORITY 1000000 /**< priority of the constraint handler for upgrading of quadratic constraints */
135 #define NONLINCONSUPGD_PRIORITY 1000000 /**< priority of the constraint handler for upgrading of nonlinear constraints */
137 #ifdef WITH_PRINTORIGCONSTYPES
138 /** constraint type */
139 enum SCIP_Constype
140 {
141  SCIP_CONSTYPE_EMPTY = 0, /**< */
142  SCIP_CONSTYPE_FREE = 1, /**< */
143  SCIP_CONSTYPE_SINGLETON = 2, /**< */
144  SCIP_CONSTYPE_AGGREGATION = 3, /**< */
145  SCIP_CONSTYPE_VARBOUND = 4, /**< */
146  SCIP_CONSTYPE_SETPARTITION = 5, /**< */
147  SCIP_CONSTYPE_SETPACKING = 6, /**< */
148  SCIP_CONSTYPE_SETCOVERING = 7, /**< */
149  SCIP_CONSTYPE_CARDINALITY = 8, /**< */
150  SCIP_CONSTYPE_INVKNAPSACK = 9, /**< */
151  SCIP_CONSTYPE_EQKNAPSACK = 10, /**< */
152  SCIP_CONSTYPE_BINPACKING = 11, /**< */
153  SCIP_CONSTYPE_KNAPSACK = 12, /**< */
154  SCIP_CONSTYPE_INTKNAPSACK = 13, /**< */
155  SCIP_CONSTYPE_MIXEDBINARY = 14, /**< */
156  SCIP_CONSTYPE_GENERAL = 15 /**< */
157 };
158 typedef enum SCIP_Constype SCIP_CONSTYPE;
159 #endif
160 
161 /* @todo add multi-aggregation of variables that are in exactly two equations (, if not numerically an issue),
162  * maybe in fullDualPresolve(), see convertLongEquality()
163  */
164 
165 
166 /** constraint data for linear constraints */
167 struct SCIP_ConsData
168 {
169  SCIP_Real lhs; /**< left hand side of row (for ranged rows) */
170  SCIP_Real rhs; /**< right hand side of row */
171  SCIP_Real maxabsval; /**< maximum absolute value of all coefficients */
172  SCIP_Real minactivity; /**< minimal value w.r.t. the variable's local bounds for the constraint's
173  * activity, ignoring the coefficients contributing with infinite value */
174  SCIP_Real maxactivity; /**< maximal value w.r.t. the variable's local bounds for the constraint's
175  * activity, ignoring the coefficients contributing with infinite value */
176  SCIP_Real lastminactivity; /**< last minimal activity which was computed by complete summation
177  * over all contributing values */
178  SCIP_Real lastmaxactivity; /**< last maximal activity which was computed by complete summation
179  * over all contributing values */
180  SCIP_Real glbminactivity; /**< minimal value w.r.t. the variable's global bounds for the constraint's
181  * activity, ignoring the coefficients contributing with infinite value */
182  SCIP_Real glbmaxactivity; /**< maximal value w.r.t. the variable's global bounds for the constraint's
183  * activity, ignoring the coefficients contributing with infinite value */
184  SCIP_Real lastglbminactivity; /**< last global minimal activity which was computed by complete summation
185  * over all contributing values */
186  SCIP_Real lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
187  * over all contributing values */
188  SCIP_Real maxactdelta; /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
189  SCIP_VAR* maxactdeltavar; /**< variable with maximal activity contribution, or NULL if invalid */
190  SCIP_Longint possignature; /**< bit signature of coefficients that may take a positive value */
191  SCIP_Longint negsignature; /**< bit signature of coefficients that may take a negative value */
192  SCIP_ROW* row; /**< LP row, if constraint is already stored in LP row format */
193  SCIP_VAR** vars; /**< variables of constraint entries */
194  SCIP_Real* vals; /**< coefficients of constraint entries */
195  SCIP_EVENTDATA** eventdata; /**< event data for bound change events of the variables */
196  int minactivityneginf; /**< number of coefficients contributing with neg. infinite value to minactivity */
197  int minactivityposinf; /**< number of coefficients contributing with pos. infinite value to minactivity */
198  int maxactivityneginf; /**< number of coefficients contributing with neg. infinite value to maxactivity */
199  int maxactivityposinf; /**< number of coefficients contributing with pos. infinite value to maxactivity */
200  int minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
201  int minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
202  int maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
203  int maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
204  int glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
205  int glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
206  int glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
207  int glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
208  int glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
209  int glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
210  int glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
211  int glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
212  int varssize; /**< size of the vars- and vals-arrays */
213  int nvars; /**< number of nonzeros in constraint */
214  int nbinvars; /**< the number of binary variables in the constraint, only valid after
215  * sorting in stage >= SCIP_STAGE_INITSOLVE
216  */
217  unsigned int validmaxabsval:1; /**< is the maximum absolute value valid? */
218  unsigned int validactivities:1; /**< are the activity bounds (local and global) valid? */
219  unsigned int validminact:1; /**< is the local minactivity valid? */
220  unsigned int validmaxact:1; /**< is the local maxactivity valid? */
221  unsigned int validglbminact:1; /**< is the global minactivity valid? */
222  unsigned int validglbmaxact:1; /**< is the global maxactivity valid? */
223  unsigned int propagated:1; /**< is constraint already propagated? */
224  unsigned int boundstightened:1; /**< is constraint already propagated with bound tightening? */
225  unsigned int presolved:1; /**< is constraint already presolved? */
226  unsigned int removedfixings:1; /**< are all fixed variables removed from the constraint? */
227  unsigned int validsignature:1; /**< is the bit signature valid? */
228  unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
229  unsigned int normalized:1; /**< is the constraint in normalized form? */
230  unsigned int upgradetried:1; /**< was the constraint already tried to be upgraded? */
231  unsigned int upgraded:1; /**< is the constraint upgraded and will it be removed after preprocessing? */
232  unsigned int sorted:1; /**< are the constraint's variables sorted? */
233  unsigned int merged:1; /**< are the constraint's equal variables already merged? */
234  unsigned int cliquesadded:1; /**< were the cliques of the constraint already extracted? */
235  unsigned int implsadded:1; /**< were the implications of the constraint already extracted? */
236  unsigned int binvarssorted:1; /**< are binary variables sorted w.r.t. the absolute of their coefficient? */
237  unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
238  unsigned int hascontvar:1; /**< does the constraint contain at least one continuous variable? */
239  unsigned int hasnonbinvar:1; /**< does the constraint contain at least one non-binary variable? */
240  unsigned int hasnonbinvalid:1; /**< is the information stored in hasnonbinvar and hascontvar valid? */
241  unsigned int rangedrowpropagation:1; /**< did we perform ranged row propagation on this constraint? */
242 };
243 
244 /** event data for bound change event */
245 struct SCIP_EventData
246 {
247  SCIP_CONS* cons; /**< linear constraint to process the bound change for */
248  int varpos; /**< position of variable in vars array */
249  int filterpos; /**< position of event in variable's event filter */
250 };
251 
252 /** constraint handler data */
253 struct SCIP_ConshdlrData
254 {
255  SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
256  SCIP_LINCONSUPGRADE** linconsupgrades; /**< linear constraint upgrade methods for specializing linear constraints */
257  SCIP_Real maxaggrnormscale; /**< maximal allowed relative gain in maximum norm for constraint aggregation
258  * (0.0: disable constraint aggregation) */
259  SCIP_Real maxcardbounddist; /**< maximal relative distance from current node's dual bound to primal bound compared
260  * to best node's dual bound for separating knapsack cardinality cuts */
261  SCIP_Real mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
262  SCIP_Real maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
263  * (faster, but numerically less stable) */
264  int linconsupgradessize;/**< size of linconsupgrade array */
265  int nlinconsupgrades; /**< number of linear constraint upgrade methods */
266  int tightenboundsfreq; /**< multiplier on propagation frequency, how often the bounds are tightened */
267  int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
268  int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
269  int maxsepacuts; /**< maximal number of cuts separated per separation round */
270  int maxsepacutsroot; /**< maximal number of cuts separated per separation round in root node */
271  int nmincomparisons; /**< number for minimal pairwise presolving comparisons */
272  int naddconss; /**< number of added constraints */
273  SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
274  SCIP_Bool presolusehashing; /**< should hash table be used for detecting redundant constraints in advance */
275  SCIP_Bool separateall; /**< should all constraints be subject to cardinality cut generation instead of only
276  * the ones with non-zero dual value? */
277  SCIP_Bool aggregatevariables; /**< should presolving search for redundant variables in equations */
278  SCIP_Bool simplifyinequalities;/**< should presolving try to cancel down or delete coefficients in inequalities */
279  SCIP_Bool dualpresolving; /**< should dual presolving steps be performed? */
280  SCIP_Bool sortvars; /**< should binary variables be sorted for faster propagation? */
281  SCIP_Bool checkrelmaxabs; /**< should the violation for a constraint with side 0.0 be checked relative
282  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
283  SCIP_Bool detectcutoffbound; /**< should presolving try to detect constraints parallel to the objective
284  * function defining an upper bound and prevent these constraints from
285  * entering the LP */
286  SCIP_Bool detectlowerbound; /**< should presolving try to detect constraints parallel to the objective
287  * function defining a lower bound and prevent these constraints from
288  * entering the LP */
289  SCIP_Bool detectpartialobjective;/**< should presolving try to detect subsets of constraints parallel to
290  * the objective function */
291  SCIP_Bool rangedrowpropagation;/**< should presolving and propagation try to improve bounds, detect
292  * infeasibility, and extract sub-constraints from ranged rows and
293  * equations */
294  SCIP_Bool rangedrowartcons; /**< should presolving and propagation extract sub-constraints from ranged rows and equations?*/
295  int rangedrowmaxdepth; /**< maximum depth to apply ranged row propagation */
296  int rangedrowfreq; /**< frequency for applying ranged row propagation */
297  SCIP_Bool multaggrremove; /**< should multi-aggregations only be performed if the constraint can be
298  * removed afterwards? */
299 };
300 
301 /** linear constraint update method */
302 struct SCIP_LinConsUpgrade
303 {
304  SCIP_DECL_LINCONSUPGD((*linconsupgd)); /**< method to call for upgrading linear constraint */
305  int priority; /**< priority of upgrading method */
306  SCIP_Bool active; /**< is upgrading enabled */
307 };
308 
309 
310 /*
311  * Propagation rules
312  */
313 
314 enum Proprule
315 {
316  PROPRULE_1_RHS = 1, /**< activity residuals of all other variables tighten bounds of single
317  * variable due to the right hand side of the inequality */
318  PROPRULE_1_LHS = 2, /**< activity residuals of all other variables tighten bounds of single
319  * variable due to the left hand side of the inequality */
320  PROPRULE_1_RANGEDROW = 3, /**< fixed variables and gcd of all left variables tighten bounds of a
321  * single variable in this reanged row */
322  PROPRULE_INVALID = 0 /**< propagation was applied without a specific propagation rule */
323 };
324 typedef enum Proprule PROPRULE;
325 
326 /** inference information */
327 struct InferInfo
328 {
329  union
330  {
331  struct
332  {
333  unsigned int proprule:8; /**< propagation rule that was applied */
334  unsigned int pos:24; /**< variable position, the propagation rule was applied at */
335  } asbits;
336  int asint; /**< inference information as a single int value */
337  } val;
338 };
339 typedef struct InferInfo INFERINFO;
341 /** converts an integer into an inference information */
342 static
344  int i /**< integer to convert */
345  )
346 {
347  INFERINFO inferinfo;
348 
349  inferinfo.val.asint = i;
350 
351  return inferinfo;
352 }
353 
354 /** converts an inference information into an int */
355 static
356 int inferInfoToInt(
357  INFERINFO inferinfo /**< inference information to convert */
358  )
359 {
360  return inferinfo.val.asint;
361 }
362 
363 /** returns the propagation rule stored in the inference information */
364 static
366  INFERINFO inferinfo /**< inference information to convert */
367  )
368 {
369  return (int) inferinfo.val.asbits.proprule;
370 }
371 
372 /** returns the position stored in the inference information */
373 static
374 int inferInfoGetPos(
375  INFERINFO inferinfo /**< inference information to convert */
376  )
377 {
378  return (int) inferinfo.val.asbits.pos;
379 }
380 
381 /** constructs an inference information out of a propagation rule and a position number */
382 static
384  PROPRULE proprule, /**< propagation rule that deduced the value */
385  int pos /**< variable position, the propagation rule was applied at */
386  )
387 {
388  INFERINFO inferinfo;
389 
390  assert(pos >= 0);
391  /* in the inferinfo struct only 24 bits for 'pos' are reserved */
392  assert(pos < (1<<24));
393 
394  inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
395  inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
396 
397  return inferinfo;
398 }
400 /** constructs an inference information out of a propagation rule and a position number, returns info as int */
401 static
402 int getInferInt(
403  PROPRULE proprule, /**< propagation rule that deduced the value */
404  int pos /**< variable position, the propagation rule was applied at */
405  )
406 {
407  return inferInfoToInt(getInferInfo(proprule, pos));
408 }
409 
410 
411 /*
412  * memory growing methods for dynamically allocated arrays
413  */
414 
415 /** ensures, that linconsupgrades array can store at least num entries */
416 static
418  SCIP* scip, /**< SCIP data structure */
419  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
420  int num /**< minimum number of entries to store */
421  )
422 {
423  assert(scip != NULL);
424  assert(conshdlrdata != NULL);
425  assert(conshdlrdata->nlinconsupgrades <= conshdlrdata->linconsupgradessize);
426 
427  if( num > conshdlrdata->linconsupgradessize )
428  {
429  int newsize;
430 
431  newsize = SCIPcalcMemGrowSize(scip, num);
432  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->linconsupgrades, newsize) );
433  conshdlrdata->linconsupgradessize = newsize;
434  }
435  assert(num <= conshdlrdata->linconsupgradessize);
436 
437  return SCIP_OKAY;
438 }
439 
440 /** ensures, that vars and vals arrays can store at least num entries */
441 static
443  SCIP* scip, /**< SCIP data structure */
444  SCIP_CONSDATA* consdata, /**< linear constraint data */
445  int num /**< minimum number of entries to store */
446  )
447 {
448  assert(scip != NULL);
449  assert(consdata != NULL);
450  assert(consdata->nvars <= consdata->varssize);
451 
452  if( num > consdata->varssize )
453  {
454  int newsize;
455 
456  newsize = SCIPcalcMemGrowSize(scip, num);
457  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
458  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
459  if( consdata->eventdata != NULL )
460  {
461  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
462  }
463  consdata->varssize = newsize;
464  }
465  assert(num <= consdata->varssize);
466 
467  return SCIP_OKAY;
468 }
469 
470 
471 /*
472  * local methods for managing linear constraint update methods
473  */
474 
475 /** creates a linear constraint upgrade data object */
476 static
478  SCIP* scip, /**< SCIP data structure */
479  SCIP_LINCONSUPGRADE** linconsupgrade, /**< pointer to store the linear constraint upgrade */
480  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
481  int priority /**< priority of upgrading method */
482  )
483 {
484  assert(scip != NULL);
485  assert(linconsupgrade != NULL);
486  assert(linconsupgd != NULL);
487 
488  SCIP_CALL( SCIPallocMemory(scip, linconsupgrade) );
489  (*linconsupgrade)->linconsupgd = linconsupgd;
490  (*linconsupgrade)->priority = priority;
491  (*linconsupgrade)->active = TRUE;
492 
493  return SCIP_OKAY;
494 }
495 
496 /** frees a linear constraint upgrade data object */
497 static
498 void linconsupgradeFree(
499  SCIP* scip, /**< SCIP data structure */
500  SCIP_LINCONSUPGRADE** linconsupgrade /**< pointer to the linear constraint upgrade */
501  )
502 {
503  assert(scip != NULL);
504  assert(linconsupgrade != NULL);
505  assert(*linconsupgrade != NULL);
506 
507  SCIPfreeMemory(scip, linconsupgrade);
508 }
509 
510 /** creates constraint handler data for linear constraint handler */
511 static
513  SCIP* scip, /**< SCIP data structure */
514  SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
515  SCIP_EVENTHDLR* eventhdlr /**< event handler */
516  )
517 {
518  assert(scip != NULL);
519  assert(conshdlrdata != NULL);
520  assert(eventhdlr != NULL);
521 
522  SCIP_CALL( SCIPallocMemory(scip, conshdlrdata) );
523  (*conshdlrdata)->linconsupgrades = NULL;
524  (*conshdlrdata)->linconsupgradessize = 0;
525  (*conshdlrdata)->nlinconsupgrades = 0;
526  (*conshdlrdata)->naddconss = 0;
527 
528  /* set event handler for updating linear constraint activity bounds */
529  (*conshdlrdata)->eventhdlr = eventhdlr;
530 
531  return SCIP_OKAY;
532 }
533 
534 /** frees constraint handler data for linear constraint handler */
535 static
536 void conshdlrdataFree(
537  SCIP* scip, /**< SCIP data structure */
538  SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
539  )
540 {
541  int i;
542 
543  assert(scip != NULL);
544  assert(conshdlrdata != NULL);
545  assert(*conshdlrdata != NULL);
546 
547  for( i = 0; i < (*conshdlrdata)->nlinconsupgrades; ++i )
548  {
549  linconsupgradeFree(scip, &(*conshdlrdata)->linconsupgrades[i]);
550  }
551  SCIPfreeMemoryArrayNull(scip, &(*conshdlrdata)->linconsupgrades);
553  SCIPfreeMemory(scip, conshdlrdata);
554 }
555 
556 /** creates a linear constraint upgrade data object */
557 static
559  SCIP* scip, /**< SCIP data structure */
560  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
561  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
562  const char* conshdlrname /**< name of the constraint handler */
563  )
564 {
565  int i;
566 
567  assert(scip != NULL);
568  assert(conshdlrdata != NULL);
569  assert(linconsupgd != NULL);
570  assert(conshdlrname != NULL);
571 
572  for( i = conshdlrdata->nlinconsupgrades - 1; i >= 0; --i )
573  {
574  if( conshdlrdata->linconsupgrades[i]->linconsupgd == linconsupgd )
575  {
576 #ifdef SCIP_DEBUG
577  SCIPwarningMessage(scip, "Try to add already known upgrade message %p for constraint handler %s.\n", linconsupgd, conshdlrname);
578 #endif
579  return TRUE;
580  }
581  }
582 
583  return FALSE;
584 }
585 
586 /** adds a linear constraint update method to the constraint handler's data */
587 static
589  SCIP* scip, /**< SCIP data structure */
590  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
591  SCIP_LINCONSUPGRADE* linconsupgrade /**< linear constraint upgrade method */
592  )
593 {
594  int i;
595 
596  assert(scip != NULL);
597  assert(conshdlrdata != NULL);
598  assert(linconsupgrade != NULL);
599 
600  SCIP_CALL( conshdlrdataEnsureLinconsupgradesSize(scip, conshdlrdata, conshdlrdata->nlinconsupgrades+1) );
601 
602  for( i = conshdlrdata->nlinconsupgrades;
603  i > 0 && conshdlrdata->linconsupgrades[i-1]->priority < linconsupgrade->priority; --i )
604  {
605  conshdlrdata->linconsupgrades[i] = conshdlrdata->linconsupgrades[i-1];
606  }
607  assert(0 <= i && i <= conshdlrdata->nlinconsupgrades);
608  conshdlrdata->linconsupgrades[i] = linconsupgrade;
609  conshdlrdata->nlinconsupgrades++;
610 
611  return SCIP_OKAY;
612 }
613 
614 /*
615  * local methods
616  */
617 
618 /** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
619 static
621  SCIP* scip, /**< SCIP data structure */
622  SCIP_CONS* cons, /**< linear constraint */
623  SCIP_VAR* var, /**< variable of constraint entry */
624  SCIP_Real val /**< coefficient of constraint entry */
625  )
626 {
627  SCIP_CONSDATA* consdata;
628 
629  assert(scip != NULL);
630  assert(cons != NULL);
631  assert(var != NULL);
632 
633  consdata = SCIPconsGetData(cons);
634  assert(consdata != NULL);
635  assert(!SCIPisZero(scip, val));
637  if( SCIPisPositive(scip, val) )
638  {
639  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
640  !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
641  }
642  else
643  {
644  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
645  !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
646  }
647 
648  return SCIP_OKAY;
649 }
650 
651 /** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
652 static
654  SCIP* scip, /**< SCIP data structure */
655  SCIP_CONS* cons, /**< linear constraint */
656  SCIP_VAR* var, /**< variable of constraint entry */
657  SCIP_Real val /**< coefficient of constraint entry */
658  )
659 {
660  SCIP_CONSDATA* consdata;
661 
662  assert(scip != NULL);
663  assert(cons != NULL);
664  assert(var != NULL);
665 
666  consdata = SCIPconsGetData(cons);
667  assert(consdata != NULL);
668  assert(!SCIPisZero(scip, val));
670  if( SCIPisPositive(scip, val) )
671  {
672  SCIP_CALL( SCIPunlockVarCons(scip, var, cons,
673  !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
674  }
675  else
676  {
677  SCIP_CALL( SCIPunlockVarCons(scip, var, cons,
678  !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
679  }
680 
681  return SCIP_OKAY;
682 }
683 
684 /** creates event data for variable at given position, and catches events */
685 static
687  SCIP* scip, /**< SCIP data structure */
688  SCIP_CONS* cons, /**< linear constraint */
689  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
690  int pos /**< array position of variable to catch bound change events for */
691  )
692 {
693  SCIP_CONSDATA* consdata;
694  assert(scip != NULL);
695  assert(cons != NULL);
696  assert(eventhdlr != NULL);
697 
698  consdata = SCIPconsGetData(cons);
699  assert(consdata != NULL);
700 
701  assert(0 <= pos && pos < consdata->nvars);
702  assert(consdata->vars != NULL);
703  assert(consdata->vars[pos] != NULL);
704  assert(SCIPvarIsTransformed(consdata->vars[pos]));
705  assert(consdata->eventdata != NULL);
706  assert(consdata->eventdata[pos] == NULL);
707 
708  SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
709  consdata->eventdata[pos]->cons = cons;
710  consdata->eventdata[pos]->varpos = pos;
711 
712  SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
715  eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
716 
717  return SCIP_OKAY;
718 }
719 
720 /** deletes event data for variable at given position, and drops events */
721 static
723  SCIP* scip, /**< SCIP data structure */
724  SCIP_CONS* cons, /**< linear constraint */
725  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
726  int pos /**< array position of variable to catch bound change events for */
727  )
728 {
729  SCIP_CONSDATA* consdata;
730  assert(scip != NULL);
731  assert(cons != NULL);
732  assert(eventhdlr != NULL);
733 
734  consdata = SCIPconsGetData(cons);
735  assert(consdata != NULL);
736 
737  assert(0 <= pos && pos < consdata->nvars);
738  assert(consdata->vars[pos] != NULL);
739  assert(consdata->eventdata != NULL);
740  assert(consdata->eventdata[pos] != NULL);
741  assert(consdata->eventdata[pos]->cons == cons);
742  assert(consdata->eventdata[pos]->varpos == pos);
743 
744  SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
747  eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
748 
749  SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
750 
751  return SCIP_OKAY;
752 }
753 
754 /** catches bound change events for all variables in transformed linear constraint */
755 static
757  SCIP* scip, /**< SCIP data structure */
758  SCIP_CONS* cons, /**< linear constraint */
759  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
760  )
761 {
762  SCIP_CONSDATA* consdata;
763  int i;
764 
765  assert(scip != NULL);
766  assert(cons != NULL);
767 
768  consdata = SCIPconsGetData(cons);
769  assert(consdata != NULL);
770  assert(consdata->eventdata == NULL);
771 
772  /* allocate eventdata array */
773  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
774  assert(consdata->eventdata != NULL);
775  BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
776 
777  /* catch event for every single variable */
778  for( i = 0; i < consdata->nvars; ++i )
779  {
780  SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
781  }
782 
783  return SCIP_OKAY;
784 }
785 
786 /** drops bound change events for all variables in transformed linear constraint */
787 static
789  SCIP* scip, /**< SCIP data structure */
790  SCIP_CONS* cons, /**< linear constraint */
791  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
792  )
793 {
794  SCIP_CONSDATA* consdata;
795  int i;
796 
797  assert(scip != NULL);
798  assert(cons != NULL);
799 
800  consdata = SCIPconsGetData(cons);
801  assert(consdata != NULL);
802  assert(consdata->eventdata != NULL);
803 
804  /* drop event of every single variable */
805  for( i = consdata->nvars - 1; i >= 0; --i )
806  {
807  SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
808  }
809 
810  /* free eventdata array */
811  SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
812  assert(consdata->eventdata == NULL);
813 
814  return SCIP_OKAY;
815 }
816 
817 /** returns whether we are in a stage, where the variable events should be caught */
818 static
820  SCIP* scip /**< SCIP data structure */
821  )
822 {
823  assert(scip != NULL);
824 
826 }
827 
828 /** creates a linear constraint data */
829 static
831  SCIP* scip, /**< SCIP data structure */
832  SCIP_CONSDATA** consdata, /**< pointer to linear constraint data */
833  int nvars, /**< number of nonzeros in the constraint */
834  SCIP_VAR** vars, /**< array with variables of constraint entries */
835  SCIP_Real* vals, /**< array with coefficients of constraint entries */
836  SCIP_Real lhs, /**< left hand side of row */
837  SCIP_Real rhs /**< right hand side of row */
838  )
839 {
840  int v;
841 
842  assert(scip != NULL);
843  assert(consdata != NULL);
844  assert(nvars == 0 || vars != NULL);
845  assert(nvars == 0 || vals != NULL);
847  if( SCIPisInfinity(scip, rhs) )
848  rhs = SCIPinfinity(scip);
849  else if( SCIPisInfinity(scip, -rhs) )
850  rhs = -SCIPinfinity(scip);
851 
852  if( SCIPisInfinity(scip, -lhs) )
853  lhs = -SCIPinfinity(scip);
854  else if( SCIPisInfinity(scip, lhs) )
855  lhs = SCIPinfinity(scip);
856 
857  if( SCIPisGT(scip, lhs, rhs) )
858  {
859  SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
860  SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", lhs, rhs);
861  }
862 
863  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
864 
865  (*consdata)->varssize = nvars;
866  (*consdata)->nvars = nvars;
867  (*consdata)->hascontvar = FALSE;
868  (*consdata)->hasnonbinvar = FALSE;
869  (*consdata)->hasnonbinvalid = TRUE;
870  if( nvars > 0 )
871  {
872  int k;
873 
874  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, vars, nvars) );
875  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, vals, nvars) );
876  k = 0;
877  for( v = 0; v < nvars; ++v )
878  {
879  assert((*consdata)->vars[v] != NULL);
880  if( !SCIPisZero(scip, (*consdata)->vals[v]) )
881  {
882  (*consdata)->vars[k] = (*consdata)->vars[v];
883  (*consdata)->vals[k] = (*consdata)->vals[v];
884  k++;
885 
886  /* update hascontvar and hasnonbinvar flags */
887  if( !(*consdata)->hascontvar )
888  {
889  SCIP_VARTYPE vartype = SCIPvarGetType((*consdata)->vars[v]);
890 
891  if( vartype != SCIP_VARTYPE_BINARY )
892  {
893  (*consdata)->hasnonbinvar = TRUE;
894 
895  if( vartype == SCIP_VARTYPE_CONTINUOUS )
896  (*consdata)->hascontvar = TRUE;
897  }
898  }
899  }
900  }
901  (*consdata)->nvars = k;
902  }
903  else
904  {
905  (*consdata)->vars = NULL;
906  (*consdata)->vals = NULL;
907  }
908  (*consdata)->eventdata = NULL;
909 
910  (*consdata)->row = NULL;
911  (*consdata)->lhs = lhs;
912  (*consdata)->rhs = rhs;
913  (*consdata)->maxabsval = SCIP_INVALID;
914  (*consdata)->minactivity = SCIP_INVALID;
915  (*consdata)->maxactivity = SCIP_INVALID;
916  (*consdata)->lastminactivity = SCIP_INVALID;
917  (*consdata)->lastmaxactivity = SCIP_INVALID;
918  (*consdata)->maxactdelta = SCIP_INVALID;
919  (*consdata)->maxactdeltavar = NULL;
920  (*consdata)->minactivityneginf = -1;
921  (*consdata)->minactivityposinf = -1;
922  (*consdata)->maxactivityneginf = -1;
923  (*consdata)->maxactivityposinf = -1;
924  (*consdata)->minactivityneghuge = -1;
925  (*consdata)->minactivityposhuge = -1;
926  (*consdata)->maxactivityneghuge = -1;
927  (*consdata)->maxactivityposhuge = -1;
928  (*consdata)->glbminactivity = SCIP_INVALID;
929  (*consdata)->glbmaxactivity = SCIP_INVALID;
930  (*consdata)->lastglbminactivity = SCIP_INVALID;
931  (*consdata)->lastglbmaxactivity = SCIP_INVALID;
932  (*consdata)->glbminactivityneginf = -1;
933  (*consdata)->glbminactivityposinf = -1;
934  (*consdata)->glbmaxactivityneginf = -1;
935  (*consdata)->glbmaxactivityposinf = -1;
936  (*consdata)->glbminactivityneghuge = -1;
937  (*consdata)->glbminactivityposhuge = -1;
938  (*consdata)->glbmaxactivityneghuge = -1;
939  (*consdata)->glbmaxactivityposhuge = -1;
940  (*consdata)->possignature = 0;
941  (*consdata)->negsignature = 0;
942  (*consdata)->validmaxabsval = FALSE;
943  (*consdata)->validactivities = FALSE;
944  (*consdata)->validminact = FALSE;
945  (*consdata)->validmaxact = FALSE;
946  (*consdata)->validglbminact = FALSE;
947  (*consdata)->validglbmaxact = FALSE;
948  (*consdata)->propagated = FALSE;
949  (*consdata)->boundstightened = FALSE;
950  (*consdata)->presolved = FALSE;
951  (*consdata)->removedfixings = FALSE;
952  (*consdata)->validsignature = FALSE;
953  (*consdata)->changed = TRUE;
954  (*consdata)->normalized = FALSE;
955  (*consdata)->upgradetried = FALSE;
956  (*consdata)->upgraded = FALSE;
957  (*consdata)->sorted = (nvars <= 1);
958  (*consdata)->merged = (nvars <= 1);
959  (*consdata)->cliquesadded = FALSE;
960  (*consdata)->implsadded = FALSE;
961  (*consdata)->binvarssorted = FALSE;
962  (*consdata)->nbinvars = -1;
963  (*consdata)->varsdeleted = FALSE;
964  (*consdata)->rangedrowpropagation = FALSE;
965 
966  if( SCIPisTransformed(scip) )
967  {
968  /* get transformed variables */
969  SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
970  }
971 
972  /* capture variables */
973  for( v = 0; v < (*consdata)->nvars; v++ )
974  {
975  assert((*consdata)->vars[v] != NULL);
976  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
977  SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
978  }
979 
980  return SCIP_OKAY;
981 }
982 
983 /** frees a linear constraint data */
984 static
986  SCIP* scip, /**< SCIP data structure */
987  SCIP_CONSDATA** consdata /**< pointer to linear constraint data */
988  )
989 {
990  int v;
991 
992  assert(scip != NULL);
993  assert(consdata != NULL);
994  assert(*consdata != NULL);
995  assert((*consdata)->varssize >= 0);
996 
997  /* release the row */
998  if( (*consdata)->row != NULL )
999  {
1000  SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row) );
1001  }
1002 
1003  /* release variables */
1004  for( v = 0; v < (*consdata)->nvars; v++ )
1005  {
1006  assert((*consdata)->vars[v] != NULL);
1007  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1008  SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
1009  }
1010 
1011  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1012  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1013  SCIPfreeBlockMemory(scip, consdata);
1014 
1015  return SCIP_OKAY;
1016 }
1017 
1018 /** prints linear constraint in CIP format to file stream */
1019 static
1021  SCIP* scip, /**< SCIP data structure */
1022  SCIP_CONSDATA* consdata, /**< linear constraint data */
1023  FILE* file /**< output file (or NULL for standard output) */
1024  )
1025 {
1026  assert(scip != NULL);
1027  assert(consdata != NULL);
1028 
1029  /* print left hand side for ranged rows */
1030  if( !SCIPisInfinity(scip, -consdata->lhs)
1031  && !SCIPisInfinity(scip, consdata->rhs)
1032  && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1033  SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1034 
1035  /* print coefficients and variables */
1036  if( consdata->nvars == 0 )
1037  SCIPinfoMessage(scip, file, "0");
1038  else
1039  {
1040  /* post linear sum of the linear constraint */
1041  SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
1042  }
1043 
1044  /* print right hand side */
1045  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1046  SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1047  else if( !SCIPisInfinity(scip, consdata->rhs) )
1048  SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1049  else if( !SCIPisInfinity(scip, -consdata->lhs) )
1050  SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1051  else
1052  SCIPinfoMessage(scip, file, " [free]");
1053 
1054  return SCIP_OKAY;
1055 }
1056 
1057 /** invalidates activity bounds, such that they are recalculated in next get */
1058 static
1060  SCIP_CONSDATA* consdata /**< linear constraint */
1061  )
1062 {
1063  assert(consdata != NULL);
1064 
1065  consdata->validactivities = FALSE;
1066  consdata->validminact = FALSE;
1067  consdata->validmaxact = FALSE;
1068  consdata->validglbminact = FALSE;
1069  consdata->validglbmaxact = FALSE;
1070  consdata->validmaxabsval = FALSE;
1071  consdata->hasnonbinvalid = FALSE;
1072  consdata->minactivity = SCIP_INVALID;
1073  consdata->maxactivity = SCIP_INVALID;
1074  consdata->lastminactivity = SCIP_INVALID;
1075  consdata->lastmaxactivity = SCIP_INVALID;
1076  consdata->maxabsval = SCIP_INVALID;
1077  consdata->maxactdelta = SCIP_INVALID;
1078  consdata->maxactdeltavar = NULL;
1079  consdata->minactivityneginf = -1;
1080  consdata->minactivityposinf = -1;
1081  consdata->maxactivityneginf = -1;
1082  consdata->maxactivityposinf = -1;
1083  consdata->minactivityneghuge = -1;
1084  consdata->minactivityposhuge = -1;
1085  consdata->maxactivityneghuge = -1;
1086  consdata->maxactivityposhuge = -1;
1087  consdata->glbminactivity = SCIP_INVALID;
1088  consdata->glbmaxactivity = SCIP_INVALID;
1089  consdata->lastglbminactivity = SCIP_INVALID;
1090  consdata->lastglbmaxactivity = SCIP_INVALID;
1091  consdata->glbminactivityneginf = -1;
1092  consdata->glbminactivityposinf = -1;
1093  consdata->glbmaxactivityneginf = -1;
1094  consdata->glbmaxactivityposinf = -1;
1095  consdata->glbminactivityneghuge = -1;
1096  consdata->glbminactivityposhuge = -1;
1097  consdata->glbmaxactivityneghuge = -1;
1098  consdata->glbmaxactivityposhuge = -1;
1099 }
1100 
1101 /** compute the pseudo activity of a constraint */
1102 static
1104  SCIP* scip, /**< SCIP data structure */
1105  SCIP_CONSDATA* consdata /**< linear constraint data */
1106  )
1107 {
1108  int i;
1109  int pseudoactivityposinf;
1110  int pseudoactivityneginf;
1111  SCIP_Real pseudoactivity;
1112  SCIP_Real bound;
1113  SCIP_Real val;
1114 
1115  pseudoactivity = 0;
1116  pseudoactivityposinf = 0;
1117  pseudoactivityneginf = 0;
1118 
1119  for( i = consdata->nvars - 1; i >= 0; --i )
1120  {
1121  val = consdata->vals[i];
1122  bound = (SCIPvarGetBestBoundType(consdata->vars[i]) == SCIP_BOUNDTYPE_LOWER) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1123  if( SCIPisInfinity(scip, bound) )
1124  {
1125  if( val > 0.0 )
1126  pseudoactivityposinf++;
1127  else
1128  pseudoactivityneginf++;
1129  }
1130  else
1131  {
1132  if( SCIPisInfinity(scip, -bound) )
1133  {
1134  if( val > 0.0 )
1135  pseudoactivityneginf++;
1136  else
1137  pseudoactivityposinf++;
1138  }
1139  else
1140  pseudoactivity += val * bound;
1141  }
1142  }
1143 
1144  if( pseudoactivityneginf > 0 && pseudoactivityposinf > 0 )
1145  return SCIP_INVALID;
1146  else if( pseudoactivityneginf > 0 )
1147  return -SCIPinfinity(scip);
1148  else if( pseudoactivityposinf > 0 )
1149  return SCIPinfinity(scip);
1150 
1151  return pseudoactivity;
1152 }
1153 
1154 /** recompute the minactivity of a constraint */
1155 static
1157  SCIP* scip, /**< SCIP data structure */
1158  SCIP_CONSDATA* consdata /**< linear constraint data */
1159  )
1160 {
1161  int i;
1162  SCIP_Real bound;
1163 
1164  consdata->minactivity = 0;
1165 
1166  for( i = consdata->nvars - 1; i >= 0; --i )
1167  {
1168  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1169  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1170  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1171  consdata->minactivity += consdata->vals[i] * bound;
1172  }
1173 
1174  /* the activity was just computed from scratch and is valid now */
1175  consdata->validminact = TRUE;
1176 
1177  /* the activity was just computed from scratch, mark it to be reliable */
1178  consdata->lastminactivity = consdata->minactivity;
1179 }
1180 
1181 /** recompute the maxactivity of a constraint */
1182 static
1184  SCIP* scip, /**< SCIP data structure */
1185  SCIP_CONSDATA* consdata /**< linear constraint data */
1186  )
1187 {
1188  int i;
1189  SCIP_Real bound;
1190 
1191  consdata->maxactivity = 0;
1192 
1193  for( i = consdata->nvars - 1; i >= 0; --i )
1194  {
1195  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbLocal(consdata->vars[i]) : SCIPvarGetLbLocal(consdata->vars[i]);
1196  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1197  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1198  consdata->maxactivity += consdata->vals[i] * bound;
1199  }
1200 
1201  /* the activity was just computed from scratch and is valid now */
1202  consdata->validmaxact = TRUE;
1203 
1204  /* the activity was just computed from scratch, mark it to be reliable */
1205  consdata->lastmaxactivity = consdata->maxactivity;
1206 }
1207 
1208 /** recompute the global minactivity of a constraint */
1209 static
1211  SCIP* scip, /**< SCIP data structure */
1212  SCIP_CONSDATA* consdata /**< linear constraint data */
1213  )
1214 {
1215  int i;
1216  SCIP_Real bound;
1217 
1218  consdata->glbminactivity = 0;
1219 
1220  for( i = consdata->nvars - 1; i >= 0; --i )
1221  {
1222  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbGlobal(consdata->vars[i]) : SCIPvarGetUbGlobal(consdata->vars[i]);
1223  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound) )
1224  consdata->glbminactivity += consdata->vals[i] * bound;
1225  }
1227  /* the activity was just computed from scratch and is valid now */
1228  consdata->validglbminact = TRUE;
1229 
1230  /* the activity was just computed from scratch, mark it to be reliable */
1231  consdata->lastglbminactivity = consdata->glbminactivity;
1232 }
1233 
1234 /** recompute the global maxactivity of a constraint */
1235 static
1237  SCIP* scip, /**< SCIP data structure */
1238  SCIP_CONSDATA* consdata /**< linear constraint data */
1239  )
1240 {
1241  int i;
1242  SCIP_Real bound;
1243 
1244  consdata->glbmaxactivity = 0;
1245 
1246  for( i = consdata->nvars - 1; i >= 0; --i )
1247  {
1248  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbGlobal(consdata->vars[i]) : SCIPvarGetLbGlobal(consdata->vars[i]);
1249  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound) )
1250  consdata->glbmaxactivity += consdata->vals[i] * bound;
1251  }
1253  /* the activity was just computed from scratch and is valid now */
1254  consdata->validglbmaxact = TRUE;
1255 
1256  /* the activity was just computed from scratch, mark it to be reliable */
1257  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
1258 }
1259 
1260 /** calculates maximum absolute value of coefficients */
1261 static
1263  SCIP_CONSDATA* consdata /**< linear constraint data */
1264  )
1265 {
1266  SCIP_Real absval;
1267  int i;
1268 
1269  assert(consdata != NULL);
1270  assert(!consdata->validmaxabsval);
1271  assert(consdata->maxabsval >= SCIP_INVALID);
1272 
1273  consdata->validmaxabsval = TRUE;
1274  consdata->maxabsval = 0.0;
1275  for( i = 0; i < consdata->nvars; ++i )
1276  {
1277  absval = consdata->vals[i];
1278  absval = REALABS(absval);
1279  if( absval > consdata->maxabsval )
1280  consdata->maxabsval = absval;
1281  }
1282 }
1283 
1284 /** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
1285 static
1287  SCIP_CONSDATA* consdata /**< linear constraint data */
1288  )
1289 {
1290  int v;
1291 
1292  assert(!consdata->hasnonbinvalid);
1293  consdata->hasnonbinvar = FALSE;
1294  consdata->hascontvar = FALSE;
1295 
1296  for( v = consdata->nvars - 1; v >= 0; --v )
1297  {
1298  SCIP_VARTYPE vartype = SCIPvarGetType(consdata->vars[v]);
1299 
1300  if( vartype != SCIP_VARTYPE_BINARY )
1301  {
1302  consdata->hasnonbinvar = TRUE;
1303 
1304  if( vartype == SCIP_VARTYPE_CONTINUOUS )
1305  {
1306  consdata->hascontvar = TRUE;
1307  break;
1308  }
1309  }
1310  }
1311  assert(consdata->hascontvar || v < 0);
1312 
1313  consdata->hasnonbinvalid = TRUE;
1314 }
1315 
1316 
1317 #ifdef CHECKMAXACTDELTA
1318 /* checks that the stored maximal activity delta (if not invalid) is correct */
1319 static
1321  SCIP* scip, /**< SCIP data structure */
1322  SCIP_CONSDATA* consdata /**< linear constraint data */
1323  )
1324 {
1325  if( consdata->maxactdelta != SCIP_INVALID )
1326  {
1327  SCIP_Real maxactdelta = 0.0;
1328  SCIP_Real domain;
1329  SCIP_Real delta;
1330  SCIP_Real lb;
1331  SCIP_Real ub;
1332  int v;
1333 
1334  for( v = consdata->nvars - 1; v >= 0; --v )
1335  {
1336  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1337  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1338 
1339  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1340  {
1341  maxactdelta = SCIPinfinity(scip);
1342  break;
1343  }
1344 
1345  domain = ub - lb;
1346  delta = REALABS(consdata->vals[v]) * domain;
1347 
1348  if( delta > maxactdelta )
1349  {
1350  maxactdelta = delta;
1351  }
1352  }
1353  assert(SCIPisFeasEQ(scip, maxactdelta, consdata->maxactdelta));
1354  }
1355 }
1356 #else
1357 #define checkMaxActivityDelta(scip, consdata) /**/
1358 #endif
1359 
1360 /** recompute maximal activity contribution for a single variable */
1361 static
1363  SCIP* scip, /**< SCIP data structure */
1364  SCIP_CONSDATA* consdata /**< linear constraint data */
1365  )
1366 {
1367  SCIP_Real delta;
1368  int v;
1369 
1370  consdata->maxactdelta = 0.0;
1371 
1372  if( !consdata->hasnonbinvalid )
1374 
1375  /* easy case, the problem consists only of binary variables */
1376  if( !consdata->hasnonbinvar )
1377  {
1378  for( v = consdata->nvars - 1; v >= 0; --v )
1379  {
1380  if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
1381  {
1382  delta = REALABS(consdata->vals[v]);
1383 
1384  if( delta > consdata->maxactdelta )
1385  {
1386  consdata->maxactdelta = delta;
1387  consdata->maxactdeltavar = consdata->vars[v];
1388  }
1389  }
1390  }
1391  return;
1392  }
1393 
1394  for( v = consdata->nvars - 1; v >= 0; --v )
1395  {
1396  SCIP_Real domain;
1397  SCIP_Real lb;
1398  SCIP_Real ub;
1399 
1400  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1401  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1402 
1403  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1404  {
1405  consdata->maxactdelta = SCIPinfinity(scip);
1406  consdata->maxactdeltavar = consdata->vars[v];
1407  break;
1408  }
1409 
1410  domain = ub - lb;
1411  delta = REALABS(consdata->vals[v]) * domain;
1412 
1413  if( delta > consdata->maxactdelta )
1414  {
1415  consdata->maxactdelta = delta;
1416  consdata->maxactdeltavar = consdata->vars[v];
1417  }
1418  }
1419 }
1420 
1421 
1422 /** updates activities for a change in a bound */
1423 static
1425  SCIP* scip, /**< SCIP data structure */
1426  SCIP_CONSDATA* consdata, /**< linear constraint data */
1427  SCIP_VAR* var, /**< variable that has been changed; can be NULL for global bound changes */
1428  SCIP_Real oldbound, /**< old bound of variable */
1429  SCIP_Real newbound, /**< new bound of variable */
1430  SCIP_Real val, /**< coefficient of constraint entry */
1431  SCIP_BOUNDTYPE boundtype, /**< type of the bound change */
1432  SCIP_Bool global, /**< is it a global or a local bound change? */
1433  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1434  )
1435 {
1436  SCIP_Real* activity;
1437  SCIP_Real* lastactivity;
1438  int* activityposinf;
1439  int* activityneginf;
1440  int* activityposhuge;
1441  int* activityneghuge;
1442  SCIP_Real delta;
1443  SCIP_Bool validact;
1444 
1445  assert(scip != NULL);
1446  assert(consdata != NULL);
1447  assert(global || (var != NULL));
1448  assert(consdata->validactivities);
1449  assert(consdata->minactivity < SCIP_INVALID);
1450  assert(consdata->maxactivity < SCIP_INVALID);
1451  assert(consdata->lastminactivity < SCIP_INVALID);
1452  assert(consdata->lastmaxactivity < SCIP_INVALID);
1453  assert(consdata->minactivityneginf >= 0);
1454  assert(consdata->minactivityposinf >= 0);
1455  assert(consdata->maxactivityneginf >= 0);
1456  assert(consdata->maxactivityposinf >= 0);
1457  assert(consdata->minactivityneghuge >= 0);
1458  assert(consdata->minactivityposhuge >= 0);
1459  assert(consdata->maxactivityneghuge >= 0);
1460  assert(consdata->maxactivityposhuge >= 0);
1461  assert(consdata->glbminactivity < SCIP_INVALID);
1462  assert(consdata->glbmaxactivity < SCIP_INVALID);
1463  assert(consdata->lastglbminactivity < SCIP_INVALID);
1464  assert(consdata->lastglbmaxactivity < SCIP_INVALID);
1465  assert(consdata->glbminactivityneginf >= 0);
1466  assert(consdata->glbminactivityposinf >= 0);
1467  assert(consdata->glbmaxactivityneginf >= 0);
1468  assert(consdata->glbmaxactivityposinf >= 0);
1469  assert(consdata->glbminactivityneghuge >= 0);
1470  assert(consdata->glbminactivityposhuge >= 0);
1471  assert(consdata->glbmaxactivityneghuge >= 0);
1472  assert(consdata->glbmaxactivityposhuge >= 0);
1473 
1474  delta = 0.0;
1475 
1476  /* we are updating global activities */
1477  if( global )
1478  {
1479  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1480  * lower bound + pos. coef: update minactivity
1481  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1482  * upper bound + pos. coef: update maxactivity
1483  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1484  */
1485  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1486  {
1487  if( val > 0.0 )
1488  {
1489  activity = &(consdata->glbminactivity);
1490  lastactivity = &(consdata->lastglbminactivity);
1491  activityposinf = &(consdata->glbminactivityposinf);
1492  activityneginf = &(consdata->glbminactivityneginf);
1493  activityposhuge = &(consdata->glbminactivityposhuge);
1494  activityneghuge = &(consdata->glbminactivityneghuge);
1495  validact = consdata->validglbminact;
1496  }
1497  else
1498  {
1499  activity = &(consdata->glbmaxactivity);
1500  lastactivity = &(consdata->lastglbmaxactivity);
1501  activityposinf = &(consdata->glbmaxactivityneginf);
1502  activityneginf = &(consdata->glbmaxactivityposinf);
1503  activityposhuge = &(consdata->glbmaxactivityposhuge);
1504  activityneghuge = &(consdata->glbmaxactivityneghuge);
1505  validact = consdata->validglbmaxact;
1506  }
1507  }
1508  else
1509  {
1510  if( val > 0.0 )
1511  {
1512  activity = &(consdata->glbmaxactivity);
1513  lastactivity = &(consdata->lastglbmaxactivity);
1514  activityposinf = &(consdata->glbmaxactivityposinf);
1515  activityneginf = &(consdata->glbmaxactivityneginf);
1516  activityposhuge = &(consdata->glbmaxactivityposhuge);
1517  activityneghuge = &(consdata->glbmaxactivityneghuge);
1518  validact = consdata->validglbmaxact;
1519  }
1520  else
1521  {
1522  activity = &(consdata->glbminactivity);
1523  lastactivity = &(consdata->lastglbminactivity);
1524  activityposinf = &(consdata->glbminactivityneginf);
1525  activityneginf = &(consdata->glbminactivityposinf);
1526  activityposhuge = &(consdata->glbminactivityposhuge);
1527  activityneghuge = &(consdata->glbminactivityneghuge);
1528  validact = consdata->validglbminact;
1529  }
1530  }
1531  }
1532  /* we are updating local activities */
1533  else
1534  {
1535  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1536  * lower bound + pos. coef: update minactivity
1537  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1538  * upper bound + pos. coef: update maxactivity
1539  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1540  */
1541  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1542  {
1543  if( val > 0.0 )
1544  {
1545  activity = &(consdata->minactivity);
1546  lastactivity = &(consdata->lastminactivity);
1547  activityposinf = &(consdata->minactivityposinf);
1548  activityneginf = &(consdata->minactivityneginf);
1549  activityposhuge = &(consdata->minactivityposhuge);
1550  activityneghuge = &(consdata->minactivityneghuge);
1551  validact = consdata->validminact;
1552  }
1553  else
1554  {
1555  activity = &(consdata->maxactivity);
1556  lastactivity = &(consdata->lastmaxactivity);
1557  activityposinf = &(consdata->maxactivityneginf);
1558  activityneginf = &(consdata->maxactivityposinf);
1559  activityposhuge = &(consdata->maxactivityposhuge);
1560  activityneghuge = &(consdata->maxactivityneghuge);
1561  validact = consdata->validmaxact;
1562  }
1563  }
1564  else
1565  {
1566  if( val > 0.0 )
1567  {
1568  activity = &(consdata->maxactivity);
1569  lastactivity = &(consdata->lastmaxactivity);
1570  activityposinf = &(consdata->maxactivityposinf);
1571  activityneginf = &(consdata->maxactivityneginf);
1572  activityposhuge = &(consdata->maxactivityposhuge);
1573  activityneghuge = &(consdata->maxactivityneghuge);
1574  validact = consdata->validmaxact;
1575  }
1576  else
1577  {
1578  activity = &(consdata->minactivity);
1579  lastactivity = &(consdata->lastminactivity);
1580  activityposinf = &(consdata->minactivityneginf);
1581  activityneginf = &(consdata->minactivityposinf);
1582  activityposhuge = &(consdata->minactivityposhuge);
1583  activityneghuge = &(consdata->minactivityneghuge);
1584  validact = consdata->validminact;
1585  }
1586  }
1587  }
1588 
1589  /* old bound was +infinity */
1590  if( SCIPisInfinity(scip, oldbound) )
1591  {
1592  assert((*activityposinf) >= 1);
1593 
1594  /* we only have to do something if the new bound is not again +infinity */
1595  if( !SCIPisInfinity(scip, newbound) )
1596  {
1597  /* decrease the counter for positive infinite contributions */
1598  (*activityposinf)--;
1599 
1600  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1601  if( SCIPisInfinity(scip, -newbound) )
1602  (*activityneginf)++;
1603  /* if the contribution of this variable is too large, increase the counter for huge values */
1604  else if( SCIPisHugeValue(scip, val * newbound) )
1605  {
1606  (*activityposhuge)++;
1607  }
1608  else if( SCIPisHugeValue(scip, -val * newbound) )
1609  {
1610  (*activityneghuge)++;
1611  }
1612  /* "normal case": just add the contribution to the activity */
1613  else
1614  delta = val * newbound;
1615  }
1616  }
1617  /* old bound was -infinity */
1618  else if( SCIPisInfinity(scip, -oldbound) )
1619  {
1620  assert((*activityneginf) >= 1);
1621 
1622  /* we only have to do something ig the new bound is not again -infinity */
1623  if( !SCIPisInfinity(scip, -newbound) )
1624  {
1625  /* decrease the counter for negative infinite contributions */
1626  (*activityneginf)--;
1627 
1628  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1629  if( SCIPisInfinity(scip, newbound) )
1630  (*activityposinf)++;
1631  /* if the contribution of this variable is too large, increase the counter for huge values */
1632  else if( SCIPisHugeValue(scip, val * newbound) )
1633  {
1634  (*activityposhuge)++;
1635  }
1636  else if( SCIPisHugeValue(scip, -val * newbound) )
1637  {
1638  (*activityneghuge)++;
1639  }
1640  /* "normal case": just add the contribution to the activity */
1641  else
1642  delta = val * newbound;
1643  }
1644  }
1645  /* old contribution was too large and positive */
1646  else if( SCIPisHugeValue(scip, val * oldbound) )
1647  {
1648  assert((*activityposhuge) >= 1);
1649 
1650  /* decrease the counter for huge positive contributions; it might be increased again later,
1651  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1652  */
1653  (*activityposhuge)--;
1654 
1655  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1656  if( SCIPisInfinity(scip, newbound) )
1657  (*activityposinf)++;
1658  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1659  else if( SCIPisInfinity(scip, -newbound) )
1660  (*activityneginf)++;
1661  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1662  else if( SCIPisHugeValue(scip, val * newbound) )
1663  {
1664  (*activityposhuge)++;
1665  }
1666  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1667  else if( SCIPisHugeValue(scip, -val * newbound) )
1668  {
1669  (*activityneghuge)++;
1670  }
1671  /* "normal case": just add the contribution to the activity */
1672  else
1673  delta = val * newbound;
1674  }
1675  /* old contribution was too large and negative */
1676  else if( SCIPisHugeValue(scip, -val * oldbound) )
1677  {
1678  assert((*activityneghuge) >= 1);
1679 
1680  /* decrease the counter for huge negative contributions; it might be increased again later,
1681  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1682  */
1683  (*activityneghuge)--;
1684 
1685  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1686  if( SCIPisInfinity(scip, newbound) )
1687  (*activityposinf)++;
1688  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1689  else if( SCIPisInfinity(scip, -newbound) )
1690  (*activityneginf)++;
1691  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1692  else if( SCIPisHugeValue(scip, val * newbound) )
1693  {
1694  (*activityposhuge)++;
1695  }
1696  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1697  else if( SCIPisHugeValue(scip, -val * newbound) )
1698  {
1699  (*activityneghuge)++;
1700  }
1701  /* "normal case": just add the contribution to the activity */
1702  else
1703  delta = val * newbound;
1704  }
1705  /* old bound was finite and not too large */
1706  else
1707  {
1708  /* if the new bound is +infinity, the old contribution has to be subtracted
1709  * and the counter for positive infinite contributions has to be increased
1710  */
1711  if( SCIPisInfinity(scip, newbound) )
1712  {
1713  (*activityposinf)++;
1714  delta = -val * oldbound;
1715  }
1716  /* if the new bound is -infinity, the old contribution has to be subtracted
1717  * and the counter for negative infinite contributions has to be increased
1718  */
1719  else if( SCIPisInfinity(scip, -newbound) )
1720  {
1721  (*activityneginf)++;
1722  delta = -val * oldbound;
1723  }
1724  /* if the contribution of this variable is too large, increase the counter for huge values */
1725  else if( SCIPisHugeValue(scip, val * newbound) )
1726  {
1727  (*activityposhuge)++;
1728  delta = -val * oldbound;
1729  }
1730  else if( SCIPisHugeValue(scip, -val * newbound) )
1731  {
1732  (*activityneghuge)++;
1733  delta = -val * oldbound;
1734  }
1735  /* "normal case": just update the activity */
1736  else
1737  delta = val * (newbound - oldbound);
1738  }
1739 
1740  /* update the activity, if the current value is valid and there was a change in the finite part */
1741  if( validact && (delta != 0.0) )
1742  {
1743  /* if the absolute value of the activity is increased, this is regarded as reliable,
1744  * otherwise, we check whether we can still trust the updated value
1745  */
1746  (*activity) = (*activity) + delta;
1747  assert(!SCIPisInfinity(scip, -(*activity)) && !SCIPisInfinity(scip, *activity));
1748 
1749  if( REALABS((*lastactivity)) < REALABS(*activity) )
1750  {
1751  (*lastactivity) = (*activity);
1752  }
1753  else
1754  {
1755  if( checkreliability && SCIPisUpdateUnreliable(scip, (*activity), (*lastactivity)) )
1756  {
1757  SCIPdebugMessage("%s activity of linear constraint unreliable after update: %16.9g\n",
1758  (global ? "global " : ""), (*activity));
1759 
1760  /* mark the activity that was just changed and is not reliable anymore to be invalid */
1761  if( global )
1762  {
1763  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1764  consdata->validglbminact = FALSE;
1765  else
1766  consdata->validglbmaxact = FALSE;
1767  }
1768  else
1769  {
1770  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1771  consdata->validminact = FALSE;
1772  else
1773  consdata->validmaxact = FALSE;
1774  }
1775  }
1776  }
1777  }
1778 }
1779 
1780 /** updates minimum and maximum activity for a change in lower bound */
1781 static
1783  SCIP* scip, /**< SCIP data structure */
1784  SCIP_CONSDATA* consdata, /**< linear constraint data */
1785  SCIP_VAR* var, /**< variable that has been changed */
1786  SCIP_Real oldlb, /**< old lower bound of variable */
1787  SCIP_Real newlb, /**< new lower bound of variable */
1788  SCIP_Real val, /**< coefficient of constraint entry */
1789  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1790  )
1791 {
1792  assert(scip != NULL);
1793  assert(consdata != NULL);
1794  assert(var != NULL);
1795 
1796  if( consdata->validactivities )
1797  {
1798  consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE, checkreliability);
1799 
1800  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
1801  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
1802  }
1803 }
1804 
1805 /** updates minimum and maximum activity for a change in upper bound */
1806 static
1808  SCIP* scip, /**< SCIP data structure */
1809  SCIP_CONSDATA* consdata, /**< linear constraint data */
1810  SCIP_VAR* var, /**< variable that has been changed */
1811  SCIP_Real oldub, /**< old upper bound of variable */
1812  SCIP_Real newub, /**< new upper bound of variable */
1813  SCIP_Real val, /**< coefficient of constraint entry */
1814  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1815  )
1816 {
1817  assert(scip != NULL);
1818  assert(consdata != NULL);
1819  assert(var != NULL);
1820 
1821  if( consdata->validactivities )
1822  {
1823  consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE, checkreliability);
1824 
1825  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
1826  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
1827  }
1828 }
1829 
1830 /** updates minimum and maximum global activity for a change in the global lower bound */
1831 static
1833  SCIP* scip, /**< SCIP data structure */
1834  SCIP_CONSDATA* consdata, /**< linear constraint data */
1835  SCIP_Real oldlb, /**< old lower bound of variable */
1836  SCIP_Real newlb, /**< new lower bound of variable */
1837  SCIP_Real val, /**< coefficient of constraint entry */
1838  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1839  )
1840 {
1841  assert(scip != NULL);
1842  assert(consdata != NULL);
1843 
1844  if( consdata->validactivities )
1845  {
1846  consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE, checkreliability);
1847 
1848  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
1849  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
1850  }
1851 }
1852 
1853 /** updates minimum and maximum global activity for a change in global upper bound */
1854 static
1856  SCIP* scip, /**< SCIP data structure */
1857  SCIP_CONSDATA* consdata, /**< linear constraint data */
1858  SCIP_Real oldub, /**< old upper bound of variable */
1859  SCIP_Real newub, /**< new upper bound of variable */
1860  SCIP_Real val, /**< coefficient of constraint entry */
1861  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1862  )
1863 {
1864  assert(scip != NULL);
1865  assert(consdata != NULL);
1866 
1867  if( consdata->validactivities )
1868  {
1869  consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE, checkreliability);
1870 
1871  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
1872  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
1873  }
1874 }
1875 
1876 /** updates minimum and maximum activity and maximum absolute value for coefficient addition */
1877 static
1879  SCIP* scip, /**< SCIP data structure */
1880  SCIP_CONSDATA* consdata, /**< linear constraint data */
1881  SCIP_VAR* var, /**< variable of constraint entry */
1882  SCIP_Real val, /**< coefficient of constraint entry */
1883  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1884  )
1885 {
1886  assert(scip != NULL);
1887  assert(consdata != NULL);
1888  assert(var != NULL);
1889 
1890  /* update maximum absolute value */
1891  if( consdata->validmaxabsval )
1892  {
1893  SCIP_Real absval;
1895  assert(consdata->maxabsval < SCIP_INVALID);
1896 
1897  absval = REALABS(val);
1898  consdata->maxabsval = MAX(consdata->maxabsval, absval);
1899  }
1900 
1901  /* update minimal and maximal activity */
1902  if( consdata->validactivities )
1903  {
1904  assert(consdata->minactivity < SCIP_INVALID);
1905  assert(consdata->maxactivity < SCIP_INVALID);
1906  assert(consdata->glbminactivity < SCIP_INVALID);
1907  assert(consdata->glbmaxactivity < SCIP_INVALID);
1908 
1909  consdataUpdateActivitiesLb(scip, consdata, var, 0.0, SCIPvarGetLbLocal(var), val, checkreliability);
1910  consdataUpdateActivitiesUb(scip, consdata, var, 0.0, SCIPvarGetUbLocal(var), val, checkreliability);
1911  consdataUpdateActivitiesGlbLb(scip, consdata, 0.0, SCIPvarGetLbGlobal(var), val, checkreliability);
1912  consdataUpdateActivitiesGlbUb(scip, consdata, 0.0, SCIPvarGetUbGlobal(var), val, checkreliability);
1913  }
1914 }
1915 
1916 /** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
1917 static
1919  SCIP* scip, /**< SCIP data structure */
1920  SCIP_CONSDATA* consdata, /**< linear constraint data */
1921  SCIP_VAR* var, /**< variable of constraint entry */
1922  SCIP_Real val, /**< coefficient of constraint entry */
1923  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1924  )
1925 {
1926  assert(scip != NULL);
1927  assert(consdata != NULL);
1928  assert(var != NULL);
1929 
1930  /* invalidate maximum absolute value, if this coefficient was the maximum */
1931  if( consdata->validmaxabsval )
1932  {
1933  SCIP_Real absval;
1935  absval = REALABS(val);
1936 
1937  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
1938  {
1939  consdata->validmaxabsval = FALSE;
1940  consdata->maxabsval = SCIP_INVALID;
1941  }
1942  }
1943 
1944  /* update minimal and maximal activity */
1945  if( consdata->validactivities )
1946  {
1947  assert(consdata->minactivity < SCIP_INVALID);
1948  assert(consdata->maxactivity < SCIP_INVALID);
1949  assert(consdata->glbminactivity < SCIP_INVALID);
1950  assert(consdata->glbmaxactivity < SCIP_INVALID);
1951 
1952  consdataUpdateActivitiesLb(scip, consdata, var, SCIPvarGetLbLocal(var), 0.0, val, checkreliability);
1953  consdataUpdateActivitiesUb(scip, consdata, var, SCIPvarGetUbLocal(var), 0.0, val, checkreliability);
1954  consdataUpdateActivitiesGlbLb(scip, consdata, SCIPvarGetLbGlobal(var), 0.0, val, checkreliability);
1955  consdataUpdateActivitiesGlbUb(scip, consdata, SCIPvarGetUbGlobal(var), 0.0, val, checkreliability);
1956  }
1957 }
1958 
1959 /** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
1960 static
1962  SCIP* scip, /**< SCIP data structure */
1963  SCIP_CONSDATA* consdata, /**< linear constraint data */
1964  SCIP_VAR* var, /**< variable of constraint entry */
1965  SCIP_Real oldval, /**< old coefficient of constraint entry */
1966  SCIP_Real newval, /**< new coefficient of constraint entry */
1967  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1968  )
1969 {
1970  assert(scip != NULL);
1971  assert(consdata != NULL);
1972  assert(var != NULL);
1973 
1974  /* old zero coefficients should be handled by consdataUpdateAddCoef() */
1975  assert(!SCIPisZero(scip, oldval));
1976 
1977  /* new zero coefficients should be handled by consdataUpdateDelCoef() */
1978  assert(!SCIPisZero(scip, newval));
1979 
1980  /* update maximum absolute value */
1981  if( consdata->validmaxabsval )
1982  {
1983  SCIP_Real absval;
1984 
1985  absval = REALABS(newval);
1986 
1987  if( SCIPisGE(scip, absval, consdata->maxabsval) )
1988  {
1989  consdata->maxabsval = absval;
1990  }
1991  else
1992  {
1993  absval = REALABS(oldval);
1994 
1995  /* invalidate maximum absolute value */
1996  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
1997  {
1998  consdata->validmaxabsval = FALSE;
1999  consdata->maxabsval = SCIP_INVALID;
2000  }
2001  }
2002  }
2003 
2004  /* update maximum activity delta */
2005  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
2006  {
2007  SCIP_Real domain;
2008  SCIP_Real delta;
2009 
2010  assert(!SCIPisInfinity(scip, SCIPvarGetLbLocal(var)));
2011  assert(!SCIPisInfinity(scip, SCIPvarGetUbLocal(var)));
2012 
2013  domain = SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var);
2014  delta = REALABS(newval) * domain;
2015 
2016  if( delta > consdata->maxactdelta )
2017  {
2018  consdata->maxactdelta = delta;
2019  consdata->maxactdeltavar = var;
2020  }
2021  else
2022  {
2023  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
2024  if( consdata->maxactdeltavar == var )
2025  consdata->maxactdelta = SCIP_INVALID;
2026  }
2027  }
2028 
2029  /* @todo do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
2030  consdataUpdateDelCoef(scip, consdata, var, oldval, checkreliability);
2031  consdataUpdateAddCoef(scip, consdata, var, newval, checkreliability);
2032 }
2033 
2034 /** returns the maximum absolute value of all coefficients in the constraint */
2035 static
2037  SCIP_CONSDATA* consdata /**< linear constraint data */
2038  )
2039 {
2040  assert(consdata != NULL);
2041 
2042  if( !consdata->validmaxabsval )
2043  consdataCalcMaxAbsval(consdata);
2044  assert(consdata->validmaxabsval);
2045  assert(consdata->maxabsval < SCIP_INVALID);
2046 
2047  return consdata->maxabsval;
2048 }
2049 
2050 /** calculates minimum and maximum local and global activity for constraint from scratch;
2051  * additionally recalculates maximum absolute value of coefficients
2052  */
2053 static
2055  SCIP* scip, /**< SCIP data structure */
2056  SCIP_CONSDATA* consdata /**< linear constraint data */
2057  )
2058 {
2059  int i;
2060 
2061  assert(scip != NULL);
2062  assert(consdata != NULL);
2063  assert(!consdata->validactivities);
2064  assert(consdata->minactivity >= SCIP_INVALID || consdata->validminact);
2065  assert(consdata->maxactivity >= SCIP_INVALID || consdata->validmaxact);
2066  assert(consdata->glbminactivity >= SCIP_INVALID || consdata->validglbminact);
2067  assert(consdata->glbmaxactivity >= SCIP_INVALID || consdata->validglbmaxact);
2068 
2069  consdata->validmaxabsval = TRUE;
2070  consdata->validactivities = TRUE;
2071  consdata->validminact = TRUE;
2072  consdata->validmaxact = TRUE;
2073  consdata->validglbminact = TRUE;
2074  consdata->validglbmaxact = TRUE;
2075  consdata->maxabsval = 0.0;
2076  consdata->minactivity = 0.0;
2077  consdata->maxactivity = 0.0;
2078  consdata->lastminactivity = 0.0;
2079  consdata->lastmaxactivity = 0.0;
2080  consdata->minactivityneginf = 0;
2081  consdata->minactivityposinf = 0;
2082  consdata->maxactivityneginf = 0;
2083  consdata->maxactivityposinf = 0;
2084  consdata->minactivityneghuge = 0;
2085  consdata->minactivityposhuge = 0;
2086  consdata->maxactivityneghuge = 0;
2087  consdata->maxactivityposhuge = 0;
2088  consdata->glbminactivity = 0.0;
2089  consdata->glbmaxactivity = 0.0;
2090  consdata->lastglbminactivity = 0.0;
2091  consdata->lastglbmaxactivity = 0.0;
2092  consdata->glbminactivityneginf = 0;
2093  consdata->glbminactivityposinf = 0;
2094  consdata->glbmaxactivityneginf = 0;
2095  consdata->glbmaxactivityposinf = 0;
2096  consdata->glbminactivityneghuge = 0;
2097  consdata->glbminactivityposhuge = 0;
2098  consdata->glbmaxactivityneghuge = 0;
2099  consdata->glbmaxactivityposhuge = 0;
2100 
2101  for( i = 0; i < consdata->nvars; ++i )
2102  consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], FALSE);
2103 
2104  consdata->lastminactivity = consdata->minactivity;
2105  consdata->lastmaxactivity = consdata->maxactivity;
2106  consdata->lastglbminactivity = consdata->glbminactivity;
2107  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
2108 }
2109 
2110 /** gets minimal activity for constraint and given values of counters for infinite and huge contributions
2111  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2112  */
2113 static
2114 void getMinActivity(
2115  SCIP* scip, /**< SCIP data structure */
2116  SCIP_CONSDATA* consdata, /**< linear constraint */
2117  int posinf, /**< number of coefficients contributing pos. infinite value */
2118  int neginf, /**< number of coefficients contributing neg. infinite value */
2119  int poshuge, /**< number of coefficients contributing huge pos. value */
2120  int neghuge, /**< number of coefficients contributing huge neg. value */
2121  SCIP_Real delta, /**< value to subtract from stored minactivity
2122  * (contribution of the variable set to zero when getting residual activity) */
2123  SCIP_Bool global, /**< should the global or local minimal activity be returned? */
2124  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2125  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2126  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2127  * i.e. is <= the exact minactivity (in case of huge contributing values) */
2128  SCIP_Bool* issettoinfinity /**< pointer to store whether minactivity was set to infinity or calculated */
2129  )
2131  assert(scip != NULL);
2132  assert(consdata != NULL);
2133  assert(posinf >= 0);
2134  assert(neginf >= 0);
2135  assert(poshuge >= 0);
2136  assert(neghuge >= 0);
2137  assert(minactivity != NULL);
2138  assert(isrelax != NULL);
2139  assert(issettoinfinity != NULL);
2140 
2141  /* if we have pos. infinite contributions, the minactivity is +infty */
2142  if( posinf > 0 )
2143  {
2144  *minactivity = SCIPinfinity(scip);
2145  *issettoinfinity = TRUE;
2146  *isrelax = FALSE;
2147  }
2148  /* if we have neg. (and no pos.) infinite contributions, the minactivity is -infty */
2149  else if( neginf > 0 )
2150  {
2151  *minactivity = -SCIPinfinity(scip);
2152  *issettoinfinity = TRUE;
2153  *isrelax = FALSE;
2154  }
2155  /* if we have neg. huge contributions, we only know that -infty is a relaxation of the minactivity */
2156  else if( neghuge > 0 )
2157  {
2158  *minactivity = -SCIPinfinity(scip);
2159  *issettoinfinity = TRUE;
2160  *isrelax = TRUE;
2161  }
2162  /* we do not need a good relaxation and we have positve huge contributions, so we just return -infty as activity */
2163  else if( !goodrelax && poshuge > 0 )
2164  {
2165  *minactivity = -SCIPinfinity(scip);
2166  *issettoinfinity = TRUE;
2167  *isrelax = TRUE;
2168  }
2169  else
2170  {
2171  SCIP_Real tmpactivity;
2172 
2173  /* recompute minactivity if it is not valid */
2174  if( global )
2175  {
2176  if( !consdata->validglbminact )
2177  consdataRecomputeGlbMinactivity(scip, consdata);
2178  assert(consdata->validglbminact);
2179 
2180  tmpactivity = consdata->glbminactivity;
2181  }
2182  else
2183  {
2184  if( !consdata->validminact )
2185  consdataRecomputeMinactivity(scip, consdata);
2186  assert(consdata->validminact);
2187 
2188  tmpactivity = consdata->minactivity;
2189  }
2190 
2191  /* we have no infinite and no neg. huge contributions, but pos. huge contributions;
2192  * a feasible relaxation of the minactivity is the number of positive huge contributions
2193  * times the minimum value counting as "huge" plus finite (and non-huge) part of minactivity - delta
2194  */
2195  if( poshuge > 0 )
2196  {
2197  *minactivity = 1.0 * poshuge * SCIPgetHugeValue(scip) + (tmpactivity - delta);
2198  *issettoinfinity = FALSE;
2199  *isrelax = TRUE;
2200  }
2201  /* all counters are zero, so the minactivity is just stored and we subtract the delta */
2202  else
2203  {
2204  *minactivity = tmpactivity - delta;
2205  *issettoinfinity = FALSE;
2206  *isrelax = FALSE;
2207  }
2208  }
2209 }
2210 
2211 /** gets maximal activity for constraint and given values of counters for infinite and huge contributions
2212  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2213  */
2214 static
2215 void getMaxActivity(
2216  SCIP* scip, /**< SCIP data structure */
2217  SCIP_CONSDATA* consdata, /**< linear constraint */
2218  int posinf, /**< number of coefficients contributing pos. infinite value */
2219  int neginf, /**< number of coefficients contributing neg. infinite value */
2220  int poshuge, /**< number of coefficients contributing huge pos. value */
2221  int neghuge, /**< number of coefficients contributing huge neg. value */
2222  SCIP_Real delta, /**< value to subtract from stored maxactivity
2223  * (contribution of the variable set to zero when getting residual activity) */
2224  SCIP_Bool global, /**< should the global or local maximal activity be returned? */
2225  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2226  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2227  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2228  * i.e. is >= the exact maxactivity (in case of huge contributing values) */
2229  SCIP_Bool* issettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2230  )
2232  assert(scip != NULL);
2233  assert(consdata != NULL);
2234  assert(posinf >= 0);
2235  assert(neginf >= 0);
2236  assert(poshuge >= 0);
2237  assert(neghuge >= 0);
2238  assert(maxactivity != NULL);
2239  assert(isrelax != NULL);
2240  assert(issettoinfinity != NULL);
2241 
2242  /* if we have neg. infinite contributions, the maxactivity is -infty */
2243  if( neginf > 0 )
2244  {
2245  *maxactivity = -SCIPinfinity(scip);
2246  *issettoinfinity = TRUE;
2247  *isrelax = FALSE;
2248  }
2249  /* if we have pos. (and no neg.) infinite contributions, the maxactivity is +infty */
2250  else if( posinf > 0 )
2251  {
2252  *maxactivity = SCIPinfinity(scip);
2253  *issettoinfinity = TRUE;
2254  *isrelax = FALSE;
2255  }
2256  /* if we have pos. huge contributions, we only know that +infty is a relaxation of the maxactivity */
2257  else if( poshuge > 0 )
2258  {
2259  *maxactivity = SCIPinfinity(scip);
2260  *issettoinfinity = TRUE;
2261  *isrelax = TRUE;
2262  }
2263  /* we do not need a good relaxation and we have positve huge contributions, so we just return +infty as activity */
2264  else if( !goodrelax && neghuge > 0 )
2265  {
2266  *maxactivity = SCIPinfinity(scip);
2267  *issettoinfinity = TRUE;
2268  *isrelax = TRUE;
2269  }
2270  else
2271  {
2272  SCIP_Real tmpactivity;
2273 
2274  /* recompute maxactivity if it is not valid */
2275  if( global )
2276  {
2277  if( !consdata->validglbmaxact )
2278  consdataRecomputeGlbMaxactivity(scip, consdata);
2279  assert(consdata->validglbmaxact);
2280 
2281  tmpactivity = consdata->glbmaxactivity;
2282  }
2283  else
2284  {
2285  if( !consdata->validmaxact )
2286  consdataRecomputeMaxactivity(scip, consdata);
2287  assert(consdata->validmaxact);
2288 
2289  tmpactivity = consdata->maxactivity;
2290  }
2291 
2292  /* we have no infinite, and no pos. huge contributions, but neg. huge contributions;
2293  * a feasible relaxation of the maxactivity is minus the number of negative huge contributions
2294  * times the minimum value counting as "huge" plus the finite (and non-huge) part of maxactivity minus delta
2295  */
2296  if( neghuge > 0 )
2297  {
2298  *maxactivity = -1.0 * neghuge * SCIPgetHugeValue(scip) + tmpactivity - delta;
2299  *issettoinfinity = FALSE;
2300  *isrelax = TRUE;
2301  }
2302  /* all counters are zero, so the maxactivity is just stored and we subtract the delta */
2303  else
2304  {
2305  *maxactivity = tmpactivity - delta;
2306  *issettoinfinity = FALSE;
2307  *isrelax = FALSE;
2308  }
2309  }
2310 }
2311 
2312 /** gets activity bounds for constraint */
2313 static
2315  SCIP* scip, /**< SCIP data structure */
2316  SCIP_CONSDATA* consdata, /**< linear constraint */
2317  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2318  * relaxed acticities ignored, anyway? */
2319  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2320  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2321  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2322  * i.e. <= the exact minactivity (in case of huge contributions),
2323  * or equal to the exact minimal activity */
2324  SCIP_Bool* maxisrelax /**< pointer to store whether the returned maxactivity is just a relaxation,
2325  * i.e. >= the exact maxactivity (in case of huge contributions),
2326  * or equal to the exact maximal activity */
2327  )
2328 {
2329  SCIP_Bool issettoinfinity;
2331  assert(scip != NULL);
2332  assert(consdata != NULL);
2333  assert(minactivity != NULL);
2334  assert(maxactivity != NULL);
2335 
2336  if( !consdata->validactivities )
2337  {
2338  consdataCalcActivities(scip, consdata);
2339  assert(consdata->validminact);
2340  assert(consdata->validmaxact);
2341  }
2342  assert(consdata->minactivity < SCIP_INVALID);
2343  assert(consdata->maxactivity < SCIP_INVALID);
2344  assert(consdata->minactivityneginf >= 0);
2345  assert(consdata->minactivityposinf >= 0);
2346  assert(consdata->maxactivityneginf >= 0);
2347  assert(consdata->maxactivityposinf >= 0);
2348 
2349  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2350  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2351  minactivity, minisrelax, &issettoinfinity);
2352 
2353  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2354  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2355  maxactivity, maxisrelax, &issettoinfinity);
2356 }
2357 
2358 /** calculates activity bounds for constraint after setting variable to zero */
2359 static
2361  SCIP* scip, /**< SCIP data structure */
2362  SCIP_CONSDATA* consdata, /**< linear constraint */
2363  SCIP_VAR* cancelvar, /**< variable to calculate activity residual for */
2364  SCIP_Real* resactivity, /**< pointer to store the residual activity */
2365  SCIP_Bool isminresact, /**< should minimal or maximal residual activity be calculated? */
2366  SCIP_Bool useglobalbounds /**< should global or local bounds be used? */
2367  )
2368 {
2369  SCIP_VAR* var;
2370  SCIP_Real val;
2371  SCIP_Real lb;
2372  SCIP_Real ub;
2373  int v;
2374 
2375  assert(scip != NULL);
2376  assert(consdata != NULL);
2377  assert(cancelvar != NULL);
2378  assert(resactivity != NULL);
2379 
2380  *resactivity = 0.0;
2381 
2382  for( v = 0; v < consdata->nvars; ++v )
2383  {
2384  var = consdata->vars[v];
2385  assert(var != NULL);
2386  if( var == cancelvar )
2387  continue;
2388 
2389  val = consdata->vals[v];
2390 
2391  if( useglobalbounds )
2392  {
2393  lb = SCIPvarGetLbGlobal(var);
2394  ub = SCIPvarGetUbGlobal(var);
2395  }
2396  else
2397  {
2398  lb = SCIPvarGetLbLocal(var);
2399  ub = SCIPvarGetUbLocal(var);
2400  }
2401 
2402  assert(!SCIPisZero(scip, val));
2403  assert(SCIPisLE(scip, lb, ub));
2404 
2405  if( val > 0.0 )
2406  {
2407  if( isminresact )
2408  {
2409  assert(!SCIPisInfinity(scip, -lb));
2410  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2411  *resactivity += val*lb;
2412  }
2413  else
2414  {
2415  assert(!SCIPisInfinity(scip, ub));
2416  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2417  *resactivity += val*ub;
2418  }
2419  }
2420  else
2421  {
2422  if( isminresact)
2423  {
2424  assert(!SCIPisInfinity(scip, ub));
2425  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2426  *resactivity += val*ub;
2427  }
2428  else
2429  {
2430  assert(!SCIPisInfinity(scip, -lb));
2431  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2432  *resactivity += val*lb;
2433  }
2434  }
2435  }
2436  assert(!SCIPisInfinity(scip, *resactivity) && !SCIPisInfinity(scip, -(*resactivity)));
2437 }
2438 
2439 /** gets activity bounds for constraint after setting variable to zero */
2440 static
2442  SCIP* scip, /**< SCIP data structure */
2443  SCIP_CONSDATA* consdata, /**< linear constraint */
2444  SCIP_VAR* var, /**< variable to calculate activity residual for */
2445  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2446  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2447  * relaxed acticities ignored, anyway? */
2448  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity */
2449  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity */
2450  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2451  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2452  * contributions), or equal to the exact residual minactivity */
2453  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2454  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2455  * contributions), or equal to the exact residual minactivity */
2456  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2457  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2458  )
2459 {
2460  SCIP_Real minactbound;
2461  SCIP_Real maxactbound;
2462  SCIP_Real absval;
2463 
2464  assert(scip != NULL);
2465  assert(consdata != NULL);
2466  assert(var != NULL);
2467  assert(minresactivity != NULL);
2468  assert(maxresactivity != NULL);
2469  assert(minisrelax != NULL);
2470  assert(maxisrelax != NULL);
2471  assert(isminsettoinfinity != NULL);
2472  assert(ismaxsettoinfinity != NULL);
2473 
2474  /* get activity bounds of linear constraint */
2475  if( !consdata->validactivities )
2476  {
2477  consdataCalcActivities(scip, consdata);
2478  assert(consdata->validminact);
2479  assert(consdata->validmaxact);
2480  }
2481  assert(consdata->minactivity < SCIP_INVALID);
2482  assert(consdata->maxactivity < SCIP_INVALID);
2483  assert(consdata->minactivityneginf >= 0);
2484  assert(consdata->minactivityposinf >= 0);
2485  assert(consdata->maxactivityneginf >= 0);
2486  assert(consdata->maxactivityposinf >= 0);
2487  assert(consdata->minactivityneghuge >= 0);
2488  assert(consdata->minactivityposhuge >= 0);
2489  assert(consdata->maxactivityneghuge >= 0);
2490  assert(consdata->maxactivityposhuge >= 0);
2491 
2492  if( val > 0.0 )
2493  {
2494  minactbound = SCIPvarGetLbLocal(var);
2495  maxactbound = SCIPvarGetUbLocal(var);
2496  absval = val;
2497  }
2498  else
2499  {
2500  minactbound = -SCIPvarGetUbLocal(var);
2501  maxactbound = -SCIPvarGetLbLocal(var);
2502  absval = -val;
2503  }
2504 
2505  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2506  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2507  */
2508  if( SCIPisInfinity(scip, minactbound) )
2509  {
2510  assert(consdata->minactivityposinf >= 1);
2511 
2512  getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
2513  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2514  minresactivity, minisrelax, isminsettoinfinity);
2515  }
2516  else if( SCIPisInfinity(scip, -minactbound) )
2517  {
2518  assert(consdata->minactivityneginf >= 1);
2519 
2520  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
2521  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2522  minresactivity, minisrelax, isminsettoinfinity);
2523  }
2524  else if( SCIPisHugeValue(scip, minactbound * absval) )
2525  {
2526  assert(consdata->minactivityposhuge >= 1);
2527 
2528  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2529  consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2530  minresactivity, minisrelax, isminsettoinfinity);
2531  }
2532  else if( SCIPisHugeValue(scip, -minactbound * absval) )
2533  {
2534  assert(consdata->minactivityneghuge >= 1);
2535 
2536  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2537  consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
2538  minresactivity, minisrelax, isminsettoinfinity);
2539  }
2540  else
2541  {
2542  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2543  consdata->minactivityposhuge, consdata->minactivityneghuge, absval * minactbound, FALSE, goodrelax,
2544  minresactivity, minisrelax, isminsettoinfinity);
2545  }
2546 
2547  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
2548  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2549  */
2550  if( SCIPisInfinity(scip, -maxactbound) )
2551  {
2552  assert(consdata->maxactivityneginf >= 1);
2553 
2554  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
2555  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2556  maxresactivity, maxisrelax, ismaxsettoinfinity);
2557  }
2558  else if( SCIPisInfinity(scip, maxactbound) )
2559  {
2560  assert(consdata->maxactivityposinf >= 1);
2561 
2562  getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
2563  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2564  maxresactivity, maxisrelax, ismaxsettoinfinity);
2565  }
2566  else if( SCIPisHugeValue(scip, absval * maxactbound) )
2567  {
2568  assert(consdata->maxactivityposhuge >= 1);
2569 
2570  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2571  consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2572  maxresactivity, maxisrelax, ismaxsettoinfinity);
2573  }
2574  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
2575  {
2576  assert(consdata->maxactivityneghuge >= 1);
2577 
2578  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2579  consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
2580  maxresactivity, maxisrelax, ismaxsettoinfinity);
2581  }
2582  else
2583  {
2584  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2585  consdata->maxactivityposhuge, consdata->maxactivityneghuge, absval * maxactbound, FALSE, goodrelax,
2586  maxresactivity, maxisrelax, ismaxsettoinfinity);
2587  }
2588 }
2589 
2590 /** gets global activity bounds for constraint */
2591 static
2593  SCIP* scip, /**< SCIP data structure */
2594  SCIP_CONSDATA* consdata, /**< linear constraint */
2595  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2596  * relaxed acticities ignored, anyway? */
2597  SCIP_Real* glbminactivity, /**< pointer to store the minimal activity, or NULL, if not needed */
2598  SCIP_Real* glbmaxactivity, /**< pointer to store the maximal activity, or NULL, if not needed */
2599  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2600  * i.e. <= the exact minactivity (in case of huge contributions),
2601  * or equal to the exact minimal activity */
2602  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2603  * i.e. >= the exact maxactivity (in case of huge contributions),
2604  * or equal to the exact maximal activity */
2605  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2606  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2607  )
2609  assert(scip != NULL);
2610  assert(consdata != NULL);
2611  assert((glbminactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL)
2612  || (glbmaxactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2613 
2614  if( !consdata->validactivities )
2615  {
2616  consdataCalcActivities(scip, consdata);
2617  assert(consdata->validglbminact);
2618  assert(consdata->validglbmaxact);
2619  }
2620  assert(consdata->glbminactivity < SCIP_INVALID);
2621  assert(consdata->glbmaxactivity < SCIP_INVALID);
2622  assert(consdata->glbminactivityneginf >= 0);
2623  assert(consdata->glbminactivityposinf >= 0);
2624  assert(consdata->glbmaxactivityneginf >= 0);
2625  assert(consdata->glbmaxactivityposinf >= 0);
2626  assert(consdata->glbminactivityneghuge >= 0);
2627  assert(consdata->glbminactivityposhuge >= 0);
2628  assert(consdata->glbmaxactivityneghuge >= 0);
2629  assert(consdata->glbmaxactivityposhuge >= 0);
2630 
2631  if( glbminactivity != NULL )
2632  {
2633  assert(isminsettoinfinity != NULL);
2634  assert(minisrelax != NULL);
2635 
2636  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2637  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2638  glbminactivity, minisrelax, isminsettoinfinity);
2639  }
2640 
2641  if( glbmaxactivity != NULL )
2642  {
2643  assert(ismaxsettoinfinity != NULL);
2644  assert(maxisrelax != NULL);
2645 
2646  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2647  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2648  glbmaxactivity, maxisrelax, ismaxsettoinfinity);
2649  }
2650 }
2651 
2652 /** gets global activity bounds for constraint after setting variable to zero */
2653 static
2655  SCIP* scip, /**< SCIP data structure */
2656  SCIP_CONSDATA* consdata, /**< linear constraint */
2657  SCIP_VAR* var, /**< variable to calculate activity residual for */
2658  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2659  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2660  * relaxed acticities ignored, anyway? */
2661  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity, or NULL, if not needed */
2662  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity, or NULL, if not needed */
2663  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2664  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2665  * contributions), or equal to the exact residual minactivity */
2666  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2667  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2668  * contributions), or equal to the exact residual minactivity */
2669  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2670  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2671  )
2672 {
2673  SCIP_Real minactbound;
2674  SCIP_Real maxactbound;
2675  SCIP_Real absval;
2676 
2677  assert(scip != NULL);
2678  assert(consdata != NULL);
2679  assert(var != NULL);
2680  assert((minresactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL )
2681  || (maxresactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2682 
2683  /* get activity bounds of linear constraint */
2684  if( !consdata->validactivities )
2685  consdataCalcActivities(scip, consdata);
2686 
2687  assert(consdata->glbminactivity < SCIP_INVALID);
2688  assert(consdata->glbmaxactivity < SCIP_INVALID);
2689  assert(consdata->glbminactivityneginf >= 0);
2690  assert(consdata->glbminactivityposinf >= 0);
2691  assert(consdata->glbmaxactivityneginf >= 0);
2692  assert(consdata->glbmaxactivityposinf >= 0);
2693 
2694  if( val > 0.0 )
2695  {
2696  minactbound = SCIPvarGetLbGlobal(var);
2697  maxactbound = SCIPvarGetUbGlobal(var);
2698  absval = val;
2699  }
2700  else
2701  {
2702  minactbound = -SCIPvarGetUbGlobal(var);
2703  maxactbound = -SCIPvarGetLbGlobal(var);
2704  absval = -val;
2705  }
2706 
2707  if( minresactivity != NULL )
2708  {
2709  assert(isminsettoinfinity != NULL);
2710  assert(minisrelax != NULL);
2711 
2712  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2713  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2714  */
2715  if( SCIPisInfinity(scip, minactbound) )
2716  {
2717  assert(consdata->glbminactivityposinf >= 1);
2718 
2719  getMinActivity(scip, consdata, consdata->glbminactivityposinf - 1, consdata->glbminactivityneginf,
2720  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2721  minresactivity, minisrelax, isminsettoinfinity);
2722  }
2723  else if( SCIPisInfinity(scip, -minactbound) )
2724  {
2725  assert(consdata->glbminactivityneginf >= 1);
2726 
2727  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf - 1,
2728  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2729  minresactivity, minisrelax, isminsettoinfinity);
2730  }
2731  else if( SCIPisHugeValue(scip, minactbound * absval) )
2732  {
2733  assert(consdata->glbminactivityposhuge >= 1);
2734 
2735  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2736  consdata->glbminactivityposhuge - 1, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2737  minresactivity, minisrelax, isminsettoinfinity);
2738  }
2739  else if( SCIPisHugeValue(scip, -minactbound * absval) )
2740  {
2741  assert(consdata->glbminactivityneghuge >= 1);
2742 
2743  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2744  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge - 1, 0.0, TRUE, goodrelax,
2745  minresactivity, minisrelax, isminsettoinfinity);
2746  }
2747  else
2748  {
2749  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2750  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, absval * minactbound, TRUE,
2751  goodrelax, minresactivity, minisrelax, isminsettoinfinity);
2752  }
2753  }
2754 
2755  if( maxresactivity != NULL )
2756  {
2757  assert(ismaxsettoinfinity != NULL);
2758  assert(maxisrelax != NULL);
2759 
2760  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
2761  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2762  */
2763  if( SCIPisInfinity(scip, -maxactbound) )
2764  {
2765  assert(consdata->glbmaxactivityneginf >= 1);
2766 
2767  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf - 1,
2768  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2769  maxresactivity, maxisrelax, ismaxsettoinfinity);
2770  }
2771  else if( SCIPisInfinity(scip, maxactbound) )
2772  {
2773  assert(consdata->glbmaxactivityposinf >= 1);
2774 
2775  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf - 1, consdata->glbmaxactivityneginf,
2776  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2777  maxresactivity, maxisrelax, ismaxsettoinfinity);
2778  }
2779  else if( SCIPisHugeValue(scip, absval * maxactbound) )
2780  {
2781  assert(consdata->glbmaxactivityposhuge >= 1);
2782 
2783  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2784  consdata->glbmaxactivityposhuge - 1, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2785  maxresactivity, maxisrelax, ismaxsettoinfinity);
2786  }
2787  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
2788  {
2789  assert(consdata->glbmaxactivityneghuge >= 1);
2790 
2791  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2792  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge - 1, 0.0, TRUE, goodrelax,
2793  maxresactivity, maxisrelax, ismaxsettoinfinity);
2794  }
2795  else
2796  {
2797  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2798  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, absval * maxactbound, TRUE,
2799  goodrelax, maxresactivity, maxisrelax, ismaxsettoinfinity);
2800  }
2801  }
2802 }
2803 
2804 /** calculates the activity of the linear constraint for given solution */
2805 static
2807  SCIP* scip, /**< SCIP data structure */
2808  SCIP_CONSDATA* consdata, /**< linear constraint data */
2809  SCIP_SOL* sol /**< solution to get activity for, NULL to current solution */
2810  )
2811 {
2812  SCIP_Real activity;
2813 
2814  assert(scip != NULL);
2815  assert(consdata != NULL);
2816 
2817  if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
2818  activity = consdataComputePseudoActivity(scip, consdata);
2819  else
2820  {
2821  SCIP_Real solval;
2822  int nposinf;
2823  int nneginf;
2824  SCIP_Bool negsign;
2825  int v;
2826 
2827  activity = 0.0;
2828  nposinf = 0;
2829  nneginf = 0;
2830  negsign = 0;
2831 
2832  for( v = 0; v < consdata->nvars; ++v )
2833  {
2834  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
2835 
2836  if( consdata->vals[v] < 0 )
2837  negsign = TRUE;
2838  else
2839  negsign = FALSE;
2840 
2841  if( (SCIPisInfinity(scip, solval) && !negsign) || (SCIPisInfinity(scip, -solval) && negsign) )
2842  ++nposinf;
2843  else if( (SCIPisInfinity(scip, solval) && negsign) || (SCIPisInfinity(scip, -solval) && !negsign) )
2844  ++nneginf;
2845  else
2846  activity += consdata->vals[v] * solval;
2847  }
2848  assert(nneginf >= 0 && nposinf >= 0);
2849 
2850  SCIPdebugMessage("activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", activity, nposinf, nneginf);
2851 
2852  /* check for amount of infinity values and correct the activity */
2853  if( nposinf > 0 && nneginf > 0 )
2854  activity = (consdata->rhs + consdata->lhs) / 2;
2855  else if( nposinf > 0 )
2856  activity = SCIPinfinity(scip);
2857  else if( nneginf > 0 )
2858  activity = -SCIPinfinity(scip);
2859 
2860  SCIPdebugMessage("corrected activity of linear constraint: %.15g\n", activity);
2861  }
2862 
2863  if( activity == SCIP_INVALID ) /*lint !e777*/
2864  return activity;
2865  else if( activity < 0 )
2866  activity = MAX(activity, -SCIPinfinity(scip)); /*lint !e666*/
2867  else
2868  activity = MIN(activity, SCIPinfinity(scip)); /*lint !e666*/
2869 
2870  return activity;
2871 }
2872 
2873 /** calculates the feasibility of the linear constraint for given solution */
2874 static
2876  SCIP* scip, /**< SCIP data structure */
2877  SCIP_CONSDATA* consdata, /**< linear constraint data */
2878  SCIP_SOL* sol /**< solution to get feasibility for, NULL to current solution */
2879  )
2880 {
2881  SCIP_Real activity;
2882 
2883  assert(scip != NULL);
2884  assert(consdata != NULL);
2885 
2886  activity = consdataGetActivity(scip, consdata, sol);
2887 
2888  if( activity == SCIP_INVALID ) /*lint !e777*/
2889  return -SCIPinfinity(scip);
2890 
2891  return MIN(consdata->rhs - activity, activity - consdata->lhs);
2892 }
2893 
2894 /** returns the signature bitmask for the given variable */
2895 static
2897  SCIP_VAR* var /**< variable */
2898  )
2899 {
2900  int sigidx;
2901 
2902  assert(var != NULL);
2903 
2904  sigidx = SCIPvarGetIndex(var) % (int)(8*sizeof(SCIP_Longint));
2905  return ((SCIP_Longint)1) << sigidx; /*lint !e703*/
2906 }
2907 
2908 /** updates bit signatures after adding a single coefficient */
2909 static
2911  SCIP_CONSDATA* consdata, /**< linear constraint data */
2912  int pos /**< position of coefficient to update signatures for */
2913  )
2914 {
2915  SCIP_Longint varsignature;
2916  SCIP_Real lb;
2917  SCIP_Real ub;
2918  SCIP_Real val;
2919 
2920  assert(consdata != NULL);
2921  assert(consdata->validsignature);
2922 
2923  varsignature = getVarSignature(consdata->vars[pos]);
2924  lb = SCIPvarGetLbGlobal(consdata->vars[pos]);
2925  ub = SCIPvarGetUbGlobal(consdata->vars[pos]);
2926  val = consdata->vals[pos];
2927  if( (val > 0.0 && ub > 0.0) || (val < 0.0 && lb < 0.0) )
2928  consdata->possignature |= varsignature;
2929  if( (val > 0.0 && lb < 0.0) || (val < 0.0 && ub > 0.0) )
2930  consdata->negsignature |= varsignature;
2931 }
2932 
2933 /** calculates the bit signatures of the given constraint data */
2934 static
2936  SCIP_CONSDATA* consdata /**< linear constraint data */
2937  )
2938 {
2939  assert(consdata != NULL);
2940 
2941  if( !consdata->validsignature )
2942  {
2943  int i;
2944 
2945  consdata->validsignature = TRUE;
2946  consdata->possignature = 0;
2947  consdata->negsignature = 0;
2948  for( i = 0; i < consdata->nvars; ++i )
2949  consdataUpdateSignatures(consdata, i);
2950  }
2952 
2953 /** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
2954 static
2955 SCIP_DECL_SORTINDCOMP(consdataCompVar)
2956 { /*lint --e{715}*/
2957  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
2958 
2959  assert(consdata != NULL);
2960  assert(0 <= ind1 && ind1 < consdata->nvars);
2961  assert(0 <= ind2 && ind2 < consdata->nvars);
2962 
2963  return SCIPvarCompare(consdata->vars[ind1], consdata->vars[ind2]);
2964 }
2965 
2966 /** permutes the constraint's variables according to a given permutation. */
2967 static
2968 void permSortConsdata(
2969  SCIP_CONSDATA* consdata, /**< the constraint data */
2970  int* perm, /**< the target permutation */
2971  int nvars /**< the number of variables */
2972  )
2973 { /*lint --e{715}*/
2974  SCIP_VAR* varv;
2975  SCIP_EVENTDATA* eventdatav;
2976  SCIP_Real valv;
2977  int v;
2978  int i;
2979  int nexti;
2980 
2981  assert(perm != NULL);
2982  assert(consdata != NULL);
2983 
2984  /* permute the variables in the linear constraint according to the target permutation */
2985  eventdatav = NULL;
2986  for( v = 0; v < nvars; ++v )
2987  {
2988  if( perm[v] != v )
2989  {
2990  varv = consdata->vars[v];
2991  valv = consdata->vals[v];
2992  if( consdata->eventdata != NULL )
2993  eventdatav = consdata->eventdata[v];
2994  i = v;
2995  do
2996  {
2997  assert(0 <= perm[i] && perm[i] < nvars);
2998  assert(perm[i] != i);
2999  consdata->vars[i] = consdata->vars[perm[i]];
3000  consdata->vals[i] = consdata->vals[perm[i]];
3001  if( consdata->eventdata != NULL )
3002  {
3003  consdata->eventdata[i] = consdata->eventdata[perm[i]];
3004  consdata->eventdata[i]->varpos = i;
3005  }
3006  nexti = perm[i];
3007  perm[i] = i;
3008  i = nexti;
3009  }
3010  while( perm[i] != v );
3011  consdata->vars[i] = varv;
3012  consdata->vals[i] = valv;
3013  if( consdata->eventdata != NULL )
3014  {
3015  consdata->eventdata[i] = eventdatav;
3016  consdata->eventdata[i]->varpos = i;
3017  }
3018  perm[i] = i;
3019  }
3020  }
3021 #ifdef SCIP_DEBUG
3022  /* check sorting */
3023  for( v = 0; v < nvars; ++v )
3024  {
3025  assert(perm[v] == v);
3026  assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
3027  }
3028 #endif
3029 }
3030 
3031 /** sorts linear constraint's variables depending on the stage of the solving process:
3032  * - during PRESOLVING
3033  * sorts variables by binaries, integers, implicit integers, and continuous variables,
3034  * and the variables of the same type by non-decreasing variable index
3035  *
3036  * - during SOLVING
3037  * sorts binary variables of the remaining problem w.r.t the absolute of their coefficient.
3038  * This fastens the propagation time of the constraint handler.
3039  */
3040 static
3042  SCIP* scip, /**< SCIP data structure */
3043  SCIP_CONSDATA* consdata /**< linear constraint data */
3044  )
3045 {
3046  assert(scip != NULL);
3047  assert(consdata != NULL);
3048 
3049  /* check if there are variables for sorting */
3050  if( consdata->nvars <= 1 )
3051  {
3052  consdata->sorted = TRUE;
3053  consdata->binvarssorted = TRUE;
3054  }
3055  else if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE && !consdata->sorted )
3056  {
3057  int* perm;
3058 
3059  /* get temporary memory to store the sorted permutation */
3060  SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
3061 
3062  /* call sorting method */
3063  SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
3064 
3065  permSortConsdata(consdata, perm, consdata->nvars);
3066 
3067  /* free temporary memory */
3068  SCIPfreeBufferArray(scip, &perm);
3069 
3070  consdata->sorted = TRUE;
3071  consdata->binvarssorted = FALSE;
3072  }
3073  else if( SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->binvarssorted )
3074  {
3075  SCIP_EVENTDATA** eventdata;
3076  SCIP_VAR** vars;
3077  SCIP_Real* vals;
3078  int nvars;
3079  int v;
3080  int lastbin;
3081 
3082  nvars = consdata->nvars;
3083  vars = consdata->vars;
3084  vals = consdata->vals;
3085  eventdata = consdata->eventdata;
3086  assert(vars != NULL || nvars == 0);
3087  assert(vals != NULL || nvars == 0);
3088 
3089  lastbin = 0;
3090  /* count binary variables and permute variables such that binaries appear first in the sorted vars array */
3091  for( v = 0; v < nvars; ++v )
3092  {
3093  assert( vars != NULL); /* for flexelint */
3094  assert( vals != NULL); /* for flexelint */
3095  if( SCIPvarIsBinary(vars[v]) )
3096  {
3097  /* swap variable at the end of the binary variables, if necessary */
3098  if( lastbin < v )
3099  {
3100  SCIP_VAR* tmpvar;
3101  SCIP_Real tmpval;
3102 
3103  tmpvar = vars[lastbin];
3104  tmpval = vals[lastbin];
3105 
3106  vars[lastbin] = vars[v];
3107  vals[lastbin] = vals[v];
3108 
3109  vars[v] = tmpvar;
3110  vals[v] = tmpval;
3111 
3112  if( eventdata != NULL )
3113  {
3114  SCIP_EVENTDATA* tmpeventdata;
3115 
3116  tmpeventdata = eventdata[lastbin];
3117  eventdata[lastbin] = eventdata[v];
3118  eventdata[lastbin]->varpos = lastbin;
3119  eventdata[v] = tmpeventdata;
3120  eventdata[v]->varpos = v;
3121  }
3122  assert(SCIPvarIsBinary(vars[lastbin]));
3123  }
3124 #ifndef NDEBUG
3125  else
3126  assert(lastbin == v);
3127 #endif
3128  ++lastbin;
3129  }
3130  }
3131  consdata->nbinvars = lastbin;
3132 
3133 #ifndef NDEBUG
3134  /* check sorting */
3135  for( v = 0; v < nvars; ++v )
3136  {
3137  assert(vars != NULL); /* for flexelint */
3138  assert(eventdata == NULL || eventdata[v]->varpos == v);
3139  assert((v >= consdata->nbinvars && !SCIPvarIsBinary(vars[v])) || (v < consdata->nbinvars && SCIPvarIsBinary(vars[v])));
3140  }
3141 #endif
3142 
3143  if( consdata->nbinvars > 1 )
3144  {
3145  SCIP_Real* absvals;
3146  int* perm;
3147 
3148  assert(lastbin == consdata->nbinvars);
3149  assert(lastbin <= nvars);
3150  assert(vals != NULL);
3151 
3152  /* initialize absolute coefficients and the target permutation for binary variables */
3153  SCIP_CALL( SCIPallocBufferArray(scip, &absvals, lastbin) );
3154  SCIP_CALL( SCIPallocBufferArray(scip, &perm, lastbin) );
3155 
3156  for( v = 0; v < lastbin; ++v )
3157  {
3158  absvals[v] = ABS(vals[v]);
3159  perm[v] = v;
3160  }
3161 
3162  /* execute the sorting */
3163  SCIPsortDownRealInt(absvals, perm, lastbin);
3164 
3165  permSortConsdata(consdata, perm, lastbin);
3166 
3167  /* free temporary arrays */
3168  SCIPfreeBufferArray(scip, &perm);
3169  SCIPfreeBufferArray(scip, &absvals);
3170  }
3171  consdata->binvarssorted = TRUE;
3172 
3173  /* presolve sorting cannot be guaranteed after binary sorting */
3174  consdata->sorted = (consdata->sorted && consdata->nbinvars == 0);
3175  }
3176  assert(SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE || consdata->binvarssorted);
3177  assert(SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE || consdata->sorted);
3178 
3179  return SCIP_OKAY;
3180 }
3181 
3182 
3183 /*
3184  * local linear constraint handler methods
3185  */
3186 
3187 /** sets left hand side of linear constraint */
3188 static
3190  SCIP* scip, /**< SCIP data structure */
3191  SCIP_CONS* cons, /**< linear constraint */
3192  SCIP_Real lhs /**< new left hand side */
3193  )
3194 {
3195  SCIP_CONSDATA* consdata;
3196 
3197  assert(scip != NULL);
3198  assert(cons != NULL);
3199  assert(!SCIPisInfinity(scip, lhs));
3200 
3201  /* adjust value to not be smaller than -inf */
3202  if ( SCIPisInfinity(scip, -lhs) )
3203  lhs = -SCIPinfinity(scip);
3204 
3205  consdata = SCIPconsGetData(cons);
3206  assert(consdata != NULL);
3207  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3208  assert(!SCIPisInfinity(scip, consdata->lhs));
3209 
3210  /* check whether the side is not changed */
3211  if( SCIPisEQ(scip, consdata->lhs, lhs) )
3212  return SCIP_OKAY;
3213 
3214  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3215  if( SCIPisEQ(scip, lhs, consdata->rhs) )
3216  {
3217  consdata->rhs = lhs;
3218  assert(consdata->row == NULL);
3219  }
3220 
3221  /* if necessary, update the rounding locks of variables */
3222  if( SCIPconsIsLocked(cons) )
3223  {
3224  if( SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -lhs) )
3225  {
3226  SCIP_VAR** vars;
3227  SCIP_Real* vals;
3228  int v;
3229 
3230  /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
3231  vars = consdata->vars;
3232  vals = consdata->vals;
3233 
3234  for( v = 0; v < consdata->nvars; ++v )
3235  {
3236  assert(vars[v] != NULL);
3237  assert(!SCIPisZero(scip, vals[v]));
3238 
3239  if( SCIPisPositive(scip, vals[v]) )
3240  {
3241  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3242  }
3243  else
3244  {
3245  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3246  }
3247  }
3248  }
3249  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -lhs) )
3250  {
3251  SCIP_VAR** vars;
3252  SCIP_Real* vals;
3253  int v;
3254 
3255  /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
3256  vars = consdata->vars;
3257  vals = consdata->vals;
3258 
3259  for( v = 0; v < consdata->nvars; ++v )
3260  {
3261  assert(vars[v] != NULL);
3262  assert(!SCIPisZero(scip, vals[v]));
3263 
3264  if( SCIPisPositive(scip, vals[v]) )
3265  {
3266  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3267  }
3268  else
3269  {
3270  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3271  }
3272  }
3273  }
3274  }
3275 
3276  /* 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 */
3277  if( !SCIPisInfinity(scip, -lhs) && SCIPisGT(scip, lhs, consdata->lhs) )
3278  {
3279  consdata->propagated = FALSE;
3280  consdata->boundstightened = FALSE;
3281  consdata->presolved = FALSE;
3282  consdata->cliquesadded = FALSE;
3283  consdata->implsadded = FALSE;
3284  }
3285 
3286  /* set new left hand side and update constraint data */
3287  consdata->lhs = lhs;
3288  consdata->changed = TRUE;
3289  consdata->normalized = FALSE;
3290  consdata->upgradetried = FALSE;
3291  consdata->rangedrowpropagation = FALSE;
3292 
3293  /* update the lhs of the LP row */
3294  if( consdata->row != NULL )
3295  {
3296  SCIP_CALL( SCIPchgRowLhs(scip, consdata->row, lhs) );
3297  }
3298 
3299  return SCIP_OKAY;
3300 }
3301 
3302 /** sets right hand side of linear constraint */
3303 static
3305  SCIP* scip, /**< SCIP data structure */
3306  SCIP_CONS* cons, /**< linear constraint */
3307  SCIP_Real rhs /**< new right hand side */
3308  )
3309 {
3310  SCIP_CONSDATA* consdata;
3311 
3312  assert(scip != NULL);
3313  assert(cons != NULL);
3314  assert(!SCIPisInfinity(scip, -rhs));
3315 
3316  /* adjust value to not be larger than inf */
3317  if ( SCIPisInfinity(scip, rhs) )
3318  rhs = SCIPinfinity(scip);
3319 
3320  consdata = SCIPconsGetData(cons);
3321  assert(consdata != NULL);
3322  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3323  assert(!SCIPisInfinity(scip, -consdata->rhs));
3324 
3325  /* check whether the side is not changed */
3326  if( SCIPisEQ(scip, consdata->rhs, rhs) )
3327  return SCIP_OKAY;
3328 
3329  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3330  if( SCIPisEQ(scip, rhs, consdata->lhs) )
3331  {
3332  consdata->lhs = rhs;
3333  assert(consdata->row == NULL);
3334  }
3335 
3336  /* if necessary, update the rounding locks of variables */
3337  if( SCIPconsIsLocked(cons) )
3338  {
3339  assert(SCIPconsIsTransformed(cons));
3340 
3341  if( SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, rhs) )
3342  {
3343  SCIP_VAR** vars;
3344  SCIP_Real* vals;
3345  int v;
3346 
3347  /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
3348  vars = consdata->vars;
3349  vals = consdata->vals;
3350 
3351  for( v = 0; v < consdata->nvars; ++v )
3352  {
3353  assert(vars[v] != NULL);
3354  assert(!SCIPisZero(scip, vals[v]));
3355 
3356  if( SCIPisPositive(scip, vals[v]) )
3357  {
3358  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3359  }
3360  else
3361  {
3362  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3363  }
3364  }
3365  }
3366  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, rhs) )
3367  {
3368  SCIP_VAR** vars;
3369  SCIP_Real* vals;
3370  int v;
3371 
3372  /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
3373  vars = consdata->vars;
3374  vals = consdata->vals;
3375 
3376  for( v = 0; v < consdata->nvars; ++v )
3377  {
3378  assert(vars[v] != NULL);
3379  assert(!SCIPisZero(scip, vals[v]));
3380 
3381  if( SCIPisPositive(scip, vals[v]) )
3382  {
3383  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3384  }
3385  else
3386  {
3387  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3388  }
3389  }
3390  }
3391  }
3392 
3393  /* 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 */
3394  if( !SCIPisInfinity(scip, rhs) && SCIPisLT(scip, rhs, consdata->rhs) )
3395  {
3396  consdata->propagated = FALSE;
3397  consdata->boundstightened = FALSE;
3398  consdata->presolved = FALSE;
3399  consdata->cliquesadded = FALSE;
3400  consdata->implsadded = FALSE;
3401  }
3402 
3403  /* set new right hand side and update constraint data */
3404  consdata->rhs = rhs;
3405  consdata->changed = TRUE;
3406  consdata->normalized = FALSE;
3407  consdata->upgradetried = FALSE;
3408  consdata->rangedrowpropagation = FALSE;
3409 
3410  /* update the rhs of the LP row */
3411  if( consdata->row != NULL )
3412  {
3413  SCIP_CALL( SCIPchgRowRhs(scip, consdata->row, rhs) );
3414  }
3415 
3416  return SCIP_OKAY;
3417 }
3418 
3419 /** adds coefficient in linear constraint */
3420 static
3422  SCIP* scip, /**< SCIP data structure */
3423  SCIP_CONS* cons, /**< linear constraint */
3424  SCIP_VAR* var, /**< variable of constraint entry */
3425  SCIP_Real val /**< coefficient of constraint entry */
3426  )
3427 {
3428  SCIP_CONSDATA* consdata;
3429  SCIP_Bool transformed;
3430 
3431  assert(scip != NULL);
3432  assert(cons != NULL);
3433  assert(var != NULL);
3434 
3435  /* ignore coefficient if it is nearly zero */
3436  if( SCIPisZero(scip, val) )
3437  return SCIP_OKAY;
3438 
3439  consdata = SCIPconsGetData(cons);
3440  assert(consdata != NULL);
3441 
3442  /* are we in the transformed problem? */
3443  transformed = SCIPconsIsTransformed(cons);
3444 
3445  /* always use transformed variables in transformed constraints */
3446  if( transformed )
3447  {
3448  SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
3449  }
3450  assert(var != NULL);
3451  assert(transformed == SCIPvarIsTransformed(var));
3452 
3453  SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
3454  consdata->vars[consdata->nvars] = var;
3455  consdata->vals[consdata->nvars] = val;
3456  consdata->nvars++;
3457  /* capture variable */
3458  SCIP_CALL( SCIPcaptureVar(scip, var) );
3459 
3460  /* if we are in transformed problem, the variable needs an additional event data */
3461  if( transformed )
3462  {
3463  if( consdata->eventdata != NULL )
3464  {
3465  SCIP_CONSHDLR* conshdlr;
3466  SCIP_CONSHDLRDATA* conshdlrdata;
3467 
3468  /* check for event handler */
3469  conshdlr = SCIPconsGetHdlr(cons);
3470  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3471  assert(conshdlrdata != NULL);
3472  assert(conshdlrdata->eventhdlr != NULL);
3473 
3474  /* initialize eventdata array */
3475  consdata->eventdata[consdata->nvars-1] = NULL;
3476 
3477  /* catch bound change events of variable */
3478  SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
3479  }
3480 
3481  /* update minimum and maximum activities */
3482  consdataUpdateAddCoef(scip, consdata, var, val, FALSE);
3483 
3484  /* update maximum activity delta */
3485  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
3486  {
3487  SCIP_Real lb;
3488  SCIP_Real ub;
3489 
3490  lb = SCIPvarGetLbLocal(var);
3491  ub = SCIPvarGetUbLocal(var);
3492 
3493  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
3494  {
3495  consdata->maxactdelta = SCIPinfinity(scip);
3496  consdata->maxactdeltavar = var;
3497  }
3498  else
3499  {
3500  SCIP_Real domain = ub - lb;
3501  SCIP_Real delta = REALABS(val) * domain;
3502 
3503  if( delta > consdata->maxactdelta )
3504  {
3505  consdata->maxactdelta = delta;
3506  consdata->maxactdeltavar = var;
3507  }
3508  }
3509  }
3510  }
3511 
3512  /* install rounding locks for new variable */
3513  SCIP_CALL( lockRounding(scip, cons, var, val) );
3514 
3515  consdata->propagated = FALSE;
3516  consdata->boundstightened = FALSE;
3517  consdata->presolved = FALSE;
3518  consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
3519 
3520  if( consdata->validsignature )
3521  consdataUpdateSignatures(consdata, consdata->nvars-1);
3522 
3523  consdata->changed = TRUE;
3524  consdata->normalized = FALSE;
3525  consdata->upgradetried = FALSE;
3526  consdata->cliquesadded = FALSE;
3527  consdata->implsadded = FALSE;
3528  consdata->rangedrowpropagation = FALSE;
3529 
3530  if( consdata->nvars == 1 )
3531  {
3532  consdata->binvarssorted = TRUE;
3533  consdata->sorted = TRUE;
3534  consdata->merged = TRUE;
3535  }
3536  else
3537  {
3538  consdata->binvarssorted = consdata->binvarssorted && !SCIPvarIsBinary(var);
3539  consdata->sorted = consdata->sorted
3540  && (SCIPvarCompare(consdata->vars[consdata->nvars-2], consdata->vars[consdata->nvars-1]) <= 0);
3541  consdata->merged = FALSE;
3542  }
3543 
3544  /* update hascontvar and hasnonbinvar flags */
3545  if( consdata->hasnonbinvalid && !consdata->hascontvar )
3546  {
3547  SCIP_VARTYPE vartype = SCIPvarGetType(var);
3548 
3549  if( vartype != SCIP_VARTYPE_BINARY )
3550  {
3551  consdata->hasnonbinvar = TRUE;
3552 
3553  if( vartype == SCIP_VARTYPE_CONTINUOUS )
3554  consdata->hascontvar = TRUE;
3555  }
3556  }
3557 
3558  /* add the new coefficient to the LP row */
3559  if( consdata->row != NULL )
3560  {
3561  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, val) );
3562  }
3563 
3564  return SCIP_OKAY;
3565 }
3566 
3567 /** deletes coefficient at given position from linear constraint data */
3568 static
3570  SCIP* scip, /**< SCIP data structure */
3571  SCIP_CONS* cons, /**< linear constraint */
3572  int pos /**< position of coefficient to delete */
3573  )
3574 {
3575  SCIP_CONSDATA* consdata;
3576  SCIP_VAR* var;
3577  SCIP_Real val;
3578 
3579  assert(scip != NULL);
3580  assert(cons != NULL);
3581 
3582  consdata = SCIPconsGetData(cons);
3583  assert(consdata != NULL);
3584  assert(0 <= pos && pos < consdata->nvars);
3586  var = consdata->vars[pos];
3587  val = consdata->vals[pos];
3588  assert(var != NULL);
3589 
3590  /* remove rounding locks for deleted variable */
3591  SCIP_CALL( unlockRounding(scip, cons, var, val) );
3592 
3593  /* if we are in transformed problem, delete the event data of the variable */
3594  if( SCIPconsIsTransformed(cons) )
3595  {
3596  SCIP_CONSHDLR* conshdlr;
3597  SCIP_CONSHDLRDATA* conshdlrdata;
3598 
3599  /* check for event handler */
3600  conshdlr = SCIPconsGetHdlr(cons);
3601  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3602  assert(conshdlrdata != NULL);
3603  assert(conshdlrdata->eventhdlr != NULL);
3604 
3605  /* drop bound change events of variable */
3606  if( consdata->eventdata != NULL )
3607  {
3608  SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
3609  assert(consdata->eventdata[pos] == NULL);
3610  }
3611  }
3612 
3613  /* move the last variable to the free slot */
3614  if( pos != consdata->nvars-1 )
3615  {
3616  consdata->binvarssorted = consdata->binvarssorted && !SCIPvarIsBinary(consdata->vars[pos]);
3617 
3618  consdata->vars[pos] = consdata->vars[consdata->nvars-1];
3619  consdata->vals[pos] = consdata->vals[consdata->nvars-1];
3620 
3621  if( consdata->eventdata != NULL )
3622  {
3623  consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
3624  assert(consdata->eventdata[pos] != NULL);
3625  consdata->eventdata[pos]->varpos = pos;
3626  }
3627  consdata->sorted = consdata->sorted && (pos + 2 >= consdata->nvars || (SCIPvarCompare(consdata->vars[pos], consdata->vars[pos + 1]) <= 0));
3628  }
3629  consdata->nvars--;
3630 
3631  /* if at most one variable is left, the activities should be recalculated (to correspond exactly to the bounds
3632  * of the remaining variable, or give exactly 0.0)
3633  */
3634  if( consdata->nvars <= 1 )
3635  consdataInvalidateActivities(consdata);
3636  else
3637  {
3638  if( SCIPconsIsTransformed(cons) )
3639  {
3640  /* if we are in transformed problem, update minimum and maximum activities */
3641  consdataUpdateDelCoef(scip, consdata, var, val, TRUE);
3642 
3643  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
3644  * delta needs to be recalculated on the next real propagation
3645  */
3646  if( consdata->maxactdeltavar == var )
3647  {
3648  consdata->maxactdelta = SCIP_INVALID;
3649  consdata->maxactdeltavar = NULL;
3650  }
3651  }
3652  }
3653 
3654  consdata->propagated = FALSE;
3655  consdata->boundstightened = FALSE;
3656  consdata->presolved = FALSE;
3657  consdata->validsignature = FALSE;
3658  consdata->changed = TRUE;
3659  consdata->normalized = FALSE;
3660  consdata->upgradetried = FALSE;
3661  consdata->cliquesadded = FALSE;
3662  consdata->implsadded = FALSE;
3663  consdata->rangedrowpropagation = FALSE;
3664 
3665  /* check if hasnonbinvar flag might be incorrect now */
3666  if( consdata->hasnonbinvar && SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
3667  {
3668  consdata->hasnonbinvalid = FALSE;
3669  }
3670 
3671  /* delete coefficient from the LP row */
3672  if( consdata->row != NULL )
3673  {
3674  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, -val) );
3675  }
3676 
3677  /* release variable */
3678  SCIP_CALL( SCIPreleaseVar(scip, &var) );
3679 
3680  return SCIP_OKAY;
3681 }
3682 
3683 /** changes coefficient value at given position of linear constraint data */
3684 static
3686  SCIP* scip, /**< SCIP data structure */
3687  SCIP_CONS* cons, /**< linear constraint */
3688  int pos, /**< position of coefficient to delete */
3689  SCIP_Real newval /**< new value of coefficient */
3690  )
3691 {
3692  SCIP_CONSDATA* consdata;
3693  SCIP_VAR* var;
3694  SCIP_Real val;
3695 
3696  assert(scip != NULL);
3697  assert(cons != NULL);
3698  assert(!SCIPisZero(scip, newval));
3699 
3700  consdata = SCIPconsGetData(cons);
3701  assert(consdata != NULL);
3702  assert(0 <= pos && pos < consdata->nvars);
3703  assert(!SCIPisZero(scip, newval));
3704 
3705  var = consdata->vars[pos];
3706  val = consdata->vals[pos];
3707  assert(var != NULL);
3708  assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
3709 
3710  /* if necessary, update the rounding locks of the variable */
3711  if( SCIPconsIsLocked(cons) && newval * val < 0.0 )
3712  {
3713  assert(SCIPconsIsTransformed(cons));
3714 
3715  /* remove rounding locks for variable with old coefficient */
3716  SCIP_CALL( unlockRounding(scip, cons, var, val) );
3717 
3718  /* install rounding locks for variable with new coefficient */
3719  SCIP_CALL( lockRounding(scip, cons, var, newval) );
3720  }
3721 
3722  /* change the value */
3723  consdata->vals[pos] = newval;
3724 
3725  consdata->binvarssorted = consdata->binvarssorted && !SCIPvarIsBinary(var);
3726 
3727  /* update minimum and maximum activities */
3728  if( SCIPconsIsTransformed(cons) )
3729  consdataUpdateChgCoef(scip, consdata, var, val, newval, TRUE);
3730 
3731  consdata->propagated = FALSE;
3732  consdata->boundstightened = FALSE;
3733  consdata->presolved = FALSE;
3734  consdata->validsignature = consdata->validsignature && (newval * val > 0.0);
3735  consdata->changed = TRUE;
3736  consdata->normalized = FALSE;
3737  consdata->upgradetried = FALSE;
3738  consdata->cliquesadded = FALSE;
3739  consdata->implsadded = FALSE;
3740  consdata->rangedrowpropagation = FALSE;
3741 
3742  return SCIP_OKAY;
3743 }
3744 
3745 /** scales a linear constraint with a constant scalar */
3746 static
3748  SCIP* scip, /**< SCIP data structure */
3749  SCIP_CONS* cons, /**< linear constraint to scale */
3750  SCIP_Real scalar /**< value to scale constraint with */
3751  )
3752 {
3753  SCIP_CONSDATA* consdata;
3754  SCIP_Real newval;
3755  SCIP_Real absscalar;
3756  int i;
3757 
3758  assert(scip != NULL);
3759  assert(cons != NULL);
3760 
3761  consdata = SCIPconsGetData(cons);
3762  assert(consdata != NULL);
3763  assert(consdata->row == NULL);
3764  assert(!SCIPisEQ(scip, scalar, 1.0));
3765 
3766  /* scale the coefficients */
3767  for( i = consdata->nvars - 1; i >= 0; --i )
3768  {
3769  newval = scalar * consdata->vals[i];
3770 
3771  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
3772  * flooring down our new value
3773  */
3774  if( SCIPisScalingIntegral(scip, consdata->vals[i], scalar) )
3775  newval = SCIPfeasFloor(scip, newval + 0.5);
3776 
3777  if( SCIPisZero(scip, newval) )
3778  {
3779  SCIPwarningMessage(scip, "coefficient %.15g of variable <%s> in linear constraint <%s> scaled to zero (scalar: %.15g)\n",
3780  consdata->vals[i], SCIPvarGetName(consdata->vars[i]), SCIPconsGetName(cons), scalar);
3781  SCIP_CALL( delCoefPos(scip, cons, i) );
3782  }
3783  else
3784  consdata->vals[i] = newval;
3785  }
3786 
3787  /* scale the sides */
3788  if( scalar < 0.0 )
3789  {
3790  SCIP_Real lhs;
3791 
3792  lhs = consdata->lhs;
3793  consdata->lhs = -consdata->rhs;
3794  consdata->rhs = -lhs;
3795  }
3796  absscalar = REALABS(scalar);
3797  if( !SCIPisInfinity(scip, -consdata->lhs) )
3798  {
3799  newval = absscalar * consdata->lhs;
3800 
3801  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
3802  * flooring down our new value
3803  */
3804  if( SCIPisScalingIntegral(scip, consdata->lhs, absscalar) )
3805  consdata->lhs = SCIPfeasFloor(scip, newval + 0.5);
3806  else
3807  consdata->lhs = newval;
3808  }
3809  if( !SCIPisInfinity(scip, consdata->rhs) )
3810  {
3811  newval = absscalar * consdata->rhs;
3812 
3813  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasCeil, we subtract 0.5 before ceiling up
3814  * our new value
3815  */
3816  if( SCIPisScalingIntegral(scip, consdata->rhs, absscalar) )
3817  consdata->rhs = SCIPfeasCeil(scip, newval - 0.5);
3818  else
3819  consdata->rhs = newval;
3820  }
3821 
3822  consdataInvalidateActivities(consdata);
3823  consdata->cliquesadded = FALSE;
3824  consdata->implsadded = FALSE;
3825 
3826  return SCIP_OKAY;
3827 }
3828 
3829 /* perform deletion of variables in all constraints of the constraint handler */
3830 static
3832  SCIP* scip, /**< SCIP data structure */
3833  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3834  SCIP_CONS** conss, /**< array of constraints */
3835  int nconss /**< number of constraints */
3836  )
3837 {
3838  SCIP_CONSDATA* consdata;
3839  int i;
3840  int v;
3841 
3842  assert(scip != NULL);
3843  assert(conshdlr != NULL);
3844  assert(conss != NULL);
3845  assert(nconss >= 0);
3846  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
3848  /* iterate over all constraints */
3849  for( i = 0; i < nconss; i++ )
3850  {
3851  consdata = SCIPconsGetData(conss[i]);
3852 
3853  /* constraint is marked, that some of its variables were deleted */
3854  if( consdata->varsdeleted )
3855  {
3856  /* iterate over all variables of the constraint and delete them from the constraint */
3857  for( v = consdata->nvars - 1; v >= 0; --v )
3858  {
3859  if( SCIPvarIsDeleted(consdata->vars[v]) )
3860  {
3861  SCIP_CALL( delCoefPos(scip, conss[i], v) );
3862  }
3863  }
3864  consdata->varsdeleted = FALSE;
3865  }
3866  }
3867 
3868  return SCIP_OKAY;
3869 }
3870 
3871 
3872 /** normalizes a linear constraint with the following rules:
3873  * - if all coefficients have them same absolute value, change them to (-)1.0
3874  * - multiplication with +1 or -1:
3875  * Apply the following rules in the given order, until the sign of the factor is determined. Later rules only apply,
3876  * if the current rule doesn't determine the sign):
3877  * 1. the right hand side must not be negative
3878  * 2. the right hand side must not be infinite
3879  * 3. the absolute value of the right hand side must be greater than that of the left hand side
3880  * 4. the number of positive coefficients must not be smaller than the number of negative coefficients
3881  * 5. multiply with +1
3882  * - rationals to integrals
3883  * Try to identify a rational representation of the fractional coefficients, and multiply all coefficients
3884  * by the smallest common multiple of all denominators to get integral coefficients.
3885  * Forbid large denominators due to numerical stability.
3886  * - division by greatest common divisor
3887  * If all coefficients are integral, divide them by the greatest common divisor.
3888  */
3889 static
3891  SCIP* scip, /**< SCIP data structure */
3892  SCIP_CONS* cons /**< linear constraint to normalize */
3893  )
3894 {
3895  SCIP_CONSDATA* consdata;
3896  SCIP_VAR** vars;
3897  SCIP_Real* vals;
3898  SCIP_Longint scm;
3899  SCIP_Longint nominator;
3900  SCIP_Longint denominator;
3901  SCIP_Longint gcd;
3902  SCIP_Longint maxmult;
3903  SCIP_Real epsilon;
3904  SCIP_Real feastol;
3905  SCIP_Real maxabsval;
3906  SCIP_Bool success;
3907  SCIP_Bool onlyintegral;
3908  int nvars;
3909  int mult;
3910  int nposcoeffs;
3911  int nnegcoeffs;
3912  int i;
3913  int v;
3914 
3915  assert(scip != NULL);
3916  assert(cons != NULL);
3917 
3918  /* we must not change a modifiable constraint in any way */
3919  if( SCIPconsIsModifiable(cons) )
3920  return SCIP_OKAY;
3921 
3922  /* get constraint data */
3923  consdata = SCIPconsGetData(cons);
3924  assert(consdata != NULL);
3925 
3926  /* check, if the constraint is already normalized */
3927  if( consdata->normalized )
3928  return SCIP_OKAY;
3929 
3930  /* get coefficient arrays */
3931  vals = consdata->vals;
3932  nvars = consdata->nvars;
3933  vars = consdata->vars;
3934  assert(nvars == 0 || vars != NULL);
3935  assert(nvars == 0 || vals != NULL);
3936 
3937  if( nvars == 0 )
3938  {
3939  consdata->normalized = TRUE;
3940  return SCIP_OKAY;
3941  }
3942 
3943  assert(vars != NULL);
3944  assert(vals != NULL);
3945 
3946  /* get maximal absolute coefficient */
3947  maxabsval = consdataGetMaxAbsval(consdata);
3948 
3949  /* check if all coefficients are in absolute value equal, and not 1.0 */
3950  if( !SCIPisEQ(scip, maxabsval, 1.0) )
3951  {
3952  SCIP_Bool abscoefsequ;
3953 
3954  abscoefsequ = TRUE;
3955 
3956  for( v = nvars - 1; v >= 0; --v )
3957  {
3958  if( !SCIPisEQ(scip, REALABS(vals[v]), maxabsval) )
3959  {
3960  abscoefsequ = FALSE;
3961  break;
3962  }
3963  }
3964 
3965  /* all coefficients are in absolute value equal, so change them to (-)1.0 */
3966  if( abscoefsequ )
3967  {
3968  SCIPdebugMessage("divide linear constraint with %g, because all coefficients are in absolute value the same\n", maxabsval);
3969  SCIPdebugPrintCons(scip, cons, NULL);
3970  SCIP_CALL( scaleCons(scip, cons, 1/maxabsval) );
3971 
3972  if( consdata->validmaxabsval )
3973  {
3974  if( !SCIPisEQ(scip, consdata->maxabsval, 1.0) )
3975  consdata->maxabsval = 1.0;
3976 
3977  maxabsval = 1.0;
3978  }
3979  else
3980  {
3981  /* get maximal absolute coefficient */
3982  maxabsval = consdataGetMaxAbsval(consdata);
3983  }
3984 
3985  /* get new consdata information, because scalecons() might have deleted variables */
3986  vals = consdata->vals;
3987  nvars = consdata->nvars;
3988  vars = consdata->vars;
3989 
3990  assert(nvars == 0 || vars != NULL);
3991  assert(nvars == 0 || vals != NULL);
3992  }
3993  }
3994 
3995  /* nvars might have changed */
3996  if( nvars == 0 )
3997  {
3998  consdata->normalized = TRUE;
3999  return SCIP_OKAY;
4000  }
4001 
4002  assert(vars != NULL);
4003  assert(vals != NULL);
4004 
4005  /* calculate the maximal multiplier for common divisor calculation:
4006  * |p/q - val| < epsilon and q < feastol/epsilon => |p - q*val| < feastol
4007  * which means, a value of feastol/epsilon should be used as maximal multiplier;
4008  * additionally, we don't want to scale the constraint if this would lead to too
4009  * large coefficients
4010  */
4011  epsilon = SCIPepsilon(scip) * 0.9; /* slightly decrease epsilon to be safe in rational conversion below */
4012  feastol = SCIPfeastol(scip);
4013  maxmult = (SCIP_Longint)(feastol/epsilon + feastol);
4014  maxmult = MIN(maxmult, (SCIP_Longint)( MAXSCALEDCOEF/MAX(maxabsval, 1.0)));
4015 
4016  if( !consdata->hasnonbinvalid )
4017  consdataCheckNonbinvar(consdata);
4018 
4019  /* if all variables are of integral type we will allow a greater multiplier */
4020  if( !consdata->hascontvar )
4021  {
4022  if( SCIPvarGetType(vars[nvars - 1]) != SCIP_VARTYPE_CONTINUOUS )
4023  {
4024  maxmult = (SCIP_Longint) (MAXSCALEDCOEFINTEGER/(MAX(maxabsval, 1.0)));
4025  }
4026  }
4027  else
4028  {
4029  SCIP_Bool foundcont;
4030 
4031  foundcont = FALSE;
4032 
4033  for( v = nvars - 1; v >= 0; --v )
4034  {
4035  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
4036  {
4037  foundcont = TRUE;
4038  break;
4039  }
4040  }
4041 
4042  if( !foundcont )
4043  {
4044  maxmult = (SCIP_Longint) (MAXSCALEDCOEFINTEGER/(MAX(maxabsval, 1.0)));
4045  }
4046  }
4047 
4048  /*
4049  * multiplication with +1 or -1
4050  */
4051  mult = 0;
4052 
4053  /* 1. the right hand side must not be negative */
4054  if( SCIPisPositive(scip, consdata->lhs) )
4055  mult = +1;
4056  else if( SCIPisNegative(scip, consdata->rhs) )
4057  mult = -1;
4058 
4059  if( mult == 0 )
4060  {
4061  /* 2. the right hand side must not be infinite */
4062  if( SCIPisInfinity(scip, -consdata->lhs) )
4063  mult = +1;
4064  else if( SCIPisInfinity(scip, consdata->rhs) )
4065  mult = -1;
4066  }
4067 
4068  if( mult == 0 )
4069  {
4070  /* 3. the absolute value of the right hand side must be greater than that of the left hand side */
4071  if( SCIPisGT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4072  mult = +1;
4073  else if( SCIPisLT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4074  mult = -1;
4075  }
4076 
4077  if( mult == 0 )
4078  {
4079  /* 4. the number of positive coefficients must not be smaller than the number of negative coefficients */
4080  nposcoeffs = 0;
4081  nnegcoeffs = 0;
4082  for( i = 0; i < nvars; ++i )
4083  {
4084  if( vals[i] > 0.0 )
4085  nposcoeffs++;
4086  else
4087  nnegcoeffs++;
4088  }
4089  if( nposcoeffs > nnegcoeffs )
4090  mult = +1;
4091  else if( nposcoeffs < nnegcoeffs )
4092  mult = -1;
4093  }
4094 
4095  if( mult == 0 )
4096  {
4097  /* 5. multiply with +1 */
4098  mult = +1;
4099  }
4100 
4101  assert(mult == +1 || mult == -1);
4102  if( mult == -1 )
4103  {
4104  /* scale the constraint with -1 */
4105  SCIPdebugMessage("multiply linear constraint with -1.0\n");
4106  SCIPdebugPrintCons(scip, cons, NULL);
4107  SCIP_CALL( scaleCons(scip, cons, -1.0) );
4108 
4109  /* scalecons() can delete variables, but scaling with -1 should not do that */
4110  assert(nvars == consdata->nvars);
4111  }
4112 
4113  /*
4114  * rationals to integrals
4115  *
4116  * @todo try scaling only on behalf of non-continuous variables
4117  */
4118  success = TRUE;
4119  scm = 1;
4120  for( i = 0; i < nvars && success && scm <= maxmult; ++i )
4121  {
4122  if( !SCIPisIntegral(scip, vals[i]) )
4123  {
4124  /* epsilon has been slightly decreased above - to be on the safe side */
4125  success = SCIPrealToRational(vals[i], -epsilon, epsilon , maxmult, &nominator, &denominator);
4126  if( success )
4127  scm = SCIPcalcSmaComMul(scm, denominator);
4128  }
4129  }
4130  assert(scm >= 1);
4131 
4132  /* it might be that we have really big coefficients, but all are integral, in that case we want to divide them by
4133  * their greatest common divisor
4134  */
4135  onlyintegral = TRUE;
4136  if( scm == 1 )
4137  {
4138  for( i = nvars - 1; i >= 0; --i )
4139  {
4140  if( !SCIPisIntegral(scip, vals[i]) )
4141  {
4142  onlyintegral = FALSE;
4143  break;
4144  }
4145  }
4146  }
4147 
4148  success = success && (scm <= maxmult || (scm == 1 && onlyintegral));
4149  if( success && scm != 1 )
4150  {
4151  /* scale the constraint with the smallest common multiple of all denominators */
4152  SCIPdebugMessage("scale linear constraint with %" SCIP_LONGINT_FORMAT " to make coefficients integral\n", scm);
4153  SCIPdebugPrintCons(scip, cons, NULL);
4154  SCIP_CALL( scaleCons(scip, cons, (SCIP_Real)scm) );
4155 
4156  if( consdata->validmaxabsval )
4157  {
4158  consdata->maxabsval *= REALABS((SCIP_Real)scm);
4159  if( !SCIPisIntegral(scip, consdata->maxabsval) )
4160  {
4161  consdata->validmaxabsval = FALSE;
4162  consdata->maxabsval = SCIP_INVALID;
4163  consdataCalcMaxAbsval(consdata);
4164  }
4165  }
4166 
4167  /* get new consdata information, because scalecons() might have deleted variables */
4168  vals = consdata->vals;
4169  nvars = consdata->nvars;
4170  assert(nvars == 0 || vals != NULL);
4171  }
4172 
4173  /*
4174  * division by greatest common divisor
4175  */
4176  if( success && nvars >= 1 )
4177  {
4178  /* all coefficients are integral: divide them by their greatest common divisor */
4179  assert(SCIPisIntegral(scip, vals[0]));
4180 
4181  gcd = (SCIP_Longint)(REALABS(vals[0]) + feastol);
4182  for( i = 1; i < nvars && gcd > 1; ++i )
4183  {
4184  assert(SCIPisIntegral(scip, vals[i]));
4185  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[i]) + feastol));
4186  }
4187 
4188  if( gcd > 1 )
4189  {
4190  /* divide the constraint by the greatest common divisor of the coefficients */
4191  SCIPdebugMessage("divide linear constraint by greatest common divisor %" SCIP_LONGINT_FORMAT "\n", gcd);
4192  SCIPdebugPrintCons(scip, cons, NULL);
4193  SCIP_CALL( scaleCons(scip, cons, 1.0/(SCIP_Real)gcd) );
4194 
4195  if( consdata->validmaxabsval )
4196  {
4197  consdata->maxabsval /= REALABS((SCIP_Real)gcd);
4198  }
4199  }
4200  }
4201 
4202  /* mark constraint to be normalized */
4203  consdata->normalized = TRUE;
4204 
4205  SCIPdebugMessage("normalized constraint:\n");
4206  SCIPdebugPrintCons(scip, cons, NULL);
4207 
4208  return SCIP_OKAY;
4209 }
4210 
4211 /** replaces multiple occurrences of a variable by a single coefficient */
4212 static
4214  SCIP* scip, /**< SCIP data structure */
4215  SCIP_CONS* cons /**< linear constraint */
4216  )
4217 {
4218  SCIP_CONSDATA* consdata;
4219  SCIP_VAR* var;
4220  SCIP_Real valsum;
4221  int v;
4222 
4223  assert(scip != NULL);
4224  assert(cons != NULL);
4225 
4226  consdata = SCIPconsGetData(cons);
4227  assert(consdata != NULL);
4228 
4229  if( consdata->merged )
4230  return SCIP_OKAY;
4231 
4232  /* sort the constraint */
4233  SCIP_CALL( consdataSort(scip, consdata) );
4234 
4235  /* go backwards through the constraint looking for multiple occurrences of the same variable;
4236  * backward direction is necessary, since delCoefPos() modifies the given position and
4237  * the subsequent ones
4238  */
4239  v = consdata->nvars-1;
4240  while( v >= 1 )
4241  {
4242  var = consdata->vars[v];
4243  if( consdata->vars[v-1] == var )
4244  {
4245  valsum = consdata->vals[v];
4246  do
4247  {
4248  SCIP_CALL( delCoefPos(scip, cons, v) );
4249  --v;
4250  valsum += consdata->vals[v];
4251  }
4252  while( v >= 1 && consdata->vars[v-1] == var );
4253 
4254  /* modify the last existing occurrence of the variable */
4255  assert(consdata->vars[v] == var);
4256  if( SCIPisZero(scip, valsum) )
4257  {
4258  SCIP_CALL( delCoefPos(scip, cons, v) );
4259 
4260  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
4261  * delta needs to be recalculated on the next real propagation
4262  */
4263  if( consdata->maxactdeltavar == var )
4264  {
4265  consdata->maxactdelta = SCIP_INVALID;
4266  consdata->maxactdeltavar = NULL;
4267  }
4268  }
4269  else
4270  {
4271  SCIP_CALL( chgCoefPos(scip, cons, v, valsum) );
4272  }
4273  }
4274  --v;
4275  }
4276 
4277  consdata->merged = TRUE;
4278 
4279  return SCIP_OKAY;
4280 }
4281 
4282 /** replaces all fixed and aggregated variables by their non-fixed counterparts */
4283 static
4285  SCIP* scip, /**< SCIP data structure */
4286  SCIP_CONS* cons, /**< linear constraint */
4287  SCIP_Bool* infeasible /**< pointer to store if infeasibility is detected; or NULL if this
4288  * information is not needed; in this case, we apply all fixings
4289  * instead of stopping after the first infeasible one */
4290  )
4291 {
4292  SCIP_CONSDATA* consdata;
4293  SCIP_VAR* var;
4294  SCIP_VAR** aggrvars;
4295  SCIP_Real val;
4296  SCIP_Real* aggrscalars;
4297  SCIP_Real fixedval;
4298  SCIP_Real aggrconst;
4299  int v;
4300  int naggrvars;
4301  int i;
4302 
4303  assert(scip != NULL);
4304  assert(cons != NULL);
4305 
4306  if( infeasible != NULL )
4307  *infeasible = FALSE;
4308 
4309  consdata = SCIPconsGetData(cons);
4310  assert(consdata != NULL);
4311 
4312  if( !consdata->removedfixings )
4313  {
4314  SCIP_Real lhssubtrahend;
4315  SCIP_Real rhssubtrahend;
4316 
4317  lhssubtrahend = 0.0;
4318  rhssubtrahend = 0.0;
4319 
4320  SCIPdebugMessage("applying fixings:\n");
4321  SCIPdebugPrintCons(scip, cons, NULL);
4322 
4323  v = 0;
4324  while( v < consdata->nvars )
4325  {
4326  var = consdata->vars[v];
4327  val = consdata->vals[v];
4328  assert(SCIPvarIsTransformed(var));
4329 
4330  switch( SCIPvarGetStatus(var) )
4331  {
4333  SCIPerrorMessage("original variable in transformed linear constraint\n");
4334  return SCIP_INVALIDDATA;
4335 
4336  case SCIP_VARSTATUS_LOOSE:
4337  case SCIP_VARSTATUS_COLUMN:
4338  ++v;
4339  break;
4340 
4341  case SCIP_VARSTATUS_FIXED:
4342  assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)));
4343  fixedval = SCIPvarGetLbGlobal(var);
4344  if( !SCIPisInfinity(scip, -consdata->lhs) )
4345  {
4346  if( SCIPisInfinity(scip, ABS(fixedval)) )
4347  {
4348  if( val * fixedval > 0.0 )
4349  {
4350  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
4351  }
4352  else
4353  {
4354  if( infeasible != NULL )
4355  {
4356  /* if lhs gets infinity it means that the problem is infeasible */
4357  *infeasible = TRUE;
4358  return SCIP_OKAY;
4359  }
4360  else
4361  {
4362  SCIP_CALL( chgLhs(scip, cons, SCIPinfinity(scip)) );
4363  }
4364  }
4365  }
4366  else
4367  lhssubtrahend += val * fixedval;
4368  }
4369  if( !SCIPisInfinity(scip, consdata->rhs) )
4370  {
4371  if( SCIPisInfinity(scip, ABS(fixedval)) )
4372  {
4373  if( val * fixedval > 0.0 )
4374  {
4375  if( infeasible != NULL )
4376  {
4377  /* if rhs gets -infinity it means that the problem is infeasible */
4378  *infeasible = TRUE;
4379  return SCIP_OKAY;
4380  }
4381  else
4382  {
4383  SCIP_CALL( chgRhs(scip, cons, -SCIPinfinity(scip)) );
4384  }
4385  }
4386  else
4387  {
4388  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
4389  }
4390  }
4391  else
4392  rhssubtrahend += val * fixedval;
4393  }
4394  SCIP_CALL( delCoefPos(scip, cons, v) );
4395  break;
4396 
4398  {
4399  SCIP_VAR* activevar = SCIPvarGetAggrVar(var);
4400  SCIP_Real activescalar = val * SCIPvarGetAggrScalar(var);
4401  SCIP_Real activeconstant = val * SCIPvarGetAggrConstant(var);
4402 
4403  assert(activevar != NULL);
4404  SCIP_CALL( SCIPgetProbvarSum(scip, &activevar, &activescalar, &activeconstant) );
4405  assert(activevar != NULL);
4406 
4407  if( !SCIPisZero(scip, activescalar) )
4408  {
4409  SCIP_CALL( addCoef(scip, cons, activevar, activescalar) );
4410  }
4411 
4412  if( !SCIPisZero(scip, activeconstant) )
4413  {
4414  if( !SCIPisInfinity(scip, -consdata->lhs) )
4415  lhssubtrahend += activeconstant;
4416  if( !SCIPisInfinity(scip, consdata->rhs) )
4417  rhssubtrahend += activeconstant;
4418  }
4419 
4420  SCIP_CALL( delCoefPos(scip, cons, v) );
4421  break;
4422  }
4425  naggrvars = SCIPvarGetMultaggrNVars(var);
4426  aggrvars = SCIPvarGetMultaggrVars(var);
4427  aggrscalars = SCIPvarGetMultaggrScalars(var);
4428  for( i = 0; i < naggrvars; ++i )
4429  {
4430  SCIP_CALL( addCoef(scip, cons, aggrvars[i], val * aggrscalars[i]) );
4431  }
4432  aggrconst = SCIPvarGetMultaggrConstant(var);
4433 
4434  if( !SCIPisInfinity(scip, -consdata->lhs) )
4435  lhssubtrahend += val * aggrconst;
4436  if( !SCIPisInfinity(scip, consdata->rhs) )
4437  rhssubtrahend += val * aggrconst;
4438 
4439  SCIP_CALL( delCoefPos(scip, cons, v) );
4440  break;
4441 
4443  SCIP_CALL( addCoef(scip, cons, SCIPvarGetNegationVar(var), -val) );
4444  aggrconst = SCIPvarGetNegationConstant(var);
4445 
4446  if( !SCIPisInfinity(scip, -consdata->lhs) )
4447  lhssubtrahend += val * aggrconst;
4448  if( !SCIPisInfinity(scip, consdata->rhs) )
4449  rhssubtrahend += val * aggrconst;
4450 
4451  SCIP_CALL( delCoefPos(scip, cons, v) );
4452  break;
4453 
4454  default:
4455  SCIPerrorMessage("unknown variable status\n");
4456  SCIPABORT();
4457  return SCIP_INVALIDDATA; /*lint !e527*/
4458  }
4459  }
4460 
4461  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->lhs) )
4462  {
4463  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4464  * causing wrong fixings of other variables --> better use a real zero here;
4465  * for small numbers, polishing the difference might lead to wrong results -->
4466  * better use the exact difference in this case
4467  */
4468  if( SCIPisEQ(scip, lhssubtrahend, consdata->lhs) && SCIPisFeasGE(scip, REALABS(lhssubtrahend), 1.0) )
4469  {
4470  SCIP_CALL( chgLhs(scip, cons, 0.0) );
4471  }
4472  else
4473  {
4474  SCIP_CALL( chgLhs(scip, cons, consdata->lhs - lhssubtrahend) );
4475  }
4476  }
4477  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->rhs))
4478  {
4479 
4480  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4481  * causing wrong fixings of other variables --> better use a real zero here;
4482  * for small numbers, polishing the difference might lead to wrong results -->
4483  * better use the exact difference in this case
4484  */
4485  if( SCIPisEQ(scip, rhssubtrahend, consdata->rhs ) && SCIPisFeasGE(scip, REALABS(rhssubtrahend), 1.0) )
4486  {
4487  SCIP_CALL( chgRhs(scip, cons, 0.0) );
4488  }
4489  else
4490  {
4491  SCIP_CALL( chgRhs(scip, cons, consdata->rhs - rhssubtrahend) );
4492  }
4493  }
4494 
4495  consdata->removedfixings = TRUE;
4496 
4497  SCIPdebugMessage("after fixings:\n");
4498  SCIPdebugPrintCons(scip, cons, NULL);
4499 
4500  /* if aggregated variables have been replaced, multiple entries of the same variable are possible and we have
4501  * to clean up the constraint
4502  */
4503  SCIP_CALL( mergeMultiples(scip, cons) );
4504 
4505  SCIPdebugMessage("after merging:\n");
4506  SCIPdebugPrintCons(scip, cons, NULL);
4507  }
4508  assert(consdata->removedfixings);
4509 
4510 #ifndef NDEBUG
4511  /* check, if all fixings are applied */
4512  for( v = 0; v < consdata->nvars; ++v )
4513  assert(SCIPvarIsActive(consdata->vars[v]));
4514 #endif
4515 
4516  return SCIP_OKAY;
4517 }
4518 
4519 /** for each variable in the linear constraint, except the inferred variable, adds one bound to the conflict analysis'
4520  * candidate store (bound depends on sign of coefficient and whether the left or right hand side was the reason for the
4521  * inference variable's bound change); the conflict analysis can be initialized with the linear constraint being the
4522  * conflict detecting constraint by using NULL as inferred variable
4523  */
4524 static
4526  SCIP* scip, /**< SCIP data structure */
4527  SCIP_CONS* cons, /**< constraint that inferred the bound change */
4528  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
4529  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4530  int inferpos, /**< position of the inferred variable in the vars array */
4531  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the bound change? */
4532  )
4533 {
4534  SCIP_CONSDATA* consdata;
4535  SCIP_VAR** vars;
4536  SCIP_Real* vals;
4537  int nvars;
4538  int i;
4539 
4540  assert(scip != NULL);
4541  assert(cons != NULL);
4542 
4543  consdata = SCIPconsGetData(cons);
4544  assert(consdata != NULL);
4545  vars = consdata->vars;
4546  vals = consdata->vals;
4547  nvars = consdata->nvars;
4548  assert(vars != NULL || nvars == 0);
4549  assert(vals != NULL || nvars == 0);
4550  assert(-1 <= inferpos && inferpos < nvars);
4551  assert((infervar == NULL) == (inferpos == -1));
4552  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
4553 
4554  /* for each variable, add the bound to the conflict queue, that is responsible for the minimal or maximal
4555  * residual value, depending on whether the left or right hand side is responsible for the bound change:
4556  * - if the right hand side is the reason, the minimal residual activity is responsible
4557  * - if the left hand side is the reason, the maximal residual activity is responsible
4558  */
4559 
4560  /* if the variable is integral we only need to add reason bounds until the propagation could be applied */
4561  if( infervar == NULL || SCIPvarIsIntegral(infervar) )
4562  {
4563  SCIP_Real minresactivity;
4564  SCIP_Real maxresactivity;
4565  SCIP_Bool minisrelax;
4566  SCIP_Bool maxisrelax;
4567  SCIP_Bool isminsettoinfinity;
4568  SCIP_Bool ismaxsettoinfinity;
4569 
4570  minresactivity = -SCIPinfinity(scip);
4571  maxresactivity = SCIPinfinity(scip);
4572 
4573  /* calculate the minimal and maximal global activity of all other variables involved in the constraint */
4574  if( infervar != NULL )
4575  {
4576  assert(vals != NULL); /* for flexelint */
4577  if( reasonisrhs )
4578  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, &minresactivity, NULL,
4579  &minisrelax, NULL, &isminsettoinfinity, NULL);
4580  else
4581  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, NULL, &maxresactivity,
4582  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4583  }
4584  else
4585  {
4586  if( reasonisrhs )
4587  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minresactivity, NULL,
4588  &minisrelax, NULL, &isminsettoinfinity, NULL);
4589  else
4590  consdataGetGlbActivityBounds(scip, consdata, FALSE, NULL, &maxresactivity,
4591  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4592  }
4593 
4594  /* we can only do something clever, if the residual activity is finite and not relaxed */
4595  if( (reasonisrhs && !isminsettoinfinity && !minisrelax) || (!reasonisrhs && !ismaxsettoinfinity && !maxisrelax) ) /*lint !e644*/
4596  {
4597  SCIP_Real rescap;
4598  SCIP_Bool resactisinf;
4599 
4600  resactisinf = FALSE;
4601 
4602  /* calculate the residual capacity that would be left, if the variable would be set to one more / one less
4603  * than its inferred bound
4604  */
4605  if( infervar != NULL )
4606  {
4607  assert(vals != NULL); /* for flexelint */
4608 
4609  if( reasonisrhs )
4610  {
4611  if( SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
4612  {
4613  consdataGetReliableResidualActivity(scip, consdata, infervar, &minresactivity, TRUE, TRUE);
4614  if( SCIPisInfinity(scip, -minresactivity) )
4615  resactisinf = TRUE;
4616  }
4617  rescap = consdata->rhs - minresactivity;
4618  }
4619  else
4620  {
4621  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
4622  {
4623  consdataGetReliableResidualActivity(scip, consdata, infervar, &maxresactivity, FALSE, TRUE);
4624  if( SCIPisInfinity(scip, maxresactivity) )
4625  resactisinf = TRUE;
4626  }
4627  rescap = consdata->lhs - maxresactivity;
4628  }
4629 
4630  if( reasonisrhs == (vals[inferpos] > 0.0) )
4631  rescap -= vals[inferpos] * (SCIPvarGetUbAtIndex(infervar, bdchgidx, TRUE) + 1.0);
4632  else
4633  rescap -= vals[inferpos] * (SCIPvarGetLbAtIndex(infervar, bdchgidx, TRUE) - 1.0);
4634  }
4635  else
4636  rescap = (reasonisrhs ? consdata->rhs - minresactivity : consdata->lhs - maxresactivity);
4637 
4638  if( !resactisinf )
4639  {
4640  /* now add bounds as reasons until the residual capacity is exceeded */
4641  for( i = 0; i < nvars; ++i )
4642  {
4643  assert(vars != NULL); /* for flexelint */
4644  assert(vals != NULL); /* for flexelint */
4645 
4646  /* zero coefficients and the infered variable can be ignored */
4647  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
4648  continue;
4649 
4650  /* check if the residual capacity is exceeded */
4651  if( (reasonisrhs && SCIPisFeasNegative(scip, rescap))
4652  || (!reasonisrhs && SCIPisFeasPositive(scip, rescap)) )
4653  break;
4654 
4655  /* update the residual capacity due to the local bound of this variable */
4656  if( reasonisrhs == (vals[i] > 0.0) )
4657  {
4658  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound */
4659  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
4660  rescap -= vals[i] * (SCIPvarGetLbAtIndex(vars[i], bdchgidx, FALSE) - SCIPvarGetLbGlobal(vars[i]));
4661  }
4662  else
4663  {
4664  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound */
4665  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
4666  rescap -= vals[i] * (SCIPvarGetUbAtIndex(vars[i], bdchgidx, FALSE) - SCIPvarGetUbGlobal(vars[i]));
4667  }
4668  }
4669  return SCIP_OKAY;
4670  }
4671  }
4672  }
4673 
4674  /* for a bound change on a continuous variable, all locally changed bounds are responsible */
4675  for( i = 0; i < nvars; ++i )
4676  {
4677  assert(vars != NULL); /* for flexelint */
4678  assert(vals != NULL); /* for flexelint */
4679 
4680  /* zero coefficients and the infered variable can be ignored */
4681  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
4682  continue;
4683 
4684  if( reasonisrhs == (vals[i] > 0.0) )
4685  {
4686  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound is responsible */
4687  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
4688  }
4689  else
4690  {
4691  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound is responsible */
4692  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
4693  }
4694  }
4695 
4696  return SCIP_OKAY;
4697 }
4698 
4699 /** for each variable in the linear ranged row constraint, except the inferred variable, adds the bounds of all fixed
4700  * variables to the conflict analysis' candidate store; the conflict analysis can be initialized
4701  * with the linear constraint being the conflict detecting constraint by using NULL as inferred variable
4702  */
4703 static
4705  SCIP* scip, /**< SCIP data structure */
4706  SCIP_CONS* cons, /**< constraint that inferred the bound change */
4707  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
4708  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4709  int inferpos /**< position of the inferred variable in the vars array, or -1 */
4710  )
4711 {
4712  SCIP_CONSDATA* consdata;
4713  SCIP_VAR** vars;
4714  int nvars;
4715  int v;
4716 
4717  assert(scip != NULL);
4718  assert(cons != NULL);
4719 
4720  consdata = SCIPconsGetData(cons);
4721  assert(consdata != NULL);
4722  vars = consdata->vars;
4723  nvars = consdata->nvars;
4724  assert(vars != NULL || nvars == 0);
4725  assert(-1 <= inferpos && inferpos < nvars);
4726  assert((infervar == NULL) == (inferpos == -1));
4727  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
4728 
4729  /* collect all fixed variables */
4730  for( v = nvars - 1; v >= 0; --v )
4731  {
4732  assert(vars != NULL); /* for flexelint */
4733 
4734  /* need to add old bounds before propagation of inferrence variable */
4735  if( vars[v] == infervar )
4736  {
4737  assert(vars[v] != NULL);
4738 
4739  if( !SCIPisEQ(scip, SCIPvarGetLbAtIndex(vars[v], bdchgidx, FALSE), SCIPvarGetLbGlobal(vars[v])) )
4740  {
4741  /* @todo get boundchange index before this last boundchange and correct the index */
4742  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
4743  }
4744 
4745  if( !SCIPisEQ(scip, SCIPvarGetUbAtIndex(vars[v], bdchgidx, FALSE), SCIPvarGetUbGlobal(vars[v])) )
4746  {
4747  /* @todo get boundchange index before this last boundchange and correct the index */
4748  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
4749  }
4750 
4751  continue;
4752  }
4753 
4754  /* check for fixed variables */
4755  if( SCIPisEQ(scip, SCIPvarGetLbAtIndex(vars[v], bdchgidx, FALSE), SCIPvarGetUbAtIndex(vars[v], bdchgidx, FALSE)) )
4756  {
4757  /* add all bounds of fixed variables which lead to the boundchange of the given inference variable */
4758  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
4759  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
4760  }
4761  }
4762 
4763  return SCIP_OKAY;
4764 }
4765 
4766 /** add reasoning variables to conflict candidate queue which led to the conflict */
4767 static
4769  SCIP* scip, /**< SCIP data structure */
4770  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
4771  int nvars, /**< number of variables reasoning the infeasibility */
4772  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
4773  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
4774  )
4775 {
4776  int v;
4777 
4778  assert(scip != NULL);
4779 
4780  /* collect all variables for which the local bounds differ from their global bounds */
4781  for( v = nvars - 1; v >= 0; --v )
4782  {
4783  assert(vars != NULL);
4785  /* check for local bound changes variables */
4786  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(vars[v]), SCIPvarGetLbGlobal(vars[v])) )
4787  {
4788  /* add conflict bound */
4789  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], 0) );
4790  }
4791 
4792  if( !SCIPisEQ(scip, SCIPvarGetUbLocal(vars[v]), SCIPvarGetUbGlobal(vars[v])) )
4793  {
4794  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], 0) );
4795  }
4796  }
4797 
4798  if( var != NULL )
4799  {
4800  if( bound < SCIPvarGetLbLocal(var) )
4801  {
4802  SCIP_CALL( SCIPaddConflictLb(scip, var, 0) );
4803  }
4804 
4805  if( bound > SCIPvarGetUbLocal(var) )
4806  {
4807  SCIP_CALL( SCIPaddConflictUb(scip, var, 0) );
4808  }
4809  }
4810 
4811  return SCIP_OKAY;
4812 }
4813 
4814 /** resolves a propagation on the given variable by supplying the variables needed for applying the corresponding
4815  * propagation rule (see propagateCons()):
4816  * (1) activity residuals of all other variables tighten bounds of single variable
4817  */
4818 static
4820  SCIP* scip, /**< SCIP data structure */
4821  SCIP_CONS* cons, /**< constraint that inferred the bound change */
4822  SCIP_VAR* infervar, /**< variable that was deduced */
4823  INFERINFO inferinfo, /**< inference information */
4824  SCIP_BOUNDTYPE boundtype, /**< the type of the changed bound (lower or upper bound) */
4825  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4826  SCIP_RESULT* result /**< pointer to store the result of the propagation conflict resolving call */
4827  )
4828 {
4829  SCIP_CONSDATA* consdata;
4830  SCIP_VAR** vars;
4831 #ifndef NDEBUG
4832  SCIP_Real* vals;
4833 #endif
4834  int nvars;
4835  int inferpos;
4836 
4837  assert(scip != NULL);
4838  assert(cons != NULL);
4839  assert(result != NULL);
4840 
4841  consdata = SCIPconsGetData(cons);
4842  assert(consdata != NULL);
4843  vars = consdata->vars;
4844  nvars = consdata->nvars;
4845 #ifndef NDEBUG
4846  vals = consdata->vals;
4847  assert(vars != NULL);
4848  assert(vals != NULL);
4849 #endif
4850 
4851  /* get the position of the inferred variable in the vars array */
4852  inferpos = inferInfoGetPos(inferinfo);
4853  if( inferpos >= nvars || vars[inferpos] != infervar )
4854  {
4855  /* find inference variable in constraint */
4856  /**@todo use a binary search here; the variables can be sorted by variable index */
4857  for( inferpos = 0; inferpos < nvars && vars[inferpos] != infervar; ++inferpos )
4858  {}
4859  }
4860  assert(inferpos < nvars);
4861  assert(vars[inferpos] == infervar);
4862  assert(!SCIPisZero(scip, vals[inferpos]));
4863 
4864  switch( inferInfoGetProprule(inferinfo) )
4865  {
4866  case PROPRULE_1_RHS:
4867  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
4868  * constraint (only taking the other variables into account) didn't leave enough space for a larger
4869  * domain in order to not exceed the right hand side of the inequality
4870  */
4871  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_UPPER));
4872  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, TRUE) );
4873  *result = SCIP_SUCCESS;
4874  break;
4875 
4876  case PROPRULE_1_LHS:
4877  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
4878  * constraint (only taking the other variables into account) didn't leave enough space for a larger
4879  * domain in order to not fall below the left hand side of the inequality
4880  */
4881  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_LOWER));
4882  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, FALSE) );
4883  *result = SCIP_SUCCESS;
4884  break;
4885 
4886  case PROPRULE_1_RANGEDROW:
4887  /* the bound of the variable was tightened, because some variables were already fixed and the leftover only allow
4888  * the given inference variable to their bounds in this given ranged row
4889  */
4890 
4891  /* check that we really have a ranged row here */
4892  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
4893  SCIP_CALL( addConflictFixedVars(scip, cons, infervar, bdchgidx, inferpos) );
4894  *result = SCIP_SUCCESS;
4895  break;
4896 
4897  case PROPRULE_INVALID:
4898  default:
4899  SCIPerrorMessage("invalid inference information %d in linear constraint <%s> at position %d for %s bound of variable <%s>\n",
4900  inferInfoGetProprule(inferinfo), SCIPconsGetName(cons), inferInfoGetPos(inferinfo),
4901  boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper", SCIPvarGetName(infervar));
4902  SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
4903  SCIPinfoMessage(scip, NULL, ";\n");
4904  return SCIP_INVALIDDATA;
4905  }
4906 
4907  return SCIP_OKAY;
4908 }
4909 
4910 /** analyzes conflicting bounds on given constraint, and adds conflict constraint to problem */
4911 static
4913  SCIP* scip, /**< SCIP data structure */
4914  SCIP_CONS* cons, /**< conflict detecting constraint */
4915  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the conflict? */
4916  )
4917 {
4918  /* conflict analysis can only be applied in solving stage and if it is turned on */
4920  return SCIP_OKAY;
4921 
4922  /* initialize conflict analysis */
4924 
4925  /* add the conflicting bound for each variable of infeasible constraint to conflict candidate queue */
4926  SCIP_CALL( addConflictBounds(scip, cons, NULL, NULL, -1, reasonisrhs) );
4927 
4928  /* analyze the conflict */
4929  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
4930 
4931  return SCIP_OKAY;
4932 }
4933 
4934 /** check if there is any hope of tightening some bounds */
4935 static
4937  SCIP* scip, /**< SCIP data structure */
4938  SCIP_CONS* cons /**< linear constraint */
4939  )
4940 {
4941  SCIP_CONSDATA* consdata;
4942  int infcountmin;
4943  int infcountmax;
4944 
4945  consdata = SCIPconsGetData(cons);
4946  assert(consdata != NULL);
4947 
4948  infcountmin = consdata->minactivityneginf
4949  + consdata->minactivityposinf
4950  + consdata->minactivityneghuge
4951  + consdata->minactivityposhuge;
4952  infcountmax = consdata->maxactivityneginf
4953  + consdata->maxactivityposinf
4954  + consdata->maxactivityneghuge
4955  + consdata->maxactivityposhuge;
4956 
4957  if( infcountmin > 1 && infcountmax > 1 )
4958  return FALSE;
4959 
4960  return TRUE;
4961 }
4962 
4963 /** tighten upper bound */
4964 static
4966  SCIP* scip, /**< SCIP data structure */
4967  SCIP_CONS* cons, /**< linear constraint */
4968  int pos, /**< variable position */
4969  PROPRULE proprule, /**< propagation rule that deduced the value */
4970  SCIP_Real newub, /**< new upper bound */
4971  SCIP_Real oldub, /**< old upper bound */
4972  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
4973  int* nchgbds, /**< pointer to count the total number of tightened bounds */
4974  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
4975  )
4976 {
4977  SCIP_CONSDATA* consdata;
4978  SCIP_VAR* var;
4979  SCIP_Real lb;
4980  SCIP_Bool infeasible;
4981  SCIP_Bool tightened;
4982 
4983  assert(cons != NULL);
4984  assert(!SCIPisInfinity(scip, newub));
4985 
4986  consdata = SCIPconsGetData(cons);
4987  assert(consdata != NULL);
4988  var = consdata->vars[pos];
4989  assert(var != NULL);
4990 
4991  lb = SCIPvarGetLbLocal(var);
4992  newub = SCIPadjustedVarUb(scip, var, newub);
4993 
4994  if( force || SCIPisUbBetter(scip, newub, lb, oldub) )
4995  {
4996  SCIP_VARTYPE vartype;
4997 
4998  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
4999  SCIPconsGetName(cons), SCIPvarGetName(var), lb, oldub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newub);
5000 
5001  vartype = SCIPvarGetType(var);
5002 
5003  /* tighten upper bound */
5004  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5005 
5006  if( infeasible )
5007  {
5008  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5009  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5010 
5011  /* analyze conflict */
5012  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
5013 
5014  *cutoff = TRUE;
5015  }
5016  else if( tightened )
5017  {
5018  assert(SCIPisFeasLE(scip, SCIPvarGetUbLocal(var), oldub));
5019  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5020  SCIPconsGetName(cons), SCIPvarGetName(var), lb, SCIPvarGetUbLocal(var));
5021 
5022  (*nchgbds)++;
5023 
5024  /* if variable type was changed we might be able to upgrade the constraint */
5025  if( vartype != SCIPvarGetType(var) )
5026  consdata->upgradetried = FALSE;
5027  }
5028  }
5029  return SCIP_OKAY;
5030 }
5031 
5032 /** tighten lower bound */
5033 static
5035  SCIP* scip, /**< SCIP data structure */
5036  SCIP_CONS* cons, /**< linear constraint */
5037  int pos, /**< variable position */
5038  PROPRULE proprule, /**< propagation rule that deduced the value */
5039  SCIP_Real newlb, /**< new lower bound */
5040  SCIP_Real oldlb, /**< old lower bound */
5041  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5042  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5043  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5044  )
5045 {
5046  SCIP_CONSDATA* consdata;
5047  SCIP_VAR* var;
5048  SCIP_Real ub;
5049  SCIP_Bool infeasible;
5050  SCIP_Bool tightened;
5051 
5052  assert(cons != NULL);
5053  assert(!SCIPisInfinity(scip, newlb));
5054 
5055  consdata = SCIPconsGetData(cons);
5056  assert(consdata != NULL);
5057  var = consdata->vars[pos];
5058  assert(var != NULL);
5059 
5060  ub = SCIPvarGetUbLocal(var);
5061  newlb = SCIPadjustedVarLb(scip, var, newlb);
5062 
5063  if( force || SCIPisLbBetter(scip, newlb, oldlb, ub) )
5064  {
5065  SCIP_VARTYPE vartype;
5066 
5067  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
5068  SCIPconsGetName(cons), SCIPvarGetName(var), oldlb, ub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newlb);
5069 
5070  vartype = SCIPvarGetType(var);
5071 
5072  /* tighten lower bound */
5073  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5074 
5075  if( infeasible )
5076  {
5077  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5078  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5079 
5080  /* analyze conflict */
5081  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
5082 
5083  *cutoff = TRUE;
5084  }
5085  else if( tightened )
5086  {
5087  assert(SCIPisFeasGE(scip, SCIPvarGetLbLocal(var), oldlb));
5088  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5089  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetLbLocal(var), ub);
5090 
5091  (*nchgbds)++;
5092 
5093  /* if variable type was changed we might be able to upgrade the constraint */
5094  if( vartype != SCIPvarGetType(var) )
5095  consdata->upgradetried = FALSE;
5096  }
5097  }
5098  return SCIP_OKAY;
5099 }
5100 
5101 /** tightens bounds of a single variable due to activity bounds (easy case) */
5102 static
5104  SCIP* scip, /**< SCIP data structure */
5105  SCIP_CONS* cons, /**< linear constraint */
5106  int pos, /**< position of the variable in the vars array */
5107  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5108  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5109  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5110  )
5111 {
5112  SCIP_CONSDATA* consdata;
5113  SCIP_VAR* var;
5114  SCIP_Real val;
5115  SCIP_Real lb;
5116  SCIP_Real ub;
5117  SCIP_Real lhs;
5118  SCIP_Real rhs;
5120  assert(scip != NULL);
5121  assert(cons != NULL);
5122  assert(cutoff != NULL);
5123  assert(nchgbds != NULL);
5124 
5125  /* we cannot tighten variables' bounds, if the constraint may be not complete */
5126  if( SCIPconsIsModifiable(cons) )
5127  return SCIP_OKAY;
5128 
5129  consdata = SCIPconsGetData(cons);
5130  assert(consdata != NULL);
5131  assert(0 <= pos && pos < consdata->nvars);
5132 
5133  *cutoff = FALSE;
5134 
5135  var = consdata->vars[pos];
5136  assert(var != NULL);
5137 
5138  /* we cannot tighten bounds of multi-aggregated variables */
5140  return SCIP_OKAY;
5141 
5142  val = consdata->vals[pos];
5143  lhs = consdata->lhs;
5144  rhs = consdata->rhs;
5145  assert(!SCIPisZero(scip, val));
5146  assert(!SCIPisInfinity(scip, lhs));
5147  assert(!SCIPisInfinity(scip, -rhs));
5148 
5149  lb = SCIPvarGetLbLocal(var);
5150  ub = SCIPvarGetUbLocal(var);
5151  assert(SCIPisLE(scip, lb, ub));
5152 
5153  /* recompute activities if needed */
5154  if( !consdata->validactivities )
5155  consdataCalcActivities(scip, consdata);
5156  assert(consdata->validactivities);
5157  if( !consdata->validminact )
5158  consdataRecomputeMinactivity(scip, consdata);
5159  assert(consdata->validminact);
5160  if( !consdata->validmaxact )
5161  consdataRecomputeMaxactivity(scip, consdata);
5162  assert(consdata->validmaxact);
5163 
5164  if( val > 0.0 )
5165  {
5166  /* check, if we can tighten the variable's upper bound */
5167  if( !SCIPisInfinity(scip, rhs) )
5168  {
5169  SCIP_Real slack;
5170  SCIP_Real alpha;
5171 
5172  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5173  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5174  {
5175  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5176  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5177 
5178  *cutoff = TRUE;
5179  return SCIP_OKAY;
5180  }
5181 
5182  slack = rhs - consdata->minactivity;
5183 
5184  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5185  * it to zero
5186  */
5187  if( !SCIPisPositive(scip, slack) )
5188  slack = 0.0;
5189 
5190  alpha = val * (ub - lb);
5191  assert(!SCIPisNegative(scip, alpha));
5192 
5193  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5194  {
5195  SCIP_Real newub;
5196 
5197  /* compute new upper bound */
5198  newub = lb + (slack / val);
5199 
5200  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_RHS, newub, ub, cutoff, nchgbds, force) );
5201 
5202  if( *cutoff )
5203  {
5204  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5205  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5206 
5207  return SCIP_OKAY;
5208  }
5209 
5210  /* collect the new upper bound which is needed for the lower bound computation */
5211  ub = SCIPvarGetUbLocal(var);
5212  }
5213  }
5214 
5215  /* check, if we can tighten the variable's lower bound */
5216  if( !SCIPisInfinity(scip, -lhs) )
5217  {
5218  SCIP_Real slack;
5219  SCIP_Real alpha;
5220 
5221  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5222  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5223  {
5224  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5225  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5226 
5227  *cutoff = TRUE;
5228  return SCIP_OKAY;
5229  }
5230 
5231  slack = consdata->maxactivity - lhs;
5232 
5233  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5234  * it to zero
5235  */
5236  if( !SCIPisPositive(scip, slack) )
5237  slack = 0.0;
5238 
5239  alpha = val * (ub - lb);
5240  assert(!SCIPisNegative(scip, alpha));
5241 
5242  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5243  {
5244  SCIP_Real newlb;
5245 
5246  /* compute new lower bound */
5247  newlb = ub - (slack / val);
5248 
5249  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_LHS, newlb, lb, cutoff, nchgbds, force) );
5250 
5251  if( *cutoff )
5252  {
5253  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5254  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5255 
5256  return SCIP_OKAY;
5257  }
5258  }
5259  }
5260  }
5261  else
5262  {
5263  /* check, if we can tighten the variable's lower bound */
5264  if( !SCIPisInfinity(scip, rhs) )
5265  {
5266  SCIP_Real slack;
5267  SCIP_Real alpha;
5268 
5269  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5270  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5271  {
5272  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5273  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5274 
5275  *cutoff = TRUE;
5276  return SCIP_OKAY;
5277  }
5278 
5279  slack = rhs - consdata->minactivity;
5280 
5281  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5282  * it to zero
5283  */
5284  if( !SCIPisPositive(scip, slack) )
5285  slack = 0.0;
5286 
5287  alpha = val * (lb - ub);
5288  assert(!SCIPisNegative(scip, alpha));
5289 
5290  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5291  {
5292  SCIP_Real newlb;
5293 
5294  /* compute new lower bound */
5295  newlb = ub + slack / val;
5296 
5297  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_RHS, newlb, lb, cutoff, nchgbds, force) );
5298 
5299  if( *cutoff )
5300  {
5301  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5302  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5303 
5304  return SCIP_OKAY;
5305  }
5306  /* collect the new lower bound which is needed for the upper bound computation */
5307  lb = SCIPvarGetLbLocal(var);
5308  }
5309  }
5310 
5311  /* check, if we can tighten the variable's upper bound */
5312  if( !SCIPisInfinity(scip, -lhs) )
5313  {
5314  SCIP_Real slack;
5315  SCIP_Real alpha;
5316 
5317  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5318  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5319  {
5320  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5321  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5322 
5323  *cutoff = TRUE;
5324  return SCIP_OKAY;
5325  }
5326 
5327  slack = consdata->maxactivity - lhs;
5328 
5329  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5330  * it to zero
5331  */
5332  if( !SCIPisPositive(scip, slack) )
5333  slack = 0.0;
5334 
5335  alpha = val * (lb - ub);
5336  assert(!SCIPisNegative(scip, alpha));
5337 
5338  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5339  {
5340  SCIP_Real newub;
5341 
5342  /* compute new upper bound */
5343  newub = lb - (slack / val);
5344 
5345  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_LHS, newub, ub, cutoff, nchgbds, force) );
5346 
5347  if( *cutoff )
5348  {
5349  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5350  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5351 
5352  return SCIP_OKAY;
5353  }
5354  }
5355  }
5356  }
5357 
5358  return SCIP_OKAY;
5359 }
5360 
5361 /** analyzes conflicting bounds on given ranged row constraint, and adds conflict constraint to problem */
5362 static
5364  SCIP* scip, /**< SCIP data structure */
5365  SCIP_CONS* cons, /**< conflict detecting constraint */
5366  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
5367  int nvars, /**< number of variables reasoning the infeasibility */
5368  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
5369  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
5370  )
5371 {
5372 #ifndef NDEBUG
5373  SCIP_CONSDATA* consdata;
5374 
5375  assert(scip != NULL);
5376  assert(cons != NULL);
5377 
5378  consdata = SCIPconsGetData(cons);
5379  assert(consdata != NULL);
5380  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5381 #endif
5382 
5383  /* conflict analysis can only be applied in solving stage and if it is turned on */
5385  return SCIP_OKAY;
5386 
5387  /* initialize conflict analysis */
5389 
5390  /* add the conflicting fixed variables of this ranged row constraint to conflict candidate queue */
5391  SCIP_CALL( addConflictFixedVars(scip, cons, NULL, NULL, -1) );
5392 
5393  /* add reasoning variables to conflict candidate queue which led to the conflict */
5394  SCIP_CALL( addConflictReasonVars(scip, vars, nvars, var, bound) );
5395 
5396  /* analyze the conflict */
5397  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5398 
5399  return SCIP_OKAY;
5400 }
5401 
5402 /** propagate ranged rows
5403  *
5404  * Check ranged rows for possible solutions, possibly detect infeasibility, fix variables due to having only one possible
5405  * solution, tighten bounds if having only two possible solutions or add constraints which propagate a subset of
5406  * variables better.
5407  *
5408  * Example:
5409  * c1: 12 x1 + 9 x2 - x3 = 0 with x1, x2 free and 1 <= x3 <= 2
5410  *
5411  * x3 needs to be a multiple of 3, so the instance is infeasibile.
5412  *
5413  * Example:
5414  * c1: 12 x1 + 9 x2 - x3 = 1 with x1, x2 free and 1 <= x3 <= 2
5415  *
5416  * The only posible value for x3 is 2, so the variable will be fixed.
5417  *
5418  * @todo add holes if possible
5419  */
5420 static
5422  SCIP* scip, /**< SCIP data structure */
5423  SCIP_CONS* cons, /**< linear constraint */
5424  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
5425  int* nfixedvars, /**< pointer to count number of fixed variables */
5426  int* nchgbds, /**< pointer to count the number of bound changes */
5427  int* naddconss /**< pointer to count number of added constraints */
5428  )
5429 {
5430  SCIP_CONSHDLRDATA* conshdlrdata;
5431  SCIP_CONSHDLR* conshdlr;
5432  SCIP_CONSDATA* consdata;
5433  SCIP_VAR** infcheckvars;
5434  SCIP_Real* infcheckvals;
5435  SCIP_Real minactinfvars;
5436  SCIP_Real maxactinfvars;
5438  SCIP_Real ub;
5439  SCIP_Real feastol;
5440  SCIP_Real fixedact;
5441  SCIP_Real lhs;
5442  SCIP_Real rhs;
5443  SCIP_Real absminbincoef;
5444  SCIP_Longint gcd;
5445  SCIP_Longint gcdtmp;
5446  SCIP_Bool minactinfvarsinvalid;
5447  SCIP_Bool maxactinfvarsinvalid;
5448  SCIP_Bool possiblegcd;
5449  SCIP_Bool gcdisone;
5450  SCIP_Bool addartconss;
5451  int ninfcheckvars;
5452  int nunfixedvars;
5453  int nfixedconsvars;
5454  int ncontvars;
5455  int pos;
5456  int v;
5457 
5458  assert(scip != NULL);
5459  assert(cons != NULL);
5460  assert(cutoff != NULL);
5461  assert(nfixedvars != NULL);
5462  assert(nchgbds != NULL);
5463  assert(naddconss != NULL);
5464 
5465  /* modifiable constraint can be changed so we do not have all necessary information */
5466  if( SCIPconsIsModifiable(cons) )
5467  return SCIP_OKAY;
5468 
5469  consdata = SCIPconsGetData(cons);
5470  assert(consdata != NULL);
5471 
5472  /* at least three variables are needed */
5473  if( consdata->nvars < 3 )
5474  return SCIP_OKAY;
5475 
5476  /* if we already presolved this constraint */
5477  if( consdata->rangedrowpropagation )
5478  return SCIP_OKAY;
5479 
5480  /* if we have too many continuous variables, so stop here */
5481  if( (consdata->sorted || consdata->binvarssorted) && SCIPvarGetType(consdata->vars[1]) == SCIP_VARTYPE_CONTINUOUS )
5482  return SCIP_OKAY;
5483 
5484  /* do nothing on normal inequalities */
5485  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
5486  return SCIP_OKAY;
5487 
5488  /* get constraint handler data */
5489  conshdlr = SCIPconsGetHdlr(cons);
5490  assert(conshdlr != NULL);
5491  conshdlrdata = SCIPconshdlrGetData(conshdlr);
5492  assert(conshdlrdata != NULL);
5493 
5494  addartconss = conshdlrdata->rangedrowartcons;
5495 
5496  fixedact = 0;
5497  nfixedconsvars = 0;
5498  /* calculate fixed activity and number of fixed variables */
5499  for( v = consdata->nvars - 1; v >= 0; --v )
5500  {
5501  /* all zero coefficients should be eliminated */
5502  assert(!SCIPisZero(scip, consdata->vals[v]));
5503 
5504  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5505  {
5506  fixedact += SCIPvarGetLbLocal(consdata->vars[v]) * consdata->vals[v];
5507  ++nfixedconsvars;
5508  }
5509  }
5510 
5511  /* do not work with huge fixed activities */
5512  if( SCIPisHugeValue(scip, REALABS(fixedact)) )
5513  return SCIP_OKAY;
5514 
5515  /* compute lhs and rhs for unfixed variables only and get number of unfixed variables */
5516  assert(!SCIPisInfinity(scip, -fixedact) && !SCIPisInfinity(scip, fixedact));
5517  lhs = consdata->lhs - fixedact;
5518  rhs = consdata->rhs - fixedact;
5519  nunfixedvars = consdata->nvars - nfixedconsvars;
5520 
5521  /* allocate temporary memory for variables and coefficients which may lead to infeasibility */
5522  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvars, nunfixedvars) );
5523  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvals, nunfixedvars) );
5524 
5525  absminbincoef = SCIP_REAL_MAX;
5526  ncontvars = 0;
5527  gcdisone = TRUE;
5528  possiblegcd = TRUE;
5529 
5530  /* we now partition all unfixed variables in two groups:
5531  *
5532  * the first one contains all integral variable with integral
5533  * coefficient so that all variables in this group will have a gcd greater than 1, this group will be implicitly
5534  * given
5535  *
5536  * the second group will contain all left unfixed variables and will be saved as infcheckvars with corresponding
5537  * coefficients as infcheckvals, the order of these variables should be the same as in the consdata object
5538  */
5539 
5540  /* find first integral variables with integral coefficient greater than 1, thereby collecting all other unfixed
5541  * variables
5542  */
5543  ninfcheckvars = 0;
5544  v = -1;
5545  pos = -1;
5546  do
5547  {
5548  ++v;
5549 
5550  /* partition the variables, do not change the order of collection, because it might be used later on */
5551  while( v < consdata->nvars && (SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5552  !SCIPisIntegral(scip, consdata->vals[v]) || SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0)) )
5553  {
5554  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5555  {
5556  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5557  {
5558  ++ncontvars;
5559  }
5560  else if( SCIPvarIsBinary(consdata->vars[v]) )
5561  {
5562  SCIP_Real absval;
5563 
5564  absval = REALABS(consdata->vals[v]);
5565 
5566  if( absminbincoef > absval )
5567  absminbincoef = absval;
5568  }
5569 
5570  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5571  possiblegcd = FALSE;
5572  infcheckvars[ninfcheckvars] = consdata->vars[v];
5573  infcheckvals[ninfcheckvars] = consdata->vals[v];
5574  ++ninfcheckvars;
5575 
5576  if( pos == -1 )
5577  pos = v;
5578  }
5579  ++v;
5580  }
5581  }
5582  while( v < consdata->nvars && SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) );
5583 
5584  /* if the first group of variables is empty, we stop */
5585  /* @todo try to propagate/split up a constraint of the form:
5586  * x_1 + ... + x_m + a_1*y_1 + ... + a_n*y_n = k + c,
5587  * 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]
5588  */
5589  if( v == consdata->nvars )
5590  goto TERMINATE;
5591 
5592  assert(!SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])));
5593  assert(SCIPisIntegral(scip, consdata->vals[v]) && SCIPvarGetType(consdata->vars[v]) != SCIP_VARTYPE_CONTINUOUS && REALABS(consdata->vals[v]) > 1.5);
5594 
5595  feastol = SCIPfeastol(scip);
5596 
5597  gcd = (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol);
5598  assert(gcd >= 2);
5599 
5600  /* go on to partition the variables, do not change the order of collection, because it might be used later on;
5601  * calculate gcd over the first part of variables */
5602  for( ; v < consdata->nvars; ++v )
5603  {
5604  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5605  continue;
5606 
5607  if( SCIPvarIsBinary(consdata->vars[v]) )
5608  {
5609  SCIP_Real absval;
5610 
5611  absval = REALABS(consdata->vals[v]);
5612 
5613  if( absminbincoef > absval )
5614  absminbincoef = absval;
5615  }
5616 
5617  if( !SCIPisIntegral(scip, consdata->vals[v]) || SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5618  SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0) )
5619  {
5620  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5621  ++ncontvars;
5622 
5623  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5624  possiblegcd = FALSE;
5625  infcheckvars[ninfcheckvars] = consdata->vars[v];
5626  infcheckvals[ninfcheckvars] = consdata->vals[v];
5627 
5628  ++ninfcheckvars;
5629 
5630  if( pos == -1 )
5631  pos = v;
5632  }
5633  else
5634  {
5635  assert(REALABS(consdata->vals[v]) > 1.5);
5636 
5637  gcdtmp = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol));
5638  assert(gcdtmp >= 1);
5639 
5640  if( gcdtmp == 1 )
5641  {
5642  infcheckvars[ninfcheckvars] = consdata->vars[v];
5643  infcheckvals[ninfcheckvars] = consdata->vals[v];
5644 
5645  ++ninfcheckvars;
5646 
5647  if( pos == -1 )
5648  pos = v;
5649  }
5650  else
5651  gcd = gcdtmp;
5652  }
5653  }
5654  assert(gcd >= 2);
5655 
5656  /* it should not happen that all variables are of integral type and have a gcd >= 2, this should be done by
5657  * normalizeCons() */
5658  if( ninfcheckvars == 0 )
5659  goto TERMINATE;
5660 
5661  assert(pos >= 0);
5662 
5663  minactinfvarsinvalid = FALSE;
5664  maxactinfvarsinvalid = FALSE;
5665  maxactinfvars = 0.0;
5666  minactinfvars = 0.0;
5667 
5668  /* calculate activities over all infcheckvars */
5669  for( v = ninfcheckvars - 1; v >= 0; --v )
5670  {
5671  lb = SCIPvarGetLbLocal(infcheckvars[v]);
5672  ub = SCIPvarGetUbLocal(infcheckvars[v]);
5673 
5674  if( SCIPisInfinity(scip, -lb) )
5675  {
5676  if( infcheckvals[v] < 0.0 )
5677  maxactinfvarsinvalid = TRUE;
5678  else
5679  minactinfvarsinvalid = TRUE;
5680  }
5681  else
5682  {
5683  if( infcheckvals[v] < 0.0 )
5684  maxactinfvars += infcheckvals[v] * lb;
5685  else
5686  minactinfvars += infcheckvals[v] * lb;
5687  }
5688 
5689  if( SCIPisInfinity(scip, ub) )
5690  {
5691  if( infcheckvals[v] > 0.0 )
5692  maxactinfvarsinvalid = TRUE;
5693  else
5694  minactinfvarsinvalid = TRUE;
5695  }
5696  else
5697  {
5698  if( infcheckvals[v] > 0.0 )
5699  maxactinfvars += infcheckvals[v] * ub;
5700  else
5701  minactinfvars += infcheckvals[v] * ub;
5702  }
5703 
5704  /* better abort on to big values */
5705  if( SCIPisHugeValue(scip, -minactinfvars) )
5706  minactinfvarsinvalid = TRUE;
5707  if( SCIPisHugeValue(scip, maxactinfvars) )
5708  maxactinfvarsinvalid = TRUE;
5709 
5710  if( minactinfvarsinvalid || maxactinfvarsinvalid )
5711  goto TERMINATE;
5712  }
5713  assert(!minactinfvarsinvalid && !maxactinfvarsinvalid);
5714 
5715  SCIPdebugMessage("minactinfvarsinvalid = %u, minactinfvars = %g, maxactinfvarsinvalid = %u, maxactinfvars = %g, gcd = %lld, ninfcheckvars = %d, ncontvars = %d\n",
5716  minactinfvarsinvalid, minactinfvars, maxactinfvarsinvalid, maxactinfvars, gcd, ninfcheckvars, ncontvars);
5717 
5718  /* @todo maybe we took the wrong variables as infcheckvars we could try to exchange integer variables */
5719  /* @todo if minactinfvarsinvalid or maxactinfvarsinvalid are true, try to exchange both partitions to maybe get valid
5720  * activities */
5721  /* @todo calculate minactivity and maxactivity for all non-intcheckvars, and use this for better bounding,
5722  * !!!note!!!
5723  * that therefore the conflict variables in addConflictFixedVars() need to be extended by all variables which
5724  * are not at their global bound
5725  */
5726 
5727  /* check if between left hand side and right hand side exist a feasible point, if not the constraint leads to
5728  * infeasibility */
5729  if( !SCIPisIntegral(scip, (lhs - maxactinfvars) / gcd) &&
5730  SCIPisGT(scip, SCIPceil(scip, (lhs - maxactinfvars) / gcd) * gcd, rhs - minactinfvars) )
5731  {
5732  SCIPdebugMessage("no feasible value exist, constraint <%s> lead to infeasibility", SCIPconsGetName(cons));
5733  SCIPdebugPrintCons(scip, cons, NULL);
5734 
5735  /* start conflict analysis */
5736  /* @todo improve conflict analysis by adding relaxed bounds */
5737  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
5738 
5739  *cutoff = TRUE;
5740  }
5741  else if( ncontvars == 0 )
5742  {
5743  SCIP_Longint gcdinfvars = -1;
5744 
5745  /* check for gcd over all infcheckvars */
5746  if( possiblegcd )
5747  {
5748  v = ninfcheckvars - 1;
5749  gcdinfvars = (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol);
5750  assert(gcdinfvars >= 2);
5751 
5752  for( ; v >= 0 && gcdinfvars >= 2; --v )
5753  {
5754  gcdinfvars = SCIPcalcGreComDiv(gcdinfvars, (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol));
5755  }
5756  }
5757  else if( gcdisone )
5758  gcdinfvars = 1;
5759 
5760  SCIPdebugMessage("gcdinfvars =%lld, possiblegcd = %u\n", gcdinfvars, possiblegcd);
5761 
5762  /* compute solutions for this ranged row, if all variables are of integral type with integral coefficients */
5763  if( gcdinfvars >= 1 )
5764  {
5765  SCIP_Real value;
5766  SCIP_Real value2;
5767  SCIP_Real minvalue = SCIP_INVALID;
5768  SCIP_Real maxvalue = SCIP_INVALID;
5769  int nsols = 0;
5770 
5771  value = minactinfvars;
5772 
5773  /* check how many possible solutions exist */
5774  while( SCIPisLE(scip, value, maxactinfvars) )
5775  {
5776  value2 = value + gcd * (SCIPceil(scip, (lhs - value) / gcd));
5777 
5778  if( SCIPisGE(scip, value2, lhs) && SCIPisLE(scip, value2, rhs) )
5779  {
5780  ++nsols;
5781 
5782  /* early termination if we found more than two solutions */
5783  if( nsols == 3 )
5784  break;
5785 
5786  if( minvalue == SCIP_INVALID ) /*lint !e777*/
5787  minvalue = value;
5788 
5789  maxvalue = value;
5790  }
5791  value += gcdinfvars;
5792  }
5793  assert(nsols < 2 || minvalue <= maxvalue);
5794 
5795  /* determine last possible solution for better bounding */
5796  if( nsols == 3 )
5797  {
5798  value = maxactinfvars;
5799 
5800  /* check how many possible solutions exist */
5801  while( SCIPisGE(scip, value, minactinfvars) )
5802  {
5803  value2 = value + gcd * (SCIPfloor(scip, (rhs - value) / gcd));
5804 
5805  if( SCIPisGE(scip, value2, lhs) && SCIPisLE(scip, value2, rhs) )
5806  {
5807  maxvalue = value;
5808  assert(maxvalue > minvalue);
5809  break;
5810  }
5811  value -= gcdinfvars;
5812  }
5813  }
5814 
5815  SCIPdebugMessage("here nsols %s %d, minsolvalue = %g, maxsolvalue = %g, ninfcheckvars = %d, nunfixedvars = %d\n",
5816  nsols > 2 ? ">=" : "=", nsols, minvalue, maxvalue, ninfcheckvars, nunfixedvars);
5817 
5818  /* no possible solution found */
5819  if( nsols == 0 )
5820  {
5821  SCIPdebugMessage("gcdinfvars = %lld, gcd = %lld, correctedlhs = %g, correctedrhs = %g\n",
5822  gcdinfvars, gcd, lhs, rhs);
5823  SCIPdebugMessage("no solution found; constraint <%s> lead to infeasibility\n", SCIPconsGetName(cons));
5824  SCIPdebugPrintCons(scip, cons, NULL);
5825 
5826  /* start conflict analysis */
5827  /* @todo improve conflict analysis by adding relaxed bounds */
5828  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
5829 
5830  *cutoff = TRUE;
5831  }
5832  /* if only one solution exist we can extract a new constraint or fix variables */
5833  else if( nsols == 1 )
5834  {
5835  assert(minvalue == maxvalue); /*lint !e777*/
5836 
5837  /* we can fix the only variable in our second set of variables */
5838  if( ninfcheckvars == 1 )
5839  {
5840  SCIP_Bool fixed;
5841 
5842  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
5843 
5844  SCIPdebugMessage("fixing single variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
5845  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]),
5846  SCIPvarGetUbLocal(infcheckvars[0]), maxvalue/infcheckvals[0]);
5847 
5848  /* fix variable to only possible value */
5849  SCIP_CALL( SCIPinferVarFixCons(scip, infcheckvars[0], maxvalue/infcheckvals[0], cons,
5850  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &fixed) );
5851 
5852  if( *cutoff )
5853  {
5854  /* start conflict analysis */
5855  /* @todo improve conflict analysis by adding relaxed bounds */
5856  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
5857  }
5858 
5859  if( fixed )
5860  ++(*nfixedvars);
5861  }
5862  else
5863  {
5864  /* check for exactly one unfixed variable which is not part of the infcheckvars */
5865  if( ninfcheckvars == nunfixedvars - 1 )
5866  {
5867  SCIP_Real bound;
5868  SCIP_Bool foundvar = FALSE;
5869  SCIP_Bool fixed;
5870  int w = 0;
5871 
5872  assert(ninfcheckvars > 0);
5873 
5874  /* find variable which is not an infcheckvar and fix it */
5875  for( v = 0; v < consdata->nvars - 1; ++v )
5876  {
5877  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5878  {
5879  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
5880  {
5881 #ifndef NDEBUG
5882  int v2 = v + 1;
5883  int w2 = w;
5884 
5885  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
5886 
5887  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
5888  {
5889  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
5890  continue;
5891 
5892  assert(consdata->vars[v2] == infcheckvars[w2]);
5893  ++w2;
5894  }
5895  assert(w2 == ninfcheckvars);
5896 #endif
5897  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
5898 
5899  foundvar = TRUE;
5900 
5901  if( consdata->vals[v] < 0 )
5902  {
5903  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
5904  }
5905  else
5906  {
5907  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
5908  }
5909 
5910  SCIPdebugMessage("fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
5911  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
5912  SCIPvarGetUbLocal(consdata->vars[v]), bound);
5913 
5914  /* fix variable to only possible value */
5915  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
5916  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
5917 
5918  if( *cutoff )
5919  {
5920  /* start conflict analysis */
5921  /* @todo improve conflict analysis by adding relaxed bounds */
5922  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
5923  consdata->vars[v], bound) );
5924  }
5925 
5926  if( fixed )
5927  ++(*nfixedvars);
5928 
5929  break;
5930  }
5931 
5932  ++w;
5933  }
5934  }
5935 
5936  /* maybe last variable was the not infcheckvar */
5937  if( !foundvar )
5938  {
5939  assert(v == consdata->nvars - 1);
5940  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
5941 
5942  if( consdata->vals[v] < 0 )
5943  {
5944  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
5945  }
5946  else
5947  {
5948  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
5949  }
5950 
5951  SCIPdebugMessage("fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
5952  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
5953  SCIPvarGetUbLocal(consdata->vars[v]), bound);
5954 
5955  /* fix variable to only possible value */
5956  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
5957  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
5958 
5959  if( *cutoff )
5960  {
5961  /* start conflict analysis */
5962  /* @todo improve conflict analysis by adding relaxed bounds */
5963  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
5964  consdata->vars[v], bound) );
5965  }
5966 
5967  if( fixed )
5968  ++(*nfixedvars);
5969  }
5970  }
5971  else if( !SCIPinProbing(scip) && SCIPgetDepth(scip) < 1 && !SCIPinRepropagation(scip) && addartconss &&
5972  (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
5973  {
5974  /* aggregation possible if we have two variables, but this will be done later on */
5975  SCIP_CONS* newcons;
5976  char name[SCIP_MAXSTRLEN];
5977 
5978  /* create, add, and release new artificial constraint */
5979  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
5980  ++conshdlrdata->naddconss;
5981 
5982  SCIPdebugMessage("adding artificial constraint %s\n", name);
5983 
5984  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals,
5985  maxvalue, maxvalue, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
5986  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
5987 
5988  SCIPdebugPrintCons(scip, newcons, NULL);
5989 
5990  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
5991 
5992  ++(*naddconss);
5993  }
5994  }
5995  }
5996  /* at least two solutions */
5997  else
5998  {
5999  /* @todo if we found more then one solution, we may reduced domains due to dualpresolving? */
6000 
6001  /* only one variable in the second set, so we can bound this variables */
6002  if( ninfcheckvars == 1 )
6003  {
6004  SCIP_Bool tightened;
6005  SCIP_Real newlb;
6006  SCIP_Real newub;
6007 
6008  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6009 
6010  if( infcheckvals[0] < 0 )
6011  {
6012  newlb = maxvalue/infcheckvals[0];
6013  newub = minvalue/infcheckvals[0];
6014  }
6015  else
6016  {
6017  newlb = minvalue/infcheckvals[0];
6018  newub = maxvalue/infcheckvals[0];
6019  }
6020  assert(newlb < newub);
6021 
6022  if( newlb > SCIPvarGetLbLocal(infcheckvars[0]) )
6023  {
6024  /* update lower bound of variable */
6025  SCIPdebugMessage("tightening lower bound of variable <%s> from %g to %g\n",
6026  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]), newlb);
6027 
6028  /* tighten variable lower bound to minimal possible value */
6029  SCIP_CALL( SCIPinferVarLbCons(scip, infcheckvars[0], newlb, cons,
6030  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6031 
6032  if( *cutoff )
6033  {
6034  /* start conflict analysis */
6035  /* @todo improve conflict analysis by adding relaxed bounds */
6036  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6037  }
6038 
6039  if( tightened )
6040  ++(*nchgbds);
6041  }
6042 
6043  if( newub < SCIPvarGetUbLocal(infcheckvars[0]) )
6044  {
6045  /* update upper bound of variable */
6046  SCIPdebugMessage("tightening upper bound of variable <%s> from %g to %g\n",
6047  SCIPvarGetName(infcheckvars[0]), SCIPvarGetUbLocal(infcheckvars[0]), newub);
6048 
6049  /* tighten variable upper bound to maximal possible value */
6050  SCIP_CALL( SCIPinferVarUbCons(scip, infcheckvars[0], newub, cons,
6051  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6052 
6053  if( *cutoff )
6054  {
6055  /* start conflict analysis */
6056  /* @todo improve conflict analysis by adding relaxed bounds */
6057  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6058  }
6059 
6060  if( tightened )
6061  ++(*nchgbds);
6062  }
6063  }
6064  /* check if we have only one not infcheckvars, if so we can tighten this variable */
6065  else if( ninfcheckvars == nunfixedvars - 1 )
6066  {
6067  SCIP_Bool foundvar = FALSE;
6068  SCIP_Bool tightened;
6069  SCIP_Real newlb;
6070  SCIP_Real newub;
6071  int w = 0;
6072 
6073  assert(ninfcheckvars > 0);
6074  assert(minvalue < maxvalue);
6075 
6076  /* find variable which is not an infcheckvar and fix it */
6077  for( v = 0; v < consdata->nvars - 1; ++v )
6078  {
6079  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6080  {
6081  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6082  {
6083 #ifndef NDEBUG
6084  int v2 = v + 1;
6085  int w2 = w;
6086 
6087  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6088 
6089  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6090  {
6091  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6092  continue;
6093 
6094  assert(consdata->vars[v2] == infcheckvars[w2]);
6095  ++w2;
6096  }
6097  assert(w2 == ninfcheckvars);
6098 #endif
6099 
6100  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6101  foundvar = TRUE;
6102 
6103  if( consdata->vals[v] < 0 )
6104  {
6105  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6106  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6107  }
6108  else
6109  {
6110  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6111  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6112  }
6113  assert(SCIPisLE(scip, newlb, newub));
6114 
6115  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6116  {
6117  /* update lower bound of variable */
6118  SCIPdebugMessage("tightening lower bound of variable <%s> from %g to %g\n",
6119  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6120 
6121  /* tighten variable lower bound to minimal possible value */
6122  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6123  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6124 
6125  if( *cutoff )
6126  {
6127  /* start conflict analysis */
6128  /* @todo improve conflict analysis by adding relaxed bounds */
6129  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6130  consdata->vars[v], newlb) );
6131  }
6132 
6133  if( tightened )
6134  ++(*nchgbds);
6135  }
6136 
6137  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6138  {
6139  /* update upper bound of variable */
6140  SCIPdebugMessage("tightening upper bound of variable <%s> from %g to %g\n",
6141  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6142 
6143  /* tighten variable upper bound to maximal possible value */
6144  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6145  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6146 
6147  if( *cutoff )
6148  {
6149  /* start conflict analysis */
6150  /* @todo improve conflict analysis by adding relaxed bounds */
6151  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6152  consdata->vars[v], newub) );
6153  }
6154 
6155  if( tightened )
6156  ++(*nchgbds);
6157  }
6158 
6159  break;
6160  }
6161 
6162  ++w;
6163  }
6164  }
6165 
6166  /* maybe last variable was the not infcheckvar */
6167  if( !foundvar )
6168  {
6169  assert(v == consdata->nvars - 1);
6170  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6171 
6172  if( consdata->vals[v] < 0 )
6173  {
6174  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6175  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6176  }
6177  else
6178  {
6179  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6180  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6181  }
6182  assert(SCIPisLE(scip, newlb, newub));
6183 
6184  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6185  {
6186  /* update lower bound of variable */
6187  SCIPdebugMessage("tightening lower bound of variable <%s> from %g to %g\n",
6188  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6189 
6190  /* tighten variable lower bound to minimal possible value */
6191  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6192  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6193 
6194  if( *cutoff )
6195  {
6196  /* start conflict analysis */
6197  /* @todo improve conflict analysis by adding relaxed bounds */
6198  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newlb) );
6199  }
6200 
6201  if( tightened )
6202  ++(*nchgbds);
6203  }
6204 
6205  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6206  {
6207  /* update upper bound of variable */
6208  SCIPdebugMessage("tightening upper bound of variable <%s> from %g to %g\n",
6209  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6210 
6211  /* tighten variable upper bound to maximal possible value */
6212  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6213  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6214 
6215  if( *cutoff )
6216  {
6217  /* start conflict analysis */
6218  /* @todo improve conflict analysis by adding relaxed bounds */
6219  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newub) );
6220  }
6221 
6222  if( tightened )
6223  ++(*nchgbds);
6224  }
6225  }
6226  }
6227  /* at least two solutions and more than one variable, so we add a new constraint which bounds the feasible
6228  * region for our infcheckvars, if possible
6229  */
6230  else if( !SCIPinProbing(scip) && SCIPgetDepth(scip) < 1 && !SCIPinRepropagation(scip) && addartconss &&
6231  (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6232  {
6233  SCIP_CONS* newcons;
6234  char name[SCIP_MAXSTRLEN];
6235  SCIP_Real newlhs;
6236  SCIP_Real newrhs;
6237 
6238  assert(maxvalue > minvalue);
6239 
6240  if( SCIPisGT(scip, minvalue, minactinfvars) )
6241  newlhs = minvalue;
6242  else
6243  newlhs = -SCIPinfinity(scip);
6244 
6245  if( SCIPisLT(scip, maxvalue, maxactinfvars) )
6246  newrhs = maxvalue;
6247  else
6248  newrhs = SCIPinfinity(scip);
6249 
6250  if( !SCIPisInfinity(scip, -newlhs) || !SCIPisInfinity(scip, newrhs) )
6251  {
6252  /* create, add, and release new artificial constraint */
6253  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons1_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6254  ++conshdlrdata->naddconss;
6255 
6256  SCIPdebugMessage("adding artificial constraint %s\n", name);
6257 
6258  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6259  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6260  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6261 
6262  SCIPdebugPrintCons(scip, newcons, NULL);
6263  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6264 
6265  ++(*naddconss);
6266  }
6267  /* @todo maybe add constraint for all variables which are not infcheckvars, lhs should be minvalue, rhs
6268  * should be maxvalue */
6269  }
6270  }
6271  }
6272  }
6273  else if( ncontvars < ninfcheckvars && !SCIPinProbing(scip) && SCIPgetDepth(scip) < 1 )
6274  {
6275  SCIP_Real maxact = 0.0;
6276  SCIP_Real minact = 0.0;
6277  int w = 0;
6278 
6279  /* compute activities of non-infcheckvars */
6280  for( v = 0; v < consdata->nvars; ++v )
6281  {
6282  if( w < ninfcheckvars && consdata->vars[v] == infcheckvars[w] )
6283  {
6284  ++w;
6285  continue;
6286  }
6287 
6288  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6289  {
6290  if( SCIPvarIsBinary(consdata->vars[v]) )
6291  {
6292  if( consdata->vals[v] > 0.0 )
6293  maxact += consdata->vals[v];
6294  else
6295  minact += consdata->vals[v];
6296  }
6297  else
6298  {
6299  SCIP_Real tmpval;
6300 
6301  assert(SCIPvarIsIntegral(consdata->vars[v]));
6302 
6303  if( consdata->vals[v] > 0.0 )
6304  {
6305  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6306 
6307  if( SCIPisHugeValue(scip, -tmpval) )
6308  break;
6309 
6310  minact += tmpval;
6311 
6312  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6313 
6314  if( SCIPisHugeValue(scip, tmpval) )
6315  break;
6316 
6317  maxact += tmpval;
6318  }
6319  else
6320  {
6321  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6322 
6323  if( SCIPisHugeValue(scip, -tmpval) )
6324  break;
6325 
6326  minact += tmpval;
6327 
6328  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6329 
6330  if( SCIPisHugeValue(scip, tmpval) )
6331  break;
6332 
6333  maxact += tmpval;
6334  }
6335  }
6336  }
6337  }
6338  if( !SCIPinProbing(scip) && SCIPgetDepth(scip) < 1 && !SCIPinRepropagation(scip) && v == consdata->nvars
6339  && addartconss && !SCIPisHugeValue(scip, -minact) && !SCIPisHugeValue(scip, maxact) )
6340  {
6341  SCIP_CONS* newcons;
6342  char name[SCIP_MAXSTRLEN];
6343  SCIP_Real newlhs;
6344  SCIP_Real newrhs;
6345 
6346  assert(maxact > minact);
6347  assert(w == ninfcheckvars);
6348 
6349  newlhs = lhs - maxact;
6350  newrhs = rhs - minact;
6351  assert(newlhs < newrhs);
6352 
6353  /* create, add, and release new artificial constraint */
6354  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons2_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6355  ++conshdlrdata->naddconss;
6356 
6357  SCIPdebugMessage("adding artificial constraint %s\n", name);
6358 
6359  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6360  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6361  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6362 
6363  SCIPdebugPrintCons(scip, newcons, NULL);
6364  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6365 
6366  ++(*naddconss);
6367  }
6368  }
6369 
6370  TERMINATE:
6371  SCIPfreeBufferArray(scip, &infcheckvals);
6372  SCIPfreeBufferArray(scip, &infcheckvars);
6373 
6374  consdata->rangedrowpropagation = TRUE;
6375 
6376  return SCIP_OKAY;
6377 }
6378 
6379 /** tightens bounds of a single variable due to activity bounds */
6380 static
6382  SCIP* scip, /**< SCIP data structure */
6383  SCIP_CONS* cons, /**< linear constraint */
6384  int pos, /**< position of the variable in the vars array */
6385  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
6386  int* nchgbds, /**< pointer to count the total number of tightened bounds */
6387  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
6388  )
6389 {
6390  SCIP_CONSDATA* consdata;
6391  SCIP_VAR* var;
6392  SCIP_Real val;
6393  SCIP_Real lb;
6394  SCIP_Real ub;
6395  SCIP_Real minresactivity;
6396  SCIP_Real maxresactivity;
6398  SCIP_Real rhs;
6399  SCIP_Bool infeasible;
6400  SCIP_Bool tightened;
6401  SCIP_Bool minisrelax;
6402  SCIP_Bool maxisrelax;
6403  SCIP_Bool isminsettoinfinity;
6404  SCIP_Bool ismaxsettoinfinity;
6405 
6406  assert(scip != NULL);
6407  assert(cons != NULL);
6408  assert(cutoff != NULL);
6409  assert(nchgbds != NULL);
6410 
6411  /* we cannot tighten variables' bounds, if the constraint may be not complete */
6412  if( SCIPconsIsModifiable(cons) )
6413  return SCIP_OKAY;
6414 
6415  consdata = SCIPconsGetData(cons);
6416  assert(consdata != NULL);
6417  assert(0 <= pos && pos < consdata->nvars);
6418 
6419  *cutoff = FALSE;
6420 
6421  var = consdata->vars[pos];
6422 
6423  /* we cannot tighten bounds of multi-aggregated variables */
6425  return SCIP_OKAY;
6426 
6427  val = consdata->vals[pos];
6428  lhs = consdata->lhs;
6429  rhs = consdata->rhs;
6430  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
6431  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
6432  assert(var != NULL);
6433  assert(!SCIPisZero(scip, val));
6434  assert(!SCIPisInfinity(scip, lhs));
6435  assert(!SCIPisInfinity(scip, -rhs));
6436 
6437  lb = SCIPvarGetLbLocal(var);
6438  ub = SCIPvarGetUbLocal(var);
6439  assert(SCIPisLE(scip, lb, ub));
6440 
6441  if( val > 0.0 )
6442  {
6443  /* check, if we can tighten the variable's bounds */
6444  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6445  {
6446  SCIP_Real newub;
6447 
6448  newub = (rhs - minresactivity)/val;
6449 
6450  if( !SCIPisInfinity(scip, newub) &&
6451  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
6452  {
6453  SCIP_Bool activityunreliable;
6454  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6455 
6456  /* check minresactivities for reliability */
6457  if( activityunreliable )
6458  {
6459  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6460  newub = (rhs - minresactivity)/val;
6461  activityunreliable = SCIPisInfinity(scip, -minresactivity) ||
6462  (!SCIPisUbBetter(scip, newub, lb, ub) && (!SCIPisFeasLT(scip, newub, ub) || !SCIPvarIsIntegral(var))
6463  && (!force || !SCIPisLT(scip, newub, ub)));
6464  }
6465 
6466  if( !activityunreliable )
6467  {
6468  /* tighten upper bound */
6469  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
6470  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
6471  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6472  &infeasible, &tightened) );
6473  if( infeasible )
6474  {
6475  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6476  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
6477 
6478  /* analyze conflict */
6479  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6480 
6481  *cutoff = TRUE;
6482  return SCIP_OKAY;
6483  }
6484  if( tightened )
6485  {
6486  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6487  assert(SCIPisFeasLE(scip, ub, newub));
6488  (*nchgbds)++;
6489 
6490  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6491  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6492  }
6493  }
6494  }
6495  }
6496 
6497  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
6498  {
6499  SCIP_Real newlb;
6500 
6501  newlb = (lhs - maxresactivity)/val;
6502  if( !SCIPisInfinity(scip, -newlb) &&
6503  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6504  {
6505  /* check maxresactivities for reliability */
6506  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
6507  {
6508  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
6509  newlb = (lhs - maxresactivity)/val;
6510 
6511  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisLbBetter(scip, newlb, lb, ub)
6512  && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6513  && (!force || !SCIPisGT(scip, newlb, lb))) )
6514  return SCIP_OKAY;
6515  }
6516 
6517  /* tighten lower bound */
6518  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6519  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6520  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_LHS, pos), force,
6521  &infeasible, &tightened) );
6522  if( infeasible )
6523  {
6524  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6525  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6526 
6527  /* analyze conflict */
6528  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
6529 
6530  *cutoff = TRUE;
6531  return SCIP_OKAY;
6532  }
6533  if( tightened )
6534  {
6535  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6536  assert(SCIPisFeasGE(scip, lb, newlb));
6537  (*nchgbds)++;
6538  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6539  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6540  }
6541  }
6542  }
6543  }
6544  else
6545  {
6546  /* check, if we can tighten the variable's bounds */
6547  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6548  {
6549  SCIP_Real newlb;
6550 
6551  newlb = (rhs - minresactivity)/val;
6552  if( !SCIPisInfinity(scip, -newlb) &&
6553  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6554  {
6555  SCIP_Bool activityunreliable;
6556  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6557  /* check minresactivities for reliability */
6558  if( activityunreliable )
6559  {
6560  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6561  newlb = (rhs - minresactivity)/val;
6562 
6563  activityunreliable = SCIPisInfinity(scip, -minresactivity)
6564  || (!SCIPisLbBetter(scip, newlb, lb, ub) && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6565  && (!force || !SCIPisGT(scip, newlb, lb)));
6566  }
6567 
6568  if( !activityunreliable )
6569  {
6570  /* tighten lower bound */
6571  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6572  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6573  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6574  &infeasible, &tightened) );
6575  if( infeasible )
6576  {
6577  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6578  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6579 
6580  /* analyze conflict */
6581  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6582 
6583  *cutoff = TRUE;
6584  return SCIP_OKAY;
6585  }
6586  if( tightened )
6587  {
6588  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6589  assert(SCIPisFeasGE(scip, lb, newlb));
6590  (*nchgbds)++;
6591  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6592  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6593  }
6594  }
6595  }
6596  }
6597 
6598  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
6599  {
6600  SCIP_Real newub;
6601 
6602  newub = (lhs - maxresactivity)/val;
6603  if( !SCIPisInfinity(scip, newub) &&
6604  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
6605  {
6606  /* check maxresactivities for reliability */
6607  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
6608  {
6609  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
6610  newub = (lhs - maxresactivity)/val;
6611 
6612  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisUbBetter(scip, newub, lb, ub)
6613  && (!SCIPisFeasLT(scip, newub, ub) && !SCIPvarIsIntegral(var))
6614  && (!force || !SCIPisLT(scip, newub, ub))) )
6615  return SCIP_OKAY;
6616  }
6617 
6618  /* tighten upper bound */
6619  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g], newub=%.15g\n",
6620  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
6621  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_LHS, pos), force,
6622  &infeasible, &tightened) );
6623  if( infeasible )
6624  {
6625  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6626  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
6627 
6628  /* analyze conflict */
6629  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
6630 
6631  *cutoff = TRUE;
6632  return SCIP_OKAY;
6633  }
6634  if( tightened )
6635  {
6636  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6637  assert(SCIPisFeasLE(scip, ub, newub));
6638  (*nchgbds)++;
6639  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6640  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6641  }
6642  }
6643  }
6644  }
6645 
6646  return SCIP_OKAY;
6647 }
6648 
6649 #define MAXTIGHTENROUNDS 10
6650 
6651 /** tightens bounds of variables in constraint due to activity bounds */
6652 static
6654  SCIP* scip, /**< SCIP data structure */
6655  SCIP_CONS* cons, /**< linear constraint */
6656  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
6657  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
6658  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
6659  int* nchgbds /**< pointer to count the total number of tightened bounds */
6660  )
6661 {
6662  SCIP_CONSDATA* consdata;
6663  int nvars;
6664  int nrounds;
6665  int lastchange;
6666  int oldnchgbds;
6667  int v;
6668  SCIP_Bool force;
6669  SCIP_Bool easycase;
6670 
6671  assert(scip != NULL);
6672  assert(cons != NULL);
6673  assert(nchgbds != NULL);
6674  assert(cutoff != NULL);
6675 
6676  *cutoff = FALSE;
6677 
6678  /* we cannot tighten variables' bounds, if the constraint may be not complete */
6679  if( SCIPconsIsModifiable(cons) )
6680  return SCIP_OKAY;
6681 
6682  /* if a constraint was created after presolve, then it may hold fixed variables
6683  * if there are even multi-aggregated variables, then we cannot do bound tightening on these
6684  * thus, ensure here again that variable fixings have been applied
6685  */
6686  SCIP_CALL( applyFixings(scip, cons, cutoff) );
6687  if( *cutoff )
6688  return SCIP_OKAY;
6689 
6690  /* check if constraint has any chances of tightening bounds */
6691  if( !canTightenBounds(scip, cons) )
6692  return SCIP_OKAY;
6693 
6694  consdata = SCIPconsGetData(cons);
6695  assert(consdata != NULL);
6696 
6697  nvars = consdata->nvars;
6698  force = (nvars == 1) && !SCIPconsIsModifiable(cons);
6699 
6700  /* ensure that the variables are properly sorted */
6701  if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->binvarssorted )
6702  {
6703  SCIP_CALL( consdataSort(scip, consdata) );
6704  assert(consdata->binvarssorted);
6705  }
6706 
6707  /* update maximal activity delta if necessary */
6708  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
6709  consdataRecomputeMaxActivityDelta(scip, consdata);
6710 
6711  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
6712  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
6713  checkMaxActivityDelta(scip, consdata);
6714 
6715  /* this may happen if all variables are fixed */
6716  if( SCIPisFeasZero(scip, consdata->maxactdelta) )
6717  return SCIP_OKAY;
6718 
6719  if( !SCIPisInfinity(scip, consdata->maxactdelta) )
6720  {
6721  SCIP_Real slack;
6722  SCIP_Real surplus;
6723  SCIP_Real minactivity;
6724  SCIP_Real maxactivity;
6725  SCIP_Bool minisrelax;
6726  SCIP_Bool maxisrelax;
6727 
6728  /* use maximal activity delta to skip propagation (cannot deduce anything) */
6729  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minisrelax, &maxisrelax);
6730  assert(!SCIPisInfinity(scip, minactivity));
6731  assert(!SCIPisInfinity(scip, -maxactivity));
6732 
6733  slack = (SCIPisInfinity(scip, consdata->rhs) || SCIPisInfinity(scip, -minactivity)) ? SCIPinfinity(scip) : (consdata->rhs - minactivity);
6734  surplus = (SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, maxactivity)) ? SCIPinfinity(scip) : (maxactivity - consdata->lhs);
6735 
6736  /* check if the constraint will propagate */
6737  if( SCIPisLE(scip, consdata->maxactdelta, MIN(slack, surplus)) )
6738  return SCIP_OKAY;
6739  }
6740 
6741  /* check if we can use fast implementation for easy and numerically well behaved cases */
6742  easycase = SCIPisLT(scip, consdata->maxactdelta, maxeasyactivitydelta);
6743 
6744  /* as long as the bounds might be tightened again, try to tighten them; abort after a maximal number of rounds */
6745  lastchange = -1;
6746  for( nrounds = 0; (force || !consdata->boundstightened) && nrounds < MAXTIGHTENROUNDS; ++nrounds )
6747  {
6748  /* mark the constraint to have the variables' bounds tightened */
6749  consdata->boundstightened = TRUE;
6750 
6751  /* try to tighten the bounds of each variable in the constraint. During solving process, the binary variable
6752  * sorting enables skipping variables
6753  */
6754  v = 0;
6755  while( v < nvars && v != lastchange && !(*cutoff) )
6756  {
6757  oldnchgbds = *nchgbds;
6758 
6759  assert(!sortvars || SCIPgetStage(scip) < SCIP_STAGE_SOLVING || consdata->binvarssorted);
6760 
6761  if( easycase )
6762  {
6763  SCIP_CALL( tightenVarBoundsEasy(scip, cons, v, cutoff, nchgbds, force) );
6764  }
6765  else
6766  {
6767  SCIP_CALL( tightenVarBounds(scip, cons, v, cutoff, nchgbds, force) );
6768  }
6769 
6770  /* if there was no progress, skip the rest of the binary variables */
6771  if( *nchgbds > oldnchgbds )
6772  {
6773  lastchange = v;
6774  ++v;
6775  }
6776  else if( consdata->binvarssorted && v < consdata->nbinvars - 1
6777  && !SCIPisFeasEQ(scip, SCIPvarGetUbLocal(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v])) )
6778  v = consdata->nbinvars;
6779  else
6780  ++v;
6781  }
6782  }
6783 
6784 #ifndef NDEBUG
6785  if( force && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
6786  assert(*cutoff || SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->vars[0]), SCIPvarGetUbLocal(consdata->vars[0])));
6787 #endif
6788 
6789  return SCIP_OKAY;
6790 }
6791 
6792 /** checks linear constraint for feasibility of given solution or current solution */
6793 static
6795  SCIP* scip, /**< SCIP data structure */
6796  SCIP_CONS* cons, /**< linear constraint */
6797  SCIP_SOL* sol, /**< solution to be checked, or NULL for current solution */
6798  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
6799  SCIP_Bool checkrelmaxabs, /**< Should the violation for a constraint with side 0.0 be checked relative
6800  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
6801  SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
6802  )
6803 {
6804  SCIP_CONSDATA* consdata;
6805  SCIP_Real activity;
6806 
6807  assert(scip != NULL);
6808  assert(cons != NULL);
6809  assert(violated != NULL);
6811  SCIPdebugMessage("checking linear constraint <%s>\n", SCIPconsGetName(cons));
6812  SCIPdebugPrintCons(scip, cons, NULL);
6813 
6814  consdata = SCIPconsGetData(cons);
6815  assert(consdata != NULL);
6816 
6817  *violated = FALSE;
6818 
6819  if( consdata->row != NULL )
6820  {
6821  if( !checklprows && SCIProwIsInLP(consdata->row) )
6822  return SCIP_OKAY;
6823  else if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
6824  activity = consdataComputePseudoActivity(scip, consdata);
6825  else
6826  activity = SCIPgetRowSolActivity(scip, consdata->row, sol);
6827  }
6828  else
6829  activity = consdataGetActivity(scip, consdata, sol);
6830 
6831  SCIPdebugMessage(" consdata activity=%.15g (lhs=%.15g, rhs=%.15g, row=%p, checklprows=%u, rowinlp=%u, sol=%p, hascurrentnodelp=%u)\n",
6832  activity, consdata->lhs, consdata->rhs, (void*)consdata->row, checklprows,
6833  consdata->row == NULL ? 0 : SCIProwIsInLP(consdata->row), (void*)sol,
6834  consdata->row == NULL ? FALSE : SCIPhasCurrentNodeLP(scip));
6835 
6836  /* the activity of pseudo solutions may be invalid if it comprises positive and negative infinity contributions; we
6837  * return infeasible for safety
6838  */
6839  if( activity == SCIP_INVALID ) /*lint !e777*/
6840  {
6841  assert(sol == NULL);
6842  *violated = TRUE;
6843 
6844  /* reset constraint age since we are in enforcement */
6845  SCIP_CALL( SCIPresetConsAge(scip, cons) );
6846  }
6847  else if( SCIPisFeasLT(scip, activity, consdata->lhs) || SCIPisFeasGT(scip, activity, consdata->rhs) )
6848  {
6849  /* the "normal" check: one of the two sides is violated */
6850  if( !checkrelmaxabs )
6851  {
6852  *violated = TRUE;
6853 
6854  /* only reset constraint age if we are in enforcement */
6855  if( sol == NULL )
6856  {
6857  SCIP_CALL( SCIPresetConsAge(scip, cons) );
6858  }
6859  }
6860  /* the (much) more complicated check: we try to disregard random noise and violations of a 0.0 side which are
6861  * small compared to the absolute values occuring in the activity
6862  */
6863  else
6864  {
6865  SCIP_Real maxabs;
6866  SCIP_Real coef;
6867  SCIP_Real absval;
6868  SCIP_Real solval;
6869  int v;
6870 
6871  maxabs = 1.0;
6872 
6873  /* compute maximum absolute value */
6874  for( v = 0; v < consdata->nvars; ++v )
6875  {
6876  if( consdata->vals != NULL )
6877  {
6878  coef = consdata->vals[v];
6879  }
6880  else
6881  coef = 1.0;
6882 
6883  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
6884  absval = REALABS( coef * solval );
6885  maxabs = MAX( maxabs, absval );
6886  }
6887 
6888  /* regard left hand side, first */
6889  if( SCIPisFeasLT(scip, activity, consdata->lhs) )
6890  {
6891  /* check whether violation is random noise */
6892  if( (consdata->lhs - activity) <= (1e-15 * maxabs) )
6893  {
6894  SCIPdebugMessage(" lhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
6895  consdata->lhs - activity, maxabs);
6896  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
6897 
6898  /* only increase constraint age if we are in enforcement */
6899  if( sol == NULL )
6900  {
6901  SCIP_CALL( SCIPincConsAge(scip, cons) );
6902  }
6903  }
6904  /* lhs is violated and lhs is 0.0: use relative tolerance w.r.t. largest absolute value */
6905  else if( SCIPisZero(scip, consdata->lhs) )
6906  {
6907  if( (consdata->lhs - activity) <= (SCIPfeastol(scip) * maxabs) )
6908  {
6909  SCIPdebugMessage(" lhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
6910  consdata->lhs - activity, maxabs);
6911  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
6912 
6913  /* only increase constraint age if we are in enforcement */
6914  if( sol == NULL )
6915  {
6916  SCIP_CALL( SCIPincConsAge(scip, cons) );
6917  }
6918  }
6919  else
6920  {
6921  *violated = TRUE;
6922 
6923  /* only reset constraint age if we are in enforcement */
6924  if( sol == NULL )
6925  {
6926  SCIP_CALL( SCIPresetConsAge(scip, cons) );
6927  }
6928  }
6929  }
6930  else
6931  {
6932  *violated = TRUE;
6933 
6934  /* only reset constraint age if we are in enforcement */
6935  if( sol == NULL )
6936  {
6937  SCIP_CALL( SCIPresetConsAge(scip, cons) );
6938  }
6939  }
6940  }
6941 
6942  /* now regard right hand side */
6943  if( SCIPisFeasGT(scip, activity, consdata->rhs) )
6944  {
6945  /* check whether violation is random noise */
6946  if( (activity - consdata->rhs) <= (1e-15 * maxabs) )
6947  {
6948  SCIPdebugMessage(" rhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
6949  activity - consdata->rhs, maxabs);
6950  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
6951 
6952  /* only increase constraint age if we are in enforcement */
6953  if( sol == NULL )
6954  {
6955  SCIP_CALL( SCIPincConsAge(scip, cons) );
6956  }
6957  }
6958  /* rhs is violated and rhs is 0.0, use relative tolerance w.r.t. largest absolute value */
6959  else if( SCIPisZero(scip, consdata->rhs) )
6960  {
6961  if( (activity - consdata->rhs) <= (SCIPfeastol(scip) * maxabs) )
6962  {
6963  SCIPdebugMessage(" rhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
6964  activity - consdata->rhs, maxabs);
6965  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
6966 
6967  /* only increase constraint age if we are in enforcement */
6968  if( sol == NULL )
6969  {
6970  SCIP_CALL( SCIPincConsAge(scip, cons) );
6971  }
6972  }
6973  else
6974  {
6975  *violated = TRUE;
6976 
6977  /* only reset constraint age if we are in enforcement */
6978  if( sol == NULL )
6979  {
6980  SCIP_CALL( SCIPresetConsAge(scip, cons) );
6981  }
6982  }
6983  }
6984  else
6985  {
6986  *violated = TRUE;
6987 
6988  /* only reset constraint age if we are in enforcement */
6989  if( sol == NULL )
6990  {
6991  SCIP_CALL( SCIPresetConsAge(scip, cons) );
6992  }
6993  }
6994  }
6995  }
6996  }
6997  else
6998  {
6999  /* only increase constraint age if we are in enforcement */
7000  if( sol == NULL )
7001  {
7002  SCIP_CALL( SCIPincConsAge(scip, cons) );
7003  }
7004  }
7005 
7006  return SCIP_OKAY;
7007 }
7008 
7009 /** creates an LP row in a linear constraint data */
7010 static
7012  SCIP* scip, /**< SCIP data structure */
7013  SCIP_CONS* cons /**< linear constraint */
7014  )
7015 {
7016  SCIP_CONSDATA* consdata;
7017 
7018  assert(scip != NULL);
7019  assert(cons != NULL);
7020 
7021  consdata = SCIPconsGetData(cons);
7022  assert(consdata != NULL);
7023  assert(consdata->row == NULL);
7024 
7025  SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, SCIPconsGetHdlr(cons), SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
7028  SCIP_CALL( SCIPaddVarsToRow(scip, consdata->row, consdata->nvars, consdata->vars, consdata->vals) );
7029 
7030  return SCIP_OKAY;
7031 }
7032 
7033 /** adds linear constraint as cut to the LP */
7034 static
7036  SCIP* scip, /**< SCIP data structure */
7037  SCIP_CONS* cons, /**< linear constraint */
7038  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
7039  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7040  )
7041 {
7042  SCIP_CONSDATA* consdata;
7043 
7044  assert(scip != NULL);
7045  assert(cons != NULL);
7046 
7047  consdata = SCIPconsGetData(cons);
7048  assert(consdata != NULL);
7049 
7050  if( consdata->row == NULL )
7051  {
7052  /* convert consdata object into LP row */
7053  SCIP_CALL( createRow(scip, cons) );
7054  }
7055  assert(consdata->row != NULL);
7056 
7057  /* insert LP row as cut */
7058  if( !SCIProwIsInLP(consdata->row) )
7059  {
7060  SCIPdebugMessage("adding relaxation of linear constraint <%s>: ", SCIPconsGetName(cons));
7061  SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->row, NULL)) );
7062  /* if presolving is turned off, the row might be trivial */
7063  if ( ! SCIPisInfinity(scip, -consdata->lhs) || ! SCIPisInfinity(scip, consdata->rhs) )
7064  {
7065  SCIP_CALL( SCIPaddCut(scip, sol, consdata->row, FALSE, cutoff) );
7066  }
7067 #ifndef NDEBUG
7068  else
7069  {
7070  int pr;
7071  int cr;
7072  SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrounds", &pr) );
7073  SCIP_CALL( SCIPgetIntParam(scip, "constraints/linear/maxprerounds", &cr) );
7074  assert( pr == 0 || cr == 0 );
7075  }
7076 #endif
7077  }
7078 
7079  return SCIP_OKAY;
7080 }
7081 
7082 /** separates linear constraint: adds linear constraint as cut, if violated by given solution */
7083 static
7085  SCIP* scip, /**< SCIP data structure */
7086  SCIP_CONS* cons, /**< linear constraint */
7087  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
7088  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
7089  SCIP_Bool separatecards, /**< should knapsack cardinality cuts be generated? */
7090  SCIP_Bool separateall, /**< should all constraints be subject to cardinality cut generation instead of only
7091  * the ones with non-zero dual value? */
7092  int* ncuts, /**< pointer to add up the number of found cuts */
7093  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7094  )
7095 {
7096  SCIP_CONSDATA* consdata;
7097  SCIP_Bool violated;
7098  int oldncuts;
7099 
7100  assert(scip != NULL);
7101  assert(conshdlrdata != NULL);
7102  assert(cons != NULL);
7103  assert(cutoff != NULL);
7104 
7105  consdata = SCIPconsGetData(cons);
7106  assert(ncuts != NULL);
7107  assert(consdata != NULL);
7108 
7109  oldncuts = *ncuts;
7110  *cutoff = FALSE;
7111 
7112  SCIP_CALL( checkCons(scip, cons, sol, (sol != NULL), conshdlrdata->checkrelmaxabs, &violated) );
7113 
7114  if( violated )
7115  {
7116  /* insert LP row as cut */
7117  SCIP_CALL( addRelaxation(scip, cons, sol, cutoff) );
7118  (*ncuts)++;
7119  }
7120  else if( !SCIPconsIsModifiable(cons) && separatecards )
7121  {
7122  /* relax linear constraint into knapsack constraint and separate lifted cardinality cuts */
7123  if( !separateall && sol == NULL )
7124  {
7125  /* we only want to call the knapsack cardinality cut separator for rows that have a non-zero dual solution */
7126  if( consdata->row != NULL && SCIProwIsInLP(consdata->row) )
7127  {
7128  SCIP_Real dualsol;
7129 
7130  dualsol = SCIProwGetDualsol(consdata->row);
7131  if( SCIPisFeasNegative(scip, dualsol) )
7132  {
7133  if( !SCIPisInfinity(scip, consdata->rhs) )
7134  {
7135  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7136  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7137  }
7138  }
7139  else if( SCIPisFeasPositive(scip, dualsol) )
7140  {
7141  if( !SCIPisInfinity(scip, -consdata->lhs) )
7142  {
7143  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7144  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7145  }
7146  }
7147  }
7148  }
7149  else
7150  {
7151  if( !SCIPisInfinity(scip, consdata->rhs) )
7152  {
7153  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7154  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7155  }
7156  if( !SCIPisInfinity(scip, -consdata->lhs) )
7157  {
7158  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7159  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7160  }
7161  }
7162  }
7163 
7164  if( *ncuts > oldncuts )
7165  {
7166  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7167  }
7168 
7169  return SCIP_OKAY;
7170 }
7171 
7172 /** propagation method for linear constraints */
7173 static
7175  SCIP* scip, /**< SCIP data structure */
7176  SCIP_CONS* cons, /**< linear constraint */
7177  SCIP_Bool tightenbounds, /**< should the variable's bounds be tightened? */
7178  SCIP_Bool rangedrowpropagation,/**< should ranged row propagation be performed? */
7179  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7180  SCIP_Bool sortvars, /**< should variable sorting for faster propagation be used? */
7181  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
7182  int* nchgbds /**< pointer to count the total number of tightened bounds */
7183  )
7184 {
7185  SCIP_CONSDATA* consdata;
7186  SCIP_Real minactivity;
7187  SCIP_Real maxactivity;
7188  SCIP_Bool minactisrelax;
7189  SCIP_Bool maxactisrelax;
7191  assert(scip != NULL);
7192  assert(cons != NULL);
7193  assert(cutoff != NULL);
7194  assert(nchgbds != NULL);
7195 
7196  /*SCIPdebugMessage("propagating linear constraint <%s>\n", SCIPconsGetName(cons));*/
7197 
7198  consdata = SCIPconsGetData(cons);
7199  assert(consdata != NULL);
7200 
7201  *cutoff = FALSE;
7202 
7203  /* check, if constraint is already propagated */
7204  if( consdata->propagated && (!tightenbounds || consdata->boundstightened) )
7205  return SCIP_OKAY;
7206 
7207  /* mark constraint as propagated */
7208  consdata->propagated = TRUE;
7209 
7210  /* we can only infer activity bounds of the linear constraint, if it is not modifiable */
7211  if( !SCIPconsIsModifiable(cons) )
7212  {
7213  /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
7214  if( !SCIPinRepropagation(scip) )
7215  {
7216  SCIP_CALL( SCIPincConsAge(scip, cons) );
7217  }
7218 
7219  /* tighten the variable's bounds */
7220  if( tightenbounds )
7221  {
7222  int oldnchgbds;
7223 
7224  oldnchgbds = *nchgbds;
7225 
7226  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7227 
7228  if( *nchgbds > oldnchgbds )
7229  {
7230  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7231  }
7232  }
7233 
7234  /* propagate ranged rows */
7235  if( rangedrowpropagation && tightenbounds && !(*cutoff) )
7236  {
7237  int nfixedvars;
7238  int naddconss;
7239  int oldnchgbds;
7240 
7241  nfixedvars = 0;
7242  naddconss = 0;
7243  oldnchgbds = *nchgbds;
7244 
7245  SCIP_CALL( rangedRowPropagation(scip, cons, cutoff, &nfixedvars, nchgbds, &naddconss) );
7246 
7247  if( *cutoff )
7248  {
7249  SCIPdebugMessage("linear constraint <%s> is infeasible\n", SCIPconsGetName(cons));
7250  }
7251  else
7252  {
7253  SCIPdebugMessage("linear constraint <%s> found %d bound changes and %d fixings\n", SCIPconsGetName(cons), *nchgbds - oldnchgbds, nfixedvars);
7254  }
7255 
7256  if( nfixedvars > 0 )
7257  *nchgbds += 2*nfixedvars;
7258  }
7259 
7260  /* check constraint for infeasibility and redundancy */
7261  if( !(*cutoff) )
7262  {
7263  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
7264 
7265  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) )
7266  {
7267  SCIPdebugMessage("linear constraint <%s> is infeasible (rhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7268  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7269 
7270  /* analyze conflict */
7271  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
7272 
7273  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7274  *cutoff = TRUE;
7275  }
7276  else if( SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
7277  {
7278  SCIPdebugMessage("linear constraint <%s> is infeasible (lhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7279  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7280 
7281  /* analyze conflict */
7282  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7283 
7284  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7285  *cutoff = TRUE;
7286  }
7287  else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
7288  {
7289  SCIPdebugMessage("linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7290  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7291  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
7292  }
7293  }
7294  }
7295 
7296  return SCIP_OKAY;
7297 }
7298 
7299 
7300 /*
7301  * Presolving methods
7302  */
7303 
7304 /** converts all variables with fixed domain into FIXED variables */
7305 static
7307  SCIP* scip, /**< SCIP data structure */
7308  SCIP_CONS* cons, /**< linear constraint */
7309  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
7310  int* nfixedvars /**< pointer to count the total number of fixed variables */
7311  )
7312 {
7313  SCIP_CONSDATA* consdata;
7314  SCIP_VAR* var;
7315  SCIP_VARSTATUS varstatus;
7316  SCIP_Real lb;
7317  SCIP_Real ub;
7318  SCIP_Bool fixed;
7319  SCIP_Bool infeasible;
7320  int v;
7321 
7322  assert(scip != NULL);
7323  assert(cons != NULL);
7324  assert(cutoff != NULL);
7325  assert(nfixedvars != NULL);
7326 
7327  consdata = SCIPconsGetData(cons);
7328  assert(consdata != NULL);
7329 
7330  for( v = 0; v < consdata->nvars; ++v )
7331  {
7332  assert(consdata->vars != NULL);
7333  var = consdata->vars[v];
7334  varstatus = SCIPvarGetStatus(var);
7335 
7336  if( varstatus != SCIP_VARSTATUS_FIXED )
7337  {
7338  lb = SCIPvarGetLbGlobal(var);
7339  ub = SCIPvarGetUbGlobal(var);
7340  if( SCIPisEQ(scip, lb, ub) )
7341  {
7342  SCIP_Real fixval;
7343 
7344  fixval = SCIPselectSimpleValue(lb, ub, MAXDNOM);
7345  SCIPdebugMessage("converting variable <%s> with fixed bounds [%.15g,%.15g] into fixed variable fixed at %.15g\n",
7346  SCIPvarGetName(var), lb, ub, fixval);
7347  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
7348  if( infeasible )
7349  {
7350  SCIPdebugMessage(" -> infeasible fixing\n");
7351  *cutoff = TRUE;
7352  return SCIP_OKAY;
7353  }
7354  if( fixed )
7355  (*nfixedvars)++;
7356  }
7357  }
7358  }
7359 
7360  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
7361 
7362  if( infeasible )
7363  {
7364  SCIPdebugMessage(" -> infeasible fixing\n");
7365  *cutoff = TRUE;
7366  return SCIP_OKAY;
7367  }
7368 
7369  assert(consdata->removedfixings);
7370 
7371  return SCIP_OKAY;
7372 }
7373 
7374 #define MAX_CLIQUE_NONZEROS_PER_CONS 1000000
7375 
7376 /** extracts cliques of the constraint and adds them to SCIP
7377  *
7378  * The following clique extraction mechanism are implemeneted
7379  *
7380  * 1. collect binary variables and sort them in non increasing order, then
7381  *
7382  * a) if the constraint has a finite right hand side and the negative infinity counters for the minactivity are zero
7383  * then add the variables as a clique for which all successive pairs of coefficients fullfill the following
7384  * condition
7385  *
7386  * minactivity + vals[i] + vals[i+1] > rhs
7387  *
7388  * and also add the binary to binary implication also for non-successive variables for which the same argument
7389  * holds
7390  *
7391  * minactivity + vals[i] + vals[j] > rhs
7392  *
7393  * 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
7394  * binary to binary implications x1 = 1 => x4 = 0 and x2 = 1 => x4 = 0
7395  *
7396  * b) if the constraint has a finite left hand side and the positive infinity counters for the maxactivity are zero
7397  * then add the variables as a clique for which all successive pairs of coefficients fullfill the follwoing
7398  * condition
7399  *
7400  * maxactivity + vals[i] + vals[i-1] < lhs
7401  *
7402  * and also add the binary to binary implication also for non-successive variables for which the same argument
7403  * holds
7404  *
7405  * maxactivity + vals[i] + vals[j] < lhs
7406  *
7407  * e.g. you could multiply the above example by -1
7408  *
7409  * c) the constraint has a finite right hand side and a finite minactivity then add the variables as a negated
7410  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7411  * condition
7412  *
7413  * minactivity - vals[i] - vals[i-1] > rhs
7414  *
7415  * and also add the binary to binary implication also for non-successive variables for which the
7416  * same argument holds
7417  *
7418  * minactivity - vals[i] - vals[j] > rhs
7419  *
7420  * e.g. -4 x1 -3 x2 - 2 x3 + 2 x4 <= -4 would lead to the (negated) clique (~x1, ~x2) and the binary to binary
7421  * implication x1 = 0 => x3 = 1
7422  *
7423  * d) the constraint has a finite left hand side and a finite maxactivity then add the variables as a negated
7424  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7425  * condition
7426  *
7427  * maxactivity - vals[i] - vals[i+1] < lhs
7428  *
7429  * and also add the binary to binary implication also for non-successive variables for which the same argument
7430  * holds
7431  *
7432  * maxactivity - vals[i] - vals[j] < lhs
7433  *
7434  * e.g. you could multiply the above example by -1
7435  *
7436  * 2. if the linear constraint represents a set-packing or set-partitioning constraint, the whole constraint is added
7437  * as clique, (this part is done at the end of the method)
7438  *
7439  */
7440 static
7442  SCIP* scip, /**< SCIP data structure */
7443  SCIP_CONS* cons, /**< linear constraint */
7444  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7445  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
7446  int* nfixedvars, /**< pointer to count number of fixed variables */
7447  int* nchgbds, /**< pointer to count the total number of tightened bounds */
7448  SCIP_Bool* cutoff /**< pointer to store TRUE, if a cutoff was found */
7449  )
7450 {
7451  SCIP_VAR** vars;
7452  SCIP_Real* vals;
7453  SCIP_CONSDATA* consdata;
7454  SCIP_Bool lhsclique;
7455  SCIP_Bool rhsclique;
7456  SCIP_Bool finitelhs;
7457  SCIP_Bool finiterhs;
7458  SCIP_Bool finiteminact;
7459  SCIP_Bool finitemaxact;
7460  SCIP_Bool finitenegminact;
7461  SCIP_Bool finitenegmaxact;
7462  SCIP_Bool finiteposminact;
7463  SCIP_Bool finiteposmaxact;
7464  SCIP_Bool infeasible;
7465  SCIP_Bool stopped;
7466  int cliquenonzerosadded;
7467  int v;
7468  int i;
7469  int nposcoefs;
7470  int nnegcoefs;
7471  int nvars;
7472 
7473  assert(scip != NULL);
7474  assert(cons != NULL);
7475  assert(nfixedvars != NULL);
7476  assert(nchgbds != NULL);
7477  assert(cutoff != NULL);
7478  assert(!SCIPconsIsDeleted(cons));
7479 
7480  consdata = SCIPconsGetData(cons);
7481  assert(consdata != NULL);
7482 
7483  if( consdata->nvars < 2 )
7484  return SCIP_OKAY;
7485 
7486  /* add implications if posibble
7487  *
7488  * for now we only add binary to non-binary implications, and this is only done for the binary variable with the
7489  * maximal absolute contribution and also only if this variable would force all other variables to their bound
7490  * corresponding to the global minimal activity of the constraint
7491  */
7492  if( !consdata->implsadded )
7493  {
7494  /* sort variables by variable type */
7495  SCIP_CALL( consdataSort(scip, consdata) );
7496 
7497  /* @todo we might extract implications/cliques if SCIPvarIsBinary() variables exist and we have integer variables
7498  * up front, might change sorting correspondingly
7499  */
7500  /* fast abort if no binaries exist */
7501  if( !SCIPvarIsBinary(consdata->vars[0]) )
7502  return SCIP_OKAY;
7503 
7504  nvars = consdata->nvars;
7505  vars = consdata->vars;
7506  vals = consdata->vals;
7507 
7508  /* recompute activities if needed */
7509  if( !consdata->validactivities )
7510  consdataCalcActivities(scip, consdata);
7511  assert(consdata->validactivities);
7512 
7513  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
7514  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
7515  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
7516  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
7517  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
7518  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
7519  finiteminact = (finitenegminact && finiteposminact);
7520  finitemaxact = (finitenegmaxact && finiteposmaxact);
7521 
7522  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
7523  {
7524  SCIP_Real maxabscontrib = -1.0;
7525  SCIP_Bool posval = FALSE;
7526  SCIP_Bool allbinary = TRUE;
7527  int oldnchgbds = *nchgbds;
7528  int nbdchgs = 0;
7529  int nimpls = 0;
7530  int position = -1;
7531 
7532  /* we need a valid minimal/maximal activity to add cliques */
7533  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
7534  {
7535  consdataRecomputeGlbMinactivity(scip, consdata);
7536  assert(consdata->validglbminact);
7537  }
7538 
7539  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
7540  {
7541  consdataRecomputeGlbMaxactivity(scip, consdata);
7542  assert(consdata->validglbmaxact);
7543  }
7544  assert(consdata->validglbminact || consdata->validglbmaxact);
7545 
7546  /* @todo extend this to local/constraint probing */
7547 
7548  /* determine maximal contribution to the activity */
7549  for( v = nvars - 1; v >= 0; --v )
7550  {
7551  if( SCIPvarIsBinary(vars[v]) )
7552  {
7553  if( vals[v] > 0 )
7554  {
7555  SCIP_Real value = vals[v] * SCIPvarGetUbGlobal(vars[v]);
7556 
7557  if( value > maxabscontrib )
7558  {
7559  maxabscontrib = value;
7560  position = v;
7561  posval = TRUE;
7562  }
7563  }
7564  else
7565  {
7566  SCIP_Real value = vals[v] * SCIPvarGetLbGlobal(vars[v]);
7567 
7568  value = REALABS(value);
7569 
7570  if( value > maxabscontrib )
7571  {
7572  maxabscontrib = value;
7573  position = v;
7574  posval = FALSE;
7575  }
7576  }
7577  }
7578  else
7579  allbinary = FALSE;
7580  }
7581  assert(0 <= position && position < nvars);
7582 
7583  if( !SCIPisEQ(scip, maxabscontrib, 1.0) && !allbinary )
7584  {
7585  /* if the right hand side and the minimal activity are finite and changing the variable with the biggest
7586  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
7587  * implications
7588  */
7589  if( finiterhs && finiteminact && SCIPisEQ(scip, consdata->glbminactivity, consdata->rhs - maxabscontrib) )
7590  {
7591  for( v = nvars - 1; v >= 0; --v )
7592  {
7593  /* binary to binary implications will be collected when extrating cliques */
7594  if( !SCIPvarIsBinary(vars[v]) )
7595  {
7596  if( v != position )
7597  {
7598  if( vals[v] > 0 )
7599  {
7600  /* add implications */
7601  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
7602  ++nimpls;
7603  *nchgbds += nbdchgs;
7604  }
7605  else
7606  {
7607  /* add implications */
7608  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
7609  ++nimpls;
7610  *nchgbds += nbdchgs;
7611  }
7612 
7613  if( infeasible )
7614  {
7615  *cutoff = TRUE;
7616  break;
7617  }
7618  }
7619  }
7620  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
7621  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
7622  break;
7623  }
7624  }
7625 
7626  /* if the left hand side and the maximal activity are finite and changing the variable with the biggest
7627  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
7628  * implications
7629  */
7630  if( finitelhs && finitemaxact && SCIPisEQ(scip, consdata->glbmaxactivity, consdata->lhs - maxabscontrib) )
7631  {
7632  for( v = nvars - 1; v >= 0; --v )
7633  {
7634  /* binary to binary implications will be collected when extrating cliques */
7635  if( !SCIPvarIsBinary(vars[v]) )
7636  {
7637  if( v != position )
7638  {
7639  if( vals[v] > 0 )
7640  {
7641  /* add implications */
7642  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
7643  ++nimpls;
7644  *nchgbds += nbdchgs;
7645  }
7646  else
7647  {
7648  /* add implications */
7649  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
7650  ++nimpls;
7651  *nchgbds += nbdchgs;
7652  }
7653 
7654  if( infeasible )
7655  {
7656  *cutoff = TRUE;
7657  break;
7658  }
7659  }
7660  }
7661  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
7662  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
7663  break;
7664  }
7665  }
7666 
7667  /* did we find some implications */
7668  if( nimpls > 0 )
7669  {
7670  SCIPdebugMessage("extracted %d implications from constraint %s which led to %d bound changes, %scutoff detetcted\n", nimpls, SCIPconsGetName(cons), *nchgbds - oldnchgbds, *cutoff ? "" : "no ");
7671 
7672  if( *cutoff )
7673  return SCIP_OKAY;
7674 
7675  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
7676  if( *nchgbds - oldnchgbds > 0 )
7677  {
7678  /* check for fixed variables */
7679  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
7680  if( *cutoff )
7681  return SCIP_OKAY;
7682 
7683  /* tighten variable's bounds */
7684  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7685  if( *cutoff )
7686  return SCIP_OKAY;
7687 
7688  /* check for fixed variables */
7689  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
7690  if( *cutoff )
7691  return SCIP_OKAY;
7692  }
7693  }
7694  }
7695  }
7696 
7697  consdata->implsadded = TRUE;
7698  }
7699 
7700  /* check if we already added the cliques of this constraint */
7701  if( consdata->cliquesadded )
7702  return SCIP_OKAY;
7703 
7704  consdata->cliquesadded = TRUE;
7705  cliquenonzerosadded = 0;
7706  stopped = FALSE;
7707 
7708  /* sort variables by variable type */
7709  SCIP_CALL( consdataSort(scip, consdata) );
7710 
7711  nvars = consdata->nvars;
7712  vars = consdata->vars;
7713  vals = consdata->vals;
7714 
7715  /**@todo extract more cliques, implications and variable bounds from linear constraints */
7716 
7717  /* recompute activities if needed */
7718  if( !consdata->validactivities )
7719  consdataCalcActivities(scip, consdata);
7720  assert(consdata->validactivities);
7721 
7722  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
7723  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
7724  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
7725  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
7726  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
7727  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
7728  finiteminact = (finitenegminact && finiteposminact);
7729  finitemaxact = (finitenegmaxact && finiteposmaxact);
7730 
7731  /* 1. we wheck whether some variables do not fit together into this constraint and add the corresponding clique
7732  * information
7733  */
7734  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
7735  {
7736  SCIP_VAR** binvars;
7737  SCIP_Real* binvarvals;
7738  int nposbinvars = 0;
7739  int nnegbinvars = 0;
7740  int allonebinary = 0;
7741 
7742  SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nvars) );
7743  SCIP_CALL( SCIPallocBufferArray(scip, &binvarvals, nvars) );
7744 
7745  /* collect binary variables */
7746  for( i = 0; i < nvars; ++i )
7747  {
7748  if( SCIPvarIsBinary(vars[i]) )
7749  {
7750  assert(!SCIPisZero(scip, vals[i]));
7751 
7752  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
7753  ++allonebinary;
7754 
7755  binvars[nposbinvars + nnegbinvars] = vars[i];
7756  binvarvals[nposbinvars + nnegbinvars] = vals[i];
7757 
7758  if( SCIPisPositive(scip, vals[i]) )
7759  ++nposbinvars;
7760  else
7761  ++nnegbinvars;
7762 
7763  assert(nposbinvars + nnegbinvars <= nvars);
7764  }
7765  /* stop searching for binary variables, because the constraint data is sorted */
7766  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
7767  break;
7768  }
7769  assert(nposbinvars + nnegbinvars <= nvars);
7770 
7771  /* setppc constraints will be handled later; we need at least two binary variables with same sign to extract
7772  * cliques
7773  */
7774  if( allonebinary < nvars && (nposbinvars >= 2 || nnegbinvars >= 2) )
7775  {
7776  SCIP_Real threshold;
7777  int oldnchgbds = *nchgbds;
7778  int nbdchgs;
7779  int jstart;
7780  int j;
7781 
7782  /* we need a valid minimal/maximal activity to add cliques */
7783  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
7784  {
7785  consdataRecomputeGlbMinactivity(scip, consdata);
7786  assert(consdata->validglbminact);
7787  }
7788 
7789  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
7790  {
7791  consdataRecomputeGlbMaxactivity(scip, consdata);
7792  assert(consdata->validglbmaxact);
7793  }
7794  assert(consdata->validglbminact || consdata->validglbmaxact);
7795 
7796  /* sort coefficients non-increasing to be faster in the clique search */
7797  SCIPsortDownRealPtr(binvarvals, (void**) binvars, nposbinvars + nnegbinvars);
7798 
7799  /* case a) */
7800  if( finiterhs && finitenegminact && nposbinvars >= 2 )
7801  {
7802  /* compute value that needs to be exceeded */
7803  threshold = consdata->rhs - consdata->glbminactivity;
7804 
7805  i = 0;
7806  j = i + 1;
7807 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
7808  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
7809  assert(SCIPisFeasLE(scip, binvarvals[i], threshold));
7810 #endif
7811  /* check if at least two variables are in a clique */
7812  if( SCIPisFeasGT(scip, binvarvals[i] + binvarvals[j], threshold) )
7813  {
7814  ++j;
7815  /* check for extending the clique */
7816  while( j < nposbinvars )
7817  {
7818  if( !SCIPisFeasGT(scip, binvarvals[j-1] + binvarvals[j], threshold) )
7819  break;
7820  ++j;
7821  }
7822  assert(j >= 2);
7823 
7824  /* add clique with at least two variables */
7825  SCIP_CALL( SCIPaddClique(scip, &(binvars[i]), NULL, j - i, FALSE, &infeasible, &nbdchgs) );
7826 
7827  if( infeasible )
7828  *cutoff = TRUE;
7829 
7830  *nchgbds += nbdchgs;
7831 
7832  cliquenonzerosadded += j;
7833  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
7834  stopped = TRUE;
7835 
7836  /* exchange the last variable in the clique if possible and add all new ones */
7837  if( !stopped && !(*cutoff) && j < nposbinvars )
7838  {
7839  SCIP_VAR** clqvars;
7840  int lastfit = j - 2;
7841  assert(lastfit >= i);
7842 
7843  /* copy all 'main'-clique variables */
7844  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[i]), j - i) );
7845 
7846  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
7847  while( lastfit >= i && j < nposbinvars )
7848  {
7849  /* check if two variables are in a clique */
7850  if( SCIPisFeasGT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
7851  {
7852  clqvars[lastfit + 1] = binvars[j];
7853 
7854  /* add clique with at least two variables */
7855  SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, lastfit - i + 2, FALSE, &infeasible, &nbdchgs) );
7856 
7857  if( infeasible )
7858  {
7859  *cutoff = TRUE;
7860  break;
7861  }
7862 
7863  *nchgbds += nbdchgs;
7864 
7865  cliquenonzerosadded += (lastfit - i + 2);
7866  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
7867  {
7868  stopped = TRUE;
7869  break;
7870  }
7871 
7872  ++j;
7873  }
7874  else
7875  --lastfit;
7876  }
7877 
7878  SCIPfreeBufferArray(scip, &clqvars);
7879  }
7880  }
7881  }
7882 
7883  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
7884  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
7885  {
7886  /* check for fixed variables */
7887  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
7888 
7889  if( !*cutoff )
7890  {
7891  /* tighten variable's bounds */
7892  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7893 
7894  if( !*cutoff )
7895  {
7896  /* check for fixed variables */
7897  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
7898 
7899  if( !*cutoff )
7900  {
7901  /* sort variables by variable type */
7902  SCIP_CALL( consdataSort(scip, consdata) );
7903 
7904  /* recompute activities if needed */
7905  if( !consdata->validactivities )
7906  consdataCalcActivities(scip, consdata);
7907  assert(consdata->validactivities);
7908 
7909  nvars = consdata->nvars;
7910  vars = consdata->vars;
7911  vals = consdata->vals;
7912  nposbinvars = 0;
7913  nnegbinvars = 0;
7914  allonebinary = 0;
7915 
7916  /* update binary variables */
7917  for( i = 0; i < nvars; ++i )
7918  {
7919  if( SCIPvarIsBinary(vars[i]) )
7920  {
7921  assert(!SCIPisZero(scip, vals[i]));
7922 
7923  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
7924  ++allonebinary;
7925 
7926  binvars[nposbinvars + nnegbinvars] = vars[i];
7927  binvarvals[nposbinvars + nnegbinvars] = vals[i];
7928 
7929  if( SCIPisPositive(scip, vals[i]) )
7930  ++nposbinvars;
7931  else
7932  ++nnegbinvars;
7933 
7934  assert(nposbinvars + nnegbinvars <= nvars);
7935  }
7936  /* stop searching for binary variables, because the constraint data is sorted */
7937  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
7938  break;
7939  }
7940  assert(nposbinvars + nnegbinvars <= nvars);
7941  }
7942  }
7943  }
7944 
7945  oldnchgbds = *nchgbds;
7946  }
7947 
7948  /* case b) */
7949  if( !stopped && !(*cutoff) && finitelhs && finiteposmaxact && nnegbinvars >= 2 )
7950  {
7951  /* compute value that needs to be deceeded */
7952  threshold = consdata->lhs - consdata->glbmaxactivity;
7953 
7954  i = nposbinvars + nnegbinvars - 1;
7955  j = i - 1;
7956 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
7957  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
7958  assert(SCIPisFeasGE(scip, binvarvals[i], threshold));
7959 #endif
7960  /* check if two variables are in a clique */
7961  if( SCIPisFeasLT(scip, binvarvals[i] + binvarvals[j], threshold) )
7962  {
7963  --j;
7964  /* check for extending the clique */
7965  while( j >= nposbinvars )
7966  {
7967  if( !SCIPisFeasLT(scip, binvarvals[j+1] + binvarvals[j], threshold) )
7968  break;
7969  --j;
7970  }
7971  jstart = j;
7972 
7973  assert(i - j >= 2);
7974  /* add clique with at least two variables */
7975  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), NULL, i - j, FALSE, &infeasible, &nbdchgs) );
7976 
7977  if( infeasible )
7978  *cutoff = TRUE;
7979 
7980  *nchgbds += nbdchgs;
7981 
7982  cliquenonzerosadded += (i - j);
7983  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
7984  stopped = TRUE;
7985 
7986  /* exchange the last variable in the clique if possible and add all new ones */
7987  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
7988  {
7989  SCIP_VAR** clqvars;
7990  int lastfit = jstart + 1;
7991  assert(lastfit < i);
7992 
7993  /* copy all 'main'-clique variables */
7994  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
7995  ++lastfit;
7996 
7997  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
7998  while( lastfit <= i && j >= nposbinvars )
7999  {
8000  /* check if two variables are in a clique */
8001  if( SCIPisFeasLT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8002  {
8003  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8004  clqvars[lastfit - jstart - 2] = binvars[j];
8005 
8006  assert(i - lastfit + 2 >= 2);
8007  /* add clique with at least two variables */
8008  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), NULL, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8009 
8010  if( infeasible )
8011  {
8012  *cutoff = TRUE;
8013  break;
8014  }
8015 
8016  *nchgbds += nbdchgs;
8017 
8018  cliquenonzerosadded += (i - lastfit + 2);
8019  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8020  {
8021  stopped = TRUE;
8022  break;
8023  }
8024 
8025  --j;
8026  }
8027  else
8028  ++lastfit;
8029  }
8030 
8031  SCIPfreeBufferArray(scip, &clqvars);
8032  }
8033  }
8034  }
8035 
8036  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8037  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8038  {
8039  /* check for fixed variables */
8040  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8041 
8042  if( !*cutoff )
8043  {
8044  /* tighten variable's bounds */
8045  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8046 
8047  if( !*cutoff )
8048  {
8049  /* check for fixed variables */
8050  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8051 
8052  if( !*cutoff )
8053  {
8054  /* sort variables by variable type */
8055  SCIP_CALL( consdataSort(scip, consdata) );
8056 
8057  /* recompute activities if needed */
8058  if( !consdata->validactivities )
8059  consdataCalcActivities(scip, consdata);
8060  assert(consdata->validactivities);
8061 
8062  nvars = consdata->nvars;
8063  vars = consdata->vars;
8064  vals = consdata->vals;
8065  nposbinvars = 0;
8066  nnegbinvars = 0;
8067  allonebinary = 0;
8068 
8069  /* update binary variables */
8070  for( i = 0; i < nvars; ++i )
8071  {
8072  if( SCIPvarIsBinary(vars[i]) )
8073  {
8074  assert(!SCIPisZero(scip, vals[i]));
8075 
8076  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8077  ++allonebinary;
8078 
8079  binvars[nposbinvars + nnegbinvars] = vars[i];
8080  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8081 
8082  if( SCIPisPositive(scip, vals[i]) )
8083  ++nposbinvars;
8084  else
8085  ++nnegbinvars;
8086 
8087  assert(nposbinvars + nnegbinvars <= nvars);
8088  }
8089  /* stop searching for binary variables, because the constraint data is sorted */
8090  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8091  break;
8092  }
8093  assert(nposbinvars + nnegbinvars <= nvars);
8094  }
8095  }
8096  }
8097 
8098  oldnchgbds = *nchgbds;
8099  }
8100 
8101  /* case c) */
8102  if( !(*cutoff) && finiterhs && finiteminact && nnegbinvars >= 2 )
8103  {
8104  SCIP_Bool* values;
8105 
8106  /* initialize clique values array for adding a negated clique */
8107  SCIP_CALL( SCIPallocBufferArray(scip, &values, nnegbinvars) );
8108  BMSclearMemoryArray(values, nnegbinvars);
8109 
8110  /* compute value that needs to be exceeded */
8111  threshold = consdata->rhs - consdata->glbminactivity;
8112 
8113  i = nposbinvars + nnegbinvars - 1;
8114  j = i - 1;
8115 
8116 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8117  /* check if the variable should not have already been fixed to one */
8118  assert(!SCIPisFeasGT(scip, binvarvals[i], threshold));
8119 #endif
8120 
8121  if( SCIPisFeasGT(scip, -binvarvals[i] - binvarvals[j], threshold) )
8122  {
8123  --j;
8124  /* check for extending the clique */
8125  while( j >= nposbinvars )
8126  {
8127  if( !SCIPisFeasGT(scip, -binvarvals[j+1] - binvarvals[j], threshold) )
8128  break;
8129  --j;
8130  }
8131  jstart = j;
8132 
8133  assert(i - j >= 2);
8134  /* add negated clique with at least two variables */
8135  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), values, i - j, FALSE, &infeasible, &nbdchgs) );
8136 
8137  if( infeasible )
8138  *cutoff = TRUE;
8139 
8140  *nchgbds += nbdchgs;
8141 
8142  cliquenonzerosadded += (i - j);
8143  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8144  stopped = TRUE;
8145 
8146  /* exchange the last variable in the clique if possible and add all new ones */
8147  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8148  {
8149  SCIP_VAR** clqvars;
8150  int lastfit = j + 1;
8151  assert(lastfit < i);
8152 
8153  /* copy all 'main'-clique variables */
8154  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8155  ++lastfit;
8156 
8157  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8158  while( lastfit <= i && j >= nposbinvars )
8159  {
8160  /* check if two variables are in a negated clique */
8161  if( SCIPisFeasGT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8162  {
8163  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8164  clqvars[lastfit - jstart - 2] = binvars[j];
8165 
8166  assert(i - lastfit + 2 >= 2);
8167  /* add clique with at least two variables */
8168  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), values, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8169 
8170  if( infeasible )
8171  {
8172  *cutoff = TRUE;
8173  break;
8174  }
8175 
8176  *nchgbds += nbdchgs;
8177 
8178  cliquenonzerosadded += (i - lastfit + 2);
8179  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8180  {
8181  stopped = TRUE;
8182  break;
8183  }
8184 
8185  --j;
8186  }
8187  else
8188  ++lastfit;
8189  }
8190 
8191  SCIPfreeBufferArray(scip, &clqvars);
8192  }
8193  }
8194 
8195  SCIPfreeBufferArray(scip, &values);
8196  }
8197 
8198  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8199  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8200  {
8201  /* check for fixed variables */
8202  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8203 
8204  if( !*cutoff )
8205  {
8206  /* tighten variable's bounds */
8207  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8208 
8209  if( !*cutoff )
8210  {
8211  /* check for fixed variables */
8212  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8213 
8214  if( !*cutoff )
8215  {
8216  /* sort variables by variable type */
8217  SCIP_CALL( consdataSort(scip, consdata) );
8218 
8219  /* recompute activities if needed */
8220  if( !consdata->validactivities )
8221  consdataCalcActivities(scip, consdata);
8222  assert(consdata->validactivities);
8223 
8224  nvars = consdata->nvars;
8225  vars = consdata->vars;
8226  vals = consdata->vals;
8227  nposbinvars = 0;
8228  nnegbinvars = 0;
8229  allonebinary = 0;
8230 
8231  /* update binary variables */
8232  for( i = 0; i < nvars; ++i )
8233  {
8234  if( SCIPvarIsBinary(vars[i]) )
8235  {
8236  assert(!SCIPisZero(scip, vals[i]));
8237 
8238  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8239  ++allonebinary;
8240 
8241  binvars[nposbinvars + nnegbinvars] = vars[i];
8242  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8243 
8244  if( SCIPisPositive(scip, vals[i]) )
8245  ++nposbinvars;
8246  else
8247  ++nnegbinvars;
8248 
8249  assert(nposbinvars + nnegbinvars <= nvars);
8250  }
8251  /* stop searching for binary variables, because the constraint data is sorted */
8252  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8253  break;
8254  }
8255  assert(nposbinvars + nnegbinvars <= nvars);
8256  }
8257  }
8258  }
8259  }
8260 
8261  /* case d) */
8262  if( !stopped && !(*cutoff) && finitelhs && finitemaxact && nposbinvars >= 2 )
8263  {
8264  SCIP_Bool* values;
8265 
8266  /* initialize clique values array for adding a negated clique */
8267  SCIP_CALL( SCIPallocBufferArray(scip, &values, nposbinvars) );
8268  BMSclearMemoryArray(values, nposbinvars);
8269 
8270  /* compute value that needs to be exceeded */
8271  threshold = consdata->lhs - consdata->glbmaxactivity;
8272 
8273  i = 0;
8274  j = i + 1;
8275 
8276 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8277  /* check if the variable should not have already been fixed to one */
8278  assert(!SCIPisFeasLT(scip, -binvarvals[i], threshold));
8279 #endif
8280 
8281  if( SCIPisFeasLT(scip, -binvarvals[i] - binvarvals[j], threshold) )
8282  {
8283  ++j;
8284  /* check for extending the clique */
8285  while( j < nposbinvars )
8286  {
8287  if( !SCIPisFeasLT(scip, -binvarvals[j-1] - binvarvals[j], threshold) )
8288  break;
8289  ++j;
8290  }
8291  assert(j >= 2);
8292 
8293  /* add negated clique with at least two variables */
8294  SCIP_CALL( SCIPaddClique(scip, &(binvars[i]), values, j - i, FALSE, &infeasible, &nbdchgs) );
8295 
8296  if( infeasible )
8297  *cutoff = TRUE;
8298 
8299  *nchgbds += nbdchgs;
8300 
8301  cliquenonzerosadded += j;
8302  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8303  stopped = TRUE;
8304 
8305  /* exchange the last variable in the clique if possible and add all new ones */
8306  if( !stopped && !(*cutoff) && j < nposbinvars )
8307  {
8308  SCIP_VAR** clqvars;
8309  int lastfit = j - 2;
8310  assert(lastfit >= i);
8311 
8312  /* copy all 'main'-clique variables */
8313  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[i]), j - i) );
8314 
8315  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8316  while( lastfit >= i && j < nposbinvars )
8317  {
8318  /* check if two variables are in a negated clique */
8319  if( SCIPisFeasLT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8320  {
8321  clqvars[lastfit + 1] = binvars[j];
8322 
8323  /* add clique with at least two variables */
8324  SCIP_CALL( SCIPaddClique(scip, clqvars, values, lastfit - i + 2, FALSE, &infeasible, &nbdchgs) );
8325 
8326  if( infeasible )
8327  {
8328  *cutoff = TRUE;
8329  break;
8330  }
8331 
8332  *nchgbds += nbdchgs;
8333 
8334  cliquenonzerosadded += (lastfit - i + 2);
8335  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8336  break;
8337 
8338  ++j;
8339  }
8340  else
8341  --lastfit;
8342  }
8343 
8344  SCIPfreeBufferArray(scip, &clqvars);
8345  }
8346  }
8347 
8348  SCIPfreeBufferArray(scip, &values);
8349  }
8350  }
8351 
8352  SCIPfreeBufferArray(scip, &binvarvals);
8353  SCIPfreeBufferArray(scip, &binvars);
8354 
8355  if( *cutoff )
8356  return SCIP_OKAY;
8357  }
8358 
8359  /* 2. we only check if the constraint is a set packing / partitioning constraint */
8360 
8361  /* check if all variables are binary, if the coefficients are +1 or -1, and if the right hand side is equal
8362  * to 1 - number of negative coefficients, or if the left hand side is equal to number of positive coefficients - 1
8363  */
8364  nposcoefs = 0;
8365  nnegcoefs = 0;
8366  for( i = 0; i < nvars; ++i )
8367  {
8368  if( !SCIPvarIsBinary(vars[i]) )
8369  return SCIP_OKAY;
8370  else if( SCIPisEQ(scip, vals[i], +1.0) )
8371  nposcoefs++;
8372  else if( SCIPisEQ(scip, vals[i], -1.0) )
8373  nnegcoefs++;
8374  else
8375  return SCIP_OKAY;
8376  }
8377 
8378  lhsclique = SCIPisEQ(scip, consdata->lhs, (SCIP_Real)nposcoefs - 1.0);
8379  rhsclique = SCIPisEQ(scip, consdata->rhs, 1.0 - (SCIP_Real)nnegcoefs);
8380 
8381  if( lhsclique || rhsclique )
8382  {
8383  SCIP_Bool* values;
8384  int nbdchgs;
8385 
8386  SCIPdebugMessage("linear constraint <%s>: adding clique with %d vars (%d pos, %d neg)\n",
8387  SCIPconsGetName(cons), nvars, nposcoefs, nnegcoefs);
8388  SCIP_CALL( SCIPallocBufferArray(scip, &values, nvars) );
8389 
8390  for( i = 0; i < nvars; ++i )
8391  values[i] = (rhsclique == (vals[i] > 0.0));
8392 
8393  SCIP_CALL( SCIPaddClique(scip, vars, values, nvars, SCIPisEQ(scip, consdata->lhs, consdata->rhs), &infeasible, &nbdchgs) );
8394 
8395  if( infeasible )
8396  *cutoff = TRUE;
8397 
8398  *nchgbds += nbdchgs;
8399  SCIPfreeBufferArray(scip, &values);
8400  }
8401 
8402  return SCIP_OKAY;
8403 }
8404 
8405 /** tightens left and right hand side of constraint due to integrality */
8406 static
8408  SCIP* scip, /**< SCIP data structure */
8409  SCIP_CONS* cons, /**< linear constraint */
8410  int* nchgsides /**< pointer to count number of side changes */
8411  )
8412 {
8413  SCIP_CONSDATA* consdata;
8414  SCIP_Bool integral;
8415  int i;
8416 
8417  assert(scip != NULL);
8418  assert(cons != NULL);
8419  assert(nchgsides != NULL);
8420 
8421  consdata = SCIPconsGetData(cons);
8422  assert(consdata != NULL);
8424  if( !SCIPisIntegral(scip, consdata->lhs) || !SCIPisIntegral(scip, consdata->rhs) )
8425  {
8426  integral = TRUE;
8427  for( i = 0; i < consdata->nvars && integral; ++i )
8428  {
8429  integral = SCIPisIntegral(scip, consdata->vals[i])
8430  && (SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS);
8431  }
8432  if( integral )
8433  {
8434  SCIPdebugMessage("linear constraint <%s>: make sides integral: sides=[%.15g,%.15g]\n",
8435  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
8436  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisIntegral(scip, consdata->lhs) )
8437  {
8438  SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
8439  if( !consdata->upgraded )
8440  (*nchgsides)++;
8441  }
8442  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisIntegral(scip, consdata->rhs) )
8443  {
8444  SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
8445  if( !consdata->upgraded )
8446  (*nchgsides)++;
8447  }
8448  SCIPdebugMessage("linear constraint <%s>: new integral sides: sides=[%.15g,%.15g]\n",
8449  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
8450  }
8451  }
8452 
8453  return SCIP_OKAY;
8454 }
8455 
8456 #define MAXVALRECOMP 1e+06
8457 
8458 /** tightens coefficients of binary, integer, and implicit integer variables due to activity bounds in presolving:
8459  * given an inequality lhs <= a*x + ai*xi <= rhs, with a non-continuous variable li <= xi <= ui
8460  * let minact := min{a*x + ai*xi}, maxact := max{a*x + ai*xi}
8461  * (i) ai >= 0:
8462  * if minact + ai >= lhs and maxact - ai <= rhs: (**)
8463  * - a deviation from the lower/upper bound of xi would make the left/right hand side redundant
8464  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
8465  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
8466  * - change coefficients:
8467  * ai' := max(lhs - minact, maxact - rhs)
8468  * lhs' := lhs - (ai - ai')*li
8469  * rhs' := rhs - (ai - ai')*ui
8470  * (ii) ai < 0:
8471  * if minact - ai >= lhs and maxact + ai <= rhs: (***)
8472  * - a deviation from the upper/lower bound of xi would make the left/right hand side redundant
8473  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
8474  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
8475  * - change coefficients:
8476  * ai' := min(rhs - maxact, minact - lhs)
8477  * lhs' := lhs - (ai - ai')*ui
8478  * rhs' := rhs - (ai - ai')*li
8479  *
8480  * We further try to remove redundant variable from the constraint;
8481  * Variables which fulfill conditions (**) or (***) are called surely non-redundant variables.
8482  * A deviation of only one from their bound makes the lhs/rhs feasible (i.e., redundant), even if all other
8483  * variables are set to their "worst" bound. If all variables which are not surely non-redundant cannot make
8484  * the lhs/rhs redundant, even if they are set to their "best" bound, they can be removed from the constraint.
8485  * E.g., for binary variables and an inequality x_1 +x_2 +10y_1 +10y_2 >= 5, setting either of the y_i to one
8486  * suffices to fulfill the inequality, whereas the x_i do not contribute to feasibility and can be removed.
8487  *
8488  * @todo use also some tightening procedures for (knapsack) constraints with non-integer coefficients, see
8489  * cons_knapsack.c the following methods detectRedundantVars() and tightenWeights()
8490  */
8491 static
8493  SCIP* scip, /**< SCIP data structure */
8494  SCIP_CONS* cons, /**< linear constraint */
8495  int* nchgcoefs, /**< pointer to count total number of changed coefficients */
8496  int* nchgsides /**< pointer to count number of side changes */
8497  )
8498 {
8499  SCIP_CONSDATA* consdata;
8500  SCIP_VAR* var;
8501  SCIP_Real minactivity; /* minimal value w.r.t. the variable's local bounds for the constraint's
8502  * activity, ignoring the coefficients contributing with infinite value */
8503  SCIP_Real maxactivity; /* maximal value w.r.t. the variable's local bounds for the constraint's
8504  * activity, ignoring the coefficients contributing with infinite value */
8505  SCIP_Bool minactisrelax; /* do huge finite values contribute to the minactivity? */
8506  SCIP_Bool maxactisrelax; /* do huge finite values contribute to the maxactivity? */
8507  SCIP_Real minleftactivity; /* minimal activity without surely non-redundant variables. */
8508  SCIP_Real maxleftactivity; /* maximal activity without surely non-redundant variables. */
8509  SCIP_Real aggrlhs; /* lhs without minimal activity of surely non-redundant variables. */
8510  SCIP_Real aggrrhs; /* rhs without maximal activity of surely non-redundant variables. */
8511  SCIP_Real lval; /* candidate for new value arising from considering the left hand side */
8512  SCIP_Real rval; /* candidate for new value arising from considering the left hand side */
8513  SCIP_Real val;
8514  SCIP_Real newval;
8515  SCIP_Real newlhs;
8516  SCIP_Real newrhs;
8517  SCIP_Real lb;
8518  SCIP_Real ub;
8519  int i;
8520 
8521  assert(scip != NULL);
8522  assert(cons != NULL);
8523  assert(nchgcoefs != NULL);
8524  assert(nchgsides != NULL);
8525 
8526  consdata = SCIPconsGetData(cons);
8527  assert(consdata != NULL);
8528 
8529  /* @todo Is this still needed with automatic recomputation of activities? */
8530  /* if the maximal coefficient is too large, recompute the activities */
8531  if( consdata->validmaxabsval && consdata->maxabsval > MAXVALRECOMP )
8532  {
8533  consdataRecomputeMinactivity(scip, consdata);
8534  consdataRecomputeMaxactivity(scip, consdata);
8535  }
8536 
8537  /* get the minimal and maximal activity of the constraint */
8538  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8539 
8540  minleftactivity = 0.0;
8541  maxleftactivity = 0.0;
8542 
8543  /* try to tighten each coefficient */
8544  i = 0;
8545  while( i < consdata->nvars )
8546  {
8547  var = consdata->vars[i];
8548 
8549  /* get coefficient and variable's bounds */
8550  lb = SCIPvarGetLbLocal(var);
8551  ub = SCIPvarGetUbLocal(var);
8552  val = consdata->vals[i];
8553  assert(!SCIPisZero(scip, val));
8554 
8555  /* check sign of coefficient */
8556  if( val >= 0.0 )
8557  {
8558  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
8560  SCIPisGE(scip, minactivity + val, consdata->lhs) && SCIPisLE(scip, maxactivity - val, consdata->rhs) )
8561  {
8562  /* change coefficients:
8563  * ai' := max(lhs - minact, maxact - rhs)
8564  * lhs' := lhs - (ai - ai')*li
8565  * rhs' := rhs - (ai - ai')*ui
8566  */
8567 
8568  lval = consdata->lhs - minactivity;
8569  rval = maxactivity - consdata->rhs;
8570 
8571  /* Try to avoid cancellation, if there are only two variables */
8572  if( consdata->nvars == 2 )
8573  {
8574  SCIP_Real otherval;
8575  otherval = consdata->vals[1-i];
8576 
8577  if( !SCIPisInfinity(scip, -consdata->lhs) && consdata->minactivityneginf + consdata->minactivityneginf == 0 )
8578  {
8579  lval = consdata->lhs - val*lb;
8580  lval -= otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
8581  }
8582 
8583  if( !SCIPisInfinity(scip,consdata->rhs) && consdata->maxactivityneginf + consdata->maxactivityneginf == 0 )
8584  {
8585  rval = val*ub - consdata->rhs;
8586  rval += otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
8587  }
8588  }
8589 
8590  newval = MAX(lval, rval);
8591  assert(SCIPisSumRelLE(scip, newval, val));
8592 
8593  /* Try to avoid cancellation in computation of lhs/rhs */
8594  newlhs = consdata->lhs - val * lb;
8595  newlhs += newval * lb;
8596  newrhs = consdata->rhs - val * ub;
8597  newrhs += newval * ub;
8598 
8599  if( !SCIPisSumRelEQ(scip, newval, val) )
8600  {
8601  SCIPdebugMessage("linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
8602  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
8603  minactivity, maxactivity, consdata->lhs, consdata->rhs);
8604 
8605  /* update the coefficient and the activity bounds */
8606  if( SCIPisZero(scip, newval) )
8607  {
8608  SCIP_CALL( delCoefPos(scip, cons, i) );
8609  i--;
8610  }
8611  else
8612  {
8613  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
8614  }
8615  (*nchgcoefs)++;
8616 
8617  /* get the new minimal and maximal activity of the constraint */
8618  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8619 
8620  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
8621  {
8622  SCIPdebugMessage("linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
8623 
8624  SCIP_CALL( chgLhs(scip, cons, newlhs) );
8625  (*nchgsides)++;
8626  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
8627  }
8628 
8629  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
8630  {
8631  SCIPdebugMessage("linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
8632 
8633  SCIP_CALL( chgRhs(scip, cons, newrhs) );
8634  (*nchgsides)++;
8635  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
8636  }
8637  }
8638  }
8639  else
8640  {
8641  if( !SCIPisInfinity(scip, -minleftactivity) )
8642  {
8643  assert(!SCIPisInfinity(scip, val));
8644  assert(!SCIPisInfinity(scip, lb));
8645  if( SCIPisInfinity(scip, -lb) )
8646  minleftactivity = -SCIPinfinity(scip);
8647  else
8648  minleftactivity += val * lb;
8649  }
8650 
8651  if( !SCIPisInfinity(scip, maxleftactivity) )
8652  {
8653  assert(!SCIPisInfinity(scip, val));
8654  assert(!SCIPisInfinity(scip, -ub));
8655  if( SCIPisInfinity(scip,ub) )
8656  maxleftactivity = SCIPinfinity(scip);
8657  else
8658  maxleftactivity += val * ub;
8659  }
8660  }
8661  }
8662  else
8663  {
8664  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
8666  SCIPisGE(scip, minactivity - val, consdata->lhs) && SCIPisLE(scip, maxactivity + val, consdata->rhs) )
8667  {
8668  /* change coefficients:
8669  * ai' := min(rhs - maxact, minact - lhs)
8670  * lhs' := lhs - (ai - ai')*ui
8671  * rhs' := rhs - (ai - ai')*li
8672  */
8673 
8674  lval = minactivity - consdata->lhs;
8675  rval = consdata->rhs - maxactivity;
8676 
8677  /* Try to avoid cancellation, if there are only two variables */
8678  if( consdata->nvars == 2 )
8679  {
8680  SCIP_Real otherval;
8681  otherval = consdata->vals[1-i];
8682 
8683  if( !SCIPisInfinity(scip,-consdata->lhs) && consdata->minactivityneginf + consdata->minactivityneginf == 0 )
8684  {
8685  lval = val*ub - consdata->lhs;
8686  lval += otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
8687  }
8688 
8689  if( !SCIPisInfinity(scip,consdata->rhs) && consdata->maxactivityneginf + consdata->maxactivityneginf == 0 )
8690  {
8691  rval = consdata->rhs - val*lb;
8692  rval -= otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
8693  }
8694  }
8695 
8696  newval = MIN(lval, rval);
8697  assert(SCIPisSumRelGE(scip, newval, val));
8698 
8699  /* Try to avoid cancellation in computation of lhs/rhs */
8700  newlhs = consdata->lhs - val * ub;
8701  newlhs += newval * ub;
8702  newrhs = consdata->rhs - val * lb;
8703  newrhs += newval * lb;
8704 
8705  if( !SCIPisSumRelEQ(scip, newval, val) )
8706  {
8707  SCIPdebugMessage("linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
8708  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
8709  minactivity, maxactivity, consdata->lhs, consdata->rhs);
8710 
8711  /* update the coefficient and the activity bounds */
8712  if( SCIPisZero(scip, newval) )
8713  {
8714  SCIP_CALL( delCoefPos(scip, cons, i) );
8715  i--;
8716  }
8717  else
8718  {
8719  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
8720  }
8721  (*nchgcoefs)++;
8722 
8723  /* get the new minimal and maximal activity of the constraint */
8724  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8725 
8726  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
8727  {
8728  SCIPdebugMessage("linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
8729 
8730  SCIP_CALL( chgLhs(scip, cons, newlhs) );
8731  (*nchgsides)++;
8732  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
8733  }
8734 
8735  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
8736  {
8737  SCIPdebugMessage("linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
8738 
8739  SCIP_CALL( chgRhs(scip, cons, newrhs) );
8740  (*nchgsides)++;
8741  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
8742  }
8743  }
8744  }
8745  else
8746  {
8747  if( !SCIPisInfinity(scip, -minleftactivity) )
8748  {
8749  assert(!SCIPisInfinity(scip, -val));
8750  assert(!SCIPisInfinity(scip, -ub));
8751  if( SCIPisInfinity(scip, ub) )
8752  minleftactivity = -SCIPinfinity(scip);
8753  else
8754  minleftactivity += val * ub;
8755  }
8756 
8757  if( !SCIPisInfinity(scip, maxleftactivity) )
8758  {
8759  assert(!SCIPisInfinity(scip, -val));
8760  assert(!SCIPisInfinity(scip, lb));
8761  if( SCIPisInfinity(scip, -lb) )
8762  maxleftactivity = SCIPinfinity(scip);
8763  else
8764  maxleftactivity += val * lb;
8765  }
8766  }
8767  }
8768  ++i;
8769  }
8770 
8771  SCIPdebugMessage("minleftactivity = %.15g, rhs = %.15g\n",
8772  minleftactivity, consdata->rhs);
8773  SCIPdebugMessage("maxleftactivity = %.15g, lhs = %.15g\n",
8774  maxleftactivity, consdata->lhs);
8775 
8776  /* minleft == \infty ==> minactivity == \infty */
8777  assert(!SCIPisInfinity(scip, -minleftactivity) || SCIPisInfinity(scip, -minactivity));
8778  assert(!SCIPisInfinity(scip, maxleftactivity) || SCIPisInfinity(scip, maxactivity));
8779 
8780  /* if the lhs is finite, we will check in the following whether the not non-redundant variables can make lhs feasible;
8781  * this is not valid, if the minactivity is -\infty (aggrlhs would be minus infinity in the following computation)
8782  * or if huge values contributed to the minactivity, because the minactivity is then just a relaxation
8783  * (<= the exact minactivity), and we might falsely claim variables to be redundant in the following
8784  */
8785  assert(!SCIPisInfinity(scip, minactivity));
8786  if( !SCIPisInfinity(scip, -consdata->lhs) && (SCIPisInfinity(scip, -minactivity) || minactisrelax) )
8787  return SCIP_OKAY;
8788 
8789  /* if the rhs is finite, we will check in the following whether the not non-redundant variables can make rhs feasible;
8790  * this is not valid, if the maxactivity is \infty (aggrrhs would be infinity in the following computation)
8791  * or if huge values contributed to the maxactivity, because the maxactivity is then just a relaxation
8792  * (>= the exact maxactivity), and we might falsely claim variables to be redundant in the following
8793  */
8794  assert(!SCIPisInfinity(scip, -maxactivity));
8795  if( !SCIPisInfinity(scip, consdata->rhs) && (SCIPisInfinity(scip, maxactivity) || maxactisrelax) )
8796  return SCIP_OKAY;
8797 
8798  /* correct lhs and rhs by min/max activity of surely non-redundant variables
8799  * surely non-redundant variables are all those where a deviation from the bound makes the lhs/rhs redundant
8800  */
8801  aggrlhs = consdata->lhs - minactivity + minleftactivity;
8802  aggrrhs = consdata->rhs - maxactivity + maxleftactivity;
8803 
8804  /* check if the constraint contains variables which are redundant. The reasoning is the following:
8805  * Each non-redundant variable can make the lhs/rhs feasible with a deviation of only one in the bound.
8806  * If _all_ variables which are not non-redundant together cannot make lhs/rhs feasible,
8807  * they can be removed from the constraint.
8808  * aggrrhs may contain some near-infinity value, but only if rhs is infinity.
8809  */
8810  if( (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasLT(scip, maxleftactivity, aggrlhs))
8811  && (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasGT(scip, minleftactivity, aggrrhs)) )
8812  {
8813  SCIP_Real minleftactivitypart;
8814  SCIP_Real maxleftactivitypart;
8815 
8816  assert(!SCIPisInfinity(scip, -consdata->lhs) || !SCIPisInfinity(scip, consdata->rhs));
8817 
8818  /* try to remove redundant variables from constraint */
8819  i = 0;
8820  while( i < consdata->nvars )
8821  {
8822  var = consdata->vars[i];
8823  minleftactivitypart = 0.0;
8824  maxleftactivitypart = 0.0;
8825  lb = SCIPvarGetLbLocal(var);
8826  ub = SCIPvarGetUbLocal(var);
8827 
8828  /* get coefficient and variable's bounds */
8829  val = consdata->vals[i];
8830  assert(!SCIPisZero(scip, val));
8831 
8832  /* check sign of coefficient */
8833  if( val >= 0.0 )
8834  {
8835  /* negation of condition above in case of positive val */
8836  if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ||
8837  SCIPisLT(scip, minactivity + val, consdata->lhs) || SCIPisGT(scip, maxactivity - val, consdata->rhs) )
8838  {
8839  SCIPdebugMessage("minactivity = %g\tval = %g\tlhs = %g\n", minactivity, val, consdata->lhs);
8840  SCIPdebugMessage("maxactivity = %g\tval = %g\trhs = %g\n", maxactivity, val, consdata->rhs);
8841  SCIPdebugMessage("linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
8842  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
8843 
8844  minleftactivitypart = val * lb;
8845  maxleftactivitypart = val * ub;
8846 
8847  SCIP_CALL( delCoefPos(scip, cons, i) );
8848  i--;
8849 
8850  /* get the new minimal and maximal activity of the constraint */
8851  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8852 
8853  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
8854  * huge contributions
8855  */
8856  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
8857  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
8858  }
8859  }
8860  else
8861  {
8862  /* negation of condition above in case of negative val */
8863  if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ||
8864  SCIPisLT(scip, minactivity - val, consdata->lhs) || SCIPisGT(scip, maxactivity + val, consdata->rhs) )
8865  {
8866  SCIPdebugMessage("linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
8867  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
8868 
8869  minleftactivitypart = val * ub;
8870  maxleftactivitypart = val * lb;
8871 
8872  SCIP_CALL( delCoefPos(scip, cons, i) );
8873  i--;
8874 
8875  /* get the new minimal and maximal activity of the constraint */
8876  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8877 
8878  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
8879  * huge contributions
8880  */
8881  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
8882  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
8883  }
8884  }
8885 
8886  /* the following update step is needed in every iteration cause otherwise it is possible that the surely none-
8887  * redundant variables could get deleted,
8888  * e.g. y_1 + 16y_2 >= 25, y1 with bounds [9,12], y2 with bounds [0,2], minactivity would be 9, it follows that
8889  * y_2 is surely not redundant and y_1 is redundant so we would first delete y1 and without updating the sides
8890  * we would also delete y2 and as a result we would have gotten infeasibility */
8891  /* adjust lhs and right hand side */
8892  newlhs = consdata->lhs - minleftactivitypart;
8893  newrhs = consdata->rhs - maxleftactivitypart;
8894 
8895  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisFeasEQ(scip, newlhs, consdata->lhs) )
8896  {
8897  SCIPdebugMessage("linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
8898  SCIP_CALL( chgLhs(scip, cons, newlhs) );
8899  ++(*nchgsides);
8900  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
8901  }
8902  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisFeasEQ(scip, newrhs, consdata->rhs) )
8903  {
8904  SCIPdebugMessage("linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
8905  SCIP_CALL( chgRhs(scip, cons, newrhs) );
8906  ++(*nchgsides);
8907  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
8908  }
8909  ++i;
8910  }
8911  }
8912 
8913  return SCIP_OKAY;
8914 }
8915 
8916 /* processes equality with only one variable by fixing the variable and deleting the constraint */
8917 static
8919  SCIP* scip, /**< SCIP data structure */
8920  SCIP_CONS* cons, /**< linear constraint */
8921  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
8922  int* nfixedvars, /**< pointer to count number of fixed variables */
8923  int* ndelconss /**< pointer to count number of deleted constraints */
8924  )
8925 {
8926  SCIP_CONSDATA* consdata;
8927  SCIP_VAR* var;
8928  SCIP_Real val;
8929  SCIP_Real fixval;
8930  SCIP_Bool infeasible;
8931  SCIP_Bool fixed;
8932 
8933  assert(scip != NULL);
8934  assert(cons != NULL);
8935  assert(cutoff != NULL);
8936  assert(nfixedvars != NULL);
8937  assert(ndelconss != NULL);
8938 
8939  consdata = SCIPconsGetData(cons);
8940  assert(consdata != NULL);
8941  assert(consdata->nvars == 1);
8942  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
8943 
8944  /* calculate the value to fix the variable to */
8945  var = consdata->vars[0];
8946  val = consdata->vals[0];
8947  assert(!SCIPisZero(scip, val));
8948  fixval = SCIPselectSimpleValue(consdata->lhs/val - 0.9 * SCIPepsilon(scip),
8949  consdata->rhs/val + 0.9 * SCIPepsilon(scip), MAXDNOM);
8950  SCIPdebugMessage("linear equality <%s>: fix <%s> == %.15g\n",
8951  SCIPconsGetName(cons), SCIPvarGetName(var), fixval);
8952 
8953  /* fix variable */
8954  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
8955  if( infeasible )
8956  {
8957  SCIPdebugMessage(" -> infeasible fixing\n");
8958  *cutoff = TRUE;
8959  return SCIP_OKAY;
8960  }
8961  if( fixed )
8962  (*nfixedvars)++;
8963 
8964  /* disable constraint */
8965  SCIP_CALL( SCIPdelCons(scip, cons) );
8966  if( !consdata->upgraded )
8967  (*ndelconss)++;
8968 
8969  return SCIP_OKAY;
8970 }
8971 
8972 /* processes equality with exactly two variables by aggregating one of the variables and deleting the constraint */
8973 static
8975  SCIP* scip, /**< SCIP data structure */
8976  SCIP_CONS* cons, /**< linear constraint */
8977  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
8978  int* naggrvars, /**< pointer to count number of aggregated variables */
8979  int* ndelconss /**< pointer to count number of deleted constraints */
8980  )
8981 {
8982  SCIP_CONSDATA* consdata;
8983  SCIP_Bool infeasible;
8984  SCIP_Bool redundant;
8985  SCIP_Bool aggregated;
8986 
8987  assert(scip != NULL);
8988  assert(cons != NULL);
8989  assert(cutoff != NULL);
8990  assert(naggrvars != NULL);
8991  assert(ndelconss != NULL);
8992 
8993  consdata = SCIPconsGetData(cons);
8994  assert(consdata != NULL);
8995  assert(consdata->nvars == 2);
8996  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
8997 
8998  SCIPdebugMessage("linear constraint <%s>: aggregate %.15g<%s> + %.15g<%s> == %.15g\n",
8999  SCIPconsGetName(cons), consdata->vals[0], SCIPvarGetName(consdata->vars[0]),
9000  consdata->vals[1], SCIPvarGetName(consdata->vars[1]), consdata->rhs);
9001 
9002  /* aggregate the equality */
9003  SCIP_CALL( SCIPaggregateVars(scip, consdata->vars[0], consdata->vars[1], consdata->vals[0], consdata->vals[1],
9004  consdata->rhs, &infeasible, &redundant, &aggregated) );
9005 
9006  /* check for infeasibility of aggregation */
9007  if( infeasible )
9008  {
9009  SCIPdebugMessage(" -> infeasible aggregation\n");
9010  *cutoff = TRUE;
9011  return SCIP_OKAY;
9012  }
9013 
9014  /* count the aggregation */
9015  if( aggregated )
9016  (*naggrvars)++;
9017 
9018  /* delete the constraint, if it is redundant */
9019  if( redundant )
9020  {
9021  SCIP_CALL( SCIPdelCons(scip, cons) );
9022 
9023  if( !consdata->upgraded )
9024  (*ndelconss)++;
9025  }
9026 
9027  return SCIP_OKAY;
9028 }
9029 
9030 /** calculates the new lhs and rhs of the constraint after the given variable is aggregated out */
9031 static
9033  SCIP* scip, /**< SCIP data structure */
9034  SCIP_CONSDATA* consdata, /**< linear constraint data */
9035  SCIP_VAR* slackvar, /**< variable to be aggregated out */
9036  SCIP_Real slackcoef, /**< coefficient of variable in constraint */
9037  SCIP_Real* newlhs, /**< pointer to store new lhs of constraint */
9038  SCIP_Real* newrhs /**< pointer to store new rhs of constraint */
9039  )
9040 {
9041  SCIP_Real slackvarlb;
9042  SCIP_Real slackvarub;
9043 
9044  assert(scip != NULL);
9045  assert(consdata != NULL);
9046  assert(newlhs != NULL);
9047  assert(newrhs != NULL);
9048  assert(!SCIPisInfinity(scip, -consdata->lhs));
9049  assert(!SCIPisInfinity(scip, consdata->rhs));
9050 
9051  slackvarlb = SCIPvarGetLbGlobal(slackvar);
9052  slackvarub = SCIPvarGetUbGlobal(slackvar);
9053  if( slackcoef > 0.0 )
9054  {
9055  if( SCIPisInfinity(scip, -slackvarlb) )
9056  *newrhs = SCIPinfinity(scip);
9057  else
9058  *newrhs = consdata->rhs - slackcoef * slackvarlb;
9059  if( SCIPisInfinity(scip, slackvarub) )
9060  *newlhs = -SCIPinfinity(scip);
9061  else
9062  *newlhs = consdata->lhs - slackcoef * slackvarub;
9063  }
9064  else
9065  {
9066  if( SCIPisInfinity(scip, -slackvarlb) )
9067  *newlhs = -SCIPinfinity(scip);
9068  else
9069  *newlhs = consdata->rhs - slackcoef * slackvarlb;
9070  if( SCIPisInfinity(scip, slackvarub) )
9071  *newrhs = SCIPinfinity(scip);
9072  else
9073  *newrhs = consdata->lhs - slackcoef * slackvarub;
9074  }
9075  assert(SCIPisLE(scip, *newlhs, *newrhs));
9076 }
9077 
9078 #define MAXMULTIAGGRQUOTIENT 1e+03
9079 
9080 /* processes equality with more than two variables by multi-aggregating one of the variables and converting the equality
9081  * into an inequality; if multi-aggregation is not possible, tries to identify one continuous or integer variable that
9082  * is implicitly integral by this constraint
9083  *
9084  * @todo Check whether a more clever way of avoiding aggregation of variables containing implicitly integer variables
9085  * can help.
9086  */
9087 static
9089  SCIP* scip, /**< SCIP data structure */
9090  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
9091  SCIP_CONS* cons, /**< linear constraint */
9092  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9093  int* naggrvars, /**< pointer to count number of aggregated variables */
9094  int* ndelconss /**< pointer to count number of deleted constraints */
9095  )
9096 {
9097  SCIP_CONSDATA* consdata;
9098  SCIP_VAR** vars;
9099  SCIP_Real* vals;
9100  SCIP_VARTYPE bestslacktype;
9101  SCIP_VARTYPE slacktype;
9102  SCIP_Real lhs;
9103  SCIP_Real rhs;
9104  SCIP_Real bestslackdomrng;
9105  SCIP_Real minabsval;
9106  SCIP_Real maxabsval;
9107  SCIP_Bool bestremovescons;
9108  SCIP_Bool coefszeroone;
9109  SCIP_Bool coefsintegral;
9110  SCIP_Bool varsintegral;
9111  SCIP_Bool infeasible;
9112  SCIP_Bool samevar;
9113  int supinf; /* counter for infinite contributions to the supremum of a possible
9114  * multi-aggregation
9115  */
9116  int infinf; /* counter for infinite contributions to the infimum of a possible
9117  * multi-aggregation
9118  */
9119  int maxnlocksstay;
9120  int maxnlocksremove;
9121  int bestslackpos;
9122  int bestnlocks;
9123  int ncontvars;
9124  int contvarpos;
9125  int nintvars;
9126  int nimplvars;
9127  int intvarpos;
9128  int v;
9129 
9130  assert(scip != NULL);
9131  assert(cons != NULL);
9132  assert(cutoff != NULL);
9133  assert(naggrvars != NULL);
9134 
9135  consdata = SCIPconsGetData(cons);
9136  assert(consdata != NULL);
9137  assert(consdata->nvars > 2);
9138  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9139 
9140  SCIPdebugMessage("linear constraint <%s>: try to multi-aggregate equality\n", SCIPconsGetName(cons));
9141 
9142  /* We do not want to increase the total number of non-zeros due to the multi-aggregation.
9143  * Therefore, we have to restrict the number of locks of a variable that is aggregated out.
9144  * maxnlocksstay: maximal sum of lock numbers if the constraint does not become redundant after the aggregation
9145  * maxnlocksremove: maximal sum of lock numbers if the constraint can be deleted after the aggregation
9146  */
9147  lhs = consdata->lhs;
9148  rhs = consdata->rhs;
9149  maxnlocksstay = 0;
9150  if( consdata->nvars == 3 )
9151  {
9152  /* If the constraint becomes redundant, 3 non-zeros are removed, and we get 1 additional non-zero for each
9153  * constraint the variable appears in. Thus, the variable must appear in at most 3 other constraints.
9154  */
9155  maxnlocksremove = 3;
9156  }
9157  else if( consdata->nvars == 4 )
9158  {
9159  /* If the constraint becomes redundant, 4 non-zeros are removed, and we get 2 additional non-zeros for each
9160  * constraint the variable appears in. Thus, the variable must appear in at most 2 other constraints.
9161  */
9162  maxnlocksremove = 2;
9163  }
9164  else
9165  {
9166  /* If the constraint is redundant but has more than 4 variables, we can only accept one other constraint. */
9167  maxnlocksremove = 1;
9168  }
9169 
9170  /* the locks on this constraint can be ignored */
9171  if( SCIPconsIsChecked(cons) )
9172  {
9173  if( !SCIPisInfinity(scip, -lhs) )
9174  {
9175  maxnlocksstay++;
9176  maxnlocksremove++;
9177  }
9178  if( !SCIPisInfinity(scip, rhs) )
9179  {
9180  maxnlocksstay++;
9181  maxnlocksremove++;
9182  }
9183  }
9184 
9185  /* look for a slack variable s to convert a*x + s == b into lhs <= a*x <= rhs */
9186  vars = consdata->vars;
9187  vals = consdata->vals;
9188  bestslackpos = -1;
9189  bestslacktype = SCIP_VARTYPE_BINARY;
9190  bestnlocks = INT_MAX;
9191  bestremovescons = FALSE;
9192  bestslackdomrng = 0.0;
9193  coefszeroone = TRUE;
9194  coefsintegral = TRUE;
9195  varsintegral = TRUE;
9196  ncontvars = 0;
9197  contvarpos = -1;
9198  nintvars = 0;
9199  nimplvars = 0;
9200  intvarpos = -1;
9201  minabsval = SCIPinfinity(scip);
9202  maxabsval = -1.0;
9203  for( v = 0; v < consdata->nvars; ++v )
9204  {
9205  SCIP_VAR* var;
9206  SCIP_Real val;
9207  SCIP_Real absval;
9208  SCIP_Real varlb;
9209  SCIP_Real varub;
9210  SCIP_Bool iscont;
9211  int nlocks;
9212 
9213  assert(vars != NULL);
9214  assert(vals != NULL);
9215 
9216  var = vars[v];
9217  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksDown(var) >= 1); /* because variable is locked in this equality */
9218  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksUp(var) >= 1);
9219  varlb = SCIPvarGetLbGlobal(var);
9220  varub = SCIPvarGetUbGlobal(var);
9221 
9222  val = vals[v];
9223  absval = REALABS(val);
9224  assert(SCIPisPositive(scip, absval));
9225 
9226  /* calculate minimal and maximal absolute value */
9227  if( absval < minabsval )
9228  minabsval = absval;
9229  if( absval > maxabsval )
9230  maxabsval = absval;
9231 
9232  /* do not try to multi aggregate, when numerical bad */
9233  if( maxabsval / minabsval > MAXMULTIAGGRQUOTIENT )
9234  return SCIP_OKAY;
9235 
9236  slacktype = SCIPvarGetType(var);
9237  coefszeroone = coefszeroone && SCIPisEQ(scip, absval, 1.0);
9238  coefsintegral = coefsintegral && SCIPisIntegral(scip, val);
9239  varsintegral = varsintegral && (slacktype != SCIP_VARTYPE_CONTINUOUS);
9240  iscont = (slacktype == SCIP_VARTYPE_CONTINUOUS || slacktype == SCIP_VARTYPE_IMPLINT);
9241 
9242  /* update candidates for continuous -> implint and integer -> implint conversion */
9243  if( slacktype == SCIP_VARTYPE_CONTINUOUS )
9244  {
9245  ncontvars++;
9246  contvarpos = v;
9247  }
9248  else if( slacktype == SCIP_VARTYPE_IMPLINT )
9249  {
9250  ++nimplvars;
9251  }
9252  else if( slacktype == SCIP_VARTYPE_INTEGER )
9253  {
9254  nintvars++;
9255  intvarpos = v;
9256  }
9257 
9258  /* check, if variable is already fixed or aggregated */
9259  if( !SCIPvarIsActive(var) )
9260  continue;
9261 
9262  /* check, if variable is used in too many other constraints, even if this constraint could be deleted */
9263  nlocks = SCIPvarGetNLocksDown(var) + SCIPvarGetNLocksUp(var);
9264 
9265  if( nlocks > maxnlocksremove )
9266  continue;
9267 
9268  /* check, if variable can be used as a slack variable */
9269  if( (iscont || (coefsintegral && varsintegral && SCIPisEQ(scip, absval, 1.0))) &&
9270  !SCIPdoNotMultaggrVar(scip, var) )
9271  {
9272  SCIP_Bool better;
9273  SCIP_Bool equal;
9274  SCIP_Real slackdomrng;
9275 
9276  if( SCIPisInfinity(scip, varub) || SCIPisInfinity(scip, -varlb) )
9277  slackdomrng = SCIPinfinity(scip);
9278  /* we do not want to perform multi-aggregation due to numerics, if the bounds are huge */
9279  else if( SCIPisHugeValue(scip, varub) || SCIPisHugeValue(scip, -varlb) )
9280  return SCIP_OKAY;
9281  else
9282  {
9283  slackdomrng = (varub - varlb)*absval;
9284  assert(!SCIPisInfinity(scip, slackdomrng));
9285  }
9286  equal = FALSE;
9287  better = (slacktype > bestslacktype) || (bestslackpos == -1);
9288  if( !better && slacktype == bestslacktype )
9289  {
9290  better = (nlocks < bestnlocks);
9291  if( nlocks == bestnlocks && !bestremovescons )
9292  {
9293  better = SCIPisGT(scip, slackdomrng, bestslackdomrng);
9294  equal = !better && SCIPisGE(scip, slackdomrng, bestslackdomrng);
9295  }
9296  }
9297 
9298  if( better || equal )
9299  {
9300  SCIP_Real minresactivity;
9301  SCIP_Real maxresactivity;
9302  SCIP_Real newlhs;
9303  SCIP_Real newrhs;
9304  SCIP_Bool removescons;
9305  SCIP_Bool minisrelax;
9306  SCIP_Bool maxisrelax;
9307  SCIP_Bool isminsettoinfinity;
9308  SCIP_Bool ismaxsettoinfinity;
9309 
9310  /* check if the constraint becomes redundant after multi-aggregation */
9311  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
9312  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
9313 
9314  /* do not perform the multi-aggregation due to numerics, if we have huge contributions in the residual
9315  * activity
9316  */
9317  if( minisrelax || maxisrelax )
9318  continue;
9319 
9320  getNewSidesAfterAggregation(scip, consdata, var, val, &newlhs, &newrhs);
9321  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9322 
9323  /* check resactivities for reliability */
9324  if( removescons )
9325  {
9326  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
9327  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
9328 
9329  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity)
9330  && SCIPisFeasLE(scip, newlhs, minresactivity))
9331  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
9332 
9333  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9334  }
9335 
9336  /* if parameter multaggrremove is set to TRUE, only aggregate when this removes constraint */
9337  if( conshdlrdata->multaggrremove && !removescons )
9338  continue;
9339 
9340  /* prefer variables that make the constraints redundant */
9341  if( bestremovescons && !removescons )
9342  continue;
9343 
9344  /* if the constraint does not become redundant, only accept the variable if it does not appear in
9345  * other constraints
9346  */
9347  if( !removescons && nlocks > maxnlocksstay )
9348  continue;
9349 
9350  better = better || (!bestremovescons && removescons);
9351  if( better )
9352  {
9353  bestslackpos = v;
9354  bestslacktype = slacktype;
9355  bestnlocks = nlocks;
9356  bestslackdomrng = slackdomrng;
9357  bestremovescons = removescons;
9358  }
9359  }
9360  }
9361  }
9362 
9363  /* if all coefficients and variables are integral, the right hand side must also be integral */
9364  if( coefsintegral && varsintegral && !SCIPisFeasIntegral(scip, consdata->rhs) )
9365  {
9366  SCIPdebugMessage("linear equality <%s> is integer infeasible\n", SCIPconsGetName(cons));
9367  SCIPdebugPrintCons(scip, cons, NULL);
9368  *cutoff = TRUE;
9369  return SCIP_OKAY;
9370  }
9371 
9372  supinf = 0;
9373  infinf = 0;
9374  samevar = FALSE;
9375 
9376  /* check whether the the infimum and the supremum of the multi-aggregation can be get infinite */
9377  for( v = 0; v < consdata->nvars; ++v )
9378  {
9379  if( v != bestslackpos )
9380  {
9381  if( SCIPisPositive(scip, consdata->vals[v]) )
9382  {
9383  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9384  {
9385  ++supinf;
9386  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9387  {
9388  ++infinf;
9389  samevar = TRUE;
9390  }
9391  }
9392  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9393  ++infinf;
9394 
9395  }
9396  else if( SCIPisNegative(scip, consdata->vals[v]) )
9397  {
9398  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9399  {
9400  ++supinf;
9401  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9402  {
9403  ++infinf;
9404  samevar = TRUE;
9405  }
9406  }
9407  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9408  ++infinf;
9409  }
9410  }
9411  }
9412  assert(!samevar || (supinf > 0 && infinf > 0));
9413 
9414  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
9415  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
9416  if( (samevar && (supinf > 1 || infinf > 1)) || (!samevar && supinf > 0 && infinf > 0) )
9417  {
9418  SCIPdebugMessage("do not perform multi-aggregation: infimum and supremum are both infinite\n");
9419  return SCIP_OKAY;
9420  }
9421 
9422  /* if the slack variable is of integer type, and the constraint itself may take fractional values,
9423  * we cannot aggregate the variable, because the integrality condition would get lost
9424  * Similarly, if there are implicitly integral variables we cannot aggregate, since we might
9425  * loose the integrality condition for this variable.
9426  */
9427  if( bestslackpos >= 0
9428  && (bestslacktype == SCIP_VARTYPE_CONTINUOUS || bestslacktype == SCIP_VARTYPE_IMPLINT
9429  || (coefsintegral && varsintegral && nimplvars == 0)) )
9430  {
9431  SCIP_VAR* slackvar;
9432  SCIP_Real* scalars;
9433  SCIP_Real slackcoef;
9434  SCIP_Real aggrconst;
9435  SCIP_Real newlhs;
9436  SCIP_Real newrhs;
9437  SCIP_Bool aggregated;
9438 
9439  /* we found a slack variable that only occurs in at most one other constraint:
9440  * a_1*x_1 + ... + a_k*x_k + a'*s == rhs -> s == rhs - a_1/a'*x_1 - ... - a_k/a'*x_k
9441  */
9442  assert(bestslackpos < consdata->nvars);
9443 
9444  /* do not multi aggregate binary variables */
9445  if( SCIPvarIsBinary(vars[bestslackpos]) )
9446  return SCIP_OKAY;
9447 
9448  /* convert equality into inequality by deleting the slack variable:
9449  * x + a*s == b, l <= s <= u -> b - a*u <= x <= b - a*l
9450  */
9451  slackvar = vars[bestslackpos];
9452  slackcoef = vals[bestslackpos];
9453  assert(!SCIPisZero(scip, slackcoef));
9454  aggrconst = consdata->rhs/slackcoef;
9455 
9456  getNewSidesAfterAggregation(scip, consdata, slackvar, slackcoef, &newlhs, &newrhs);
9457  assert(SCIPisLE(scip, newlhs, newrhs));
9458  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9459  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9460  SCIP_CALL( delCoefPos(scip, cons, bestslackpos) );
9461 
9462  /* allocate temporary memory */
9463  SCIP_CALL( SCIPallocBufferArray(scip, &scalars, consdata->nvars) );
9464 
9465  /* set up the multi-aggregation */
9466  SCIPdebugMessage("linear constraint <%s>: multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(slackvar));
9467  for( v = 0; v < consdata->nvars; ++v )
9468  {
9469  scalars[v] = -consdata->vals[v]/slackcoef;
9470  SCIPdebugPrintf(" %+.15g<%s>", scalars[v], SCIPvarGetName(vars[v]));
9471  }
9472  SCIPdebugPrintf(" %+.15g, bounds of <%s>: [%.15g,%.15g], nlocks=%d, maxnlocks=%d, removescons=%u\n",
9473  aggrconst, SCIPvarGetName(slackvar), SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar),
9474  bestnlocks, bestremovescons ? maxnlocksremove : maxnlocksstay, bestremovescons);
9475 
9476  /* perform the multi-aggregation */
9477  SCIP_CALL( SCIPmultiaggregateVar(scip, slackvar, consdata->nvars, vars, scalars, aggrconst,
9478  &infeasible, &aggregated) );
9479  assert(aggregated);
9480 
9481  /* free temporary memory */
9482  SCIPfreeBufferArray(scip, &scalars);
9483 
9484  /* check for infeasible aggregation */
9485  if( infeasible )
9486  {
9487  SCIPdebugMessage("linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
9488  *cutoff = TRUE;
9489  return SCIP_OKAY;
9490  }
9491 
9492  (*naggrvars)++;
9493 
9494  /* delete the constraint if it became redundant */
9495  if( bestremovescons )
9496  {
9497  SCIPdebugMessage("linear constraint <%s>: redundant after multi-aggregation\n", SCIPconsGetName(cons));
9498  SCIP_CALL( SCIPdelCons(scip, cons) );
9499 
9500  if( !consdata->upgraded )
9501  (*ndelconss)++;
9502  }
9503  }
9504  else if( ncontvars == 1 )
9505  {
9506  SCIP_VAR* var;
9507 
9508  assert(0 <= contvarpos && contvarpos < consdata->nvars);
9509  var = vars[contvarpos];
9510  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
9511 
9512  if( coefsintegral && SCIPisFeasIntegral(scip, consdata->rhs) )
9513  {
9514  /* upgrade continuous variable to an implicit one, if the absolute value of the coefficient is one */
9515  if( SCIPisEQ(scip, REALABS(vals[contvarpos]), 1.0) )
9516  {
9517  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
9518  SCIPdebugMessage("linear constraint <%s>: converting continuous variable <%s> to implicit integer variable\n",
9519  SCIPconsGetName(cons), SCIPvarGetName(var));
9520  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
9521  if( infeasible )
9522  {
9523  SCIPdebugMessage("infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
9524  *cutoff = TRUE;
9525 
9526  return SCIP_OKAY;
9527  }
9528  }
9529  /* aggregate continuous variable to an implicit one, if the absolute value of the coefficient is unequal to one */
9530  /* @todo check if the aggregation coefficient should be in some range(, which is not too big) */
9531  else if( !SCIPdoNotAggr(scip) )
9532  {
9533  SCIP_VAR* newvar;
9534  SCIP_Real absval;
9535  char newvarname[SCIP_MAXSTRLEN];
9536  SCIP_Bool redundant;
9537  SCIP_Bool aggregated;
9538 
9539  absval = REALABS(vals[contvarpos]);
9540 
9541  (void) SCIPsnprintf(newvarname, SCIP_MAXSTRLEN, "%s_impl", SCIPvarGetName(var));
9542 
9543  /* create new implicit variable for aggregation */
9544  SCIP_CALL( SCIPcreateVar(scip, &newvar, newvarname, -SCIPinfinity(scip), SCIPinfinity(scip), 0.0,
9546 
9547  /* add new variable to problem */
9548  SCIP_CALL( SCIPaddVar(scip, newvar) );
9549 
9550 #ifdef SCIP_DEBUG_SOLUTION
9551  if( SCIPdebugIsMainscip(scip) )
9552  {
9553  SCIP_Real varval;
9554  SCIP_CALL( SCIPdebugGetSolVal(scip, var, &varval) );
9555  SCIP_CALL( SCIPdebugAddSolVal(scip, newvar, absval * varval) );
9556  }
9557 #endif
9558 
9559  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
9560  SCIPdebugMessage("linear constraint <%s>: aggregating continuous variable <%s> to newly created implicit integer variable <%s>, aggregation factor = %g\n",
9561  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetName(newvar), absval);
9562 
9563  /* aggregate continuous and implicit variable */
9564  SCIP_CALL( SCIPaggregateVars(scip, var, newvar, absval, -1.0, 0.0, &infeasible, &redundant, &aggregated) );
9565 
9566  if( infeasible )
9567  {
9568  SCIPdebugMessage("infeasible aggregation of variable <%s> to implicit variable <%s>, domain is empty\n",
9569  SCIPvarGetName(var), SCIPvarGetName(newvar));
9570  *cutoff = TRUE;
9571 
9572  /* release implicit variable */
9573  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
9574 
9575  return SCIP_OKAY;
9576  }
9577 
9578  if( aggregated )
9579  (*naggrvars)++;
9580 
9581  /* release implicit variable */
9582  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
9583  }
9584 
9585  /* we do not have any event on vartype changes, so we need to manually force this constraint to be presolved
9586  * again
9587  */
9588  consdata->boundstightened = FALSE;
9589  consdata->presolved = FALSE;
9590  }
9591  }
9592  else if( ncontvars == 0 && nimplvars == 0 && nintvars == 1 && !coefszeroone )
9593  {
9594  SCIP_VAR* var;
9595 
9596  /* this seems to help for rococo instances, but does not for rout (where all coefficients are +/- 1.0)
9597  * -> we don't convert integers into implints if the row is a 0/1-row
9598  */
9599  assert(varsintegral);
9600  assert(0 <= intvarpos && intvarpos < consdata->nvars);
9601  var = vars[intvarpos];
9602  assert(SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER);
9603 
9604  if( coefsintegral
9605  && SCIPisEQ(scip, REALABS(vals[intvarpos]), 1.0)
9606  && SCIPisFeasIntegral(scip, consdata->rhs) )
9607  {
9608  /* convert the integer variable with coefficient 1.0 into an implicit integer variable */
9609  SCIPdebugMessage("linear constraint <%s>: converting integer variable <%s> to implicit integer variable\n",
9610  SCIPconsGetName(cons), SCIPvarGetName(var));
9611  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
9612  if( infeasible )
9613  {
9614  SCIPdebugMessage("infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
9615  *cutoff = TRUE;
9616 
9617  return SCIP_OKAY;
9618  }
9619  }
9620  }
9621 
9622  return SCIP_OKAY;
9623 }
9624 
9625 /** checks if the given variables and their coefficient are equal (w.r.t. scaling factor) to the objective function */
9626 static
9628  SCIP* scip, /**< SCIP data structure */
9629  SCIP_CONSDATA* consdata, /**< linear constraint data */
9630  SCIP_Real* scale, /**< pointer to store the scaling factor between the constraint and the
9631  * objective function */
9632  SCIP_Real* offset /**< pointer to store the offset of the objective function resulting by
9633  * this constraint */
9634  )
9635 {
9636  SCIP_VAR** vars;
9637  SCIP_VAR* var;
9638  SCIP_Real objval;
9639  SCIP_Bool negated;
9640  int nvars;
9641  int v;
9642 
9643  vars = consdata->vars;
9644  nvars = consdata->nvars;
9645  assert(vars != NULL);
9646 
9647  for( v = 0; v < nvars; ++v )
9648  {
9649  negated = FALSE;
9650  var = vars[v];
9651  assert(vars != NULL);
9652 
9653  if( SCIPvarIsNegated(var) )
9654  {
9655  negated = TRUE;
9656  var = SCIPvarGetNegatedVar(var);
9657  assert(var != NULL);
9658  }
9659 
9660  objval = SCIPvarGetObj(var);
9661 
9662  /* if a variable has a zero objective coefficient the linear constraint is not a subset of the objective
9663  * function
9664  */
9665  if( SCIPisZero(scip, objval) )
9666  return FALSE;
9667  else
9668  {
9669  SCIP_Real val;
9670 
9671  val = consdata->vals[v];
9672 
9673  if( negated )
9674  {
9675  if( v == 0 )
9676  {
9677  /* the first variable defines the scale */
9678  (*scale) = val / -objval;
9679 
9680  (*offset) += val;
9681  }
9682  else if( SCIPisEQ(scip, -objval * (*scale), val) )
9683  (*offset) += val;
9684  else
9685  return FALSE;
9686  }
9687  else if( v == 0 )
9688  {
9689  /* the first variable defines the scale */
9690  (*scale) = val / objval;
9691  }
9692  else if( !SCIPisEQ(scip, objval * (*scale), val) )
9693  return FALSE;
9694  }
9695  }
9696 
9697  return TRUE;
9698 }
9699 
9700 /** check if the linear equality constraint is equal to a subset of the objective function; if so we can remove the
9701  * objective coefficients and add an objective offset
9702  */
9703 static
9705  SCIP* scip, /**< SCIP data structure */
9706  SCIP_CONS* cons, /**< linear equation constraint */
9707  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
9708  )
9709 {
9710  SCIP_CONSDATA* consdata;
9711  SCIP_Real offset;
9712  SCIP_Real scale;
9713  SCIP_Bool applicable;
9714  int nobjvars;
9715  int nvars;
9716  int v;
9717 
9718  assert(scip != NULL);
9719  assert(cons != NULL);
9720  assert(conshdlrdata != NULL);
9721 
9722  consdata = SCIPconsGetData(cons);
9723  assert(consdata != NULL);
9724  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9725 
9726  nvars = consdata->nvars;
9727  nobjvars = SCIPgetNObjVars(scip);
9728 
9729  /* check if the linear equality constraints does not have more variables than the objective function */
9730  if( nvars > nobjvars || nvars == 0 )
9731  return SCIP_OKAY;
9732 
9733  /* check for allowance of algorithm */
9734  if( (nvars < nobjvars && !conshdlrdata->detectpartialobjective) ||
9735  (nvars == nobjvars && (!conshdlrdata->detectcutoffbound || !conshdlrdata->detectlowerbound)) )
9736  return SCIP_OKAY;
9737 
9738  offset = consdata->rhs;
9739  scale = 1.0;
9740 
9741  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
9742  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
9743 
9744  if( applicable )
9745  {
9746  SCIP_VAR** vars;
9747 
9748  vars = consdata->vars;
9749  assert(vars != NULL);
9750 
9751  offset /= scale;
9752 
9753  SCIPdebugMessage("linear equality constraint <%s> == %g (offset %g) is a subset of the objective function\n",
9754  SCIPconsGetName(cons), consdata->rhs, offset);
9755 
9756  /* set all objective coefficient to zero */
9757  for( v = 0; v < nvars; ++v )
9758  {
9759  SCIP_CALL( SCIPchgVarObj(scip, vars[v], 0.0) );
9760  }
9761 
9762  /* add an objective offset */
9763  SCIP_CALL( SCIPaddObjoffset(scip, offset) );
9764  }
9765 
9766  return SCIP_OKAY;
9767 }
9768 
9769 /** updates the cutoff if the given primal bound (which is implied by the given constraint) is better */
9770 static
9772  SCIP* scip, /**< SCIP data structure */
9773  SCIP_CONS* cons, /**< constraint */
9774  SCIP_Real primalbound /**< feasible primal bound */
9775  )
9776 {
9777  SCIP_Real cutoffbound;
9778 
9779  /* increase the cutoff bound value by an epsilon to ensue that solution with the value of the cutoff bound are still
9780  * accepted
9781  */
9782  cutoffbound = primalbound + SCIPcutoffbounddelta(scip);
9783 
9784  if( cutoffbound < SCIPgetCutoffbound(scip) )
9785  {
9786  SCIPdebugMessage("update cutoff bound <%g>\n", cutoffbound);
9788  SCIP_CALL( SCIPupdateCutoffbound(scip, cutoffbound) );
9789  }
9790  else
9791  {
9792  SCIP_CONSDATA* consdata;
9793 
9794  consdata = SCIPconsGetData(cons);
9795  assert(consdata != NULL);
9796 
9797  /* we cannot disable the enforcement and propagation on ranged rows, because the cutoffbound could only have
9798  * resulted from one side
9799  */
9800  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
9801  {
9802  /* in case the cutoff bound is worse then the currently known one, we additionally avoid enforcement and
9803  * propagation
9804  */
9805  SCIP_CALL( SCIPsetConsEnforced(scip, cons, FALSE) );
9806  SCIP_CALL( SCIPsetConsPropagated(scip, cons, FALSE) );
9807  }
9808  }
9809 
9810  return SCIP_OKAY;
9811 }
9812 
9813 /** check if the linear constraint is parallel to objective function; if so update the cutoff bound and avoid that the
9814  * constraint enters the LP by setting the initial and separated flag to FALSE
9815  */
9816 static
9818  SCIP* scip, /**< SCIP data structure */
9819  SCIP_CONS* cons, /**< linear constraint */
9820  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
9821  )
9822 {
9823  SCIP_CONSDATA* consdata;
9824  SCIP_Real offset;
9825  SCIP_Real scale;
9826  SCIP_Bool applicable;
9827  int nobjvars;
9828  int nvars;
9829 
9830  assert(scip != NULL);
9831  assert(cons != NULL);
9832  assert(conshdlrdata != NULL);
9834  consdata = SCIPconsGetData(cons);
9835  assert(consdata != NULL);
9836 
9837  /* ignore equalities since these are covered by the method checkPartialObjective() */
9838  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
9839  return SCIP_OKAY;
9840 
9841  nvars = consdata->nvars;
9842  nobjvars = SCIPgetNObjVars(scip);
9843 
9844  /* check if the linear inequality constraints has the same number of variables as the objective function and if the
9845  * initial and/or separated flag is set to FALSE
9846  */
9847  if( nvars != nobjvars || (!SCIPconsIsInitial(cons) && !SCIPconsIsSeparated(cons)) )
9848  return SCIP_OKAY;
9849 
9850  offset = 0.0;
9851  scale = 1.0;
9852 
9853  /* There are no variables in the ojective function and in the constraint. Thus, the constraint is redundant or proves
9854  * infeasibility. Since we have a pure feasibility problem, we do not want to set a cutoff or lower bound.
9855  */
9856  if( nobjvars == 0 )
9857  return SCIP_OKAY;
9858 
9859  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
9860  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
9861 
9862  if( applicable )
9863  {
9864  SCIP_Bool rhsfinite = !SCIPisInfinity(scip, consdata->rhs);
9865  SCIP_Bool lhsfinite = !SCIPisInfinity(scip, -consdata->lhs);
9866 
9867  if( SCIPisPositive(scip, scale) )
9868  {
9869  if( conshdlrdata->detectcutoffbound && rhsfinite )
9870  {
9871  SCIP_Real primalbound;
9872 
9873  primalbound = (consdata->rhs - offset) / scale;
9874 
9875  SCIPdebugMessage("constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
9876  SCIPconsGetName(cons), primalbound);
9877 
9878  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
9879  }
9880 
9881  if( conshdlrdata->detectlowerbound && lhsfinite )
9882  {
9883  SCIP_Real lowerbound;
9884 
9885  lowerbound = (consdata->lhs - offset) / scale;
9886 
9887  SCIPdebugMessage("constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
9888  SCIPconsGetName(cons), lowerbound);
9889 
9890  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
9891  }
9892 
9893  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !lhsfinite)) ||
9894  (conshdlrdata->detectlowerbound && !rhsfinite) )
9895  {
9896  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
9897  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
9898  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
9899  }
9900  }
9901  else
9902  {
9903  if( conshdlrdata->detectlowerbound && rhsfinite )
9904  {
9905  SCIP_Real lowerbound;
9906 
9907  lowerbound = (consdata->rhs - offset) / scale;
9908 
9909  SCIPdebugMessage("constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
9910  SCIPconsGetName(cons), lowerbound);
9911 
9912  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
9913  }
9914 
9915  if( conshdlrdata->detectcutoffbound && lhsfinite )
9916  {
9917  SCIP_Real primalbound;
9918 
9919  primalbound = (consdata->lhs - offset) / scale;
9920 
9921  SCIPdebugMessage("constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
9922  SCIPconsGetName(cons), primalbound);
9923 
9924  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
9925  }
9926 
9927  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !rhsfinite)) ||
9928  (conshdlrdata->detectlowerbound && !lhsfinite) )
9929  {
9930  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
9931  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
9932  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
9933  }
9934  }
9935  }
9936 
9937  return SCIP_OKAY;
9938 }
9939 
9940 /** converts special equalities */
9941 static
9943  SCIP* scip, /**< SCIP data structure */
9944  SCIP_CONS* cons, /**< linear constraint */
9945  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
9946  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9947  int* nfixedvars, /**< pointer to count number of fixed variables */
9948  int* naggrvars, /**< pointer to count number of aggregated variables */
9949  int* ndelconss /**< pointer to count number of deleted constraints */
9950  )
9951 {
9952  SCIP_CONSDATA* consdata;
9953 
9954  assert(scip != NULL);
9955  assert(cons != NULL);
9956  assert(conshdlrdata != NULL);
9957  assert(cutoff != NULL);
9958  assert(nfixedvars != NULL);
9959  assert(naggrvars != NULL);
9960  assert(ndelconss != NULL);
9961 
9962  consdata = SCIPconsGetData(cons);
9963  assert(consdata != NULL);
9964  assert(consdata->removedfixings);
9965 
9966  /* do nothing on inequalities */
9967  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
9968  return SCIP_OKAY;
9969 
9970  /* depending on the number of variables, call a special conversion method */
9971  if( consdata->nvars == 1 )
9972  {
9973  /* fix variable */
9974  SCIP_CALL( convertUnaryEquality(scip, cons, cutoff, nfixedvars, ndelconss) );
9975  }
9976  else if( consdata->nvars == 2 )
9977  {
9978  /* aggregate one of the variables */
9979  SCIP_CALL( convertBinaryEquality(scip, cons, cutoff, naggrvars, ndelconss) );
9980  }
9981  else
9982  {
9983  /* check if the equality is part of the objective function */
9984  SCIP_CALL( checkPartialObjective(scip, cons, conshdlrdata) );
9985 
9986  /* try to multi-aggregate one of the variables */
9987  SCIP_CALL( convertLongEquality(scip, conshdlrdata, cons, cutoff, naggrvars, ndelconss) );
9988  }
9989 
9990  return SCIP_OKAY;
9991 }
9992 
9993 /** returns whether the linear sum of all variables/coefficients except the given one divided by the given value is always
9994  * integral
9995  */
9996 static
9998  SCIP* scip, /**< SCIP data structure */
9999  SCIP_CONSDATA* consdata, /**< linear constraint */
10000  int pos, /**< position of variable to be left out */
10001  SCIP_Real val /**< value to divide the coefficients by */
10002  )
10003 {
10004  int v;
10005 
10006  assert(scip != NULL);
10007  assert(consdata != NULL);
10008  assert(0 <= pos && pos < consdata->nvars);
10009 
10010  for( v = 0; v < consdata->nvars; ++v )
10011  {
10012  if( v != pos && (!SCIPvarIsIntegral(consdata->vars[v]) || !SCIPisIntegral(scip, consdata->vals[v]/val)) )
10013  return FALSE;
10014  }
10015 
10016  return TRUE;
10017 }
10018 
10019 /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i
10020  * check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i
10021  */
10022 static
10024  SCIP* scip, /**< SCIP data structure */
10025  SCIP_Real side, /**< lhs or rhs */
10026  SCIP_Real val, /**< coefficient */
10027  SCIP_Real minresactivity, /**< minimal residual activity */
10028  SCIP_Real maxresactivity, /**< maximal residual activity */
10029  SCIP_Real* minval, /**< pointer to store calculated minval */
10030  SCIP_Real* maxval /**< pointer to store calculated maxval */
10031  )
10032 {
10033  assert(scip != NULL);
10034  assert(minval != NULL);
10035  assert(maxval != NULL);
10036 
10037  if( val > 0.0 )
10038  {
10039  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10040  *minval = -maxresactivity;
10041  else
10042  *minval = (side - maxresactivity)/val;
10043 
10044  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10045  *maxval = -minresactivity;
10046  else
10047  *maxval = (side - minresactivity)/val;
10048  }
10049  else
10050  {
10051  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10052  *minval = minresactivity;
10053  else
10054  *minval = (side - minresactivity)/val;
10055 
10056  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10057  *maxval = maxresactivity;
10058  else
10059  *maxval = (side - maxresactivity)/val;
10060  }
10061 }
10062 
10063 
10064 /* applies dual presolving for variables that are locked only once in a direction, and this locking is due to a
10065  * linear inequality
10066  */
10067 static
10069  SCIP* scip, /**< SCIP data structure */
10070  SCIP_CONS* cons, /**< linear constraint */
10071  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10072  int* nfixedvars, /**< pointer to count number of fixed variables */
10073  int* naggrvars, /**< pointer to count number of aggregated variables */
10074  int* ndelconss /**< pointer to count number of deleted constraints */
10075  )
10076 {
10077  SCIP_CONSDATA* consdata;
10078  SCIP_Bool lhsexists;
10079  SCIP_Bool rhsexists;
10080  SCIP_Bool bestisint;
10081  SCIP_Bool bestislhs;
10082  int bestpos;
10083  int i;
10084  int maxotherlocks;
10085 
10086  assert(scip != NULL);
10087  assert(cons != NULL);
10088  assert(cutoff != NULL);
10089  assert(nfixedvars != NULL);
10090  assert(naggrvars != NULL);
10091  assert(ndelconss != NULL);
10092 
10093  /* only process checked constraints (for which the locks are increased);
10094  * otherwise we would have to check for variables with nlocks == 0, and these are already processed by the
10095  * dualfix presolver
10096  */
10097  if( !SCIPconsIsChecked(cons) )
10098  return SCIP_OKAY;
10099 
10100  consdata = SCIPconsGetData(cons);
10101  assert(consdata != NULL);
10102 
10103  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
10104  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
10105 
10106  /* search for a single-locked variable which can be multi-aggregated; if a valid continuous variable was found, we
10107  * can use it safely for aggregation and break the search loop
10108  */
10109  bestpos = -1;
10110  bestisint = TRUE;
10111  bestislhs = FALSE;
10112 
10113  /* We only want to multi-aggregate variables, if they appear in maximal one additional constraint,
10114  * everything else would produce fill-in. Exceptions:
10115  * - If there are only two variables in the constraint from which the multi-aggregation arises, no fill-in will be
10116  * produced.
10117  * - If there are three variables in the constraint, multi-aggregation in three additional constraints will remove
10118  * six nonzeros (three from the constraint and the three entries of the multi-aggregated variable) and add
10119  * six nonzeros (two variables per substitution).
10120  * - If there at most four variables in the constraint, multi-aggregation in two additional constraints will remove
10121  * six nonzeros (four from the constraint and the two entries of the multi-aggregated variable) and add
10122  * six nonzeros (three variables per substitution). God exists!
10123  */
10124  if( consdata->nvars <= 2 )
10125  maxotherlocks = INT_MAX;
10126  else if( consdata->nvars == 3 )
10127  maxotherlocks = 3;
10128  else if( consdata->nvars == 4 )
10129  maxotherlocks = 2;
10130  else
10131  maxotherlocks = 1;
10132 
10133  /* if this constraint has both sides, it also provides a lock for the other side and thus we can allow one more lock */
10134  if( lhsexists && rhsexists )
10135  maxotherlocks++;
10136 
10137  for( i = 0; i < consdata->nvars && bestisint; ++i )
10138  {
10139  SCIP_VAR* var;
10140  SCIP_Bool isint;
10141  SCIP_Real val;
10142  SCIP_Real obj;
10143  SCIP_Real lb;
10144  SCIP_Real ub;
10145  SCIP_Bool agglhs;
10146  SCIP_Bool aggrhs;
10147 
10148  var = consdata->vars[i];
10150 
10151  /* if we already found a candidate, skip integers */
10152  if( bestpos >= 0 && isint )
10153  continue;
10154 
10155  /* better do not multi-aggregate binary variables, since most plugins rely on their binary variables to be either
10156  * active, fixed, or single-aggregated with another binary variable
10157  */
10158  if( SCIPvarIsBinary(var) && consdata->nvars > 2 )
10159  continue;
10160 
10161  if ( SCIPdoNotMultaggrVar(scip, var) )
10162  continue;
10163 
10164  val = consdata->vals[i];
10165  obj = SCIPvarGetObj(var);
10166  lb = SCIPvarGetLbGlobal(var);
10167  ub = SCIPvarGetUbGlobal(var);
10168 
10169  /* lhs <= a_0 * x_0 + a_1 * x_1 + ... + a_{n-1} * x_{n-1} <= rhs
10170  *
10171  * a_i >= 0, c_i >= 0, lhs exists, nlocksdown(x_i) == 1:
10172  * - constraint is the only one that forbids fixing the variable to its lower bound
10173  * - 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
10174  *
10175  * a_i <= 0, c_i <= 0, lhs exists, nlocksup(x_i) == 1:
10176  * - constraint is the only one that forbids fixing the variable to its upper bound
10177  * - 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
10178  *
10179  * a_i >= 0, c_i <= 0, rhs exists, nlocksup(x_i) == 1:
10180  * - constraint is the only one that forbids fixing the variable to its upper bound
10181  * - 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
10182  *
10183  * a_i <= 0, c_i >= 0, rhs exists, nlocksdown(x_i) == 1:
10184  * - constraint is the only one that forbids fixing the variable to its lower bound
10185  * - 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
10186  *
10187  * but: all this is only applicable, if the aggregated value is inside x_i's bounds for all possible values
10188  * of all x_j
10189  * furthermore: we only want to apply this, if no fill-in will be produced
10190  */
10191  agglhs = lhsexists
10192  && ((val > 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDown(var) == 1
10193  && SCIPvarGetNLocksUp(var) <= maxotherlocks)
10194  || (val < 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUp(var) == 1
10195  && SCIPvarGetNLocksDown(var) <= maxotherlocks));
10196  aggrhs = rhsexists
10197  && ((val > 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUp(var) == 1
10198  && SCIPvarGetNLocksDown(var) <= maxotherlocks)
10199  || (val < 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDown(var) == 1
10200  && SCIPvarGetNLocksUp(var) <= maxotherlocks));
10201  if( agglhs || aggrhs )
10202  {
10203  SCIP_Real minresactivity;
10204  SCIP_Real maxresactivity;
10205  SCIP_Real minval;
10206  SCIP_Real maxval;
10207  SCIP_Bool minisrelax;
10208  SCIP_Bool maxisrelax;
10209  SCIP_Bool isminsettoinfinity;
10210  SCIP_Bool ismaxsettoinfinity;
10211 
10212  /* calculate bounds for \sum_{j \neq i} a_j * x_j */
10213  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
10214  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
10215  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10216 
10217  /* We called consdataGetActivityResiduals() saying that we do not need a good relaxation,
10218  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
10219  * This is needed, because we do not want to rely on relaxed finite resactivities.
10220  */
10221  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
10222 
10223  if( agglhs )
10224  {
10225  /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10226  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10227 
10228  assert(SCIPisLE(scip, minval, maxval));
10229  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10230  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10231  {
10232  SCIP_Real oldmaxresactivity;
10233  SCIP_Real oldminresactivity;
10234  SCIP_Bool recalculated;
10235 
10236  recalculated = FALSE;
10237  oldmaxresactivity = maxresactivity;
10238  oldminresactivity = minresactivity;
10239 
10240  /* check minresactivity for reliability */
10241  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10242  {
10243  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10244  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10245  isminsettoinfinity = TRUE; /* here it means only that it was even calculated */
10246  }
10247 
10248  /* check maxresactivity for reliability */
10249  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10250  {
10251  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10252  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10253  ismaxsettoinfinity = TRUE; /* here it means only that it was even calculated */
10254  }
10255 
10256  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10257  if( recalculated )
10258  {
10259  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10260 
10261  /* check again if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10262  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10263 
10264  assert(SCIPisLE(scip, minval, maxval));
10265  }
10266 
10267  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10268  {
10269  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10270  * in the multi-aggregation
10271  */
10272  if( !isint || (SCIPisIntegral(scip, consdata->lhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10273  {
10274  bestpos = i;
10275  bestisint = isint;
10276  bestislhs = TRUE;
10277  continue; /* no need to also look at the right hand side */
10278  }
10279  }
10280  }
10281  }
10282 
10283  if( aggrhs )
10284  {
10285  /* check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10286  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10287 
10288  assert(SCIPisLE(scip,minval,maxval));
10289  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10290  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10291  {
10292  SCIP_Real oldmaxresactivity;
10293  SCIP_Real oldminresactivity;
10294  SCIP_Bool recalculated;
10295 
10296  recalculated = FALSE;
10297  oldmaxresactivity = maxresactivity;
10298  oldminresactivity = minresactivity;
10299 
10300  /* check minresactivity for reliability */
10301  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10302  {
10303  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10304  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10305  }
10306 
10307  /* check maxresactivity for reliability */
10308  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10309  {
10310  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10311  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10312  }
10313 
10314  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10315  if( recalculated )
10316  {
10317  /* check again if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10318  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10319  assert(SCIPisLE(scip,minval,maxval));
10320  }
10321 
10322  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10323  {
10324  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10325  * in the multi-aggregation
10326  */
10327  if( !isint || (SCIPisIntegral(scip, consdata->rhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10328  {
10329  bestpos = i;
10330  bestisint = isint;
10331  bestislhs = FALSE;
10332  }
10333  }
10334  }
10335  }
10336  }
10337  }
10338 
10339  if( bestpos >= 0 )
10340  {
10341  SCIP_VAR** aggrvars;
10342  SCIP_Real* aggrcoefs;
10343  SCIP_Real aggrconst;
10344  SCIP_VAR* bestvar;
10345  SCIP_Real bestval;
10346  int naggrs;
10347  int j;
10348  SCIP_Bool infeasible;
10349  SCIP_Bool aggregated;
10350  SCIP_Bool samevar;
10351  int supinf; /* counter for infinite contributions to the supremum of a possible
10352  * multi-aggregation
10353  */
10354  int infinf; /* counter for infinite contributions to the infimum of a possible
10355  * multi-aggregation
10356  */
10357 
10358  assert(!bestislhs || lhsexists);
10359  assert(bestislhs || rhsexists);
10360 
10361  bestvar = consdata->vars[bestpos];
10362  bestval = consdata->vals[bestpos];
10363  assert(bestisint ==
10365 
10366  /* allocate temporary memory */
10367  SCIP_CALL( SCIPallocBufferArray(scip, &aggrvars, consdata->nvars-1) );
10368  SCIP_CALL( SCIPallocBufferArray(scip, &aggrcoefs, consdata->nvars-1) );
10369 
10370  /* set up the multi-aggregation */
10371  SCIPdebugPrintCons(scip, cons, NULL);
10372  SCIPdebugMessage("linear constraint <%s> (dual): multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(bestvar));
10373  naggrs = 0;
10374  supinf = 0;
10375  infinf = 0;
10376  samevar = FALSE;
10377 
10378  for( j = 0; j < consdata->nvars; ++j )
10379  {
10380  if( j != bestpos )
10381  {
10382  aggrvars[naggrs] = consdata->vars[j];
10383  aggrcoefs[naggrs] = -consdata->vals[j]/consdata->vals[bestpos];
10384  SCIPdebugPrintf(" %+.15g<%s>", aggrcoefs[naggrs], SCIPvarGetName(aggrvars[naggrs]));
10385  if( bestisint )
10386  {
10387  /* coefficient must be integral: round it to exact integral value */
10388  assert(SCIPisIntegral(scip, aggrcoefs[naggrs]));
10389  aggrcoefs[naggrs] = SCIPfloor(scip, aggrcoefs[naggrs]+0.5);
10390  }
10391 
10392  if( SCIPisPositive(scip, aggrcoefs[naggrs]) )
10393  {
10394  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
10395  {
10396  ++supinf;
10397  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
10398  {
10399  ++infinf;
10400  samevar = TRUE;
10401  }
10402  }
10403  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
10404  ++infinf;
10405  }
10406  else if( SCIPisNegative(scip, aggrcoefs[naggrs]) )
10407  {
10408  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
10409  {
10410  ++supinf;
10411  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
10412  {
10413  ++infinf;
10414  samevar = TRUE;
10415  }
10416  }
10417  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
10418  ++infinf;
10419  }
10420 
10421  naggrs++;
10422  }
10423  }
10424  assert(!samevar || (supinf > 0 && infinf > 0));
10425 
10426  aggrconst = (bestislhs ? consdata->lhs/bestval : consdata->rhs/bestval);
10427  SCIPdebugPrintf(" %+.15g, bounds of <%s>: [%.15g,%.15g]\n", aggrconst, SCIPvarGetName(bestvar),
10428  SCIPvarGetLbGlobal(bestvar), SCIPvarGetUbGlobal(bestvar));
10429  assert(naggrs == consdata->nvars-1);
10430 
10431  /* right hand side must be integral: round it to exact integral value */
10432  if( bestisint )
10433  {
10434  assert(SCIPisIntegral(scip, aggrconst));
10435  aggrconst = SCIPfloor(scip, aggrconst+0.5);
10436  }
10437 
10438  aggregated = FALSE;
10439  infeasible = FALSE;
10440 
10441  /* perform the multi-aggregation */
10442  if( (samevar && supinf == 1 && infinf == 1) || (!samevar && (supinf == 0 || infinf == 0)) )
10443  {
10444  /* @todo if multi-aggregate makes them numerical trouble, avoid them if the coefficients differ to much, see
10445  * also convertLongEquality() early termination due to coefficients
10446  */
10447  SCIP_CALL( SCIPmultiaggregateVar(scip, bestvar, naggrs, aggrvars, aggrcoefs, aggrconst, &infeasible, &aggregated) );
10448  }
10449  else
10450  {
10451  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
10452  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
10453  SCIPdebugMessage("do not perform multi-aggregation: infimum and supremum are both infinite\n");
10454  }
10455  /* free temporary memory */
10456  SCIPfreeBufferArray(scip, &aggrcoefs);
10457  SCIPfreeBufferArray(scip, &aggrvars);
10458 
10459  /* check for infeasible aggregation */
10460  if( infeasible )
10461  {
10462  SCIPdebugMessage("linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
10463  *cutoff = TRUE;
10464  return SCIP_OKAY;
10465  }
10466 
10467  /* delete the constraint, if the aggregation was successful */
10468  if( aggregated )
10469  {
10470  SCIP_CALL( SCIPdelCons(scip, cons) );
10471 
10472  if( !consdata->upgraded )
10473  (*ndelconss)++;
10474  (*naggrvars)++;
10475  }
10476  else
10477  {
10478  SCIPdebugMessage("aggregation non successful!\n");
10479  }
10480  }
10481 
10482  return SCIP_OKAY;
10483 }
10484 
10485 #define BINWEIGHT 1
10486 #define INTWEIGHT 4
10487 #define CONTWEIGHT 8
10488 
10489 /** gets weight for variable in a "weighted number of variables" sum */
10490 static
10491 int getVarWeight(
10492  SCIP_VAR* var /**< variable to get weight for */
10493  )
10494 {
10495  switch( SCIPvarGetType(var) )
10496  {
10497  case SCIP_VARTYPE_BINARY:
10498  return BINWEIGHT;
10499  case SCIP_VARTYPE_INTEGER:
10500  case SCIP_VARTYPE_IMPLINT:
10501  return INTWEIGHT;
10503  return CONTWEIGHT;
10504  default:
10505  SCIPerrorMessage("invalid variable type\n");
10506  SCIPABORT();
10507  return 0; /*lint !e527*/
10508  }
10509 }
10510 
10511 /** tries to aggregate variables in equations a^Tx = lhs
10512  * in case there are at most two binary variables with an odd coefficient and all other
10513  * variables are not continuous and have an even coefficient then:
10514  * - exactly one odd binary variables
10515  * this binary variables y can be fixed to 0 if the lhs is even and to 1 if the lhs is odd
10516  * - lhs is odd -> y = 1
10517  * - lhs is even -> y = 0
10518  * - exactly two odd binary variables
10519  * aggregate the two binary variables with odd coefficient
10520  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
10521  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
10522  */
10523 static
10525  SCIP* scip, /**< SCIP data structure */
10526  SCIP_CONS* cons, /**< linear constraint */
10527  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10528  int* nfixedvars, /**< pointer to count number of fixed variables */
10529  int* naggrvars, /**< pointer to count number of aggregated variables */
10530  int* ndelconss /**< pointer to count number of deleted constraints */
10531  )
10532 { /*lint --e{715}*/
10533  SCIP_CONSDATA* consdata;
10534  SCIP_Bool success;
10535 
10536  assert( scip != NULL );
10537  assert( cons != NULL );
10538 
10539  consdata = SCIPconsGetData(cons);
10540  assert( consdata != NULL );
10541 
10542  /* check if the linear constraint is an equation with integral right hand side */
10543  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) || !SCIPisIntegral(scip, consdata->lhs) )
10544  return SCIP_OKAY;
10545 
10546  /* try to fix and aggregated variables until nothing is possible anymore */
10547  do
10548  {
10549  int v;
10550  int nvars;
10551  SCIP_VAR** vars;
10552  SCIP_Real* vals;
10553  SCIP_Real lhs;
10554  SCIP_Bool lhsodd;
10555 
10556  SCIP_Bool infeasible;
10557  SCIP_Bool fixed;
10558  SCIP_Bool aggregated;
10559  SCIP_Bool redundant;
10560 
10561  SCIP_VAR* var1;
10562  SCIP_VAR* var2;
10563  int noddvars;
10564 
10565  success = FALSE;
10566 
10567  lhs = consdata->lhs;
10568  vars = consdata->vars;
10569  vals = consdata->vals;
10570  nvars = consdata->nvars;
10571 
10572  assert( !SCIPisInfinity(scip, ABS(lhs)) );
10573 
10574  var1 = NULL;
10575  var2 = NULL;
10576  noddvars = 0;
10577 
10578  /* search for binary variables with an odd coefficient */
10579  for( v = 0; v < nvars && noddvars < 3; ++v )
10580  {
10581  SCIP_Longint val;
10582 
10583  /* all coefficients and variables have to be integral */
10584  if( !SCIPisIntegral(scip, vals[v]) || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
10585  return SCIP_OKAY;
10586 
10587  val = (SCIP_Longint)SCIPfeasFloor(scip, vals[v]);
10588  if( val % 2 != 0 )
10589  {
10590  /* the odd values have to belong to binary variables */
10591  if( !SCIPvarIsBinary(vars[v]) )
10592  return SCIP_OKAY;
10593 
10594  if( noddvars == 0 )
10595  var1 = vars[v];
10596  else
10597  var2 = vars[v];
10598 
10599  noddvars++;
10600  }
10601  }
10602 
10603  /* check lhs is odd or even */
10604  lhsodd = (((SCIP_Longint)SCIPfeasFloor(scip, lhs)) % 2 != 0);
10605 
10606  if( noddvars == 1 )
10607  {
10608  assert( var1 != NULL );
10609 
10610  SCIPdebugMessage("linear constraint <%s>: try fixing variable <%s> to <%g>\n",
10611  SCIPconsGetName(cons), SCIPvarGetName(var1), lhsodd ? 1.0 : 0.0);
10612 
10613  SCIP_CALL( SCIPfixVar(scip, var1, lhsodd? 1.0 : 0.0, &infeasible, &fixed) );
10614 
10615  /* check for infeasibility of fixing */
10616  if( infeasible )
10617  {
10618  SCIPdebugMessage(" -> infeasible fixing\n");
10619  *cutoff = TRUE;
10620  return SCIP_OKAY;
10621  }
10622 
10623  if( fixed )
10624  {
10625  SCIPdebugMessage(" -> feasible fixing\n");
10626  (*nfixedvars)++;
10627  success = TRUE;
10628  }
10629  }
10630  else if( noddvars == 2 )
10631  {
10632  assert( var1 != NULL );
10633  assert( var2 != NULL );
10634 
10635  /* aggregate the two variables with odd coefficient
10636  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
10637  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
10638  */
10639  SCIPdebugMessage("linear constraint <%s>: try aggregation of variables <%s> and <%s>\n",
10640  SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
10641 
10642  SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, lhsodd ? 1.0 : -1.0,
10643  lhsodd ? 1.0 : 0.0, &infeasible, &redundant, &aggregated) );
10644 
10645  /* check for infeasibility of aggregation */
10646  if( infeasible )
10647  {
10648  SCIPdebugMessage(" -> infeasible aggregation\n");
10649  *cutoff = TRUE;
10650  return SCIP_OKAY;
10651  }
10652 
10653  /* count the aggregation */
10654  if( aggregated )
10655  {
10656  SCIPdebugMessage(" -> feasible aggregation\n");
10657  (*naggrvars)++;
10658  success = TRUE;
10659  }
10660  }
10661 
10662  if( success )
10663  {
10664  /* apply fixings and aggregation to successfully rerun this presolving step */
10665  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
10666 
10667  if( infeasible )
10668  {
10669  SCIPdebugMessage(" -> infeasible fixing\n");
10670  *cutoff = TRUE;
10671  return SCIP_OKAY;
10672  }
10673 
10674  /* normalize constraint */
10675  SCIP_CALL( normalizeCons(scip, cons) );
10676  }
10677  }
10678  while( success );
10679 
10680  return SCIP_OKAY;
10681 }
10682 
10683 
10684 
10685 /** sorting method for constraint data, compares two variables on given indices, continuous variables will be sorted to
10686  * the end and for all other variables the sortation will be in non-increasing order of their absolute value of the
10687  * coefficients
10688  */
10689 static
10690 SCIP_DECL_SORTINDCOMP(consdataCompSim)
10691 { /*lint --e{715}*/
10692  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
10693  SCIP_VARTYPE vartype1;
10694  SCIP_VARTYPE vartype2;
10695  SCIP_Real value;
10696 
10697  assert(consdata != NULL);
10698  assert(0 <= ind1 && ind1 < consdata->nvars);
10699  assert(0 <= ind2 && ind2 < consdata->nvars);
10700 
10701  vartype1 = SCIPvarGetType(consdata->vars[ind1]);
10702  vartype2 = SCIPvarGetType(consdata->vars[ind2]);
10703 
10704  if( vartype1 == SCIP_VARTYPE_CONTINUOUS )
10705  {
10706  /* continuous varibles will be sorted to the back */
10707  if( vartype2 != vartype1 )
10708  return +1;
10709  /* both variables are continuous */
10710  else
10711  return 0;
10712  }
10713  /* continuous variables will be sorted to the back */
10714  else if( vartype2 == SCIP_VARTYPE_CONTINUOUS )
10715  return -1;
10716 
10717  value = REALABS(consdata->vals[ind2]) - REALABS(consdata->vals[ind1]);
10718 
10719  /* for all non-continuous variables, the variables are sorted after decreasing absolute coefficients */
10720  return (value > 0 ? +1 : (value < 0 ? -1 : 0));
10721 }
10722 
10723 /** tries to simplify coefficients and delete variables in ranged row of the form lhs <= a^Tx <= rhs, e.g. using the greatest
10724  * common divisor
10725  *
10726  * 1. lhs <= a^Tx <= rhs, forall a_i >= lhs, a_i <= rhs, and forall pairs a_i + a_j > rhs then we can change this
10727  * constraint to 1^Tx = 1
10728  */
10729 static
10731  SCIP* scip, /**< SCIP data structure */
10732  SCIP_CONS* cons, /**< linear constraint */
10733  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
10734  int* nchgsides /**< pointer to store the amount of changed sides */
10735  )
10736 {
10737  SCIP_CONSDATA* consdata;
10738  SCIP_VAR** vars;
10739  SCIP_Real* vals;
10740  SCIP_Real minval;
10741  SCIP_Real secondminval;
10742  SCIP_Real maxval;
10743  SCIP_Real lhs;
10744  SCIP_Real rhs;
10745  int nvars;
10746  int v;
10747 
10748  /* we must not change a modifiable constraint in any way */
10749  if( SCIPconsIsModifiable(cons) )
10750  return SCIP_OKAY;
10751 
10752  if( SCIPconsIsDeleted(cons) )
10753  return SCIP_OKAY;
10754 
10755  consdata = SCIPconsGetData(cons);
10756  assert(consdata != NULL);
10757 
10758  nvars = consdata->nvars;
10759 
10760  /* do not check empty or bound-constraints */
10761  if( nvars < 2 )
10762  return SCIP_OKAY;
10763 
10764  vals = consdata->vals;
10765  vars = consdata->vars;
10766  assert(vars != NULL);
10767  assert(vals != NULL);
10768 
10769  lhs = consdata->lhs;
10770  rhs = consdata->rhs;
10771  assert(!SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs));
10772  assert(!SCIPisNegative(scip, rhs));
10773 
10774  minval = SCIP_INVALID;
10775  secondminval = SCIP_INVALID;
10776  maxval = -SCIP_INVALID;
10777 
10778  for( v = nvars - 1; v >= 0; --v )
10779  {
10780  if( SCIPvarIsBinary(vars[v]) )
10781  {
10782  if( minval > vals[v] || minval == SCIP_INVALID ) /*lint !e777*/
10783  {
10784  secondminval = minval;
10785  minval = vals[v];
10786  }
10787  else if( secondminval > vals[v] || secondminval == SCIP_INVALID ) /*lint !e777*/
10788  secondminval = vals[v];
10789 
10790  if( maxval < vals[v] || maxval == -SCIP_INVALID ) /*lint !e777*/
10791  maxval = vals[v];
10792  }
10793  else
10794  break;
10795  }
10796 
10797  /* check if all variables are binary */
10798  if( v == -1 )
10799  {
10800  if( SCIPisEQ(scip, minval, maxval) && SCIPisEQ(scip, lhs, rhs) )
10801  return SCIP_OKAY;
10802 
10803  /* check if we can and need to choose exactly one binary variable */
10804  if( SCIPisGE(scip, minval, lhs) && SCIPisLE(scip, maxval, rhs) && SCIPisGT(scip, minval + secondminval, rhs) )
10805  {
10806  /* change all coefficients to 1.0 */
10807  for( v = nvars - 1; v >= 0; --v )
10808  {
10809  SCIP_CALL( chgCoefPos(scip, cons, v, 1.0) );
10810  }
10811  (*nchgcoefs) += nvars;
10812 
10813  /* replace old right and left hand side with 1.0 */
10814  SCIP_CALL( chgRhs(scip, cons, 1.0) );
10815  SCIP_CALL( chgLhs(scip, cons, 1.0) );
10816  (*nchgsides) += 2;
10817  }
10818  }
10819 
10820  return SCIP_OKAY;
10821 }
10822 
10823 /** tries to simplify coefficients and delete variables in constraints of the form lhs <= a^Tx <= rhs
10824  * for equations @see rangedRowSimplify() will be called
10825  *
10826  * there are several different coefficient reduction steps which will be applied
10827  *
10828  * 1. We try to determine parts of the constraint which will not change anything on (in-)feasibility of the constraint
10829  *
10830  * e.g. 5x1 + 5x2 + 3z1 <= 8 => 3z1 is redundant if all x are binary and -2 < 3z1 <= 3
10831  *
10832  * 2. We try to remove redundant fractional parts in a constraint
10833  *
10834  * e.g. 5.2x1 + 5.1x2 + 3x3 <= 8.3 => will be changed to 5x1 + 5x2 + 3x3 <= 8 if all x are binary
10835  *
10836  * 3. We are using the greatest common divisor for further reductions
10837  *
10838  * e.g. 10x1 + 5y2 + 5x3 + 3x4 <= 15 => will be changed to 2x1 + y2 + x3 + x4 <= 3 if all xi are binary and y2 is
10839  * integral
10840  */
10841 static
10843  SCIP* scip, /**< SCIP data structure */
10844  SCIP_CONS* cons, /**< linear constraint */
10845  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
10846  int* nchgsides /**< pointer to store the amount of changed sides */
10847  )
10848 {
10849  SCIP_CONSDATA* consdata;
10850  SCIP_VAR** vars;
10851  SCIP_Real* vals;
10852  int* perm;
10853  SCIP_Real minactsub;
10854  SCIP_Real maxactsub;
10855  SCIP_Real siderest;
10856  SCIP_Real feastol;
10857  SCIP_Real newcoef;
10858  SCIP_Real absval;
10859  SCIP_Real side;
10860  SCIP_Real lhs;
10861  SCIP_Real rhs;
10862  SCIP_Real lb;
10863  SCIP_Real ub;
10864  SCIP_Longint restcoef;
10865  SCIP_Longint oldgcd;
10866  SCIP_Longint rest;
10867  SCIP_Longint gcd;
10868  SCIP_Bool isminsettoinfinity;
10869  SCIP_Bool ismaxsettoinfinity;
10870  SCIP_Bool isminrelax;
10871  SCIP_Bool ismaxrelax;
10872  SCIP_Bool allcoefintegral;
10873  SCIP_Bool onlybin;
10874  SCIP_Bool hasrhs;
10875  SCIP_Bool haslhs;
10876  int oldnchgcoefs;
10877  int oldnchgsides;
10878  int foundbin;
10879  int candpos;
10880  int candpos2;
10881  int offsetv;
10882  int nvars;
10883  int v;
10884  int w;
10885 
10886  assert(scip != NULL);
10887  assert(cons != NULL);
10888  assert(nchgcoefs != NULL);
10889  assert(nchgsides != NULL);
10890 
10891  /* we must not change a modifiable constraint in any way */
10892  if( SCIPconsIsModifiable(cons) )
10893  return SCIP_OKAY;
10894 
10895  if( SCIPconsIsDeleted(cons) )
10896  return SCIP_OKAY;
10897 
10898  consdata = SCIPconsGetData(cons);
10899  assert(consdata != NULL);
10900 
10901  nvars = consdata->nvars;
10902 
10903  /* do not check empty or bound-constraints */
10904  if( nvars <= 2 )
10905  return SCIP_OKAY;
10906 
10907  /* update maximal activity delta if necessary */
10908  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
10909  consdataRecomputeMaxActivityDelta(scip, consdata);
10910 
10911  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
10912  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
10913  checkMaxActivityDelta(scip, consdata);
10914 
10915  /* @todo the following might be too hard, check which steps can be applied and what code must be corrected
10916  * accordingly
10917  */
10918  /* can only work with valid non-infinity activities per variable */
10919  if( SCIPisInfinity(scip, consdata->maxactdelta) )
10920  return SCIP_OKAY;
10921 
10922  /* @todo: change the following: due to vartype changes, the status of the normalization can be wrong, need an event
10923  * but the eventsystem seems to be full
10924  */
10925  consdata->normalized = FALSE;
10926 
10927  /* normalize constraint */
10928  SCIP_CALL( normalizeCons(scip, cons) );
10929  assert(consdata->normalized);
10930  assert(nvars == consdata->nvars);
10931 
10932  lhs = consdata->lhs;
10933  rhs = consdata->rhs;
10934  assert(!SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs));
10935  assert(!SCIPisNegative(scip, rhs));
10936 
10937  if( !SCIPisInfinity(scip, -lhs) )
10938  haslhs = TRUE;
10939  else
10940  haslhs = FALSE;
10941 
10942  if( !SCIPisInfinity(scip, rhs) )
10943  hasrhs = TRUE;
10944  else
10945  hasrhs = FALSE;
10946 
10947  oldnchgcoefs = *nchgcoefs;
10948  oldnchgsides = *nchgsides;
10949 
10950  /* @todo also work on ranged rows */
10951  if( haslhs && hasrhs )
10952  {
10953  SCIP_CALL( rangedRowSimplify(scip, cons, nchgcoefs, nchgsides ) );
10954 
10955  return SCIP_OKAY;
10956  }
10957  assert(haslhs != hasrhs);
10958 
10959  /* if we have a normalized inequality (not ranged) the one side should be positive, @see normalizeCons() */
10960  assert(!hasrhs || !SCIPisNegative(scip, rhs));
10961  assert(!haslhs || !SCIPisNegative(scip, lhs));
10962 
10963  /* get temporary memory to store the sorted permutation */
10964  SCIP_CALL( SCIPallocBufferArray(scip, &perm, nvars) );
10965 
10966  /* call sorting method, order continuous variables to the end and all other variables after non-increasing absolute
10967  * value of their coefficients
10968  */
10969  SCIPsort(perm, consdataCompSim, (void*)consdata, nvars);
10970 
10971  /* perform sorting after permutation array */
10972  permSortConsdata(consdata, perm, nvars);
10973  consdata->sorted = FALSE;
10974  consdata->binvarssorted = FALSE;
10975 
10976  vars = consdata->vars;
10977  vals = consdata->vals;
10978  assert(vars != NULL);
10979  assert(vals != NULL);
10980  assert(consdata->validmaxabsval ? (SCIPisFeasEQ(scip, consdata->maxabsval, REALABS(vals[0])) || SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS) : TRUE);
10981 
10982  /* free temporary memory */
10983  SCIPfreeBufferArray(scip, &perm);
10984 
10985  /* only check constraints with at least two non continuous variables */
10986  if( SCIPvarGetType(vars[1]) == SCIP_VARTYPE_CONTINUOUS )
10987  return SCIP_OKAY;
10988 
10989  /* do not process constraints when all coefficients are 1.0 */
10990  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) && ((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs))) )
10991  return SCIP_OKAY;
10992 
10993  feastol = SCIPfeastol(scip);
10994 
10995  SCIPdebugMessage("starting simplification of coefficients\n");
10996  SCIPdebugPrintCons(scip, cons, NULL);
10997 
10998  /* get global activities */
10999  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minactsub, &maxactsub,
11000  &isminrelax, &ismaxrelax, &isminsettoinfinity, &ismaxsettoinfinity);
11001 
11002  /* cannot work with infinite activities */
11003  if( isminsettoinfinity || ismaxsettoinfinity )
11004  return SCIP_OKAY;
11005 
11006  assert(!isminrelax);
11007  assert(!ismaxrelax);
11008  assert(maxactsub > minactsub);
11009  assert(!SCIPisInfinity(scip, -minactsub));
11010  assert(!SCIPisInfinity(scip, maxactsub));
11011 
11012  v = 0;
11013  offsetv = -1;
11014  side = haslhs ? lhs : rhs;
11015 
11016  /* we now determine coefficients as large as the side of the constraint to retrieve a better reduction where we
11017  * do not need to look at the large coefficients
11018  *
11019  * e.g. all x are binary, z are positive integer
11020  * c1: +5x1 + 5x2 + 3x3 + 3x4 + x5 >= 5 (x5 is redundant and does not change (in-)feasibility of this constraint)
11021  * c2: +4x1 + 4x2 + 3x3 + 3x4 + x5 >= 4 (gcd (without the coefficient of x5) after the large coefficients is 3
11022  * c3: +30x1 + 29x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 30 (gcd (without the coefficient of x2) after the large coefficients is 7
11023  *
11024  * can be changed to
11025  *
11026  * c1: +6x1 + 6x2 + 3x3 + 3x4 >= 6 (will be changed to c1: +2x1 + 2x2 + x3 + x4 >= 2)
11027  * c2: +6x1 + 6x2 + 3x3 + 3x4 + 3x5 >= 6 (will be changed to c2: +2x1 + 2x2 + x3 + x4 + x5 >= 2)
11028  * c3: +28x1 + 28x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 28 (will be changed to c3: +4x1 + 4x2 + 2x3 + 2z1 + x5 + x6 <= 4)
11029  */
11030 
11031  /* if the minimal activity is negative and we found more than one variable with a coefficient bigger than the left
11032  * hand side, we cannot apply the extra reduction step and need to reset v
11033  *
11034  * 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
11035  * coefficients due to the gcd on the "small" coefficients we would get 8x1 + 8x2 - 4x3 - 4x4 >= 8 were xi = 1
11036  * for all i is a solution
11037  *
11038  * also redundancy of variables would not be correctly determined in such a case
11039  */
11040  if( nvars > 2 && SCIPisEQ(scip, vals[0], side) && !SCIPisNegative(scip, minactsub) )
11041  {
11042  v = 1;
11043 
11044  while( v < nvars && SCIPisEQ(scip, side, vals[v]) )
11045  {
11046  /* if we have integer variable with "side"-coefficients but also with a lower bound greater than 0 we stop this
11047  * extra step, which might have worked
11048  */
11049  if( SCIPvarGetLbGlobal(vars[v]) > 0.5 )
11050  {
11051  v = 0;
11052  break;
11053  }
11054 
11055  ++v;
11056  }
11057 
11058  /* easy and quick fix: if all coefficients were equal to the side, we cannot apply further simplifications */
11059  /* todo find numerically stable normalization conditions to scale this cons to have coefficients almost equal to 1 */
11060  if( v == nvars )
11061  return SCIP_OKAY;
11062 
11063  /* cannot work with continuous variables which have a big coefficient */
11064  if( v > 0 && SCIPvarGetType(vars[v - 1]) == SCIP_VARTYPE_CONTINUOUS )
11065  return SCIP_OKAY;
11066 
11067  /* big negative coefficient, do not try to use the extra coefficient reduction step */
11068  if( SCIPisEQ(scip, side, -vals[v]) )
11069  v = 0;
11070 
11071  /* all but one variable are processed or the next variable is continuous we cannot perform the extra coefficient
11072  * reduction
11073  */
11074  if( v == nvars - 1 || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11075  v = 0;
11076 
11077  if( v > 0 )
11078  {
11079  assert(v < nvars);
11080 
11081  offsetv = v - 1;
11082 
11083  for( w = 0; w < v; ++w )
11084  {
11085  lb = SCIPvarGetLbGlobal(vars[w]);
11086  ub = SCIPvarGetUbGlobal(vars[w]);
11087 
11088  assert(vals[w] > 0);
11089 
11090  /* update residual activities */
11091  maxactsub -= ub * vals[w];
11092  minactsub -= lb * vals[w];
11093  assert(maxactsub > minactsub);
11094  }
11095  }
11096  }
11097 
11098  /* find and remove redundant variables which do not interact with the (in-)feasibility of this constraint
11099  *
11100  * e.g. let all x are binary and y1 is continuous with bounds [-3,1] then we can reduce
11101  *
11102  * 15x1 + 15x2 + 7x3 + 3x4 + y1 <= 26
11103  * to
11104  * 15x1 + 15x2 <= 26 <=> x1 + x2 <= 1
11105  */
11106  if( nvars > 2 && SCIPisIntegral(scip, vals[v]) )
11107  {
11108  SCIP_Bool redundant = FALSE;
11109 
11110  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11111  assert(gcd >= 1);
11112 
11113  if( v == 0 )
11114  {
11115  lb = SCIPvarGetLbGlobal(vars[0]);
11116  ub = SCIPvarGetUbGlobal(vars[0]);
11117 
11118  /* update residual activities */
11119  if( vals[0] > 0 )
11120  {
11121  maxactsub -= ub * vals[0];
11122  minactsub -= lb * vals[0];
11123  }
11124  else
11125  {
11126  maxactsub -= lb * vals[0];
11127  minactsub -= ub * vals[0];
11128  }
11129  assert(maxactsub > minactsub);
11130  ++v;
11131  }
11132 
11133  siderest = -SCIP_INVALID;
11134  allcoefintegral = TRUE;
11135 
11136  /* check if some variables always fit into the given constraint */
11137  for( ; v < nvars - 1; ++v )
11138  {
11139  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11140  break;
11141 
11142  if( !SCIPisIntegral(scip, vals[v]) )
11143  {
11144  allcoefintegral = FALSE;
11145  break;
11146  }
11147 
11148  /* calculate greatest common divisor for all general and binary variables */
11149  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11150 
11151  if( gcd == 1 )
11152  break;
11153 
11154  lb = SCIPvarGetLbGlobal(vars[v]);
11155  ub = SCIPvarGetUbGlobal(vars[v]);
11156 
11157  assert(!SCIPisInfinity(scip, -lb));
11158  assert(!SCIPisInfinity(scip, ub));
11159 
11160  /* update residual activities */
11161  if( vals[v] > 0 )
11162  {
11163  maxactsub -= ub * vals[v];
11164  minactsub -= lb * vals[v];
11165  }
11166  else
11167  {
11168  maxactsub -= lb * vals[v];
11169  minactsub -= ub * vals[v];
11170  }
11171  assert(SCIPisGE(scip, maxactsub, minactsub));
11172 
11173  if( hasrhs )
11174  {
11175  /* determine the remainder of the right hand side and the gcd */
11176  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11177  }
11178  else
11179  {
11180  /* determine the remainder of the left hand side and the gcd */
11181  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11182  if( SCIPisZero(scip, siderest) )
11183  siderest = gcd;
11184  }
11185 
11186  /* early termination if the activities deceed the gcd */
11187  if( (offsetv == -1 && hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd)) || (haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd) )
11188  {
11189  redundant = TRUE;
11190  break;
11191  }
11192  }
11193  assert(v < nvars || (offsetv >= 0 && gcd > 1));
11194 
11195  if( !redundant )
11196  {
11197  if( hasrhs )
11198  {
11199  /* determine the remainder of the right hand side and the gcd */
11200  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11201  }
11202  else
11203  {
11204  /* determine the remainder of the left hand side and the gcd */
11205  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11206  if( SCIPisZero(scip, siderest) )
11207  siderest = gcd;
11208  }
11209  }
11210  else
11211  ++v;
11212 
11213  SCIPdebugMessage("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", v, nvars, minactsub, maxactsub, redundant, hasrhs, siderest, gcd, offsetv);
11214 
11215  /* check if we can remove redundant variables */
11216  if( v < nvars && (redundant ||
11217  (offsetv == -1 && hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd)) ||
11218  (haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd)) )
11219  {
11220  SCIP_Real oldcoef;
11221 
11222  /* double check the redundancy */
11223 #ifndef NDEBUG
11224  SCIP_Real tmpminactsub = 0.0;
11225  SCIP_Real tmpmaxactsub = 0.0;
11226 
11227  /* recompute residual activities */
11228  for( w = v; w < nvars; ++w )
11229  {
11230  lb = SCIPvarGetLbGlobal(vars[w]);
11231  ub = SCIPvarGetUbGlobal(vars[w]);
11232 
11233  assert(!SCIPisInfinity(scip, -lb));
11234  assert(!SCIPisInfinity(scip, ub));
11235 
11236  /* update residual activities */
11237  if( vals[w] > 0 )
11238  {
11239  tmpmaxactsub += ub * vals[w];
11240  tmpminactsub += lb * vals[w];
11241  }
11242  else
11243  {
11244  tmpmaxactsub += lb * vals[w];
11245  tmpminactsub += ub * vals[w];
11246  }
11247  assert(tmpmaxactsub >= tmpminactsub);
11248  }
11249 
11250  if( hasrhs )
11251  {
11252  assert(offsetv == -1);
11253 
11254  /* determine the remainder of the right hand side and the gcd */
11255  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11256  }
11257  else
11258  {
11259  /* determine the remainder of the left hand side and the gcd */
11260  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11261  if( SCIPisZero(scip, siderest) )
11262  siderest = gcd;
11263  }
11264 
11265  /* does the redundancy really is fulfilled */
11266  assert((hasrhs && SCIPisLE(scip, tmpmaxactsub, siderest) && tmpminactsub > siderest - gcd) || (haslhs && tmpmaxactsub < siderest && SCIPisGE(scip, tmpminactsub, siderest - gcd)));
11267 #endif
11268 
11269  SCIPdebugMessage("removing %d last variables from constraint <%s>, because they never change anything on the feasibility of this constraint\n", nvars - v, SCIPconsGetName(cons));
11270 
11271  /* remove redundant variables */
11272  for( w = nvars - 1; w >= v; --w )
11273  {
11274  SCIP_CALL( delCoefPos(scip, cons, w) );
11275  }
11276  (*nchgcoefs) += (nvars - v);
11277 
11278  assert(w >= 0);
11279 
11280  oldcoef = vals[w];
11281 
11282  /* normalize constraint */
11283  SCIP_CALL( normalizeCons(scip, cons) );
11284  assert(vars == consdata->vars);
11285  assert(vals == consdata->vals);
11286  assert(w < consdata->nvars);
11287 
11288  /* compute new greatest common divisor due to normalization */
11289  gcd = (SCIP_Longint)(gcd / (oldcoef/vals[w]) + feastol);
11290  assert(gcd >= 1);
11291 
11292  /* update side */
11293  if( hasrhs )
11294  {
11295  /* replace old with new right hand side */
11296  SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
11297  rhs = consdata->rhs;
11298  }
11299  else
11300  {
11301  if( SCIPisFeasGT(scip, oldcoef/vals[w], 1.0) )
11302  {
11303  SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
11304  lhs = consdata->lhs;
11305  }
11306  else
11307  assert(offsetv == -1 || SCIPisEQ(scip, vals[offsetv], consdata->lhs));
11308  }
11309  ++(*nchgsides);
11310 
11311  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11312  assert(!haslhs || !SCIPisNegative(scip, lhs));
11313 
11314  /* get new constraint data */
11315  nvars = consdata->nvars;
11316  assert(nvars >= 2);
11317 
11318  allcoefintegral = TRUE;
11319 
11320 #ifndef NDEBUG
11321  /* check integrality */
11322  for( w = offsetv + 1; w < nvars; ++w )
11323  {
11324  assert(SCIPisIntegral(scip, vals[w]));
11325  }
11326 #endif
11327  SCIPdebugPrintCons(scip, cons, NULL);
11328  }
11329 
11330  /* try to find a better gcd, when having large coefficients */
11331  if( offsetv >= 0 && gcd == 1 )
11332  {
11333  /* calculate greatest common divisor for all general variables */
11334  gcd = (SCIP_Longint)(REALABS(vals[nvars - 1]) + feastol);
11335 
11336  if( gcd > 1 )
11337  {
11338  gcd = -1;
11339  candpos = -1;
11340 
11341  for( v = nvars - 1; v > offsetv; --v )
11342  {
11343  assert(!SCIPisZero(scip, vals[v]));
11344  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11345  break;
11346 
11347  if( !SCIPisIntegral(scip, vals[v]) )
11348  {
11349  allcoefintegral = FALSE;
11350  break;
11351  }
11352 
11353  oldgcd = gcd;
11354 
11355  if( gcd == -1 )
11356  {
11357  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11358  assert(gcd >= 1);
11359  }
11360  else
11361  {
11362  /* calculate greatest common divisor for all general and binary variables */
11363  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11364  }
11365 
11366  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
11367  * can stop searching
11368  */
11369  if( gcd == 1 )
11370  {
11371  if( !SCIPvarIsBinary(vars[v]) )
11372  break;
11373 
11374  /* found candidate */
11375  if( candpos == -1 )
11376  {
11377  gcd = oldgcd;
11378  candpos = v;
11379  }
11380  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
11381  else
11382  break;
11383  }
11384  }
11385  assert(v > offsetv || candpos > offsetv);
11386  }
11387  else
11388  candpos = -1;
11389  }
11390  else
11391  candpos = nvars - 1;
11392 
11393  /* check last coefficient for integrality */
11394  if( gcd > 1 && allcoefintegral && !redundant )
11395  {
11396  if( !SCIPisIntegral(scip, vals[nvars - 1]) )
11397  allcoefintegral = FALSE;
11398  }
11399 
11400  /* check for further necessary coefficient adjustments */
11401  if( offsetv >= 0 && gcd > 1 && allcoefintegral )
11402  {
11403  assert(offsetv + 1 < nvars);
11404  assert(0 <= candpos && candpos < nvars);
11405 
11406  if( SCIPvarGetType(vars[candpos]) != SCIP_VARTYPE_CONTINUOUS )
11407  {
11408  SCIP_Bool notchangable = FALSE;
11409 
11410 #ifndef NDEBUG
11411  /* check integrality */
11412  for( w = offsetv + 1; w < nvars; ++w )
11413  {
11414  assert(SCIPisIntegral(scip, vals[w]));
11415  }
11416 #endif
11417 
11418  if( vals[candpos] > 0 && SCIPvarIsBinary(vars[candpos]) &&
11419  SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) < gcd )
11420  {
11421  /* determine the remainder of the side and the gcd */
11422  if( hasrhs )
11423  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
11424  else
11425  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
11426  assert(rest >= 0);
11427  assert(rest < gcd);
11428 
11429  /* determine the remainder of the coefficient candidate and the gcd */
11430  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
11431  assert(restcoef >= 1);
11432  assert(restcoef < gcd);
11433 
11434  if( hasrhs )
11435  {
11436  /* calculate new coefficient */
11437  if( restcoef > rest )
11438  newcoef = vals[candpos] - restcoef + gcd;
11439  else
11440  newcoef = vals[candpos] - restcoef;
11441  }
11442  else
11443  {
11444  /* calculate new coefficient */
11445  if( rest == 0 || restcoef < rest )
11446  newcoef = vals[candpos] - restcoef;
11447  else
11448  newcoef = vals[candpos] - restcoef + gcd;
11449  }
11450 
11451 
11452  /* done */
11453 
11454  /* new coeffcient must not be zero if we would loose the implication that a variable needs to be 0 if
11455  * another with the big coefficient was set to 1
11456  */
11457  if( hasrhs && SCIPisZero(scip, newcoef) )
11458  {
11459  notchangable = TRUE;
11460  }
11461  else if( SCIPisZero(scip, newcoef) )
11462  {
11463  /* delete old redundant coefficient */
11464  SCIP_CALL( delCoefPos(scip, cons, candpos) );
11465  ++(*nchgcoefs);
11466  }
11467  else
11468  {
11469  /* replace old with new coefficient */
11470  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
11471  ++(*nchgcoefs);
11472  }
11473  }
11474  else if( vals[candpos] < 0 || !SCIPvarIsBinary(vars[candpos]) )
11475  {
11476  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol));
11477  }
11478 
11479  /* correct side and big coefficients */
11480  if( (!notchangable && hasrhs && ((!SCIPisFeasIntegral(scip, rhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(rhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd))) ||
11481  ( haslhs && (!SCIPisFeasIntegral(scip, lhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(lhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd)) )
11482  {
11483  if( haslhs )
11484  {
11485  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasCeil(scip, lhs/gcd) * gcd + feastol));
11486 
11487  SCIP_CALL( chgLhs(scip, cons, newcoef) );
11488  ++(*nchgsides);
11489  }
11490  else
11491  {
11492  assert(hasrhs);
11493  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasFloor(scip, rhs/gcd) * gcd + feastol));
11494 
11495  SCIP_CALL( chgRhs(scip, cons, newcoef) );
11496  ++(*nchgsides);
11497  }
11498 
11499  /* correct coefficients up front */
11500  for( w = offsetv; w >= 0; --w )
11501  {
11502  assert(vals[w] > 0);
11503 
11504  SCIP_CALL( chgCoefPos(scip, cons, w, newcoef) );
11505  }
11506  (*nchgcoefs) += (offsetv + 1);
11507  }
11508 
11509  if( !notchangable )
11510  {
11511  /* normalize constraint */
11512  SCIP_CALL( normalizeCons(scip, cons) );
11513  assert(vars == consdata->vars);
11514  assert(vals == consdata->vals);
11515 
11516  /* get new constraint data */
11517  nvars = consdata->nvars;
11518  assert(nvars >= 2);
11519 
11520  SCIPdebugPrintCons(scip, cons, NULL);
11521 
11522  lhs = consdata->lhs;
11523  rhs = consdata->rhs;
11524  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11525  assert(!haslhs || !SCIPisNegative(scip, lhs));
11526  }
11527  }
11528  }
11529  }
11530 
11531  /* @todo we still can remove continuous variables if they are redundant due to the non-integrality argument */
11532  /* no continuous variables are left over */
11533  if( SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS )
11534  return SCIP_OKAY;
11535 
11536  onlybin = TRUE;
11537  allcoefintegral = TRUE;
11538  /* check if all variables are of binary type */
11539  for( v = nvars - 1; v >= 0; --v )
11540  {
11541  if( !SCIPvarIsBinary(vars[v]) )
11542  onlybin = FALSE;
11543  if( !SCIPisIntegral(scip, vals[v]) )
11544  allcoefintegral = FALSE;
11545  }
11546 
11547  /* check if the non-integrality part of all integral variables is smaller than the non-inegrality part of the right
11548  * hand side or bigger than the left hand side respectively, so we can make all of them integral
11549  *
11550  * @todo there are some steps missing ....
11551  */
11552  if( (hasrhs && !SCIPisFeasIntegral(scip, rhs)) || (haslhs && !SCIPisFeasIntegral(scip, lhs)) )
11553  {
11554  SCIP_Real val;
11555  SCIP_Real newval;
11556  SCIP_Real frac = 0.0;
11557  SCIP_Bool found = FALSE;
11558 
11559  if( hasrhs )
11560  {
11561  if( allcoefintegral )
11562  {
11563  /* replace old with new right hand side */
11564  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
11565  ++(*nchgsides);
11566  }
11567  else
11568  {
11569  siderest = rhs - SCIPfloor(scip, rhs);
11570 
11571  /* try to round down all non-integral coefficients */
11572  for( v = nvars - 1; v >= 0; --v )
11573  {
11574  val = vals[v];
11575 
11576  /* add up all possible fractional parts */
11577  if( !SCIPisIntegral(scip, val) )
11578  {
11579  lb = SCIPvarGetLbGlobal(vars[v]);
11580  ub = SCIPvarGetUbGlobal(vars[v]);
11581 
11582  /* at least one bound need to be at zero */
11583  if( !onlybin && !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
11584  return SCIP_OKAY;
11585 
11586  /* swap bounds for 'standard' form */
11587  if( !SCIPisFeasZero(scip, lb) )
11588  {
11589  SCIP_Real tmp = lb;
11590  lb = ub;
11591  ub = tmp;
11592  val *= -1;
11593  }
11594 
11595  found = TRUE;
11596 
11597  frac += (val - SCIPfloor(scip, val)) * ub;
11598 
11599  /* if we exceed the fractional part of the right hand side, we cannot tighten the coefficients
11600  *
11601  * e.g. 1.1x1 + 1.1x2 + 1.4x3 + 1.02x4 <= 2.4, here we cannot floor all fractionals because
11602  * x3, x4 set to 1 would be infeasible but feasible after flooring
11603  */
11604  if( SCIPisGT(scip, frac, siderest) )
11605  return SCIP_OKAY;
11606  }
11607  }
11608  assert(v == -1);
11609 
11610  SCIPdebugMessage("rounding all non-integral coefficients and the right hand side down\n");
11611 
11612  /* round rhs and coefficients to integral values */
11613  if( found )
11614  {
11615  for( v = nvars - 1; v >= 0; --v )
11616  {
11617  val = vals[v];
11618 
11619  /* add the whole fractional part */
11620  if( !SCIPisIntegral(scip, val) )
11621  {
11622  lb = SCIPvarGetLbGlobal(vars[v]);
11623 
11624  if( SCIPisFeasZero(scip, lb) )
11625  newval = SCIPfloor(scip, val);
11626  else
11627  newval = SCIPceil(scip, val);
11628 
11629  if( SCIPisZero(scip, newval) )
11630  {
11631  /* delete old redundant coefficient */
11632  SCIP_CALL( delCoefPos(scip, cons, v) );
11633  ++(*nchgcoefs);
11634  }
11635  else
11636  {
11637  /* replace old with new coefficient */
11638  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
11639  ++(*nchgcoefs);
11640  }
11641  }
11642  }
11643  }
11644 
11645  /* replace old with new right hand side */
11646  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
11647  ++(*nchgsides);
11648  }
11649  }
11650  else
11651  {
11652  if( allcoefintegral )
11653  {
11654  /* replace old with new left hand side */
11655  SCIP_CALL( chgLhs(scip, cons, SCIPceil(scip, lhs)) );
11656  ++(*nchgsides);
11657  }
11658  else
11659  {
11660  /* cannot floor left hand side to zero */
11661  if( SCIPisLT(scip, lhs, 1.0) )
11662  return SCIP_OKAY;
11663 
11664  siderest = lhs - SCIPfloor(scip, lhs);
11665 
11666  /* try to round down all non-integral coefficients */
11667  for( v = nvars - 1; v >= 0; --v )
11668  {
11669  val = vals[v];
11670 
11671  /* add up all possible fractional parts */
11672  if( !SCIPisIntegral(scip, val) )
11673  {
11674  lb = SCIPvarGetLbGlobal(vars[v]);
11675  ub = SCIPvarGetUbGlobal(vars[v]);
11676 
11677  /* at least one bound need to be at zero */
11678  if( !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
11679  return SCIP_OKAY;
11680 
11681  /* swap bounds for 'standard' form */
11682  if( !SCIPisFeasZero(scip, lb) )
11683  {
11684  SCIP_Real tmp = lb;
11685  lb = ub;
11686  ub = tmp;
11687  val *= -1;
11688  }
11689 
11690  /* cannot floor to zero */
11691  if( SCIPisLT(scip, val, 1.0) )
11692  return SCIP_OKAY;
11693 
11694  /* the fractional part on each variable need to exceed the fractional part on the left hand side */
11695  if( SCIPisLT(scip, val - SCIPfloor(scip, val), siderest) )
11696  return SCIP_OKAY;
11697 
11698  found = TRUE;
11699 
11700  frac += (val - SCIPfloor(scip, val)) * ub;
11701 
11702  /* if we exceed the fractional part of the left hand side plus one by summing up all maximal
11703  * fractional parts of the variables, we cannot tighten the coefficients
11704  *
11705  * e.g. 4.3x1 + 1.3x2 + 1.3x3 + 1.6x4 >= 4.2, here we cannot floor all fractionals because
11706  * x2-x4 set to 1 would be feasible but not after flooring
11707  */
11708  if( SCIPisGE(scip, frac, 1 + siderest) )
11709  return SCIP_OKAY;
11710  }
11711  /* all coefficients need to be integral, otherwise we might do an invalid reduction */
11712  else
11713  return SCIP_OKAY;
11714  }
11715  assert(v == -1);
11716 
11717  SCIPdebugMessage("rounding all non-integral coefficients and the left hand side down\n");
11718 
11719  /* round lhs and coefficients to integral values */
11720  if( found )
11721  {
11722  for( v = nvars - 1; v >= 0; --v )
11723  {
11724  val = vals[v];
11725 
11726  /* add the whole fractional part */
11727  if( !SCIPisIntegral(scip, val) )
11728  {
11729  lb = SCIPvarGetLbGlobal(vars[v]);
11730 
11731  if( SCIPisFeasZero(scip, lb) )
11732  newval = SCIPfloor(scip, val);
11733  else
11734  newval = SCIPceil(scip, val);
11735 
11736  if( SCIPisZero(scip, newval) )
11737  {
11738  /* delete old redundant coefficient */
11739  SCIP_CALL( delCoefPos(scip, cons, v) );
11740  ++(*nchgcoefs);
11741  }
11742  else
11743  {
11744  /* replace old with new coefficient */
11745  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
11746  ++(*nchgcoefs);
11747  }
11748  }
11749  }
11750  }
11751 
11752  /* replace old with new left hand side */
11753  SCIP_CALL( chgLhs(scip, cons, SCIPfloor(scip, lhs)) );
11754  ++(*nchgsides);
11755  }
11756  }
11757 
11758  /* normalize constraint */
11759  SCIP_CALL( normalizeCons(scip, cons) );
11760  assert(vars == consdata->vars);
11761  assert(vals == consdata->vals);
11762 
11763  rhs = consdata->rhs;
11764  lhs = consdata->lhs;
11765 
11766  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11767  assert(!haslhs || !SCIPisNegative(scip, lhs));
11768 
11769  SCIPdebugPrintCons(scip, cons, NULL);
11770 
11771  nvars = consdata->nvars;
11772  if( nvars < 2 )
11773  return SCIP_OKAY;
11774 
11775  allcoefintegral = TRUE;
11776 #ifndef NDEBUG
11777  /* debug check if all coefficients are really integral */
11778  for( v = nvars - 1; v >= 0; --v )
11779  assert(SCIPisIntegral(scip, vals[v]));
11780 #endif
11781  }
11782 
11783  /* @todo following can also work on non integral coefficients, need more investigation */
11784  /* only check constraints with integral coefficients on all integral variables */
11785  if( !allcoefintegral )
11786  return SCIP_OKAY;
11787 
11788  /* we want to avoid numerical troubles, therefore we do not change non-integral sides */
11789  if( (hasrhs && !SCIPisIntegral(scip, rhs)) || (haslhs && !SCIPisIntegral(scip, lhs)) )
11790  return SCIP_OKAY;
11791 
11792  /* maximal absolute value of coefficients in constraint is one, so we cannot tighten it further */
11793  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) )
11794  return SCIP_OKAY;
11795 
11796  /* stop if the last coeffcients is one in absolute value and the variable is not binary */
11797  if( !SCIPvarIsBinary(vars[nvars - 1]) && SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) )
11798  return SCIP_OKAY;
11799 
11800  assert(nvars >= 2);
11801 
11802  /* start gcd procedure for all variables */
11803 
11804  do
11805  {
11806  oldnchgcoefs = *nchgcoefs;
11807  oldnchgsides = *nchgsides;
11808 
11809  /* stop if we have two coeffcients which are one in absolute value */
11810  if( SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) && SCIPisEQ(scip, REALABS(vals[nvars - 2]), 1.0) )
11811  return SCIP_OKAY;
11812 
11813  gcd = -1;
11814 
11815  /* calculate greatest common divisor over all integer variables */
11816  if( !onlybin )
11817  {
11818  foundbin = -1;
11819 
11820  for( v = nvars - 1; v >= 0; --v )
11821  {
11822  assert(!SCIPisZero(scip, vals[v]));
11823  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS);
11824 
11825  if( SCIPvarIsBinary(vars[v]) )
11826  {
11827  if( foundbin == -1 )
11828  foundbin = v;
11829  continue;
11830  }
11831 
11832  absval = REALABS(vals[v]);
11833  assert(SCIPisIntegral(scip, absval));
11834 
11835  if( gcd == -1 )
11836  {
11837  gcd = (SCIP_Longint)(absval + feastol);
11838  assert(gcd >= 1);
11839  }
11840  else
11841  {
11842  /* calculate greatest common divisor for all general variables */
11843  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(absval + feastol));
11844  }
11845  if( gcd == 1 )
11846  break;
11847  }
11848  }
11849  else
11850  foundbin = nvars - 1;
11851 
11852  /* we need at least one binary variable and a gcd greater than 1 to try to perform further coefficient changes */
11853  if( gcd == 1 || foundbin == -1)
11854  return SCIP_OKAY;
11855 
11856  assert((onlybin && gcd == -1) || (!onlybin && gcd > 1));
11857 
11858  candpos = -1;
11859  candpos2 = -1;
11860 
11861  /* calculate greatest common divisor over all integer and binary variables and determine the candidate where we might
11862  * change the coefficient
11863  */
11864  for( v = foundbin; v >= 0; --v )
11865  {
11866  if( onlybin || SCIPvarIsBinary(vars[v]) )
11867  {
11868  absval = REALABS(vals[v]);
11869  assert(SCIPisIntegral(scip, absval));
11870 
11871  oldgcd = gcd;
11872 
11873  if( gcd == -1 )
11874  {
11875  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11876  assert(gcd >= 1);
11877  }
11878  else
11879  {
11880  /* calculate greatest common divisor for all general and binary variables */
11881  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11882  }
11883 
11884  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
11885  * can terminate
11886  */
11887  if( gcd == 1 )
11888  {
11889  /* found candidate */
11890  if( candpos == -1 )
11891  {
11892  gcd = oldgcd;
11893  candpos = v;
11894 
11895  /* if we have only binary variables and both first coefficients have a gcd of 1, both are candidates for
11896  * the coefficient change
11897  */
11898  if( onlybin && v == foundbin - 1 )
11899  candpos2 = foundbin;
11900  }
11901  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
11902  else
11903  {
11904  if( onlybin && candpos == v + 1 && candpos2 == v + 2 )
11905  {
11906  assert(candpos2 == nvars - 1);
11907 
11908  /* take new candidates */
11909  candpos = candpos2;
11910 
11911  /* recalculate gcd from scratch */
11912  gcd = (SCIP_Longint)(REALABS(vals[v+1]) + feastol);
11913  assert(gcd >= 1);
11914 
11915  /* calculate greatest common divisor for all general and binary variables */
11916  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11917  if( gcd == 1 )
11918  return SCIP_OKAY;
11919  }
11920  else
11921  /* cannot determine a possible coefficient for reduction */
11922  return SCIP_OKAY;
11923  }
11924  }
11925  }
11926  }
11927  assert(gcd >= 2);
11928 
11929  /* we should have found one coefficient, that led to a gcd of 1, otherwise we could normalize the constraint
11930  * further
11931  */
11932  assert(candpos >= 0 && candpos < nvars);
11933 
11934  /* all variables and all coefficients are integral, so the side should be too */
11935  assert((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs)));
11936 
11937  /* check again, if we have a normalized inequality (not ranged) the one side should be positive,
11938  * @see normalizeCons()
11939  */
11940  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11941  assert(!haslhs || !SCIPisNegative(scip, lhs));
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  if( vals[candpos] < 0 )
11953  {
11954  restcoef = ((SCIP_Longint)(vals[candpos] - feastol)) % gcd;
11955  assert(restcoef <= -1);
11956  restcoef += gcd;
11957  }
11958  else
11959  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
11960  assert(restcoef >= 1);
11961  assert(restcoef < gcd);
11962 
11963  if( hasrhs )
11964  {
11965  if( rest > 0 )
11966  {
11967  /* replace old with new right hand side */
11968  SCIP_CALL( chgRhs(scip, cons, rhs - rest) );
11969  ++(*nchgsides);
11970  }
11971 
11972  /* calculate new coefficient */
11973  if( restcoef > rest )
11974  newcoef = vals[candpos] - restcoef + gcd;
11975  else
11976  newcoef = vals[candpos] - restcoef;
11977  }
11978  else
11979  {
11980  if( rest > 0 )
11981  {
11982  /* replace old with new left hand side */
11983  SCIP_CALL( chgLhs(scip, cons, lhs - rest + gcd) );
11984  ++(*nchgsides);
11985  }
11986 
11987  /* calculate new coefficient */
11988  if( rest == 0 || restcoef < rest )
11989  newcoef = vals[candpos] - restcoef;
11990  else
11991  newcoef = vals[candpos] - restcoef + gcd;
11992  }
11993  assert(SCIPisZero(scip, newcoef) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(newcoef) + feastol)) == gcd);
11994 
11995  SCIPdebugMessage("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));
11996 
11997  if( SCIPisZero(scip, newcoef) )
11998  {
11999  /* delete redundant coefficient */
12000  SCIP_CALL( delCoefPos(scip, cons, candpos) );
12001  }
12002  else
12003  {
12004  /* replace old with new coefficient */
12005  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12006  }
12007  ++(*nchgcoefs);
12008 
12009  /* now constraint can be normalized, might be directly done by dividing it by the gcd */
12010  SCIP_CALL( normalizeCons(scip, cons) );
12011  assert(vars == consdata->vars);
12012  assert(vals == consdata->vals);
12013 
12014  SCIPdebugPrintCons(scip, cons, NULL);
12015 
12016  rhs = consdata->rhs;
12017  lhs = consdata->lhs;
12018  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12019  assert(!haslhs || !SCIPisNegative(scip, lhs));
12020 
12021  nvars = consdata->nvars;
12022 
12023  SCIPdebugMessage("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));
12024  }
12025  while( nvars >= 2 );
12026 
12027  return SCIP_OKAY;
12028 }
12029 
12030 
12031 /* tries to aggregate an (in)equality and an equality in order to decrease the number of variables in the (in)equality:
12032  * cons0 := a * cons0 + b * cons1,
12033  * where a = val1[v] and b = -val0[v] for common variable v which removes most variable weight;
12034  * for numerical stability, we will only accept integral a and b;
12035  * the variable weight is a weighted sum over all included variables, where each binary variable weighs BINWEIGHT,
12036  * each integer or implicit integer variable weighs INTWEIGHT and each continuous variable weighs CONTWEIGHT
12037  */
12038 static
12040  SCIP* scip, /**< SCIP data structure */
12041  SCIP_CONS* cons0, /**< (in)equality to modify */
12042  SCIP_CONS* cons1, /**< equality to use for aggregation of cons0 */
12043  int* commonidx0, /**< array with indices of variables in cons0, that appear also in cons1 */
12044  int* commonidx1, /**< array with indices of variables in cons1, that appear also in cons0 */
12045  int* diffidx0minus1, /**< array with indices of variables in cons0, that don't appear in cons1 */
12046  int* diffidx1minus0, /**< array with indices of variables in cons1, that don't appear in cons0 */
12047  int nvarscommon, /**< number of variables, that appear in both constraints */
12048  int commonidxweight, /**< variable weight sum of common variables */
12049  int diffidx0minus1weight, /**< variable weight sum of variables in cons0, that don't appear in cons1 */
12050  int diffidx1minus0weight, /**< variable weight sum of variables in cons1, that don't appear in cons0 */
12051  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
12052  int* nchgcoefs, /**< pointer to count the number of changed coefficients */
12053  SCIP_Bool* aggregated /**< pointer to store whether an aggregation was made */
12054  )
12056  SCIP_CONSDATA* consdata0;
12057  SCIP_CONSDATA* consdata1;
12058  SCIP_Real a;
12059  SCIP_Real b;
12060  SCIP_Real aggrcoef;
12061  SCIP_Real scalarsum;
12062  SCIP_Real bestscalarsum;
12063  SCIP_Bool betterscalarsum;
12064  SCIP_Bool commonvarlindependent; /* indicates whether coefficient vector of common variables in linearly dependent */
12065  int varweight;
12066  int nvars;
12067  int bestvarweight;
12068  int bestnvars;
12069  int bestv;
12070  int v;
12071  int i;
12072 
12073  assert(scip != NULL);
12074  assert(cons0 != NULL);
12075  assert(cons1 != NULL);
12076  assert(commonidx0 != NULL);
12077  assert(commonidx1 != NULL);
12078  assert(diffidx0minus1 != NULL);
12079  assert(diffidx1minus0 != NULL);
12080  assert(nvarscommon >= 1);
12081  assert(commonidxweight >= nvarscommon);
12082  assert(nchgcoefs != NULL);
12083  assert(aggregated != NULL);
12084 
12085  assert(SCIPconsIsActive(cons0));
12086  assert(SCIPconsIsActive(cons1));
12087 
12088  SCIPdebugMessage("try aggregation of <%s> and <%s>\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12089 
12090  /* cons0 is an (in)equality */
12091  consdata0 = SCIPconsGetData(cons0);
12092  assert(consdata0 != NULL);
12093  assert(consdata0->nvars >= 1);
12094  assert(SCIPisLE(scip, consdata0->lhs, consdata0->rhs));
12095  assert(diffidx0minus1weight >= consdata0->nvars - nvarscommon);
12096 
12097  /* cons1 is an equality */
12098  consdata1 = SCIPconsGetData(cons1);
12099  assert(consdata1 != NULL);
12100  assert(consdata1->nvars >= 1);
12101  assert(SCIPisEQ(scip, consdata1->lhs, consdata1->rhs));
12102  assert(diffidx1minus0weight >= consdata1->nvars - nvarscommon);
12103 
12104  *aggregated = FALSE;
12105 
12106  /* search for the best common variable such that
12107  * val1[var] * consdata0 - val0[var] * consdata1
12108  * has least weighted number of variables
12109  */
12110  bestvarweight = commonidxweight + diffidx0minus1weight;
12111  bestnvars = consdata0->nvars;
12112  bestv = -1;
12113  bestscalarsum = 0.0;
12114  commonvarlindependent = TRUE;
12115  for( v = 0; v < nvarscommon; ++v )
12116  {
12117  assert(consdata0->vars[commonidx0[v]] == consdata1->vars[commonidx1[v]]);
12118  a = consdata1->vals[commonidx1[v]];
12119  b = -consdata0->vals[commonidx0[v]];
12120 
12121  /* only try aggregation, if coefficients are integral (numerical stability) */
12122  if( SCIPisIntegral(scip, a) && SCIPisIntegral(scip, b) )
12123  {
12124  /* count the number of variables in the potential new constraint a * consdata0 + b * consdata1 */
12125  varweight = diffidx0minus1weight + diffidx1minus0weight;
12126  nvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12127  scalarsum = REALABS(a) + REALABS(b);
12128  betterscalarsum = (scalarsum < bestscalarsum);
12129  for( i = 0; i < nvarscommon
12130  && (varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum)); ++i )
12131  {
12132  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12133  if( !SCIPisZero(scip, aggrcoef) )
12134  {
12135  varweight += getVarWeight(consdata0->vars[commonidx0[i]]);
12136  nvars++;
12137  }
12138  }
12139  if( varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum) )
12140  {
12141  bestv = v;
12142  bestvarweight = varweight;
12143  bestnvars = nvars;
12144  bestscalarsum = scalarsum;
12145  }
12146  }
12147 
12148  /* update commonvarlindependent flag, if still TRUE:
12149  * 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
12150  */
12151  if( commonvarlindependent && v > 0 )
12152  commonvarlindependent = SCIPisEQ(scip,
12153  consdata1->vals[commonidx1[v]] * consdata0->vals[commonidx0[0]],
12154  consdata1->vals[commonidx1[0]] * consdata0->vals[commonidx0[v]]);
12155  }
12156 
12157  /* if better aggregation was found, create new constraint and delete old one */
12158  if( (bestv != -1 || commonvarlindependent) && SCIPconsGetNUpgradeLocks(cons0) == 0 )
12159  {
12160  SCIP_CONS* newcons;
12161  SCIP_CONSDATA* newconsdata;
12162  SCIP_VAR** newvars;
12163  SCIP_Real* newvals;
12164  SCIP_Real newlhs;
12165  SCIP_Real newrhs;
12166  int newnvars;
12167 
12168  if( bestv != -1 )
12169  {
12170  /* choose multipliers such that the multiplier for the (in)equality cons0 is positive */
12171  if( consdata1->vals[commonidx1[bestv]] > 0.0 )
12172  {
12173  a = consdata1->vals[commonidx1[bestv]];
12174  b = -consdata0->vals[commonidx0[bestv]];
12175  }
12176  else
12177  {
12178  a = -consdata1->vals[commonidx1[bestv]];
12179  b = consdata0->vals[commonidx0[bestv]];
12180  }
12181  assert(SCIPisIntegral(scip, a));
12182  assert(SCIPisPositive(scip, a));
12183  assert(SCIPisIntegral(scip, b));
12184  assert(!SCIPisZero(scip, b));
12185  }
12186  else
12187  {
12188  assert(commonvarlindependent);
12189  if( consdata1->vals[commonidx1[0]] > 0.0 )
12190  {
12191  a = consdata1->vals[commonidx1[0]];
12192  b = -consdata0->vals[commonidx0[0]];
12193  }
12194  else
12195  {
12196  a = -consdata1->vals[commonidx1[0]];
12197  b = consdata0->vals[commonidx0[0]];
12198  }
12199  assert(SCIPisPositive(scip, a));
12200  assert(!SCIPisZero(scip, b));
12201 
12202  /* if a/b is integral, then we can easily choose integer multipliers */
12203  if( SCIPisIntegral(scip, a/b) )
12204  {
12205  if( a/b > 0 )
12206  {
12207  a /= b;
12208  b = 1.0;
12209  }
12210  else
12211  {
12212  a /= -b;
12213  b = -1.0;
12214  }
12215  }
12216 
12217  /* setup best* variables that were not setup above because we are in the commonvarlindependent case */
12218  bestvarweight = diffidx0minus1weight + diffidx1minus0weight;
12219  bestnvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12220  }
12221 
12222  SCIPdebugMessage("aggregate linear constraints <%s> := %.15g*<%s> + %.15g*<%s> -> nvars: %d -> %d, weight: %d -> %d\n",
12223  SCIPconsGetName(cons0), a, SCIPconsGetName(cons0), b, SCIPconsGetName(cons1),
12224  consdata0->nvars, bestnvars, commonidxweight + diffidx0minus1weight, bestvarweight);
12225  SCIPdebugPrintCons(scip, cons0, NULL);
12226  SCIPdebugPrintCons(scip, cons1, NULL);
12227 
12228  /* get temporary memory for creating the new linear constraint */
12229  SCIP_CALL( SCIPallocBufferArray(scip, &newvars, bestnvars) );
12230  SCIP_CALL( SCIPallocBufferArray(scip, &newvals, bestnvars) );
12231 
12232  /* calculate the common coefficients, if we have not recognized linear dependency */
12233  newnvars = 0;
12234  if( !commonvarlindependent )
12235  {
12236  for( i = 0; i < nvarscommon; ++i )
12237  {
12238  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12239  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12240 
12241  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12242  if( !SCIPisZero(scip, aggrcoef) )
12243  {
12244  assert(newnvars < bestnvars);
12245  newvars[newnvars] = consdata0->vars[commonidx0[i]];
12246  newvals[newnvars] = aggrcoef;
12247  newnvars++;
12248  }
12249  }
12250  }
12251  else
12252  {
12253  /* if we recognized linear dependency of the common coefficients, then the aggregation coefficient should be 0.0 for every common variable */
12254 #ifndef NDEBUG
12255  for( i = 0; i < nvarscommon; ++i )
12256  {
12257  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12258  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12259 
12260  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12261  assert(SCIPisZero(scip, aggrcoef));
12262  }
12263 #endif
12264  }
12265 
12266  /* calculate the coefficients appearing in cons0 but not in cons1 */
12267  for( i = 0; i < consdata0->nvars - nvarscommon; ++i )
12268  {
12269  assert(0 <= diffidx0minus1[i] && diffidx0minus1[i] < consdata0->nvars);
12270 
12271  aggrcoef = a * consdata0->vals[diffidx0minus1[i]];
12272  assert(!SCIPisZero(scip, aggrcoef));
12273  assert(newnvars < bestnvars);
12274  newvars[newnvars] = consdata0->vars[diffidx0minus1[i]];
12275  newvals[newnvars] = aggrcoef;
12276  newnvars++;
12277  }
12278 
12279  /* calculate the coefficients appearing in cons1 but not in cons0 */
12280  for( i = 0; i < consdata1->nvars - nvarscommon; ++i )
12281  {
12282  assert(0 <= diffidx1minus0[i] && diffidx1minus0[i] < consdata1->nvars);
12283 
12284  aggrcoef = b * consdata1->vals[diffidx1minus0[i]];
12285  assert(!SCIPisZero(scip, aggrcoef));
12286  assert(newnvars < bestnvars);
12287  newvars[newnvars] = consdata1->vars[diffidx1minus0[i]];
12288  newvals[newnvars] = aggrcoef;
12289  newnvars++;
12290  }
12291  assert(newnvars == bestnvars);
12292 
12293  /* calculate the new left and right hand side of the (in)equality */
12294  assert(!SCIPisInfinity(scip, -consdata1->lhs));
12295  assert(!SCIPisInfinity(scip, consdata1->rhs));
12296  if( SCIPisInfinity(scip, -consdata0->lhs) )
12297  newlhs = -SCIPinfinity(scip);
12298  else
12299  newlhs = a * consdata0->lhs + b * consdata1->lhs;
12300  if( SCIPisInfinity(scip, consdata0->rhs) )
12301  newrhs = SCIPinfinity(scip);
12302  else
12303  newrhs = a * consdata0->rhs + b * consdata1->rhs;
12304 
12305  /* create the new linear constraint */
12306  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, SCIPconsGetName(cons0), newnvars, newvars, newvals, newlhs, newrhs,
12308  SCIPconsIsChecked(cons0), SCIPconsIsPropagated(cons0),
12309  SCIPconsIsLocal(cons0), SCIPconsIsModifiable(cons0),
12311 
12312  newconsdata = SCIPconsGetData(newcons);
12313  assert(newconsdata != NULL);
12314 
12315  /* copy the upgraded flag from the old cons0 to the new constraint */
12316  newconsdata->upgraded = consdata0->upgraded;
12317 
12318  /* normalize the new constraint */
12319  SCIP_CALL( normalizeCons(scip, newcons) );
12320 
12321  /* check, if we really want to use the new constraint instead of the old one:
12322  * use the new one, if the maximum norm doesn't grow too much
12323  */
12324  if( consdataGetMaxAbsval(SCIPconsGetData(newcons)) <= maxaggrnormscale * consdataGetMaxAbsval(consdata0) )
12325  {
12326  SCIPdebugMessage(" -> aggregated to <%s>\n", SCIPconsGetName(newcons));
12327  SCIPdebugPrintCons(scip, newcons, NULL);
12328 
12329  /* update the statistics: we changed all coefficients */
12330  if( !consdata0->upgraded )
12331  (*nchgcoefs) += consdata0->nvars + consdata1->nvars - nvarscommon;
12332  *aggregated = TRUE;
12333 
12334  /* delete the old constraint, and add the new linear constraint to the problem */
12335  SCIP_CALL( SCIPdelCons(scip, cons0) );
12336  SCIP_CALL( SCIPaddCons(scip, newcons) );
12337  }
12338 
12339  /* release the new constraint */
12340  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
12341 
12342  /* free temporary memory */
12343  SCIPfreeBufferArray(scip, &newvals);
12344  SCIPfreeBufferArray(scip, &newvars);
12345  }
12346 
12347  return SCIP_OKAY;
12348 }
12349 
12350 /** gets the key of the given element */
12351 static
12352 SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
12353 { /*lint --e{715}*/
12354  /* the key is the element itself */
12355  return elem;
12356 }
12357 
12358 /** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables and the
12359  * coefficients are either equal or negated
12360  */
12361 static
12362 SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
12363 {
12364  SCIP* scip;
12365  SCIP_CONSDATA* consdata1;
12366  SCIP_CONSDATA* consdata2;
12367  SCIP_Bool coefsequal;
12368  SCIP_Bool coefsnegated;
12369  int i;
12370 
12371  assert(key1 != NULL);
12372  assert(key2 != NULL);
12373  consdata1 = SCIPconsGetData((SCIP_CONS*)key1);
12374  consdata2 = SCIPconsGetData((SCIP_CONS*)key2);
12375  assert(consdata1->sorted);
12376  assert(consdata2->sorted);
12377 
12378  scip = (SCIP*)userptr;
12379  assert(scip != NULL);
12380 
12381  /* checks trivial case */
12382  if( consdata1->nvars != consdata2->nvars )
12383  return FALSE;
12384 
12385  coefsequal = TRUE;
12386  coefsnegated = TRUE;
12387 
12388  for( i = 0; i < consdata1->nvars && (coefsequal || coefsnegated); ++i )
12389  {
12390  SCIP_Real val1;
12391  SCIP_Real val2;
12392 
12393  /* tests if variables are equal */
12394  if( consdata1->vars[i] != consdata2->vars[i] )
12395  {
12396  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 1 ||
12397  SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == -1);
12398  coefsequal = FALSE;
12399  coefsnegated = FALSE;
12400  break;
12401  }
12402  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 0);
12403 
12404  /* tests if coefficients are either equal or negated */
12405  val1 = consdata1->vals[i];
12406  val2 = consdata2->vals[i];
12407  coefsequal = coefsequal && SCIPisEQ(scip, val1, val2);
12408  coefsnegated = coefsnegated && SCIPisEQ(scip, val1, -val2);
12409  }
12410 
12411  return (coefsequal || coefsnegated);
12412 }
12413 
12414 #define MULTIPLIER 2048
12415 /** returns the hash value of the key */
12416 static
12417 SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
12418 {
12419  SCIP_CONSDATA* consdata;
12420  SCIP_Real maxabsrealval;
12421  unsigned int hashval;
12422  int minidx;
12423  int mididx;
12424  int maxidx;
12425  int addval;
12426 #ifndef NDEBUG
12427  SCIP* scip;
12428 
12429  scip = (SCIP*)userptr;
12430  assert(scip != NULL);
12431 #endif
12432 
12433  assert(key != NULL);
12434  consdata = SCIPconsGetData((SCIP_CONS*)key);
12435  assert(consdata != NULL);
12436  assert(consdata->nvars > 0);
12437 
12438  assert(consdata->sorted);
12439 
12440  minidx = SCIPvarGetIndex(consdata->vars[0]);
12441  mididx = SCIPvarGetIndex(consdata->vars[consdata->nvars / 2]);
12442  maxidx = SCIPvarGetIndex(consdata->vars[consdata->nvars - 1]);
12443  assert(minidx >= 0 && minidx <= maxidx);
12444 
12445  addval = (int) REALABS(consdata->vals[0]);
12446  addval += (((int) REALABS(consdata->vals[consdata->nvars / 2])) << 4); /*lint !e701*/
12447  addval += (((int) REALABS(consdata->vals[consdata->nvars - 1])) << 8); /*lint !e701*/
12448 
12449  maxabsrealval = consdataGetMaxAbsval(consdata);
12450  /* hash value depends on vectors of variable indices */
12451  if( maxabsrealval < (SCIP_Real) INT_MAX )
12452  {
12453  if( maxabsrealval < 1.0 )
12454  addval += (int) (MULTIPLIER * maxabsrealval);
12455  else
12456  addval += (int) maxabsrealval;
12457  }
12458 
12459  hashval = (consdata->nvars << 29) + (minidx << 22) + (mididx << 11) + maxidx + addval; /*lint !e701*/
12460 
12461  return hashval;
12462 }
12463 
12464 /** compares each constraint with all other constraints for possible redundancy and removes or changes constraint
12465  * accordingly; in contrast to preprocessConstraintPairs(), it uses a hash table
12466  */
12467 static
12469  SCIP* scip, /**< SCIP data structure */
12470  BMS_BLKMEM* blkmem, /**< block memory */
12471  SCIP_CONS** conss, /**< constraint set */
12472  int nconss, /**< number of constraints in constraint set */
12473  int* firstchange, /**< pointer to store first changed constraint */
12474  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
12475  int* ndelconss, /**< pointer to count number of deleted constraints */
12476  int* nchgsides /**< pointer to count number of changed left/right hand sides */
12477  )
12478 {
12479  SCIP_HASHTABLE* hashtable;
12480  int hashtablesize;
12481  int c;
12482 
12483  assert(scip != NULL);
12484  assert(blkmem != NULL);
12485  assert(conss != NULL);
12486  assert(firstchange != NULL);
12487  assert(cutoff != NULL);
12488  assert(ndelconss != NULL);
12489  assert(nchgsides != NULL);
12490 
12491  /* create a hash table for the constraint set */
12492  hashtablesize = SCIPcalcHashtableSize(10*nconss);
12493  hashtablesize = MAX(hashtablesize, HASHSIZE_LINEARCONS);
12494  SCIP_CALL( SCIPhashtableCreate(&hashtable, blkmem, hashtablesize,
12495  hashGetKeyLinearcons, hashKeyEqLinearcons, hashKeyValLinearcons, (void*) scip) );
12496 
12497  /* check all constraints in the given set for redundancy */
12498  for( c = 0; c < nconss; ++c )
12499  {
12500  SCIP_CONS* cons0;
12501  SCIP_CONS* cons1;
12502  SCIP_CONSDATA* consdata0;
12503 
12504  cons0 = conss[c];
12505 
12506  if( !SCIPconsIsActive(cons0) || SCIPconsIsModifiable(cons0) )
12507  continue;
12508 
12509  /* check for interuption */
12510  if( c % 1000 == 0 && SCIPisStopped(scip) )
12511  break;
12512 
12513  /* sorts the constraint */
12514  consdata0 = SCIPconsGetData(cons0);
12515  assert(consdata0 != NULL);
12516  SCIP_CALL( consdataSort(scip, consdata0) );
12517  assert(consdata0->sorted);
12518 
12519  /* get constraint from current hash table with same variables as cons0 and with coefficients either equal or negated
12520  * to the ones of cons0 */
12521  cons1 = (SCIP_CONS*)(SCIPhashtableRetrieve(hashtable, (void*)cons0));
12522 
12523  if( cons1 != NULL )
12524  {
12525  SCIP_CONS* consstay;
12526  SCIP_CONS* consdel;
12527  SCIP_CONSDATA* consdatastay;
12528  SCIP_CONSDATA* consdatadel;
12529  SCIP_CONSDATA* consdata1;
12530 
12531  SCIP_Real lhs;
12532  SCIP_Real rhs;
12533 
12534  assert(SCIPconsIsActive(cons1));
12535  assert(!SCIPconsIsModifiable(cons1));
12536 
12537  /* constraint found: create a new constraint with same coefficients and best left and right hand side;
12538  * delete old constraints afterwards
12539  */
12540  consdata1 = SCIPconsGetData(cons1);
12541 
12542  assert(consdata1 != NULL);
12543  assert(consdata0->nvars >= 1 && consdata0->nvars == consdata1->nvars);
12544 
12545  assert(consdata1->sorted);
12546  assert(consdata0->vars[0] == consdata1->vars[0]);
12547 
12548  if( SCIPisEQ(scip, consdata0->vals[0], consdata1->vals[0]) )
12549  {
12550  /* the coefficients of both constraints are equal */
12551  assert(consdata0->nvars < 2 || SCIPisEQ(scip, consdata0->vals[1], consdata1->vals[1]));
12552  SCIPdebugMessage("aggregate linear constraints <%s> and <%s> with equal coefficients into single ranged row\n",
12553  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12554  SCIPdebugPrintCons(scip, cons0, NULL);
12555  SCIPdebugPrintCons(scip, cons1, NULL);
12556 
12557  lhs = MAX(consdata1->lhs, consdata0->lhs);
12558  rhs = MIN(consdata1->rhs, consdata0->rhs);
12559  }
12560  else
12561  {
12562  /* the coefficients of both rows are negations */
12563  assert(SCIPisEQ(scip, consdata0->vals[0], -(consdata1->vals[0])));
12564  assert(consdata0->nvars < 2 || SCIPisEQ(scip, consdata0->vals[1], -(consdata1->vals[1])));
12565  SCIPdebugMessage("aggregate linear constraints <%s> and <%s> with negated coefficients into single ranged row\n",
12566  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12567  SCIPdebugPrintCons(scip, cons0, NULL);
12568  SCIPdebugPrintCons(scip, cons1, NULL);
12569 
12570  lhs = MAX(consdata1->lhs, -consdata0->rhs);
12571  rhs = MIN(consdata1->rhs, -consdata0->lhs);
12572  }
12573 
12574  if( SCIPisFeasLT(scip, rhs, lhs) )
12575  {
12576  SCIPdebugMessage("aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons1));
12577  *cutoff = TRUE;
12578  break;
12579  }
12580 
12581  /* ensure that lhs <= rhs holds without tolerances as we only allow such rows to enter the LP */
12582  if( lhs > rhs )
12583  {
12584  rhs = (lhs + rhs)/2;
12585  lhs = rhs;
12586  }
12587 
12588  /* check which constraint has to stay;
12589  * changes applied to an upgraded constraint will not be considered in the instance */
12590  if( consdata1->upgraded && !consdata0->upgraded )
12591  {
12592  consstay = cons0;
12593  consdatastay = consdata0;
12594  consdel = cons1;
12595  consdatadel = consdata1;
12596 
12597  /* exchange consdel with consstay in hashtable */
12598  SCIP_CALL( SCIPhashtableRemove(hashtable, (void*) consdel) );
12599  SCIP_CALL( SCIPhashtableInsert(hashtable, (void*) consstay) );
12600  }
12601  else
12602  {
12603  consstay = cons1;
12604  consdatastay = consdata1;
12605  consdel = cons0;
12606  consdatadel = consdata0;
12607  }
12608 
12609  /* update lhs and rhs of consstay */
12610  SCIP_CALL( chgLhs(scip, consstay, lhs) );
12611  SCIP_CALL( chgRhs(scip, consstay, rhs) );
12612 
12613  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
12614  SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
12615 
12616  /* delete consdel */
12617  assert(!consdatastay->upgraded || (consdatastay->upgraded && consdatadel->upgraded));
12618  SCIP_CALL( SCIPdelCons(scip, consdel) );
12619  if( !consdatadel->upgraded )
12620  (*ndelconss)++;
12621 
12622  /* update the first changed constraint to begin the next aggregation round with */
12623  if( consdatastay->changed && SCIPconsGetPos(consstay) < *firstchange )
12624  *firstchange = SCIPconsGetPos(consstay);
12625 
12626  assert(SCIPconsIsActive(consstay));
12627  }
12628  else
12629  {
12630  /* no such constraint in current hash table: insert cons0 into hash table */
12631  SCIP_CALL( SCIPhashtableInsert(hashtable, (void*) cons0) );
12632  }
12633  }
12634 #ifdef SCIP_MORE_DEBUG
12635  SCIPinfoMessage(scip, NULL, "linear pairwise comparison hashtable statistics:\n");
12637 #endif
12638 
12639  /* free hash table */
12640  SCIPhashtableFree(&hashtable);
12641 
12642  return SCIP_OKAY;
12643 }
12644 
12645 /** compares constraint with all prior constraints for possible redundancy or aggregation,
12646  * and removes or changes constraint accordingly
12647  */
12648 static
12650  SCIP* scip, /**< SCIP data structure */
12651  SCIP_CONS** conss, /**< constraint set */
12652  int firstchange, /**< first constraint that changed since last pair preprocessing round */
12653  int chkind, /**< index of constraint to check against all prior indices upto startind */
12654  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
12655  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
12656  int* ndelconss, /**< pointer to count number of deleted constraints */
12657  int* nchgsides, /**< pointer to count number of changed left/right hand sides */
12658  int* nchgcoefs /**< pointer to count number of changed coefficients */
12659  )
12660 {
12661  SCIP_CONS* cons0;
12662  SCIP_CONSDATA* consdata0;
12663  int* commonidx0;
12664  int* commonidx1;
12665  int* diffidx0minus1;
12666  int* diffidx1minus0;
12667  SCIP_Longint possignature0;
12668  SCIP_Longint negsignature0;
12669  SCIP_Bool cons0changed;
12670  SCIP_Bool cons0isequality;
12671  int diffidx1minus0size;
12672  int c;
12673  SCIP_Real cons0lhs;
12674  SCIP_Real cons0rhs;
12675  SCIP_Bool cons0upgraded;
12676 
12677  assert(scip != NULL);
12678  assert(conss != NULL);
12679  assert(firstchange <= chkind);
12680  assert(cutoff != NULL);
12681  assert(ndelconss != NULL);
12682  assert(nchgsides != NULL);
12683  assert(nchgcoefs != NULL);
12684 
12685  /* get the constraint to be checked against all prior constraints */
12686  cons0 = conss[chkind];
12687  assert(cons0 != NULL);
12688  assert(SCIPconsIsActive(cons0));
12689  assert(!SCIPconsIsModifiable(cons0));
12690 
12691  consdata0 = SCIPconsGetData(cons0);
12692  assert(consdata0 != NULL);
12693  assert(consdata0->nvars >= 1);
12694  cons0isequality = SCIPisEQ(scip, consdata0->lhs, consdata0->rhs);
12695 
12696  /* sort the constraint */
12697  SCIP_CALL( consdataSort(scip, consdata0) );
12698 
12699  /* calculate bit signatures of cons0 for potentially positive and negative coefficients */
12700  consdataCalcSignatures(consdata0);
12701  possignature0 = consdata0->possignature;
12702  negsignature0 = consdata0->negsignature;
12703 
12704  /* get temporary memory for indices of common variables */
12705  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx0, consdata0->nvars) );
12706  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx1, consdata0->nvars) );
12707  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx0minus1, consdata0->nvars) );
12708  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx1minus0, consdata0->nvars) );
12709  diffidx1minus0size = consdata0->nvars;
12710 
12711  cons0lhs = consdata0->lhs;
12712  cons0rhs = consdata0->rhs;
12713  cons0upgraded = consdata0->upgraded;
12714 
12715  /* check constraint against all prior constraints */
12716  cons0changed = consdata0->changed;
12717  consdata0->changed = FALSE;
12718  for( c = (cons0changed ? 0 : firstchange); c < chkind && !(*cutoff) && conss[chkind] != NULL; ++c )
12719  {
12720  SCIP_CONS* cons1;
12721  SCIP_CONSDATA* consdata1;
12722  SCIP_Longint possignature1;
12723  SCIP_Longint negsignature1;
12724  SCIP_Bool cons0dominateslhs;
12725  SCIP_Bool cons1dominateslhs;
12726  SCIP_Bool cons0dominatesrhs;
12727  SCIP_Bool cons1dominatesrhs;
12728  SCIP_Bool cons1isequality;
12729  SCIP_Bool coefsequal;
12730  SCIP_Bool coefsnegated;
12731  SCIP_Bool tryaggregation;
12732  int nvarscommon;
12733  int nvars0minus1;
12734  int nvars1minus0;
12735  int commonidxweight;
12736  int diffidx0minus1weight;
12737  int diffidx1minus0weight;
12738  int v0;
12739  int v1;
12740 
12741  assert(cons0lhs == consdata0->lhs); /*lint !e777*/
12742  assert(cons0rhs == consdata0->rhs); /*lint !e777*/
12743  assert(cons0upgraded == consdata0->upgraded);
12744 
12745  cons1 = conss[c];
12746 
12747  /* cons1 has become inactive during presolving of constraint pairs */
12748  if( cons1 == NULL )
12749  continue;
12750 
12751  assert(SCIPconsIsActive(cons0) && !SCIPconsIsModifiable(cons0));
12752  assert(SCIPconsIsActive(cons1) && !SCIPconsIsModifiable(cons1));
12753 
12754  consdata1 = SCIPconsGetData(cons1);
12755  assert(consdata1 != NULL);
12756 
12757  /* SCIPdebugMessage("preprocess linear constraint pair <%s>[chgd:%d, upgd:%d] and <%s>[chgd:%d, upgd:%d]\n",
12758  SCIPconsGetName(cons0), cons0changed, cons0upgraded,
12759  SCIPconsGetName(cons1), consdata1->changed, consdata1->upgraded); */
12760 
12761  /* if both constraints didn't change since last pair processing, we can ignore the pair */
12762  if( !cons0changed && !consdata1->changed )
12763  continue;
12764 
12765  /* if both constraints are already upgraded, skip the pair;
12766  * because changes on these constraints cannot be applied to the instance anymore */
12767  if( cons0upgraded && consdata1->upgraded )
12768  continue;
12769 
12770  assert(consdata1->nvars >= 1);
12771 
12772  /* sort the constraint */
12773  SCIP_CALL( consdataSort(scip, consdata1) );
12774 
12775  /* calculate bit signatures of cons1 for potentially positive and negative coefficients */
12776  consdataCalcSignatures(consdata1);
12777  possignature1 = consdata1->possignature;
12778  negsignature1 = consdata1->negsignature;
12779 
12780  /* the signatures give a quick test to check for domination and equality of coefficients */
12781  coefsequal = (possignature0 == possignature1) && (negsignature0 == negsignature1);
12782  coefsnegated = (possignature0 == negsignature1) && (negsignature0 == possignature1);
12783  cons0dominateslhs = SCIPisGE(scip, cons0lhs, consdata1->lhs)
12784  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
12785  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
12786  cons1dominateslhs = SCIPisGE(scip, consdata1->lhs, cons0lhs)
12787  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
12788  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
12789  cons0dominatesrhs = SCIPisLE(scip, cons0rhs, consdata1->rhs)
12790  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
12791  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
12792  cons1dominatesrhs = SCIPisLE(scip, consdata1->rhs, cons0rhs)
12793  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
12794  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
12795  cons1isequality = SCIPisEQ(scip, consdata1->lhs, consdata1->rhs);
12796  tryaggregation = (cons0isequality || cons1isequality) && (maxaggrnormscale > 0.0);
12797  if( !cons0dominateslhs && !cons1dominateslhs && !cons0dominatesrhs && !cons1dominatesrhs
12798  && !coefsequal && !coefsnegated && !tryaggregation )
12799  continue;
12800 
12801  /* make sure, we have enough memory for the index set of V_1 \ V_0 */
12802  if( tryaggregation && consdata1->nvars > diffidx1minus0size )
12803  {
12804  SCIP_CALL( SCIPreallocBufferArray(scip, &diffidx1minus0, consdata1->nvars) );
12805  diffidx1minus0size = consdata1->nvars;
12806  }
12807 
12808  /* check consdata0 against consdata1:
12809  * - if lhs0 >= lhs1 and for each variable v and each solution value x_v val0[v]*x_v <= val1[v]*x_v,
12810  * consdata0 dominates consdata1 w.r.t. left hand side
12811  * - if rhs0 <= rhs1 and for each variable v and each solution value x_v val0[v]*x_v >= val1[v]*x_v,
12812  * consdata0 dominates consdata1 w.r.t. right hand side
12813  * - if val0[v] == -val1[v] for all variables v, the two inequalities can be replaced by a single
12814  * ranged row (or equality)
12815  * - if at least one constraint is an equality, count the weighted number of common variables W_c
12816  * and the weighted number of variable in the difference sets W_0 = w(V_0 \ V_1), W_1 = w(V_1 \ V_0),
12817  * where the weight of each variable depends on its type, such that aggregations in order to remove the
12818  * number of continuous and integer variables are preferred:
12819  * - if W_c > W_1, try to aggregate consdata0 := a * consdata0 + b * consdata1 in order to decrease the
12820  * variable weight in consdata0, where a = +/- val1[v] and b = -/+ val0[v] for common v which leads to
12821  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
12822  * to be positive to not switch the sense of the (in)equality cons0
12823  * - if W_c > W_0, try to aggregate consdata1 := a * consdata1 + b * consdata0 in order to decrease the
12824  * variable weight in consdata1, where a = +/- val0[v] and b = -/+ val1[v] for common v which leads to
12825  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
12826  * to be positive to not switch the sense of the (in)equality cons1
12827  */
12828 
12829  /* check consdata0 against consdata1 for redundancy, or ranged row accumulation */
12830  nvarscommon = 0;
12831  commonidxweight = 0;
12832  nvars0minus1 = 0;
12833  diffidx0minus1weight = 0;
12834  nvars1minus0 = 0;
12835  diffidx1minus0weight = 0;
12836  v0 = 0;
12837  v1 = 0;
12838  while( (v0 < consdata0->nvars || v1 < consdata1->nvars)
12839  && (cons0dominateslhs || cons1dominateslhs || cons0dominatesrhs || cons1dominatesrhs
12840  || coefsequal || coefsnegated || tryaggregation) )
12841  {
12842  SCIP_VAR* var;
12843  SCIP_Real val0;
12844  SCIP_Real val1;
12845  int varcmp;
12846 
12847  /* test, if variable appears in only one or in both constraints */
12848  if( v0 < consdata0->nvars && v1 < consdata1->nvars )
12849  varcmp = SCIPvarCompare(consdata0->vars[v0], consdata1->vars[v1]);
12850  else if( v0 < consdata0->nvars )
12851  varcmp = -1;
12852  else
12853  varcmp = +1;
12854 
12855  switch( varcmp )
12856  {
12857  case -1:
12858  /* variable doesn't appear in consdata1 */
12859  var = consdata0->vars[v0];
12860  val0 = consdata0->vals[v0];
12861  val1 = 0.0;
12862  if( tryaggregation )
12863  {
12864  diffidx0minus1[nvars0minus1] = v0;
12865  nvars0minus1++;
12866  diffidx0minus1weight += getVarWeight(var);
12867  }
12868  v0++;
12869  coefsequal = FALSE;
12870  coefsnegated = FALSE;
12871  break;
12872 
12873  case +1:
12874  /* variable doesn't appear in consdata0 */
12875  var = consdata1->vars[v1];
12876  val0 = 0.0;
12877  val1 = consdata1->vals[v1];
12878  if( tryaggregation )
12879  {
12880  diffidx1minus0[nvars1minus0] = v1;
12881  nvars1minus0++;
12882  diffidx1minus0weight += getVarWeight(var);
12883  }
12884  v1++;
12885  coefsequal = FALSE;
12886  coefsnegated = FALSE;
12887  break;
12888 
12889  case 0:
12890  /* variable appears in both constraints */
12891  assert(consdata0->vars[v0] == consdata1->vars[v1]);
12892  var = consdata0->vars[v0];
12893  val0 = consdata0->vals[v0];
12894  val1 = consdata1->vals[v1];
12895  if( tryaggregation )
12896  {
12897  commonidx0[nvarscommon] = v0;
12898  commonidx1[nvarscommon] = v1;
12899  nvarscommon++;
12900  commonidxweight += getVarWeight(var);
12901  }
12902  v0++;
12903  v1++;
12904  coefsequal = coefsequal && (SCIPisEQ(scip, val0, val1));
12905  coefsnegated = coefsnegated && (SCIPisEQ(scip, val0, -val1));
12906  break;
12907 
12908  default:
12909  SCIPerrorMessage("invalid comparison result\n");
12910  var = NULL;
12911  val0 = 0.0;
12912  val1 = 0.0;
12913  SCIPABORT();
12914  }
12915  assert(var != NULL);
12916 
12917  /* update domination criteria w.r.t. the coefficient and the variable's bounds */
12918  if( SCIPisGT(scip, val0, val1) )
12919  {
12920  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
12921  {
12922  cons0dominatesrhs = FALSE;
12923  cons1dominateslhs = FALSE;
12924  }
12925  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
12926  {
12927  cons0dominateslhs = FALSE;
12928  cons1dominatesrhs = FALSE;
12929  }
12930  }
12931  else if( SCIPisLT(scip, val0, val1) )
12932  {
12933  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
12934  {
12935  cons0dominateslhs = FALSE;
12936  cons1dominatesrhs = FALSE;
12937  }
12938  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
12939  {
12940  cons0dominatesrhs = FALSE;
12941  cons1dominateslhs = FALSE;
12942  }
12943  }
12944  }
12945 
12946  /* check for disaggregated ranged rows */
12947  if( coefsequal || coefsnegated )
12948  {
12949  SCIP_CONS* consstay;
12950  SCIP_CONS* consdel;
12951 #ifndef NDEBUG
12952  SCIP_CONSDATA* consdatastay;
12953 #endif
12954  SCIP_CONSDATA* consdatadel;
12955  SCIP_Real lhs;
12956  SCIP_Real rhs;
12957  int consinddel;
12958 
12959  /* the coefficients in both rows are either equal or negated: create a new constraint with same coefficients and
12960  * best left and right hand sides; delete the old constraints afterwards
12961  */
12962  SCIPdebugMessage("aggregate linear constraints <%s> and <%s> with %s coefficients into single ranged row\n",
12963  SCIPconsGetName(cons0), SCIPconsGetName(cons1), coefsequal ? "equal" : "negated");
12964  SCIPdebugPrintCons(scip, cons0, NULL);
12965  SCIPdebugPrintCons(scip, cons1, NULL);
12966 
12967  if( coefsequal )
12968  {
12969  /* the coefficients of both rows are equal */
12970  lhs = MAX(consdata0->lhs, consdata1->lhs);
12971  rhs = MIN(consdata0->rhs, consdata1->rhs);
12972  }
12973  else
12974  {
12975  /* the coefficients of both rows are negations */
12976  lhs = MAX(consdata0->lhs, -consdata1->rhs);
12977  rhs = MIN(consdata0->rhs, -consdata1->lhs);
12978  }
12979  if( SCIPisFeasLT(scip, rhs, lhs) )
12980  {
12981  SCIPdebugMessage("aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
12982  *cutoff = TRUE;
12983  break;
12984  }
12985 
12986  /* check which constraint has to stay;
12987  * changes applied to an upgraded constraint will not be considered in the instance */
12988  if( consdata0->upgraded )
12989  {
12990  assert(!consdata1->upgraded);
12991  consstay = cons1;
12992 #ifndef NDEBUG
12993  consdatastay = consdata1;
12994 #endif
12995 
12996  consdel = cons0;
12997  consdatadel = consdata0;
12998  consinddel = chkind;
12999  }
13000  else
13001  {
13002  consstay = cons0;
13003 #ifndef NDEBUG
13004  consdatastay = consdata0;
13005 #endif
13006 
13007  consdel = cons1;
13008  consdatadel = consdata1;
13009  consinddel = c;
13010  }
13011 
13012  /* update the sides of consstay */
13013  SCIP_CALL( chgLhs(scip, consstay, lhs) );
13014  SCIP_CALL( chgRhs(scip, consstay, rhs) );
13015  if( !consdata0->upgraded )
13016  {
13017  assert(consstay == cons0);
13018  cons0lhs = consdata0->lhs;
13019  cons0rhs = consdata0->rhs;
13020  }
13021 
13022  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13023  SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
13024 
13025  assert( !consdatastay->upgraded );
13026  /* delete consdel */
13027  SCIP_CALL( SCIPdelCons(scip, consdel) );
13028  conss[consinddel] = NULL;
13029  if( !consdatadel->upgraded )
13030  (*ndelconss)++;
13031  continue;
13032  }
13033 
13034  /* check for domination: remove dominated sides, but don't touch equalities as long as they are not totally
13035  * redundant
13036  */
13037  if( cons1dominateslhs && (!cons0isequality || cons1dominatesrhs || SCIPisInfinity(scip, consdata0->rhs) ) )
13038  {
13039  /* left hand side is dominated by consdata1: delete left hand side of consdata0 */
13040  SCIPdebugMessage("left hand side of linear constraint <%s> is dominated by <%s>:\n",
13041  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13042  SCIPdebugPrintCons(scip, cons0, NULL);
13043  SCIPdebugPrintCons(scip, cons1, NULL);
13044 
13045  /* check for infeasibility */
13046  if( SCIPisFeasGT(scip, consdata1->lhs, consdata0->rhs) )
13047  {
13048  SCIPdebugMessage("linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13049  *cutoff = TRUE;
13050  break;
13051  }
13052 
13053  /* remove redundant left hand side */
13054  if( !SCIPisInfinity(scip, -consdata0->lhs) )
13055  {
13056  SCIP_CALL( chgLhs(scip, cons0, -SCIPinfinity(scip)) );
13057  cons0lhs = consdata0->lhs;
13058  cons0isequality = FALSE;
13059  if( !consdata0->upgraded )
13060  {
13061  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13062  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13063 
13064  (*nchgsides)++;
13065  }
13066  }
13067  }
13068  else if( cons0dominateslhs && (!cons1isequality || cons0dominatesrhs || SCIPisInfinity(scip, consdata1->rhs)) )
13069  {
13070  /* left hand side is dominated by consdata0: delete left hand side of consdata1 */
13071  SCIPdebugMessage("left hand side of linear constraint <%s> is dominated by <%s>:\n",
13072  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13073  SCIPdebugPrintCons(scip, cons1, NULL);
13074  SCIPdebugPrintCons(scip, cons0, NULL);
13075 
13076  /* check for infeasibility */
13077  if( SCIPisFeasGT(scip, consdata0->lhs, consdata1->rhs) )
13078  {
13079  SCIPdebugMessage("linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13080  *cutoff = TRUE;
13081  break;
13082  }
13083 
13084  /* remove redundant left hand side */
13085  if( !SCIPisInfinity(scip, -consdata1->lhs) )
13086  {
13087  SCIP_CALL( chgLhs(scip, cons1, -SCIPinfinity(scip)) );
13088  cons1isequality = FALSE;
13089  if( !consdata1->upgraded )
13090  {
13091  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13092  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13093 
13094  (*nchgsides)++;
13095  }
13096  }
13097  }
13098  if( cons1dominatesrhs && (!cons0isequality || cons1dominateslhs || SCIPisInfinity(scip, -consdata0->lhs)) )
13099  {
13100  /* right hand side is dominated by consdata1: delete right hand side of consdata0 */
13101  SCIPdebugMessage("right hand side of linear constraint <%s> is dominated by <%s>:\n",
13102  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13103  SCIPdebugPrintCons(scip, cons0, NULL);
13104  SCIPdebugPrintCons(scip, cons1, NULL);
13105 
13106  /* check for infeasibility */
13107  if( SCIPisFeasLT(scip, consdata1->rhs, consdata0->lhs) )
13108  {
13109  SCIPdebugMessage("linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13110  *cutoff = TRUE;
13111  break;
13112  }
13113 
13114  /* remove redundant right hand side */
13115  if( !SCIPisInfinity(scip, consdata0->rhs) )
13116  {
13117  SCIP_CALL( chgRhs(scip, cons0, SCIPinfinity(scip)) );
13118  cons0rhs = consdata0->rhs;
13119  cons0isequality = FALSE;
13120  if( !consdata0->upgraded )
13121  {
13122  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13123  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13124 
13125  (*nchgsides)++;
13126  }
13127  }
13128  }
13129  else if( cons0dominatesrhs && (!cons1isequality || cons0dominateslhs || SCIPisInfinity(scip, -consdata1->lhs)) )
13130  {
13131  /* right hand side is dominated by consdata0: delete right hand side of consdata1 */
13132  SCIPdebugMessage("right hand side of linear constraint <%s> is dominated by <%s>:\n",
13133  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13134  SCIPdebugPrintCons(scip, cons1, NULL);
13135  SCIPdebugPrintCons(scip, cons0, NULL);
13136 
13137  /* check for infeasibility */
13138  if( SCIPisFeasLT(scip, consdata0->rhs, consdata1->lhs) )
13139  {
13140  SCIPdebugMessage("linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13141  *cutoff = TRUE;
13142  break;
13143  }
13144 
13145  /* remove redundant right hand side */
13146  if( !SCIPisInfinity(scip, consdata1->rhs) )
13147  {
13148  SCIP_CALL( chgRhs(scip, cons1, SCIPinfinity(scip)) );
13149  cons1isequality = FALSE;
13150  if( !consdata1->upgraded )
13151  {
13152  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13153  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13154 
13155  (*nchgsides)++;
13156  }
13157  }
13158  }
13159 
13160  /* check for now redundant constraints */
13161  if( SCIPisInfinity(scip, -consdata0->lhs) && SCIPisInfinity(scip, consdata0->rhs) )
13162  {
13163  /* consdata0 became redundant */
13164  SCIPdebugMessage("linear constraint <%s> is redundant\n", SCIPconsGetName(cons0));
13165  SCIP_CALL( SCIPdelCons(scip, cons0) );
13166  conss[chkind] = NULL;
13167  if( !consdata0->upgraded )
13168  {
13169  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13170  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13171 
13172  (*ndelconss)++;
13173  }
13174  continue;
13175  }
13176  if( SCIPisInfinity(scip, -consdata1->lhs) && SCIPisInfinity(scip, consdata1->rhs) )
13177  {
13178  /* consdata1 became redundant */
13179  SCIPdebugMessage("linear constraint <%s> is redundant\n", SCIPconsGetName(cons1));
13180  SCIP_CALL( SCIPdelCons(scip, cons1) );
13181  conss[c] = NULL;
13182  if( !consdata1->upgraded )
13183  {
13184  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13185  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13186 
13187  (*ndelconss)++;
13188  }
13189  continue;
13190  }
13191 
13192  /* check, if we want to aggregate an (in)equality with an equality:
13193  * consdata0 := a * consdata0 + b * consdata1 or consdata1 := a * consdata1 + b * consdata0
13194  */
13195  if( tryaggregation )
13196  {
13197  SCIP_Bool aggregated;
13198 
13199  assert(consdata0->nvars == nvarscommon + nvars0minus1);
13200  assert(consdata1->nvars == nvarscommon + nvars1minus0);
13201 
13202  aggregated = FALSE;
13203  if( cons1isequality && !consdata0->upgraded && commonidxweight > diffidx1minus0weight )
13204  {
13205  /* W_c > W_1: try to aggregate consdata0 := a * consdata0 + b * consdata1 */
13206  SCIP_CALL( aggregateConstraints(scip, cons0, cons1, commonidx0, commonidx1, diffidx0minus1, diffidx1minus0,
13207  nvarscommon, commonidxweight, diffidx0minus1weight, diffidx1minus0weight, maxaggrnormscale,
13208  nchgcoefs, &aggregated) );
13209 
13210  /* update array of active constraints */
13211  if( aggregated )
13212  {
13213  assert(!SCIPconsIsActive(cons0));
13214  assert(SCIPconsIsActive(cons1));
13215  conss[chkind] = NULL;
13216  }
13217  }
13218  if( !aggregated && cons0isequality && !consdata1->upgraded && commonidxweight > diffidx0minus1weight )
13219  {
13220  /* W_c > W_0: try to aggregate consdata1 := a * consdata1 + b * consdata0 */
13221  SCIP_CALL( aggregateConstraints(scip, cons1, cons0, commonidx1, commonidx0, diffidx1minus0, diffidx0minus1,
13222  nvarscommon, commonidxweight, diffidx1minus0weight, diffidx0minus1weight, maxaggrnormscale,
13223  nchgcoefs, &aggregated) );
13224 
13225  /* update array of active constraints */
13226  if( aggregated )
13227  {
13228  assert(!SCIPconsIsActive(cons1));
13229  assert(SCIPconsIsActive(cons0));
13230  conss[c] = NULL;
13231  }
13232  }
13233  }
13234  }
13235 
13236  /* free temporary memory */
13237  SCIPfreeBufferArray(scip, &diffidx1minus0);
13238  SCIPfreeBufferArray(scip, &diffidx0minus1);
13239  SCIPfreeBufferArray(scip, &commonidx1);
13240  SCIPfreeBufferArray(scip, &commonidx0);
13241 
13242  return SCIP_OKAY;
13243 }
13244 
13245 /** applies full dual presolving on variables that only appear in linear constraints */
13246 static
13248  SCIP* scip, /**< SCIP data structure */
13249  SCIP_CONS** conss, /**< constraint set */
13250  int nconss, /**< number of constraints */
13251  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
13252  int* nchgbds /**< pointer to count the number of bound changes */
13253  )
13254 {
13255  SCIP_Real* redlb;
13256  SCIP_Real* redub;
13257  int* nlocksdown;
13258  int* nlocksup;
13259  SCIP_Bool* isimplint;
13260  SCIP_VAR** origvars;
13261  SCIP_VAR** vars;
13262  SCIP_VAR** conscontvars;
13263  int nvars;
13264  int nbinvars;
13265  int nintvars;
13266  int ncontvars;
13267  int v;
13268  int c;
13269 
13270  /* we calculate redundancy bounds with the following meaning:
13271  * redlb[v] == k : if x_v >= k, we can always round x_v down to x_v == k without violating any constraint
13272  * redub[v] == k : if x_v <= k, we can always round x_v up to x_v == k without violating any constraint
13273  * then:
13274  * c_v >= 0 : x_v <= redlb[v] is feasible due to optimality
13275  * c_v <= 0 : x_v >= redub[v] is feasible due to optimality
13276  */
13277 
13278  /* Additionally, we detect continuous variables that are implicitly integral.
13279  * A continuous variable j is implicit integral if it only has only +/-1 coefficients,
13280  * and all constraints (including the bounds as trivial constraints) in which:
13281  * c_j > 0: the variable is down-locked,
13282  * c_j < 0: the variable is up-locked,
13283  * c_j = 0: the variable appears
13284  * have, apart from j, only integer variables with integral coefficients and integral sides.
13285  * This is because then, the value of the variable is either determined by one of its bounds or
13286  * by one of these constraints, and in all cases, the value of the variable is integral.
13287  */
13288 
13289  assert(scip != NULL);
13290  assert(nconss == 0 || conss != NULL);
13291  assert(nchgbds != NULL);
13292  assert(!SCIPinProbing(scip));
13293 
13294  /* get active variables */
13295  nvars = SCIPgetNVars(scip);
13296  origvars = SCIPgetVars(scip);
13297 
13298  /* if the problem is a pure binary program, nothing can be achieved by full dual presolve */
13299  nbinvars = SCIPgetNBinVars(scip);
13300  if( nbinvars == nvars )
13301  return SCIP_OKAY;
13302 
13303  /* get number of continuous variables */
13304  ncontvars = SCIPgetNContVars(scip);
13305  nintvars = nvars - ncontvars;
13306 
13307  /* copy the variable array since this array might change during the curse of this algorithm */
13308  nvars = nvars - nbinvars;
13309  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &(origvars[nbinvars]), nvars) );
13310 
13311  /* allocate temporary memory */
13312  SCIP_CALL( SCIPallocBufferArray(scip, &redlb, nvars) );
13313  SCIP_CALL( SCIPallocBufferArray(scip, &redub, nvars) );
13314  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksdown, nvars) );
13315  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksup, nvars) );
13316  SCIP_CALL( SCIPallocBufferArray(scip, &isimplint, ncontvars) );
13317  SCIP_CALL( SCIPallocBufferArray(scip, &conscontvars, ncontvars) );
13318 
13319  /* initialize redundancy bounds */
13320  for( v = 0; v < nvars; ++v )
13321  {
13322  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
13323  redlb[v] = SCIPvarGetLbGlobal(vars[v]);
13324  redub[v] = SCIPvarGetUbGlobal(vars[v]);
13325  }
13326  BMSclearMemoryArray(nlocksdown, nvars);
13327  BMSclearMemoryArray(nlocksup, nvars);
13328 
13329  /* Initialize isimplint array: variable may be implied integer if rounded to their best bound they are integral.
13330  * We better not use SCIPisFeasIntegral() in these checks.
13331  */
13332  for( v = 0; v < ncontvars; v++ )
13333  {
13334  SCIP_VAR* var;
13335  SCIP_Real obj;
13336  SCIP_Real lb;
13337  SCIP_Real ub;
13338 
13339  var = vars[v + nintvars - nbinvars];
13340  lb = SCIPvarGetLbGlobal(var);
13341  ub = SCIPvarGetUbGlobal(var);
13342 
13343  obj = SCIPvarGetObj(var);
13344  if( SCIPisZero(scip, obj) )
13345  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb)) && (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
13346  else
13347  {
13348  if( SCIPisPositive(scip, obj) )
13349  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb));
13350  else
13351  {
13352  assert(SCIPisNegative(scip, obj));
13353  isimplint[v] = (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
13354  }
13355  }
13356  }
13357 
13358  /* scan all constraints */
13359  for( c = 0; c < nconss; ++c )
13360  {
13361  /* we only need to consider constraints that have been locked (i.e., checked constraints or constraints that are
13362  * part of checked disjunctions)
13363  */
13364  if( SCIPconsIsLocked(conss[c]) )
13365  {
13366  SCIP_CONSDATA* consdata;
13367  SCIP_Bool lhsexists;
13368  SCIP_Bool rhsexists;
13369  SCIP_Bool hasimpliedpotential;
13370  SCIP_Bool integralcoefs;
13371  int nlockspos;
13372  int contvarpos;
13373  int nconscontvars;
13374  int i;
13375 
13376  consdata = SCIPconsGetData(conss[c]);
13377  assert(consdata != NULL);
13378 
13379  /* get number of times the constraint was locked */
13380  nlockspos = SCIPconsGetNLocksPos(conss[c]);
13381 
13382  /* we do not want to include constraints with locked negation (this would be too weird) */
13383  if( SCIPconsGetNLocksNeg(conss[c]) > 0 )
13384  {
13385  /* mark all continuous variables as not being implicit integral */
13386  for( i = 0; i < consdata->nvars; ++i )
13387  {
13388  SCIP_VAR* var;
13389 
13390  var = consdata->vars[i];
13392  {
13393  int contv;
13394  contv = SCIPvarGetProbindex(var) - nintvars;
13395  assert(0 <= contv && contv < ncontvars); /* variable should be active due to applyFixings() */
13396  isimplint[contv] = FALSE;
13397  }
13398  }
13399  continue;
13400  }
13401 
13402  /* check for existing sides */
13403  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
13404  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
13405 
13406  /* count locks and update redundancy bounds */
13407  contvarpos = -1;
13408  nconscontvars = 0;
13409  hasimpliedpotential = FALSE;
13410  integralcoefs = !SCIPconsIsModifiable(conss[c]);
13411 
13412  for( i = 0; i < consdata->nvars; ++i )
13413  {
13414  SCIP_VAR* var;
13415  SCIP_Real val;
13416  SCIP_Real minresactivity;
13417  SCIP_Real maxresactivity;
13418  SCIP_Real newredlb;
13419  SCIP_Real newredub;
13420  SCIP_Bool minisrelax;
13421  SCIP_Bool maxisrelax;
13422  SCIP_Bool isminsettoinfinity;
13423  SCIP_Bool ismaxsettoinfinity;
13424  int arrayindex;
13425 
13426  var = consdata->vars[i];
13427  val = consdata->vals[i];
13428 
13429  /* check if still all integer variables have integral coefficients */
13430  if( SCIPvarIsIntegral(var) )
13431  integralcoefs = integralcoefs && SCIPisIntegral(scip, val);
13432 
13433  /* we do not need to process binary variables */
13434  if( SCIPvarIsBinary(var) )
13435  continue;
13436 
13437  if( SCIPconsIsModifiable(conss[c]) )
13438  {
13439  minresactivity = -SCIPinfinity(scip);
13440  maxresactivity = SCIPinfinity(scip);
13441  isminsettoinfinity = TRUE;
13442  ismaxsettoinfinity = TRUE;
13443  }
13444  else
13445  {
13446  /* calculate residual activity bounds if variable would be fixed to zero */
13447  consdataGetGlbActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
13448  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
13449 
13450  /* We called consdataGetGlbActivityResiduals() saying that we do not need a good relaxation,
13451  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
13452  * This is needed, because we do not want to rely on relaxed finite resactivities.
13453  */
13454  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
13455 
13456  /* check minresactivity for reliability */
13457  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
13458  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, TRUE);
13459 
13460  /* check maxresactivity for reliability */
13461  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
13462  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, TRUE);
13463  }
13464 
13465  arrayindex = SCIPvarGetProbindex(var) - nbinvars;
13466 
13467  assert(0 <= arrayindex && arrayindex < nvars); /* variable should be active due to applyFixings() */
13468 
13469  newredlb = redlb[arrayindex];
13470  newredub = redub[arrayindex];
13471  if( val > 0.0 )
13472  {
13473  if( lhsexists )
13474  {
13475  /* lhs <= d*x + a*y, d > 0 -> redundant in y if x >= (lhs - min{a*y})/d */
13476  nlocksdown[arrayindex] += nlockspos;
13477  newredlb = (isminsettoinfinity ? SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
13478  }
13479  if( rhsexists )
13480  {
13481  /* d*x + a*y <= rhs, d > 0 -> redundant in y if x <= (rhs - max{a*y})/d */
13482  nlocksup[arrayindex] += nlockspos;
13483  newredub = (ismaxsettoinfinity ? -SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
13484  }
13485  }
13486  else
13487  {
13488  if( lhsexists )
13489  {
13490  /* lhs <= d*x + a*y, d < 0 -> redundant in y if x <= (lhs - min{a*y})/d */
13491  nlocksup[arrayindex] += nlockspos;
13492  newredub = (isminsettoinfinity ? -SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
13493  }
13494  if( rhsexists )
13495  {
13496  /* d*x + a*y <= rhs, d < 0 -> redundant in y if x >= (rhs - max{a*y})/d */
13497  nlocksdown[arrayindex] += nlockspos;
13498  newredlb = (ismaxsettoinfinity ? SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
13499  }
13500  }
13501 
13502  /* if the variable is integer, we have to round the value to the next integral value */
13503  if( SCIPvarIsIntegral(var) )
13504  {
13505  if( !SCIPisInfinity(scip, newredlb) )
13506  newredlb = SCIPceil(scip, newredlb);
13507  if( !SCIPisInfinity(scip, -newredub) )
13508  newredub = SCIPfloor(scip, newredub);
13509  }
13510 
13511  /* update redundancy bounds */
13512  redlb[arrayindex] = MAX(redlb[arrayindex], newredlb);
13513  redub[arrayindex] = MIN(redub[arrayindex], newredub);
13514 
13515  /* collect the continuous variables of the constraint */
13517  {
13518  int contv;
13519 
13520  assert(nconscontvars < ncontvars);
13521  contvarpos = i;
13522  conscontvars[nconscontvars] = var;
13523  nconscontvars++;
13524 
13525  contv = SCIPvarGetProbindex(var) - nintvars;
13526  assert(0 <= contv && contv < ncontvars);
13527  hasimpliedpotential = hasimpliedpotential || isimplint[contv];
13528  }
13529  }
13530 
13531  /* update implied integer status of continuous variables */
13532  if( hasimpliedpotential )
13533  {
13534  if( nconscontvars > 1 || !integralcoefs )
13535  {
13536  /* there is more than one continuous variable or the integer variables have fractional coefficients:
13537  * none of the continuous variables is implied integer
13538  */
13539  for( i = 0; i < nconscontvars; i++ )
13540  {
13541  int contv;
13542  contv = SCIPvarGetProbindex(conscontvars[i]) - nintvars;
13543  assert(0 <= contv && contv < ncontvars);
13544  isimplint[contv] = FALSE;
13545  }
13546  }
13547  else
13548  {
13549  SCIP_VAR* var;
13550  SCIP_Real val;
13551  SCIP_Real absval;
13552  int contv;
13553 
13554  /* there is exactly one continuous variable and the integer variables have integral coefficients:
13555  * this is the interesting case, and we have to check whether the coefficient is +/-1 and the corresponding
13556  * side(s) of the constraint is integral
13557  */
13558  assert(nconscontvars == 1);
13559  assert(0 <= contvarpos && contvarpos < consdata->nvars);
13560  var = consdata->vars[contvarpos];
13561  val = consdata->vals[contvarpos];
13562  contv = SCIPvarGetProbindex(var) - nintvars;
13563  assert(0 <= contv && contv < ncontvars);
13564  assert(isimplint[contv]);
13565 
13566  absval = REALABS(val);
13567  if( !SCIPisEQ(scip, absval, 1.0) )
13568  isimplint[contv] = FALSE;
13569  else
13570  {
13571  SCIP_Real obj;
13572 
13573  obj = SCIPvarGetObj(var);
13574  if( obj * val >= 0.0 && lhsexists )
13575  {
13576  /* the variable may be blocked by the constraint's left hand side */
13577  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->lhs);
13578  }
13579  if( obj * val <= 0.0 && rhsexists )
13580  {
13581  /* the variable may be blocked by the constraint's left hand side */
13582  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->rhs);
13583  }
13584  }
13585  }
13586  }
13587  }
13588  }
13589 
13590  /* check if any bounds can be tightened due to optimality */
13591  for( v = 0; v < nvars; ++v )
13592  {
13593  SCIP_VAR* var;
13594  SCIP_Real obj;
13595  SCIP_Bool infeasible;
13596  SCIP_Bool tightened;
13597 
13598  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
13599  assert(SCIPvarGetNLocksDown(vars[v]) >= nlocksdown[v]);
13600  assert(SCIPvarGetNLocksUp(vars[v]) >= nlocksup[v]);
13601 
13602  var = vars[v];
13603  obj = SCIPvarGetObj(var);
13604  if( obj >= 0.0 )
13605  {
13606  /* making the variable as small as possible does not increase the objective:
13607  * check if all down locks of the variables are due to linear constraints;
13608  * if largest bound to make constraints redundant is -infinity, we better do nothing for numerical reasons
13609  */
13610  if( SCIPvarGetNLocksDown(var) == nlocksdown[v]
13611  && !SCIPisInfinity(scip, -redlb[v])
13612  && redlb[v] < SCIPvarGetUbGlobal(var) )
13613  {
13614  SCIP_Real ub;
13615 
13616  /* if x_v >= redlb[v], we can always round x_v down to x_v == redlb[v] without violating any constraint
13617  * -> tighten upper bound to x_v <= redlb[v]
13618  */
13619  SCIPdebugMessage("variable <%s> only locked down in linear constraints: dual presolve <%s>[%.15g,%.15g] <= %.15g\n",
13621  redlb[v]);
13622  SCIP_CALL( SCIPtightenVarUb(scip, var, redlb[v], FALSE, &infeasible, &tightened) );
13623  assert(!infeasible);
13624 
13625  ub = SCIPvarGetUbGlobal(var);
13626  redub[v] = MIN(redub[v], ub);
13627  if( tightened )
13628  (*nchgbds)++;
13629  }
13630  }
13631  if( obj <= 0.0 )
13632  {
13633  /* making the variable as large as possible does not increase the objective:
13634  * check if all up locks of the variables are due to linear constraints;
13635  * if smallest bound to make constraints redundant is +infinity, we better do nothing for numerical reasons
13636  */
13637  if( SCIPvarGetNLocksUp(var) == nlocksup[v]
13638  && !SCIPisInfinity(scip, redub[v])
13639  && redub[v] > SCIPvarGetLbGlobal(var) )
13640  {
13641  SCIP_Real lb;
13642 
13643  /* if x_v <= redub[v], we can always round x_v up to x_v == redub[v] without violating any constraint
13644  * -> tighten lower bound to x_v >= redub[v]
13645  */
13646  SCIPdebugMessage("variable <%s> only locked up in linear constraints: dual presolve <%s>[%.15g,%.15g] >= %.15g\n",
13648  redub[v]);
13649  SCIP_CALL( SCIPtightenVarLb(scip, var, redub[v], FALSE, &infeasible, &tightened) );
13650  assert(!infeasible);
13651 
13652  lb = SCIPvarGetLbGlobal(var);
13653  redlb[v] = MAX(redlb[v], lb);
13654  if( tightened )
13655  (*nchgbds)++;
13656  }
13657  }
13658  }
13659 
13660  /* upgrade continuous variables to implied integers */
13661  for( v = nintvars - nbinvars; v < nvars; ++v )
13662  {
13663  SCIP_VAR* var;
13664  SCIP_Bool infeasible;
13665 
13666  var = vars[v];
13667  assert(var != NULL);
13668 
13669  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
13670  assert(SCIPvarGetNLocksDown(var) >= nlocksdown[v]);
13671  assert(SCIPvarGetNLocksUp(var) >= nlocksup[v]);
13672  assert(0 <= v - nintvars + nbinvars && v - nintvars + nbinvars < ncontvars);
13673 
13674  /* we can only conclude implied integrality if the variable appears in no other constraint */
13675  if( isimplint[v - nintvars + nbinvars]
13676  && SCIPvarGetNLocksDown(var) == nlocksdown[v]
13677  && SCIPvarGetNLocksUp(var) == nlocksup[v] )
13678  {
13679 
13680  /* since we locally copied the variable array we can change the variable type immediately */
13681  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
13682 
13683  if( infeasible )
13684  {
13685  SCIPdebugMessage("infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
13686  *cutoff = TRUE;
13687 
13688  break;
13689  }
13690 
13691  SCIPdebugMessage("dual presolve: converting continuous variable <%s>[%g,%g] to implicit integer\n",
13693  }
13694  }
13695 
13696  /* free temporary memory */
13697  SCIPfreeBufferArray(scip, &conscontvars);
13698  SCIPfreeBufferArray(scip, &isimplint);
13699  SCIPfreeBufferArray(scip, &nlocksup);
13700  SCIPfreeBufferArray(scip, &nlocksdown);
13701  SCIPfreeBufferArray(scip, &redub);
13702  SCIPfreeBufferArray(scip, &redlb);
13703 
13704  SCIPfreeBufferArray(scip, &vars);
13705 
13706  return SCIP_OKAY;
13707 }
13708 
13709 
13710 /*
13711  * Callback methods of constraint handler
13712  */
13713 
13714 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
13715 static
13716 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
13717 { /*lint --e{715}*/
13718  assert(scip != NULL);
13719  assert(conshdlr != NULL);
13720  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
13721 
13722  /* call inclusion method of constraint handler */
13724 
13725  *valid = TRUE;
13726 
13727  return SCIP_OKAY;
13728 }
13729 
13730 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
13731 static
13732 SCIP_DECL_CONSFREE(consFreeLinear)
13733 { /*lint --e{715}*/
13734  SCIP_CONSHDLRDATA* conshdlrdata;
13735 
13736  assert(scip != NULL);
13737  assert(conshdlr != NULL);
13738  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
13739 
13740  /* free constraint handler data */
13741  conshdlrdata = SCIPconshdlrGetData(conshdlr);
13742  assert(conshdlrdata != NULL);
13743 
13744  conshdlrdataFree(scip, &conshdlrdata);
13745 
13746  SCIPconshdlrSetData(conshdlr, NULL);
13747 
13748  return SCIP_OKAY;
13749 }
13750 
13751 
13752 /** initialization method of constraint handler (called after problem was transformed) */
13753 static
13754 SCIP_DECL_CONSINIT(consInitLinear)
13755 {
13756  SCIP_CONSHDLRDATA* conshdlrdata;
13757  int c;
13758 
13759  assert(scip != NULL);
13760 
13761  /* check for event handler */
13762  conshdlrdata = SCIPconshdlrGetData(conshdlr);
13763  assert(conshdlrdata != NULL);
13764  assert(conshdlrdata->eventhdlr != NULL);
13765  assert(nconss == 0 || conss != NULL);
13766 
13767  /* catch events for the constraints */
13768  for( c = 0; c < nconss; ++c )
13769  {
13770  /* catch all events */
13771  SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
13772  }
13773 
13774  return SCIP_OKAY;
13775 }
13776 
13777 
13778 /** deinitialization method of constraint handler (called before transformed problem is freed) */
13779 static
13780 SCIP_DECL_CONSEXIT(consExitLinear)
13781 {
13782  SCIP_CONSHDLRDATA* conshdlrdata;
13783  int c;
13784 
13785  assert(scip != NULL);
13786 
13787  /* check for event handler */
13788  conshdlrdata = SCIPconshdlrGetData(conshdlr);
13789  assert(conshdlrdata != NULL);
13790  assert(conshdlrdata->eventhdlr != NULL);
13791 
13792  /* drop events for the constraints */
13793  for( c = nconss - 1; c >= 0; --c )
13794  {
13795  SCIP_CONSDATA* consdata;
13797  consdata = SCIPconsGetData(conss[c]);
13798  assert(consdata != NULL);
13799 
13800  if( consdata->eventdata != NULL )
13801  {
13802  /* drop all events */
13803  SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
13804  assert(consdata->eventdata == NULL);
13805  }
13806  }
13807 
13808  return SCIP_OKAY;
13809 
13810 }
13811 
13812 #ifdef WITH_PRINTORIGCONSTYPES
13813 
13814 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
13815 static
13816 SCIP_Bool isRangedRow(
13817  SCIP* scip, /**< SCIP data structure */
13818  SCIP_CONS* cons /**< constraint */
13819  )
13820 {
13821  assert(scip != NULL);
13822  assert(cons != NULL);
13823  assert(SCIPconsGetData(cons) != NULL);
13824 
13825  return !(SCIPisEQ(scip, SCIPconsGetData(cons)->lhs, SCIPconsGetData(cons)->rhs)
13826  || SCIPisInfinity(scip, -SCIPconsGetData(cons)->lhs) || SCIPisInfinity(scip, SCIPconsGetData(cons)->rhs) );
13827 }
13828 
13829 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
13830 static
13831 SCIP_Bool isFiniteNonnegativeIntegral(
13832  SCIP* scip, /**< SCIP data structure */
13833  SCIP_Real x /**< value */
13834  )
13835 {
13836  assert(scip != NULL);
13837 
13838  return (!SCIPisInfinity(scip, x) && !SCIPisNegative(scip, x) && SCIPisIntegral(scip, x));
13839 }
13840 
13841 /** presolving initialization method of constraint handler (called when presolving is about to begin) */
13842 static
13843 SCIP_DECL_CONSINITPRE(consInitpreLinear)
13844 { /*lint --e{715}*/
13845  int counter[(int)SCIP_CONSTYPE_GENERAL + 1];
13846  int c;
13847 
13848  assert(scip != NULL);
13849 
13850  /* initialize counter for constraint types to zero */
13851  BMSclearMemoryArray(counter, (int)SCIP_CONSTYPE_GENERAL + 1);
13852 
13853  /* loop through all constraints */
13854  for( c = 0; c < nconss; c++ )
13855  {
13856  SCIP_CONS* cons;
13857  SCIP_CONSDATA* consdata;
13858  int i;
13859 
13860  /* get constraint */
13861  cons = conss[c];
13862  assert(cons != NULL);
13863 
13864  /* get constraint data */
13865  consdata = SCIPconsGetData(cons);
13866  assert(consdata != NULL);
13867 
13868  /* merge multiples and delete variables with zero coefficient */
13869  SCIP_CALL( mergeMultiples(scip, cons) );
13870  for( i = 0; i < consdata->nvars; i++ )
13871  {
13872  assert(!SCIPisZero(scip, consdata->vals[i]));
13873  }
13874 
13875  /* is constraint of type SCIP_CONSTYPE_EMPTY? */
13876  if( consdata->nvars == 0 )
13877  {
13878  SCIPdebugMessage("classified as EMPTY: ");
13879  SCIPdebugPrintCons(scip, cons, NULL);
13880  counter[SCIP_CONSTYPE_EMPTY]++;
13881  continue;
13882  }
13883 
13884  /* is constraint of type SCIP_CONSTYPE_FREE? */
13885  if( SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, -consdata->lhs) )
13886  {
13887  SCIPdebugMessage("classified as FREE: ");
13888  SCIPdebugPrintCons(scip, cons, NULL);
13889  counter[SCIP_CONSTYPE_FREE]++;
13890  continue;
13891  }
13892 
13893  /* is constraint of type SCIP_CONSTYPE_SINGLETON? */
13894  if( consdata->nvars == 1 )
13895  {
13896  SCIPdebugMessage("classified as SINGLETON: ");
13897  SCIPdebugPrintCons(scip, cons, NULL);
13898  counter[SCIP_CONSTYPE_SINGLETON] += isRangedRow(scip, cons) ? 2 : 1;
13899  continue;
13900  }
13901 
13902  /* is constraint of type SCIP_CONSTYPE_AGGREGATION? */
13903  if( consdata->nvars == 2 && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
13904  {
13905  SCIPdebugMessage("classified as AGGREGATION: ");
13906  SCIPdebugPrintCons(scip, cons, NULL);
13907  counter[SCIP_CONSTYPE_AGGREGATION]++;
13908  continue;
13909  }
13910 
13911  /* is constraint of type SCIP_CONSTYPE_{VARBOUND}? */
13912  if( consdata->nvars == 2 )
13913  {
13914  SCIPdebugMessage("classified as VARBOUND: ");
13915  SCIPdebugPrintCons(scip, cons, NULL);
13916  counter[SCIP_CONSTYPE_VARBOUND] += isRangedRow(scip, cons) ? 2 : 1;
13917  continue;
13918  }
13919 
13920  /* is constraint of type SCIP_CONSTYPE_{SETPARTITION, SETPACKING, SETCOVERING, CARDINALITY, INVKNAPSACK}? */
13921  {
13922  SCIP_Real scale;
13923  SCIP_Real b;
13924  SCIP_Bool unmatched;
13925  int nnegbinvars;
13926 
13927  unmatched = FALSE;
13928  nnegbinvars = 0;
13929 
13930  scale = REALABS(consdata->vals[0]);
13931  for( i = 0; i < consdata->nvars && !unmatched; i++ )
13932  {
13933  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
13934  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
13935  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
13936  unmatched = unmatched || !SCIPisEQ(scip, REALABS(consdata->vals[i]), scale);
13937 
13938  if( consdata->vals[i] < 0.0 )
13939  nnegbinvars++;
13940  }
13941 
13942  if( !unmatched )
13943  {
13944  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
13945  {
13946  b = consdata->rhs/scale + nnegbinvars;
13947  if( SCIPisEQ(scip, 1.0, b) )
13948  {
13949  SCIPdebugMessage("classified as SETPARTITION: ");
13950  SCIPdebugPrintCons(scip, cons, NULL);
13951  counter[SCIP_CONSTYPE_SETPARTITION]++;
13952  continue;
13953  }
13954  else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
13955  {
13956  SCIPdebugMessage("classified as CARDINALITY: ");
13957  SCIPdebugPrintCons(scip, cons, NULL);
13958  counter[SCIP_CONSTYPE_CARDINALITY]++;
13959  continue;
13960  }
13961  }
13962 
13963  b = consdata->rhs/scale + nnegbinvars;
13964  if( SCIPisEQ(scip, 1.0, b) )
13965  {
13966  SCIPdebugMessage("classified as SETPACKING: ");
13967  SCIPdebugPrintCons(scip, cons, NULL);
13968  counter[SCIP_CONSTYPE_SETPACKING]++;
13969  consdata->rhs = SCIPinfinity(scip);
13970  }
13971  else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
13972  {
13973  SCIPdebugMessage("classified as INVKNAPSACK: ");
13974  SCIPdebugPrintCons(scip, cons, NULL);
13975  counter[SCIP_CONSTYPE_INVKNAPSACK]++;
13976  consdata->rhs = SCIPinfinity(scip);
13977  }
13978 
13979  b = consdata->lhs/scale + nnegbinvars;
13980  if( SCIPisEQ(scip, 1.0, b) )
13981  {
13982  SCIPdebugMessage("classified as SETCOVERING: ");
13983  SCIPdebugPrintCons(scip, cons, NULL);
13984  counter[SCIP_CONSTYPE_SETCOVERING]++;
13985  consdata->lhs = -SCIPinfinity(scip);
13986  }
13987 
13988  if( SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, consdata->rhs) )
13989  continue;
13990  }
13991  }
13992 
13993  /* is constraint of type SCIP_CONSTYPE_{EQKNAPSACK, BINPACKING, KNAPSACK}? */
13994  /* @todo If coefficients or rhs are not integral, we currently do not check
13995  * if the constraint could be scaled (finitely), such that they are.
13996  */
13997  {
13998  SCIP_Real b;
13999  SCIP_Bool unmatched;
14000 
14001  b = consdata->rhs;
14002  unmatched = FALSE;
14003  for( i = 0; i < consdata->nvars && !unmatched; i++ )
14004  {
14005  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
14006  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
14007  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
14008  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
14009 
14010  if( SCIPisNegative(scip, consdata->vals[i]) )
14011  b -= consdata->vals[i];
14012  }
14013  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
14014 
14015  if( !unmatched )
14016  {
14017  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
14018  {
14019  SCIPdebugMessage("classified as EQKNAPSACK: ");
14020  SCIPdebugPrintCons(scip, cons, NULL);
14021  counter[SCIP_CONSTYPE_EQKNAPSACK]++;
14022  continue;
14023  }
14024  else
14025  {
14026  SCIP_Bool matched;
14027 
14028  matched = FALSE;
14029  for( i = 0; i < consdata->nvars && !matched; i++ )
14030  {
14031  matched = matched || SCIPisEQ(scip, b, REALABS(consdata->vals[i]));
14032  }
14033 
14034  SCIPdebugMessage("classified as %s: ", matched ? "BINPACKING" : "KNAPSACK");
14035  SCIPdebugPrintCons(scip, cons, NULL);
14036  counter[matched ? SCIP_CONSTYPE_BINPACKING : SCIP_CONSTYPE_KNAPSACK]++;
14037  }
14038 
14039  if( SCIPisInfinity(scip, -consdata->lhs) )
14040  continue;
14041  else
14042  consdata->rhs = SCIPinfinity(scip);
14043  }
14044  }
14045 
14046  /* is constraint of type SCIP_CONSTYPE_{INTKNAPSACK}? */
14047  {
14048  SCIP_Real b;
14049  SCIP_Bool unmatched;
14050 
14051  unmatched = FALSE;
14052 
14053  b = consdata->rhs;
14054  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
14055 
14056  for( i = 0; i < consdata->nvars && !unmatched; i++ )
14057  {
14058  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
14059  unmatched = unmatched || SCIPisNegative(scip, SCIPvarGetLbGlobal(consdata->vars[i]));
14060  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
14061  unmatched = unmatched || SCIPisNegative(scip, consdata->vals[i]);
14062  }
14063 
14064  if( !unmatched )
14065  {
14066  SCIPdebugMessage("classified as INTKNAPSACK: ");
14067  SCIPdebugPrintCons(scip, cons, NULL);
14068  counter[SCIP_CONSTYPE_INTKNAPSACK]++;
14069 
14070  if( SCIPisInfinity(scip, -consdata->lhs) )
14071  continue;
14072  else
14073  consdata->rhs = SCIPinfinity(scip);
14074  }
14075  }
14076 
14077  /* is constraint of type SCIP_CONSTYPE_{MIXEDBINARY}? */
14078  {
14079  SCIP_Bool unmatched;
14080 
14081  unmatched = FALSE;
14082  for( i = 0; i < consdata->nvars && !unmatched; i++ )
14083  {
14084  if( SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS
14085  && (SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0)
14086  || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0)) )
14087  unmatched = TRUE;
14088  }
14089 
14090  if( !unmatched )
14091  {
14092  SCIPdebugMessage("classified as MIXEDBINARY (%d): ", isRangedRow(scip, cons) ? 2 : 1);
14093  SCIPdebugPrintCons(scip, cons, NULL);
14094  counter[SCIP_CONSTYPE_MIXEDBINARY] += isRangedRow(scip, cons) ? 2 : 1;
14095  continue;
14096  }
14097  }
14098 
14099  /* no special structure detected */
14100  SCIPdebugMessage("classified as GENERAL: ");
14101  SCIPdebugPrintCons(scip, cons, NULL);
14102  counter[SCIP_CONSTYPE_GENERAL] += isRangedRow(scip, cons) ? 2 : 1;
14103  }
14104 
14105  /* print statistics */
14106  SCIPinfoMessage(scip, NULL, "\n");
14107  SCIPinfoMessage(scip, NULL, "Number of constraints according to type:\n");
14108  SCIPinfoMessage(scip, NULL, "----------------------------------------\n");
14109  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_EMPTY %6d\n", 0, counter[ 0]);
14110  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_FREE %6d\n", 1, counter[ 1]);
14111  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SINGLETON %6d\n", 2, counter[ 2]);
14112  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_AGGREGATION %6d\n", 3, counter[ 3]);
14113  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_VARBOUND %6d\n", 4, counter[ 4]);
14114  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SETPARTITION %6d\n", 5, counter[ 5]);
14115  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SETPACKING %6d\n", 6, counter[ 6]);
14116  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SETCOVERING %6d\n", 7, counter[ 7]);
14117  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_CARDINALITY %6d\n", 8, counter[ 8]);
14118  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_INVKNAPSACK %6d\n", 9, counter[ 9]);
14119  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_EQKNAPSACK %6d\n", 10, counter[10]);
14120  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_BINPACKING %6d\n", 11, counter[11]);
14121  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_KNAPSACK %6d\n", 12, counter[12]);
14122  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_INTKNAPSACK %6d\n", 13, counter[13]);
14123  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_MIXEDBINARY %6d\n", 14, counter[14]);
14124  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_GENERAL %6d\n", 15, counter[15]);
14125  SCIPinfoMessage(scip, NULL, "----------------------------------------\n\n");
14126 
14127  SCIPinfoMessage(scip, NULL, " EMPTY");
14128  SCIPinfoMessage(scip, NULL, " FREE");
14129  SCIPinfoMessage(scip, NULL, " SING");
14130  SCIPinfoMessage(scip, NULL, " AGGR");
14131  SCIPinfoMessage(scip, NULL, " VARBD");
14132  SCIPinfoMessage(scip, NULL, " SETPART");
14133  SCIPinfoMessage(scip, NULL, " SETPACK");
14134  SCIPinfoMessage(scip, NULL, " SETCOV");
14135  SCIPinfoMessage(scip, NULL, " CARD");
14136  SCIPinfoMessage(scip, NULL, " INVKNAP");
14137  SCIPinfoMessage(scip, NULL, " EQKNAP");
14138  SCIPinfoMessage(scip, NULL, " BINPACK");
14139  SCIPinfoMessage(scip, NULL, " KNAP");
14140  SCIPinfoMessage(scip, NULL, " INTKNAP");
14141  SCIPinfoMessage(scip, NULL, " MIXBIN");
14142  SCIPinfoMessage(scip, NULL, " GEN\n");
14143  for( c = 0; c <= (int)SCIP_CONSTYPE_GENERAL; c++ )
14144  {
14145  SCIPinfoMessage(scip, NULL, "%9d", counter[c]);
14146  }
14147 
14148  SCIPinfoMessage(scip, NULL, "\n\n");
14149  SCIPinfoMessage(scip, NULL, "----------------------------------------\n\n");
14150 
14151  return SCIP_OKAY;
14152 }
14153 #endif
14154 
14155 
14156 /** presolving deinitialization method of constraint handler (called after presolving has been finished) */
14157 static
14158 SCIP_DECL_CONSEXITPRE(consExitpreLinear)
14159 { /*lint --e{715}*/
14160  int c;
14161 #ifdef SCIP_STATISTIC
14162  SCIP_CONSHDLRDATA* conshdlrdata;
14163  int ngoodconss;
14164  int nallconss;
14165 #endif
14166 
14167  /* delete all linear constraints that were upgraded to a more specific constraint type;
14168  * make sure, only active variables remain in the remaining constraints
14169  */
14170  assert(scip != NULL);
14171 
14172 #ifdef SCIP_STATISTIC
14173  /* count number of well behaved linear constraints */
14174  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14175  assert(conshdlrdata != NULL);
14176 
14177  ngoodconss = 0;
14178  nallconss = 0;
14179 
14180  for( c = 0; c < nconss; ++c )
14181  {
14182  SCIP_CONSDATA* consdata;
14183 
14184  if( SCIPconsIsDeleted(conss[c]) )
14185  continue;
14186 
14187  consdata = SCIPconsGetData(conss[c]);
14188  assert(consdata != NULL);
14189 
14190  if( consdata->upgraded )
14191  continue;
14192 
14193  nallconss++;
14194 
14195  consdataRecomputeMaxActivityDelta(scip, consdata);
14196 
14197  if( SCIPisLT(scip, consdata->maxactdelta, conshdlrdata->maxeasyactivitydelta) )
14198  ngoodconss++;
14199  }
14200  if( nallconss )
14201  {
14202  SCIPstatisticMessage("below threshold: %d / %d ratio= %g\n", ngoodconss, nallconss, (100.0 * ngoodconss / nallconss));
14203  }
14204 #endif
14205 
14206  for( c = 0; c < nconss; ++c )
14207  {
14208  SCIP_CONSDATA* consdata;
14209 
14210  if( SCIPconsIsDeleted(conss[c]) )
14211  continue;
14212 
14213  consdata = SCIPconsGetData(conss[c]);
14214  assert(consdata != NULL);
14215 
14216  if( consdata->upgraded )
14217  {
14218  /* this is no problem reduction, because the upgraded constraint was added to the problem before, and the
14219  * (redundant) linear constraint was only kept in order to support presolving the the linear constraint handler
14220  */
14221  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
14222  }
14223  else
14224  {
14225  /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
14226  SCIP_CALL( applyFixings(scip, conss[c], NULL) );
14227  }
14228  }
14229 
14230  return SCIP_OKAY;
14231 }
14232 
14233 
14234 /** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
14235 static
14236 SCIP_DECL_CONSEXITSOL(consExitsolLinear)
14237 { /*lint --e{715}*/
14238  int c;
14239 
14240  assert(scip != NULL);
14241 
14242  /* release the rows of all constraints */
14243  for( c = 0; c < nconss; ++c )
14244  {
14245  SCIP_CONSDATA* consdata;
14246 
14247  consdata = SCIPconsGetData(conss[c]);
14248  assert(consdata != NULL);
14249 
14250  if( consdata->row != NULL )
14251  {
14252  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
14253  }
14254  }
14255 
14256  /* if this is a restart, convert cutpool rows into linear constraints */
14257  if( restart )
14258  {
14259  int ncutsadded;
14260 
14261  ncutsadded = 0;
14262 
14263  /* create out of all active cuts in cutpool linear constraints */
14264  SCIP_CALL( SCIPconvertCutsToConss(scip, NULL, NULL, TRUE, &ncutsadded) );
14265 
14266  if( ncutsadded > 0 )
14267  {
14269  "(restart) converted %d cuts from the global cut pool into linear constraints\n", ncutsadded);
14270  /* an extra blank line should be printed separately since the buffer message handler only handles up to one
14271  * line correctly
14272  */
14274  }
14275  }
14276 
14277  return SCIP_OKAY;
14278 }
14279 
14280 
14281 /** frees specific constraint data */
14282 static
14283 SCIP_DECL_CONSDELETE(consDeleteLinear)
14284 { /*lint --e{715}*/
14285  SCIP_CONSHDLRDATA* conshdlrdata;
14286 
14287  assert(scip != NULL);
14288  assert(conshdlr != NULL);
14289  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14290 
14291  /* check for event handler */
14292  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14293  assert(conshdlrdata != NULL);
14294  assert(conshdlrdata->eventhdlr != NULL);
14295 
14296  /* free event datas */
14297  if( (*consdata)->eventdata != NULL )
14298  {
14299  /* drop bound change events of variables */
14300  SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
14301  }
14302  assert((*consdata)->eventdata == NULL);
14303 
14304  /* free linear constraint */
14305  SCIP_CALL( consdataFree(scip, consdata) );
14306 
14307  return SCIP_OKAY;
14308 }
14309 
14310 
14311 /** transforms constraint data into data belonging to the transformed problem */
14312 static
14313 SCIP_DECL_CONSTRANS(consTransLinear)
14314 { /*lint --e{715}*/
14315  SCIP_CONSHDLRDATA* conshdlrdata;
14316  SCIP_CONSDATA* sourcedata;
14317  SCIP_CONSDATA* targetdata;
14318 
14319  /*debugMessage("Trans method of linear constraints\n");*/
14320 
14321  assert(scip != NULL);
14322  assert(conshdlr != NULL);
14323  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14324  assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
14325  assert(sourcecons != NULL);
14326  assert(targetcons != NULL);
14327 
14328  sourcedata = SCIPconsGetData(sourcecons);
14329  assert(sourcedata != NULL);
14330  assert(sourcedata->row == NULL); /* in original problem, there cannot be LP rows */
14331 
14332  /* check for event handler */
14333  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14334  assert(conshdlrdata != NULL);
14335  assert(conshdlrdata->eventhdlr != NULL);
14336 
14337  /* create linear constraint data for target constraint */
14338  SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs, sourcedata->rhs) );
14339 
14340  /* create target constraint */
14341  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
14342  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
14343  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
14344  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
14345  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
14346 
14347  if( SCIPisTransformed(scip) && needEvents(scip) )
14348  {
14349  /* catch bound change events of variables */
14350  SCIP_CALL( consCatchAllEvents(scip, *targetcons, conshdlrdata->eventhdlr) );
14351  assert(targetdata->eventdata != NULL);
14352  }
14353 
14354  return SCIP_OKAY;
14355 }
14356 
14357 
14358 /** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
14359 static
14360 SCIP_DECL_CONSINITLP(consInitlpLinear)
14361 { /*lint --e{715}*/
14362  SCIP_Bool cutoff;
14363  int c;
14364 
14365  assert(scip != NULL);
14366  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14367 
14368  for( c = 0; c < nconss; ++c )
14369  {
14370  assert(SCIPconsIsInitial(conss[c]));
14371  SCIP_CALL( addRelaxation(scip, conss[c], NULL, &cutoff) );
14372  /* cannot use cutoff here, since initlp has no return value */
14373  }
14374 
14375  return SCIP_OKAY;
14377 
14378 
14379 /** separation method of constraint handler for LP solutions */
14380 static
14381 SCIP_DECL_CONSSEPALP(consSepalpLinear)
14382 { /*lint --e{715}*/
14383  SCIP_CONSHDLRDATA* conshdlrdata;
14384  SCIP_Real loclowerbound;
14385  SCIP_Real glblowerbound;
14386  SCIP_Real cutoffbound;
14387  SCIP_Real maxbound;
14388  SCIP_Bool separatecards;
14389  SCIP_Bool cutoff;
14390  int c;
14391  int depth;
14392  int nrounds;
14393  int maxsepacuts;
14394  int ncuts;
14395 
14396  assert(scip != NULL);
14397  assert(conshdlr != NULL);
14398  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14399  assert(result != NULL);
14400 
14401  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14402  assert(conshdlrdata != NULL);
14403  depth = SCIPgetDepth(scip);
14404  nrounds = SCIPgetNSepaRounds(scip);
14405 
14406  /*debugMessage("Sepa method of linear constraints\n");*/
14407 
14408  *result = SCIP_DIDNOTRUN;
14409 
14410  /* only call the separator a given number of times at each node */
14411  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
14412  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
14413  return SCIP_OKAY;
14414 
14415  /* get the maximal number of cuts allowed in a separation round */
14416  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
14417 
14418  /* check if we want to produce knapsack cardinality cuts at this node */
14419  loclowerbound = SCIPgetLocalLowerbound(scip);
14420  glblowerbound = SCIPgetLowerbound(scip);
14421  cutoffbound = SCIPgetCutoffbound(scip);
14422  maxbound = glblowerbound + conshdlrdata->maxcardbounddist * (cutoffbound - glblowerbound);
14423  separatecards = SCIPisLE(scip, loclowerbound, maxbound);
14424  separatecards = separatecards && (SCIPgetNLPBranchCands(scip) > 0);
14425 
14426  *result = SCIP_DIDNOTFIND;
14427  ncuts = 0;
14428  cutoff = FALSE;
14429 
14430  /* check all useful linear constraints for feasibility */
14431  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
14432  {
14433  /*debugMessage("separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
14434  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, separatecards, conshdlrdata->separateall, &ncuts, &cutoff) );
14435  }
14436 
14437  /* adjust return value */
14438  if( cutoff )
14439  *result = SCIP_CUTOFF;
14440  else if( ncuts > 0 )
14441  *result = SCIP_SEPARATED;
14442 
14443  /* combine linear constraints to get more cuts */
14444  /**@todo further cuts of linear constraints */
14445 
14446  return SCIP_OKAY;
14447 }
14448 
14449 
14450 /** separation method of constraint handler for arbitrary primal solutions */
14451 static
14452 SCIP_DECL_CONSSEPASOL(consSepasolLinear)
14453 { /*lint --e{715}*/
14454  SCIP_CONSHDLRDATA* conshdlrdata;
14455  int c;
14456  int depth;
14457  int nrounds;
14458  int maxsepacuts;
14459  int ncuts;
14460  SCIP_Bool cutoff;
14461 
14462  assert(scip != NULL);
14463  assert(conshdlr != NULL);
14464  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14465  assert(result != NULL);
14466 
14467  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14468  assert(conshdlrdata != NULL);
14469  depth = SCIPgetDepth(scip);
14470  nrounds = SCIPgetNSepaRounds(scip);
14471 
14472  /*debugMessage("Sepa method of linear constraints\n");*/
14473 
14474  *result = SCIP_DIDNOTRUN;
14475 
14476  /* only call the separator a given number of times at each node */
14477  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
14478  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
14479  return SCIP_OKAY;
14480 
14481  /* get the maximal number of cuts allowed in a separation round */
14482  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
14483 
14484  *result = SCIP_DIDNOTFIND;
14485  ncuts = 0;
14486  cutoff = FALSE;
14487 
14488  /* check all useful linear constraints for feasibility */
14489  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
14490  {
14491  /*debugMessage("separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
14492  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, TRUE, conshdlrdata->separateall, &ncuts, &cutoff) );
14493  }
14494 
14495  /* adjust return value */
14496  if( cutoff )
14497  *result = SCIP_CUTOFF;
14498  else if( ncuts > 0 )
14499  *result = SCIP_SEPARATED;
14500 
14501  /* combine linear constraints to get more cuts */
14502  /**@todo further cuts of linear constraints */
14503 
14504  return SCIP_OKAY;
14505 }
14506 
14507 
14508 /** constraint enforcing method of constraint handler for LP solutions */
14509 static
14510 SCIP_DECL_CONSENFOLP(consEnfolpLinear)
14511 { /*lint --e{715}*/
14512  SCIP_CONSHDLRDATA* conshdlrdata;
14513  SCIP_Bool checkrelmaxabs;
14514  SCIP_Bool violated;
14515  SCIP_Bool cutoff;
14516  int c;
14517 
14518  assert(scip != NULL);
14519  assert(conshdlr != NULL);
14520  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14521  assert(result != NULL);
14522 
14523  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14524  assert(conshdlrdata != NULL);
14525 
14526  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
14527 
14528  /*SCIPdebugMessage("Enfolp method of linear constraints\n");*/
14529 
14530  /* check for violated constraints
14531  * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
14532  */
14533  *result = SCIP_FEASIBLE;
14534 
14535  /* check all useful linear constraints for feasibility */
14536  for( c = 0; c < nusefulconss; ++c )
14537  {
14538  SCIP_CALL( checkCons(scip, conss[c], NULL, FALSE, checkrelmaxabs, &violated) );
14539 
14540  if( violated )
14541  {
14542  /* insert LP row as cut */
14543  SCIP_CALL( addRelaxation(scip, conss[c], NULL, &cutoff) );
14544  if ( cutoff )
14545  *result = SCIP_CUTOFF;
14546  else
14547  *result = SCIP_SEPARATED;
14548  }
14549  }
14550 
14551  /* check all obsolete linear constraints for feasibility */
14552  for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
14553  {
14554  SCIP_CALL( checkCons(scip, conss[c], NULL, FALSE, checkrelmaxabs, &violated) );
14555 
14556  if( violated )
14557  {
14558  /* insert LP row as cut */
14559  SCIP_CALL( addRelaxation(scip, conss[c], NULL, &cutoff) );
14560  if ( cutoff )
14561  *result = SCIP_CUTOFF;
14562  else
14563  *result = SCIP_SEPARATED;
14564  }
14565  }
14566 
14567  return SCIP_OKAY;
14568 }
14569 
14570 
14571 /** constraint enforcing method of constraint handler for pseudo solutions */
14572 static
14573 SCIP_DECL_CONSENFOPS(consEnfopsLinear)
14574 { /*lint --e{715}*/
14575  SCIP_CONSHDLRDATA* conshdlrdata;
14576  SCIP_Bool checkrelmaxabs;
14577  SCIP_Bool violated;
14578  int c;
14579 
14580  assert(scip != NULL);
14581  assert(conshdlr != NULL);
14582  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14583  assert(result != NULL);
14584 
14585  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14586  assert(conshdlrdata != NULL);
14587 
14588  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
14590  SCIPdebugMessage("Enfops method of linear constraints\n");
14591 
14592  /* if the solution is infeasible anyway due to objective value, skip the enforcement */
14593  if( objinfeasible )
14594  {
14595  SCIPdebugMessage("-> pseudo solution is objective infeasible, return.\n");
14596 
14597  *result = SCIP_DIDNOTRUN;
14598  return SCIP_OKAY;
14599  }
14600 
14601  /* check all linear constraints for feasibility */
14602  violated = FALSE;
14603  for( c = 0; c < nconss && !violated; ++c )
14604  {
14605  SCIP_CALL( checkCons(scip, conss[c], NULL, TRUE, checkrelmaxabs, &violated) );
14606  }
14607 
14608  if( violated )
14609  *result = SCIP_INFEASIBLE;
14610  else
14611  *result = SCIP_FEASIBLE;
14612 
14613  SCIPdebugMessage("-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
14614 
14615  return SCIP_OKAY;
14616 }
14617 
14618 
14619 /** feasibility check method of constraint handler for integral solutions */
14620 static
14621 SCIP_DECL_CONSCHECK(consCheckLinear)
14622 { /*lint --e{715}*/
14623  SCIP_CONSHDLRDATA* conshdlrdata;
14624  SCIP_Bool checkrelmaxabs;
14625  SCIP_Bool violated;
14626  int c;
14627 
14628  assert(scip != NULL);
14629  assert(conshdlr != NULL);
14630  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14631  assert(result != NULL);
14632 
14633  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14634  assert(conshdlrdata != NULL);
14635 
14636  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
14638  /*debugMessage("Check method of linear constraints\n");*/
14639 
14640  /* check all linear constraints for feasibility */
14641  violated = FALSE;
14642  for( c = 0; c < nconss && !violated; ++c )
14643  {
14644  SCIP_CALL( checkCons(scip, conss[c], sol, checklprows, checkrelmaxabs, &violated) );
14645  }
14646 
14647  if( violated )
14648  {
14649  *result = SCIP_INFEASIBLE;
14650 
14651  if( printreason )
14652  {
14653  SCIP_CONSDATA* consdata;
14654  SCIP_Real activity;
14655 
14656  consdata = SCIPconsGetData(conss[c-1]);
14657  assert( consdata != NULL);
14658 
14659  activity = consdataGetActivity(scip, consdata, sol);
14660 
14661  SCIP_CALL( SCIPprintCons(scip, conss[c-1], NULL ) );
14662  SCIPinfoMessage(scip, NULL, ";\n");
14663 
14664  if( activity == SCIP_INVALID ) /*lint !e777*/
14665  SCIPinfoMessage(scip, NULL, "activity invalid due to positive and negative infinity contributions\n");
14666  else if( SCIPisFeasLT(scip, activity, consdata->lhs) )
14667  SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", consdata->lhs - activity);
14668  else if( SCIPisFeasGT(scip, activity, consdata->rhs) )
14669  SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - consdata->rhs);
14670  }
14671  }
14672  else
14673  *result = SCIP_FEASIBLE;
14674 
14675  return SCIP_OKAY;
14676 }
14677 
14678 
14679 /** domain propagation method of constraint handler */
14680 static
14681 SCIP_DECL_CONSPROP(consPropLinear)
14682 { /*lint --e{715}*/
14683  SCIP_CONSHDLRDATA* conshdlrdata;
14684  SCIP_Bool rangedrowpropagation = FALSE;
14685  SCIP_Bool tightenbounds;
14686  SCIP_Bool cutoff;
14687 
14688  int nchgbds;
14689  int i;
14690 
14691  assert(scip != NULL);
14692  assert(conshdlr != NULL);
14693  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14694  assert(result != NULL);
14695 
14696  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14697  assert(conshdlrdata != NULL);
14698 
14699  /*debugMessage("Prop method of linear constraints\n");*/
14700 
14701  /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
14702  if( SCIPinProbing(scip) )
14703  tightenbounds = TRUE;
14704  else
14705  {
14706  int depth;
14707  int propfreq;
14708  int tightenboundsfreq;
14709  int rangedrowfreq;
14710 
14711  depth = SCIPgetDepth(scip);
14712  propfreq = SCIPconshdlrGetPropFreq(conshdlr);
14713  tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
14714  tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
14715  && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
14716 
14717  /* check if we want to do ranged row propagation */
14718  rangedrowpropagation = conshdlrdata->rangedrowpropagation;
14719  rangedrowpropagation = rangedrowpropagation && !SCIPinRepropagation(scip);
14720  rangedrowpropagation = rangedrowpropagation && (depth <= conshdlrdata->rangedrowmaxdepth);
14721  rangedrowfreq = propfreq * conshdlrdata->rangedrowfreq;
14722  rangedrowpropagation = rangedrowpropagation && (depth % rangedrowfreq == 0);
14723  }
14724 
14725  cutoff = FALSE;
14726  nchgbds = 0;
14727 
14728 
14729  /* process constraints marked for propagation */
14730  for( i = 0; i < nmarkedconss && !cutoff; i++ )
14731  {
14732  SCIP_CALL( SCIPunmarkConsPropagate(scip, conss[i]) );
14733  SCIP_CALL( propagateCons(scip, conss[i], tightenbounds, rangedrowpropagation,
14734  conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, &nchgbds) );
14735  }
14736 
14737  /* adjust result code */
14738  if( cutoff )
14739  *result = SCIP_CUTOFF;
14740  else if( nchgbds > 0 )
14741  *result = SCIP_REDUCEDDOM;
14742  else
14743  *result = SCIP_DIDNOTFIND;
14744 
14745  return SCIP_OKAY;
14746 }
14747 
14748 
14749 #define MAXCONSPRESOLROUNDS 10
14750 /** presolving method of constraint handler */
14751 static
14752 SCIP_DECL_CONSPRESOL(consPresolLinear)
14753 { /*lint --e{715}*/
14754  SCIP_CONSHDLRDATA* conshdlrdata;
14755  SCIP_CONS* cons;
14756  SCIP_CONSDATA* consdata;
14757  SCIP_Real minactivity;
14758  SCIP_Real maxactivity;
14759  SCIP_Bool minactisrelax;
14760  SCIP_Bool maxactisrelax;
14761  SCIP_Bool cutoff;
14762  int oldnfixedvars;
14763  int oldnaggrvars;
14764  int oldnchgbds;
14765  int oldndelconss;
14766  int oldnupgdconss;
14767  int oldnchgcoefs;
14768  int oldnchgsides;
14769  int firstchange;
14770  int firstupgradetry;
14771  int c;
14772 
14773  assert(scip != NULL);
14774  assert(conshdlr != NULL);
14775  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14776  assert(result != NULL);
14777 
14778  /*debugMessage("Presol method of linear constraints\n");*/
14779 
14780  /* remember old preprocessing counters */
14781  cutoff = FALSE;
14782  oldnfixedvars = *nfixedvars;
14783  oldnaggrvars = *naggrvars;
14784  oldnchgbds = *nchgbds;
14785  oldndelconss = *ndelconss;
14786  oldnupgdconss = *nupgdconss;
14787  oldnchgcoefs = *nchgcoefs;
14788  oldnchgsides = *nchgsides;
14789 
14790  /* get constraint handler data */
14791  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14792  assert(conshdlrdata != NULL);
14793 
14794  /* process single constraints */
14795  firstchange = INT_MAX;
14796  firstupgradetry = INT_MAX;
14797  for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
14798  {
14799  int npresolrounds;
14800  SCIP_Bool infeasible;
14801 
14802  infeasible = FALSE;
14803 
14804  cons = conss[c];
14805  assert(SCIPconsIsActive(cons));
14806  consdata = SCIPconsGetData(cons);
14807  assert(consdata != NULL);
14808 
14809  /* constraint should not be already presolved in the initial round */
14810  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->propagated);
14811  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->boundstightened);
14812  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->presolved);
14813  assert(consdata->propagated || !consdata->presolved);
14814 
14815  /* incorporate fixings and aggregations in constraint */
14816  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
14817 
14818  if( infeasible )
14819  {
14820  SCIPdebugMessage(" -> infeasible fixing\n");
14821  cutoff = TRUE;
14822  break;
14823  }
14824 
14825  assert(consdata->removedfixings);
14826 
14827  /* we can only presolve linear constraints, that are not modifiable */
14828  if( SCIPconsIsModifiable(cons) )
14829  continue;
14830 
14831  /* remember the first changed constraint to begin the next aggregation round with */
14832  if( firstchange == INT_MAX && consdata->changed )
14833  firstchange = c;
14834 
14835  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
14836  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
14837  firstupgradetry = c;
14838 
14839  /* check, if constraint is already preprocessed */
14840  if( consdata->presolved )
14841  continue;
14842 
14843  assert(SCIPconsIsActive(cons));
14844 
14845  SCIPdebugMessage("presolving linear constraint <%s>\n", SCIPconsGetName(cons));
14846  SCIPdebugPrintCons(scip, cons, NULL);
14847 
14848  /* apply presolving as long as possible on the single constraint (however, abort after a certain number of rounds
14849  * to avoid nearly infinite cycling due to very small bound changes)
14850  */
14851  npresolrounds = 0;
14852  while( !consdata->presolved && npresolrounds < MAXCONSPRESOLROUNDS && !SCIPisStopped(scip) )
14853  {
14854  assert(!cutoff);
14855  npresolrounds++;
14856 
14857  /* mark constraint being presolved and propagated */
14858  consdata->presolved = TRUE;
14859  consdata->propagated = TRUE;
14860 
14861  /* normalize constraint */
14862  SCIP_CALL( normalizeCons(scip, cons) );
14863 
14864  /* tighten left and right hand side due to integrality */
14865  SCIP_CALL( tightenSides(scip, cons, nchgsides) );
14866 
14867  /* check bounds */
14868  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
14869  {
14870  SCIPdebugMessage("linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
14871  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
14872  cutoff = TRUE;
14873  break;
14874  }
14875 
14876  /* tighten variable's bounds */
14877  SCIP_CALL( tightenBounds(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, nchgbds) );
14878  if( cutoff )
14879  break;
14880 
14881  /* check for fixed variables */
14882  SCIP_CALL( fixVariables(scip, cons, &cutoff, nfixedvars) );
14883  if( cutoff )
14884  break;
14885 
14886  /* check constraint for infeasibility and redundancy */
14887  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
14888  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) || SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
14889  {
14890  SCIPdebugMessage("linear constraint <%s> is infeasible: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
14891  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
14892  cutoff = TRUE;
14893  break;
14894  }
14895  else if( SCIPisFeasGE(scip, minactivity, consdata->lhs) && SCIPisFeasLE(scip, maxactivity, consdata->rhs) )
14896  {
14897  SCIPdebugMessage("linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
14898  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
14899  SCIP_CALL( SCIPdelCons(scip, cons) );
14900  assert(!SCIPconsIsActive(cons));
14901 
14902  if( !consdata->upgraded )
14903  (*ndelconss)++;
14904  break;
14905  }
14906  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisFeasGE(scip, minactivity, consdata->lhs) )
14907  {
14908  SCIPdebugMessage("linear constraint <%s> left hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
14909  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
14910  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
14911  if( !consdata->upgraded )
14912  (*nchgsides)++;
14913  }
14914  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisFeasLE(scip, maxactivity, consdata->rhs) )
14915  {
14916  SCIPdebugMessage("linear constraint <%s> right hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
14917  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
14918  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
14919  if( !consdata->upgraded )
14920  (*nchgsides)++;
14921  }
14922  assert(consdata->nvars >= 1); /* otherwise, it should be redundant or infeasible */
14923 
14924  /* handle empty constraint */
14925  if( consdata->nvars == 0 )
14926  {
14927  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
14928  {
14929  SCIPdebugMessage("empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
14930  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
14931  cutoff = TRUE;
14932  }
14933  else
14934  {
14935  SCIPdebugMessage("empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
14936  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
14937  SCIP_CALL( SCIPdelCons(scip, cons) );
14938  assert(!SCIPconsIsActive(cons));
14939 
14940  if( !consdata->upgraded )
14941  (*ndelconss)++;
14942  }
14943  break;
14944  }
14945 
14946  /* reduce big-M coefficients, that make the constraint redundant if the variable is on a bound */
14947  SCIP_CALL( consdataTightenCoefs(scip, cons, nchgcoefs, nchgsides) );
14948 
14949  /* try to simplify inequalities */
14950  if( conshdlrdata->simplifyinequalities )
14951  {
14952  SCIP_CALL( simplifyInequalities(scip, cons, nchgcoefs, nchgsides) );
14953  }
14954 
14955  /* aggregation variable in equations */
14956  if( conshdlrdata->aggregatevariables )
14957  {
14958  SCIP_CALL( aggregateVariables(scip, cons, &cutoff, nfixedvars, naggrvars, ndelconss) );
14959  if( cutoff )
14960  break;
14961  }
14962  }
14963 
14964  if( conshdlrdata->rangedrowpropagation && !cutoff && !SCIPisStopped(scip) )
14965  {
14966  int lastnfixedvars;
14967 
14968  lastnfixedvars = *nfixedvars;
14969 
14970  SCIP_CALL( rangedRowPropagation(scip, cons, &cutoff, nfixedvars, nchgbds, naddconss) );
14971  if( !cutoff )
14972  {
14973  if( lastnfixedvars < *nfixedvars )
14974  {
14975  SCIP_CALL( applyFixings(scip, cons, &cutoff) );
14976  }
14977  }
14978 
14979  /* extract cliques from constraint */
14980  if( !cutoff && SCIPconsIsActive(cons) )
14981  {
14982  SCIP_CALL( extractCliques(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars,
14983  nfixedvars, nchgbds, &cutoff) );
14984 
14985  /* check if the constraint got redundant or infeasible */
14986  if( !cutoff && SCIPconsIsActive(cons) && consdata->nvars == 0 )
14987  {
14988  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
14989  {
14990  SCIPdebugMessage("empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
14991  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
14992  cutoff = TRUE;
14993  }
14994  else
14995  {
14996  SCIPdebugMessage("empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
14997  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
14998  SCIP_CALL( SCIPdelCons(scip, cons) );
14999  assert(!SCIPconsIsActive(cons));
15000 
15001  if( !consdata->upgraded )
15002  (*ndelconss)++;
15003  }
15004  }
15005  }
15006 
15007  /* convert special equalities */
15008  if( !cutoff && SCIPconsIsActive(cons) )
15009  {
15010  SCIP_CALL( convertEquality(scip, cons, conshdlrdata, &cutoff, nfixedvars, naggrvars, ndelconss) );
15011  }
15012 
15013  /* apply dual presolving for variables that appear in only one constraint */
15014  if( !cutoff && SCIPconsIsActive(cons) && conshdlrdata->dualpresolving && SCIPallowDualReds(scip) )
15015  {
15016  SCIP_CALL( dualPresolve(scip, cons, &cutoff, nfixedvars, naggrvars, ndelconss) );
15017  }
15018 
15019  /* check if an inequality is parallel to the objective function */
15020  if( !cutoff && SCIPconsIsActive(cons) )
15021  {
15022  SCIP_CALL( checkParallelObjective(scip, cons, conshdlrdata) );
15023  }
15024 
15025  /* remember the first changed constraint to begin the next aggregation round with */
15026  if( firstchange == INT_MAX && consdata->changed )
15027  firstchange = c;
15028 
15029  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
15030  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
15031  firstupgradetry = c;
15032  }
15033  }
15034 
15035  /* process pairs of constraints: check them for redundancy and try to aggregate them;
15036  * only apply this expensive procedure in exhaustive presolving timing
15037  */
15038  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && (conshdlrdata->presolusehashing || conshdlrdata->presolpairwise) && !SCIPisStopped(scip) )
15039  {
15040  assert(firstchange >= 0);
15041 
15042  if( firstchange < nconss && conshdlrdata->presolusehashing )
15043  {
15044  /* detect redundant constraints; fast version with hash table instead of pairwise comparison */
15045  SCIP_CALL( detectRedundantConstraints(scip, SCIPblkmem(scip), conss, nconss, &firstchange, &cutoff,
15046  ndelconss, nchgsides) );
15047  }
15048 
15049  if( firstchange < nconss && conshdlrdata->presolpairwise )
15050  {
15051  SCIP_CONS** usefulconss;
15052  int nusefulconss;
15053  int firstchangenew;
15054  SCIP_Longint npaircomparisons;
15055 
15056  npaircomparisons = 0;
15057  oldndelconss = *ndelconss;
15058  oldnchgsides = *nchgsides;
15059  oldnchgcoefs = *nchgcoefs;
15060 
15061  /* allocate temporary memory */
15062  SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, nconss) );
15063 
15064  nusefulconss = 0;
15065  firstchangenew = -1;
15066  for( c = 0; c < nconss; ++c )
15067  {
15068  /* update firstchange */
15069  if( c == firstchange )
15070  firstchangenew = nusefulconss;
15071 
15072  /* ignore inactive and modifiable constraints */
15073  if( !SCIPconsIsActive(conss[c]) || SCIPconsIsModifiable(conss[c]) )
15074  continue;
15075 
15076  usefulconss[nusefulconss] = conss[c];
15077  ++nusefulconss;
15078  }
15079  firstchange = firstchangenew;
15080  assert(firstchangenew >= 0 && firstchangenew <= nusefulconss);
15081 
15082  for( c = firstchange; c < nusefulconss && !cutoff && !SCIPisStopped(scip); ++c )
15083  {
15084  /* constraint has become inactive or modifiable during pairwise presolving */
15085  if( usefulconss[c] == NULL )
15086  continue;
15087 
15088  npaircomparisons += (SCIPconsGetData(conss[c])->changed) ? c : (c - firstchange); /*lint !e776*/
15089 
15090  assert(SCIPconsIsActive(usefulconss[c]) && !SCIPconsIsModifiable(usefulconss[c]));
15091  SCIP_CALL( preprocessConstraintPairs(scip, usefulconss, firstchange, c, conshdlrdata->maxaggrnormscale,
15092  &cutoff, ndelconss, nchgsides, nchgcoefs) );
15093 
15094  if( npaircomparisons > conshdlrdata->nmincomparisons )
15095  {
15096  assert(npaircomparisons > 0);
15097  if( ((*ndelconss - oldndelconss) + (*nchgsides - oldnchgsides)/2.0 + (*nchgcoefs - oldnchgcoefs)/10.0) / ((SCIP_Real) npaircomparisons) < conshdlrdata->mingainpernmincomp )
15098  break;
15099  oldndelconss = *ndelconss;
15100  oldnchgsides = *nchgsides;
15101  oldnchgcoefs = *nchgcoefs;
15102  npaircomparisons = 0;
15103  }
15104  }
15105  /* free temporary memory */
15106  SCIPfreeBufferArray(scip, &usefulconss);
15107  }
15108  }
15109 
15110  /* before upgrading, check whether we can apply some additional dual presolving, because a variable only appears
15111  * in linear constraints and we therefore have full information about it
15112  */
15113  if( !cutoff && firstupgradetry < nconss
15114  && *nfixedvars == oldnfixedvars && *naggrvars == oldnaggrvars && *nchgbds == oldnchgbds && *ndelconss == oldndelconss
15115  && *nupgdconss == oldnupgdconss && *nchgcoefs == oldnchgcoefs && *nchgsides == oldnchgsides
15116  )
15117  {
15118  if( conshdlrdata->dualpresolving && SCIPallowDualReds(scip) && !SCIPisStopped(scip) )
15119  {
15120  SCIP_CALL( fullDualPresolve(scip, conss, nconss, &cutoff, nchgbds) );
15121  }
15122  }
15123 
15124  /* try to upgrade constraints into a more specific constraint type;
15125  * only upgrade constraints, if no reductions were found in this round (otherwise, the linear constraint handler
15126  * may find additional reductions before giving control away to other (less intelligent?) constraint handlers)
15127  */
15128  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && SCIPisPresolveFinished(scip) )
15129  {
15130  for( c = firstupgradetry; c < nconss && !SCIPisStopped(scip); ++c )
15131  {
15132  cons = conss[c];
15133 
15134  /* don't upgrade modifiable constraints */
15135  if( SCIPconsIsModifiable(cons) )
15136  continue;
15137 
15138  consdata = SCIPconsGetData(cons);
15139  assert(consdata != NULL);
15140 
15141  /* only upgrade completely presolved constraints, that changed since the last upgrading call */
15142  if( consdata->upgradetried )
15143  continue;
15144  /* @todo force that upgrade will be performed later? */
15145  if( !consdata->presolved )
15146  continue;
15147 
15148  consdata->upgradetried = TRUE;
15149  if( SCIPconsIsActive(cons) )
15150  {
15151  SCIP_CONS* upgdcons;
15152 
15153  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
15154  if( upgdcons != NULL )
15155  {
15156  /* add the upgraded constraint to the problem */
15157  SCIP_CALL( SCIPaddCons(scip, upgdcons) );
15158  SCIP_CALL( SCIPreleaseCons(scip, &upgdcons) );
15159  (*nupgdconss)++;
15160 
15161  /* mark the linear constraint being upgraded and to be removed after presolving;
15162  * don't delete it directly, because it may help to preprocess other linear constraints
15163  */
15164  assert(!consdata->upgraded);
15165  consdata->upgraded = TRUE;
15166 
15167  /* delete upgraded inequalities immediately;
15168  * delete upgraded equalities, if we don't need it anymore for aggregation and redundancy checking
15169  */
15170  if( SCIPisLT(scip, consdata->lhs, consdata->rhs)
15171  || !conshdlrdata->presolpairwise
15172  || (conshdlrdata->maxaggrnormscale == 0.0) )
15173  {
15174  SCIP_CALL( SCIPdelCons(scip, cons) );
15175  }
15176  }
15177  }
15178  }
15179  }
15180 
15181  /* return the correct result code */
15182  if( cutoff )
15183  *result = SCIP_CUTOFF;
15184  else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds || *ndelconss > oldndelconss
15185  || *nupgdconss > oldnupgdconss || *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides )
15186  *result = SCIP_SUCCESS;
15187  else
15188  *result = SCIP_DIDNOTFIND;
15189 
15190  return SCIP_OKAY;
15191 }
15192 
15193 
15194 /** propagation conflict resolving method of constraint handler */
15195 static
15196 SCIP_DECL_CONSRESPROP(consRespropLinear)
15197 { /*lint --e{715}*/
15198 
15199  assert(scip != NULL);
15200  assert(cons != NULL);
15201  assert(result != NULL);
15202 
15203  SCIP_CALL( resolvePropagation(scip, cons, infervar, intToInferInfo(inferinfo), boundtype, bdchgidx, result) );
15204 
15205  return SCIP_OKAY;
15206 }
15207 
15208 
15209 /** variable rounding lock method of constraint handler */
15210 static
15211 SCIP_DECL_CONSLOCK(consLockLinear)
15212 { /*lint --e{715}*/
15213  SCIP_CONSDATA* consdata;
15214  SCIP_Bool haslhs;
15215  SCIP_Bool hasrhs;
15216  int i;
15217 
15218  assert(scip != NULL);
15219  assert(cons != NULL);
15220  consdata = SCIPconsGetData(cons);
15221  assert(consdata != NULL);
15222 
15223  haslhs = !SCIPisInfinity(scip, -consdata->lhs);
15224  hasrhs = !SCIPisInfinity(scip, consdata->rhs);
15225 
15226  /* update rounding locks of every single variable */
15227  for( i = 0; i < consdata->nvars; ++i )
15228  {
15229  if( SCIPisPositive(scip, consdata->vals[i]) )
15230  {
15231  if( haslhs )
15232  {
15233  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlockspos, nlocksneg) );
15234  }
15235  if( hasrhs )
15236  {
15237  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlocksneg, nlockspos) );
15238  }
15239  }
15240  else
15241  {
15242  if( haslhs )
15243  {
15244  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlocksneg, nlockspos) );
15245  }
15246  if( hasrhs )
15247  {
15248  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlockspos, nlocksneg) );
15249  }
15250  }
15251  }
15252 
15253  return SCIP_OKAY;
15254 }
15255 
15256 
15257 /** variable deletion method of constraint handler */
15258 static
15259 SCIP_DECL_CONSDELVARS(consDelvarsLinear)
15260 {
15261  assert(scip != NULL);
15262  assert(conshdlr != NULL);
15263  assert(conss != NULL || nconss == 0);
15264 
15265  if( nconss > 0 )
15266  {
15267  SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
15268  }
15269 
15270  return SCIP_OKAY;
15271 }
15272 
15273 /** constraint display method of constraint handler */
15274 static
15275 SCIP_DECL_CONSPRINT(consPrintLinear)
15276 { /*lint --e{715}*/
15277  assert(scip != NULL);
15278  assert(conshdlr != NULL);
15279  assert(cons != NULL);
15280 
15281  SCIP_CALL( consdataPrint(scip, SCIPconsGetData(cons), file) );
15282 
15283  return SCIP_OKAY;
15284 }
15285 
15286 /** constraint copying method of constraint handler */
15287 static
15288 SCIP_DECL_CONSCOPY(consCopyLinear)
15289 { /*lint --e{715}*/
15290  SCIP_VAR** sourcevars;
15291  SCIP_Real* sourcecoefs;
15292  const char* consname;
15293  int nvars;
15294 
15295  assert(scip != NULL);
15296  assert(sourcescip != NULL);
15297  assert(sourcecons != NULL);
15298 
15299  /* get variables and coefficients of the source constraint */
15300  sourcevars = SCIPgetVarsLinear(sourcescip, sourcecons);
15301  sourcecoefs = SCIPgetValsLinear(sourcescip, sourcecons);
15302  nvars = SCIPgetNVarsLinear(sourcescip, sourcecons);
15303 
15304  if( name != NULL )
15305  consname = name;
15306  else
15307  consname = SCIPconsGetName(sourcecons);
15308 
15309  SCIP_CALL( SCIPcopyConsLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
15310  SCIPgetLhsLinear(sourcescip, sourcecons), SCIPgetRhsLinear(sourcescip, sourcecons), varmap, consmap,
15311  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
15312  assert(cons != NULL || *valid == FALSE);
15313 
15314  return SCIP_OKAY;
15315 }
15316 
15317 /** constraint parsing method of constraint handler */
15318 static
15319 SCIP_DECL_CONSPARSE(consParseLinear)
15320 { /*lint --e{715}*/
15321  SCIP_VAR** vars;
15322  SCIP_Real* coefs;
15323  int nvars;
15324  int coefssize;
15325  int requsize;
15326  SCIP_Real lhs;
15327  SCIP_Real rhs;
15328  char* endptr;
15329 
15330  assert(scip != NULL);
15331  assert(success != NULL);
15332  assert(str != NULL);
15333  assert(name != NULL);
15334  assert(cons != NULL);
15336  /* set left and right hand side to their default values */
15337  lhs = -SCIPinfinity(scip);
15338  rhs = SCIPinfinity(scip);
15339 
15340  (*success) = FALSE;
15341 
15342  /* return of string empty */
15343  if( !*str )
15344  return SCIP_OKAY;
15345 
15346  /* ignore whitespace */
15347  while( isspace((unsigned char)*str) )
15348  ++str;
15349 
15350  /* check for left hand side */
15351  if( isdigit((unsigned char)str[0]) || ((str[0] == '-' || str[0] == '+') && isdigit((unsigned char)str[1])) )
15352  {
15353  /* there is a number coming, maybe it is a left-hand-side */
15354  if( !SCIPstrToRealValue(str, &lhs, &endptr) )
15355  {
15356  SCIPerrorMessage("error parsing number from <%s>\n", str);
15357  return SCIP_OKAY;
15358  }
15359 
15360  /* ignore whitespace */
15361  while( isspace((unsigned char)*endptr) )
15362  ++endptr;
15363 
15364  if( endptr[0] != '<' || endptr[1] != '=' )
15365  {
15366  /* no '<=' coming, so it was the first coefficient, but not a left-hand-side */
15367  lhs = -SCIPinfinity(scip);
15368  }
15369  else
15370  {
15371  /* it was indeed a left-hand-side, so continue parsing after it */
15372  str = endptr + 2;
15373 
15374  /* ignore whitespace */
15375  while( isspace((unsigned char)*str) )
15376  ++str;
15377  }
15378  }
15379 
15380  /* initialize buffers for storing the variables and coefficients */
15381  coefssize = 100;
15382  SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
15383  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, coefssize) );
15384 
15385  /* parse linear sum to get variables and coefficients */
15386  SCIP_CALL( SCIPparseVarsLinearsum(scip, str, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
15387 
15388  if( *success && requsize > coefssize )
15389  {
15390  /* realloc buffers and try again */
15391  coefssize = requsize;
15392  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, coefssize) );
15393  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, coefssize) );
15394 
15395  SCIP_CALL( SCIPparseVarsLinearsum(scip, str, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
15396  assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
15397  }
15398 
15399  if( !*success )
15400  {
15401  SCIPerrorMessage("no luck in parsing linear sum '%s'\n", str);
15402  }
15403  else
15404  {
15405  (*success) = FALSE;
15406  str = endptr;
15407 
15408  /* check for left or right hand side */
15409  while( isspace((unsigned char)*str) )
15410  ++str;
15411 
15412  /* check for free constraint */
15413  if( strncmp(str, "[free]", 6) == 0 )
15414  {
15415  if( !SCIPisInfinity(scip, -lhs) )
15416  {
15417  SCIPerrorMessage("cannot have left hand side and [free] status \n");
15418  return SCIP_OKAY;
15419  }
15420  (*success) = TRUE;
15421  }
15422  else
15423  {
15424  switch( *str )
15425  {
15426  case '<':
15427  *success = SCIPstrToRealValue(str+2, &rhs, &endptr);
15428  break;
15429  case '=':
15430  if( !SCIPisInfinity(scip, -lhs) )
15431  {
15432  SCIPerrorMessage("cannot have == on rhs if there was a <= on lhs\n");
15433  return SCIP_OKAY;
15434  }
15435  else
15436  {
15437  *success = SCIPstrToRealValue(str+2, &rhs, &endptr);
15438  lhs = rhs;
15439  }
15440  break;
15441  case '>':
15442  if( !SCIPisInfinity(scip, -lhs) )
15443  {
15444  SCIPerrorMessage("cannot have => on rhs if there was a <= on lhs\n");
15445  return SCIP_OKAY;
15446  }
15447  else
15448  {
15449  *success = SCIPstrToRealValue(str+2, &lhs, &endptr);
15450  break;
15451  }
15452  case '\0':
15453  *success = TRUE;
15454  break;
15455  default:
15456  SCIPerrorMessage("unexpected character %c\n", *str);
15457  return SCIP_OKAY;
15458  }
15459  }
15460 
15461  if( *success )
15462  {
15463  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
15464  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
15465  }
15466  }
15467 
15468  SCIPfreeBufferArray(scip, &coefs);
15469  SCIPfreeBufferArray(scip, &vars);
15470 
15471  return SCIP_OKAY;
15472 }
15473 
15474 
15475 /** constraint method of constraint handler which returns the variables (if possible) */
15476 static
15477 SCIP_DECL_CONSGETVARS(consGetVarsLinear)
15478 { /*lint --e{715}*/
15479  SCIP_CONSDATA* consdata;
15480 
15481  consdata = SCIPconsGetData(cons);
15482  assert(consdata != NULL);
15483 
15484  if( varssize < consdata->nvars )
15485  (*success) = FALSE;
15486  else
15487  {
15488  assert(vars != NULL);
15489 
15490  BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
15491  (*success) = TRUE;
15492  }
15494  return SCIP_OKAY;
15495 }
15496 
15497 /** constraint method of constraint handler which returns the number of variables (if possible) */
15498 static
15499 SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
15500 { /*lint --e{715}*/
15501  SCIP_CONSDATA* consdata;
15502 
15503  consdata = SCIPconsGetData(cons);
15504  assert(consdata != NULL);
15505 
15506  (*nvars) = consdata->nvars;
15507  (*success) = TRUE;
15508 
15509  return SCIP_OKAY;
15510 }
15511 
15512 /*
15513  * Callback methods of event handler
15514  */
15516 static
15517 SCIP_DECL_EVENTEXEC(eventExecLinear)
15518 { /*lint --e{715}*/
15519  SCIP_CONS* cons;
15520  SCIP_CONSDATA* consdata;
15521  SCIP_VAR* var;
15522  SCIP_EVENTTYPE eventtype;
15523 
15524  assert(scip != NULL);
15525  assert(eventhdlr != NULL);
15526  assert(eventdata != NULL);
15527  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
15528  assert(event != NULL);
15529 
15530  cons = eventdata->cons;
15531  assert(cons != NULL);
15532  consdata = SCIPconsGetData(cons);
15533  assert(consdata != NULL);
15534 
15535  eventtype = SCIPeventGetType(event);
15536  var = SCIPeventGetVar(event);
15537 
15538  if( (eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) != 0 )
15539  {
15540  SCIP_Real oldbound;
15541  SCIP_Real newbound;
15542  SCIP_Real val;
15543  int varpos;
15544 
15545  varpos = eventdata->varpos;
15546  assert(0 <= varpos && varpos < consdata->nvars);
15547  oldbound = SCIPeventGetOldbound(event);
15548  newbound = SCIPeventGetNewbound(event);
15549  assert(var != NULL);
15550  assert(consdata->vars[varpos] == var);
15551  val = consdata->vals[varpos];
15552 
15553  /* update the activity values */
15554  if( (eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
15555  consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, val, TRUE);
15556  else
15557  {
15558  assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0);
15559  consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, val, TRUE);
15560  }
15561 
15562  consdata->presolved = FALSE;
15563  consdata->rangedrowpropagation = FALSE;
15564 
15565  /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
15566  if( (eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0 )
15567  {
15568  consdata->propagated = FALSE;
15569  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
15570 
15571  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
15572  if( consdata->maxactdeltavar == var )
15573  {
15574  consdata->maxactdelta = SCIP_INVALID;
15575  consdata->maxactdeltavar = NULL;
15576  }
15577  }
15578  /* update maximal activity delta if a bound was relaxed */
15579  else if( (eventtype & SCIP_EVENTTYPE_BOUNDRELAXED) != 0 && !SCIPisInfinity(scip, consdata->maxactdelta) )
15580  {
15581  SCIP_Real lb;
15582  SCIP_Real ub;
15583  SCIP_Real domain;
15584  SCIP_Real delta;
15585 
15586  lb = SCIPvarGetLbLocal(var);
15587  ub = SCIPvarGetUbLocal(var);
15588 
15589  domain = ub - lb;
15590  delta = REALABS(val) * domain;
15591 
15592  if( delta > consdata->maxactdelta )
15593  {
15594  consdata->maxactdelta = delta;
15595  consdata->maxactdeltavar = var;
15596  }
15597  }
15598 
15599  /* check whether bound tightening might now be successful (if the current bound was relaxed, it might be
15600  * that it can be tightened again)
15601  */
15602  if( consdata->boundstightened )
15603  {
15604  switch( eventtype )
15605  {
15608  consdata->boundstightened = (val > 0.0 && SCIPisInfinity(scip, consdata->rhs))
15609  || (val < 0.0 && SCIPisInfinity(scip, -consdata->lhs));
15610  break;
15613  consdata->boundstightened = (val > 0.0 && SCIPisInfinity(scip, -consdata->lhs))
15614  || (val < 0.0 && SCIPisInfinity(scip, consdata->rhs));
15615  break;
15616  default:
15617  SCIPerrorMessage("invalid event type %d\n", eventtype);
15618  return SCIP_INVALIDDATA;
15619  }
15620  }
15621  }
15622  else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != 0 )
15623  {
15624  /* we want to remove the fixed variable */
15625  consdata->presolved = FALSE;
15626  consdata->removedfixings = FALSE;
15627  consdata->rangedrowpropagation = FALSE;
15628 
15629  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
15630  if( consdata->maxactdeltavar == var )
15631  {
15632  consdata->maxactdelta = SCIP_INVALID;
15633  consdata->maxactdeltavar = NULL;
15634  }
15635  }
15636 
15637  else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != 0 )
15638  {
15639  /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
15640  assert(SCIPvarGetNLocksDown(var) <= 1);
15641  assert(SCIPvarGetNLocksUp(var) <= 1);
15642  consdata->presolved = FALSE;
15643  }
15644  else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != 0 )
15645  {
15646  SCIP_Real oldbound;
15647  SCIP_Real newbound;
15648  SCIP_Real val;
15649  int varpos;
15650 
15651  varpos = eventdata->varpos;
15652  assert(0 <= varpos && varpos < consdata->nvars);
15653  oldbound = SCIPeventGetOldbound(event);
15654  newbound = SCIPeventGetNewbound(event);
15655  assert(var != NULL);
15656  assert(consdata->vars[varpos] == var);
15657  val = consdata->vals[varpos];
15658 
15659  consdata->rangedrowpropagation = FALSE;
15660 
15661  /* update the activity values */
15662  if( (eventtype & SCIP_EVENTTYPE_GLBCHANGED) != 0 )
15663  consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, val, TRUE);
15664  else
15665  {
15666  assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != 0);
15667  consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, val, TRUE);
15668  }
15669  }
15670  else
15671  {
15672  assert((eventtype & SCIP_EVENTTYPE_VARDELETED) != 0);
15673  consdata->varsdeleted = TRUE;
15674  }
15675 
15676  return SCIP_OKAY;
15677 }
15678 
15679 
15680 /*
15681  * Callback methods of conflict handler
15682  */
15683 
15684 static
15685 SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
15686 { /*lint --e{715}*/
15687  SCIP_VAR** vars;
15688  SCIP_Real* vals;
15689  SCIP_Real lhs;
15690  int i;
15691 
15692  assert(scip != NULL);
15693  assert(conflicthdlr != NULL);
15694  assert(strcmp(SCIPconflicthdlrGetName(conflicthdlr), CONFLICTHDLR_NAME) == 0);
15695  assert(bdchginfos != NULL || nbdchginfos == 0);
15696  assert(result != NULL);
15697 
15698  /* don't process already resolved conflicts */
15699  if( resolved )
15700  {
15701  *result = SCIP_DIDNOTRUN;
15702  return SCIP_OKAY;
15703  }
15704 
15705  *result = SCIP_DIDNOTFIND;
15706 
15707  /* create array of variables and coefficients: sum_{i \in P} x_i - sum_{i \in N} x_i >= 1 - |N| */
15708  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
15709  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nbdchginfos) );
15710  lhs = 1.0;
15711  for( i = 0; i < nbdchginfos; ++i )
15712  {
15713  assert(bdchginfos != NULL);
15714 
15715  vars[i] = SCIPbdchginfoGetVar(bdchginfos[i]);
15716 
15717  /* we can only treat binary variables */
15718  /**@todo extend linear conflict constraints to some non-binary cases */
15719  if( !SCIPvarIsBinary(vars[i]) )
15720  break;
15721 
15722  /* check whether the variable is fixed to zero (P) or one (N) in the conflict set */
15723  if( SCIPbdchginfoGetNewbound(bdchginfos[i]) < 0.5 )
15724  vals[i] = 1.0;
15725  else
15726  {
15727  vals[i] = -1.0;
15728  lhs -= 1.0;
15729  }
15730  }
15731 
15732  if( i == nbdchginfos )
15733  {
15734  SCIP_CONS* cons;
15735  SCIP_CONS* upgdcons;
15736  char consname[SCIP_MAXSTRLEN];
15737 
15738  /* create a constraint out of the conflict set */
15739  (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "cf%"SCIP_LONGINT_FORMAT, SCIPgetNConflictConssApplied(scip));
15740  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, nbdchginfos, vars, vals, lhs, SCIPinfinity(scip),
15741  FALSE, separate, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
15742 
15743  /* try to automatically convert a linear constraint into a more specific and more specialized constraint */
15744  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
15745  if( upgdcons != NULL )
15746  {
15747  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
15748  cons = upgdcons;
15749  }
15750 
15751  /* add constraint to SCIP */
15752  SCIP_CALL( SCIPaddConsNode(scip, node, cons, validnode) );
15753  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
15754 
15755  *result = SCIP_CONSADDED;
15756  }
15757 
15758  /* free temporary memory */
15759  SCIPfreeBufferArray(scip, &vals);
15760  SCIPfreeBufferArray(scip, &vars);
15761 
15762  return SCIP_OKAY;
15763 }
15764 
15765 
15766 /*
15767  * Quadratic constraint upgrading
15768  */
15769 
15770 
15771 /** upgrades quadratic constraints with only and at least one linear variables into a linear constraint
15772  */
15773 static
15774 SCIP_DECL_QUADCONSUPGD(upgradeConsQuadratic)
15775 { /*lint --e{715}*/
15776  assert(scip != NULL);
15777  assert(cons != NULL);
15778  assert(nupgdconss != NULL);
15779  assert(upgdconss != NULL);
15780 
15781  *nupgdconss = 0;
15782 
15783  SCIPdebugMessage("upgradeConsQuadratic called for constraint <%s>\n", SCIPconsGetName(cons));
15784  SCIPdebugPrintCons(scip, cons, NULL);
15785 
15786  if( SCIPgetNQuadVarTermsQuadratic(scip, cons) > 0 )
15787  return SCIP_OKAY;
15788  if( SCIPgetNLinearVarsQuadratic(scip, cons) == 0 )
15789  return SCIP_OKAY;
15791  if( upgdconsssize < 1 )
15792  {
15793  /* signal that we need more memory */
15794  *nupgdconss = -1;
15795  return SCIP_OKAY;
15796  }
15797 
15798  *nupgdconss = 1;
15799  SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
15800  SCIPgetNLinearVarsQuadratic(scip, cons),
15801  SCIPgetLinearVarsQuadratic(scip, cons),
15802  SCIPgetCoefsLinearVarsQuadratic(scip, cons),
15803  SCIPgetLhsQuadratic(scip, cons), SCIPgetRhsQuadratic(scip, cons),
15807  SCIPconsIsStickingAtNode(cons)) );
15808  SCIPdebugMessage("created linear constraint:\n");
15809  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
15810 
15811  return SCIP_OKAY;
15812 }
15813 
15814 /** tries to upgrade a nonlinear constraint into a linear constraint */
15815 static
15816 SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
15817 {
15818  assert(nupgdconss != NULL);
15819  assert(upgdconss != NULL);
15820 
15821  *nupgdconss = 0;
15822 
15823  /* no interest in nonlinear constraints */
15824  if( SCIPgetExprgraphNodeNonlinear(scip, cons) != NULL )
15825  return SCIP_OKAY;
15826 
15827  /* no interest in constant constraints */
15828  if( SCIPgetNLinearVarsNonlinear(scip, cons) == 0 )
15829  return SCIP_OKAY;
15830 
15831  if( upgdconsssize < 1 )
15832  {
15833  /* request larger upgdconss array */
15834  *nupgdconss = -1;
15835  return SCIP_OKAY;
15836  }
15837 
15838  *nupgdconss = 1;
15839  SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
15841  SCIPgetLhsNonlinear(scip, cons), SCIPgetRhsNonlinear(scip, cons),
15845  SCIPconsIsStickingAtNode(cons)) );
15846 
15847  return SCIP_OKAY;
15848 }
15849 
15850 /*
15851  * constraint specific interface methods
15852  */
15853 
15854 /** creates the handler for linear constraints and includes it in SCIP */
15856  SCIP* scip /**< SCIP data structure */
15857  )
15858 {
15859  SCIP_CONSHDLRDATA* conshdlrdata;
15860  SCIP_CONSHDLR* conshdlr;
15861  SCIP_EVENTHDLR* eventhdlr;
15862  SCIP_CONFLICTHDLR* conflicthdlr;
15863 
15864  assert(scip != NULL);
15865 
15866  /* create event handler for bound change events */
15868  eventExecLinear, NULL) );
15869 
15870  /* create conflict handler for linear constraints */
15872  conflictExecLinear, NULL) );
15873 
15874  /* create constraint handler data */
15875  SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
15876 
15877  /* include constraint handler */
15880  consEnfolpLinear, consEnfopsLinear, consCheckLinear, consLockLinear,
15881  conshdlrdata) );
15882 
15883  assert(conshdlr != NULL);
15884 
15885  /* set non-fundamental callbacks via specific setter functions */
15886  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinear, consCopyLinear) );
15887  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinear) );
15888  SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsLinear) );
15889  SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitLinear) );
15890  SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreLinear) );
15891  SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinear) );
15892  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinear) );
15893  SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinear) );
15894  SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinear) );
15895  SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitLinear) );
15896  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinear) );
15897 #ifdef WITH_PRINTORIGCONSTYPES
15898  SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreLinear) );
15899 #endif
15900  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinear) );
15901  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolLinear, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
15902  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinear) );
15903  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropLinear, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
15905  SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinear) );
15906  SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinear, consSepasolLinear, CONSHDLR_SEPAFREQ,
15908  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinear) );
15909 
15910  if( SCIPfindConshdlr(scip, "quadratic") != NULL )
15911  {
15912  /* include function that upgrades quadratic constraint to linear constraints */
15914  }
15915 
15916  if( SCIPfindConshdlr(scip, "nonlinear") != NULL )
15917  {
15918  /* include the linear constraint upgrade in the nonlinear constraint handler */
15920  }
15921 
15922  /* add linear constraint handler parameters */
15923  SCIP_CALL( SCIPaddIntParam(scip,
15924  "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
15925  "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
15926  &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, INT_MAX, NULL, NULL) );
15927  SCIP_CALL( SCIPaddIntParam(scip,
15928  "constraints/" CONSHDLR_NAME "/maxrounds",
15929  "maximal number of separation rounds per node (-1: unlimited)",
15930  &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
15931  SCIP_CALL( SCIPaddIntParam(scip,
15932  "constraints/" CONSHDLR_NAME "/maxroundsroot",
15933  "maximal number of separation rounds per node in the root node (-1: unlimited)",
15934  &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
15935  SCIP_CALL( SCIPaddIntParam(scip,
15936  "constraints/" CONSHDLR_NAME "/maxsepacuts",
15937  "maximal number of cuts separated per separation round",
15938  &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
15939  SCIP_CALL( SCIPaddIntParam(scip,
15940  "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
15941  "maximal number of cuts separated per separation round in the root node",
15942  &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
15944  "constraints/" CONSHDLR_NAME "/presolpairwise",
15945  "should pairwise constraint comparison be performed in presolving?",
15946  &conshdlrdata->presolpairwise, TRUE, DEFAULT_PRESOLPAIRWISE, NULL, NULL) );
15948  "constraints/" CONSHDLR_NAME "/presolusehashing",
15949  "should hash table be used for detecting redundant constraints in advance",
15950  &conshdlrdata->presolusehashing, TRUE, DEFAULT_PRESOLUSEHASHING, NULL, NULL) );
15951  SCIP_CALL( SCIPaddIntParam(scip,
15952  "constraints/" CONSHDLR_NAME "/nmincomparisons",
15953  "number for minimal pairwise presolve comparisons",
15954  &conshdlrdata->nmincomparisons, TRUE, DEFAULT_NMINCOMPARISONS, 1, INT_MAX, NULL, NULL) );
15956  "constraints/" CONSHDLR_NAME "/mingainpernmincomparisons",
15957  "minimal gain per minimal pairwise presolve comparisons to repeat pairwise comparison round",
15958  &conshdlrdata->mingainpernmincomp, TRUE, DEFAULT_MINGAINPERNMINCOMP, 0.0, 1.0, NULL, NULL) );
15960  "constraints/" CONSHDLR_NAME "/maxaggrnormscale",
15961  "maximal allowed relative gain in maximum norm for constraint aggregation (0.0: disable constraint aggregation)",
15962  &conshdlrdata->maxaggrnormscale, TRUE, DEFAULT_MAXAGGRNORMSCALE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
15964  "constraints/" CONSHDLR_NAME "/maxeasyactivitydelta",
15965  "maximum activity delta to run easy propagation on linear constraint (faster, but numerically less stable)",
15966  &conshdlrdata->maxeasyactivitydelta, TRUE, DEFAULT_MAXEASYACTIVITYDELTA, 0.0, SCIP_REAL_MAX, NULL, NULL) );
15968  "constraints/" CONSHDLR_NAME "/maxcardbounddist",
15969  "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for separating knapsack cardinality cuts",
15970  &conshdlrdata->maxcardbounddist, TRUE, DEFAULT_MAXCARDBOUNDDIST, 0.0, 1.0, NULL, NULL) );
15972  "constraints/" CONSHDLR_NAME "/separateall",
15973  "should all constraints be subject to cardinality cut generation instead of only the ones with non-zero dual value?",
15974  &conshdlrdata->separateall, FALSE, DEFAULT_SEPARATEALL, NULL, NULL) );
15976  "constraints/" CONSHDLR_NAME "/aggregatevariables",
15977  "should presolving search for aggregations in equations",
15978  &conshdlrdata->aggregatevariables, TRUE, DEFAULT_AGGREGATEVARIABLES, NULL, NULL) );
15980  "constraints/" CONSHDLR_NAME "/simplifyinequalities",
15981  "should presolving try to simplify inequalities",
15982  &conshdlrdata->simplifyinequalities, TRUE, DEFAULT_SIMPLIFYINEQUALITIES, NULL, NULL) );
15984  "constraints/" CONSHDLR_NAME "/dualpresolving",
15985  "should dual presolving steps be performed?",
15986  &conshdlrdata->dualpresolving, TRUE, DEFAULT_DUALPRESOLVING, NULL, NULL) );
15988  "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
15989  &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
15991  "constraints/" CONSHDLR_NAME "/checkrelmaxabs",
15992  "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)?",
15993  &conshdlrdata->checkrelmaxabs, TRUE, DEFAULT_CHECKRELMAXABS, NULL, NULL) );
15995  "constraints/" CONSHDLR_NAME "/detectcutoffbound",
15996  "should presolving try to detect constraints parallel to the objective function defining an upper bound and prevent these constraints from entering the LP?",
15997  &conshdlrdata->detectcutoffbound, TRUE, DEFAULT_DETECTCUTOFFBOUND, NULL, NULL) );
15999  "constraints/" CONSHDLR_NAME "/detectlowerbound",
16000  "should presolving try to detect constraints parallel to the objective function defining a lower bound and prevent these constraints from entering the LP?",
16001  &conshdlrdata->detectlowerbound, TRUE, DEFAULT_DETECTLOWERBOUND, NULL, NULL) );
16003  "constraints/" CONSHDLR_NAME "/detectpartialobjective",
16004  "should presolving try to detect subsets of constraints parallel to the objective function?",
16005  &conshdlrdata->detectpartialobjective, TRUE, DEFAULT_DETECTPARTIALOBJECTIVE, NULL, NULL) );
16007  "constraints/" CONSHDLR_NAME "/rangedrowpropagation",
16008  "should presolving and propagation try to improve bounds, detect infeasibility, and extract sub-constraints from ranged rows and equations?",
16009  &conshdlrdata->rangedrowpropagation, TRUE, DEFAULT_RANGEDROWPROPAGATION, NULL, NULL) );
16011  "constraints/" CONSHDLR_NAME "/rangedrowartcons",
16012  "should presolving and propagation extract sub-constraints from ranged rows and equations?",
16013  &conshdlrdata->rangedrowartcons, TRUE, DEFAULT_RANGEDROWARTCONS, NULL, NULL) );
16014  SCIP_CALL( SCIPaddIntParam(scip,
16015  "constraints/" CONSHDLR_NAME "/rangedrowmaxdepth",
16016  "maximum depth to apply ranged row propagation",
16017  &conshdlrdata->rangedrowmaxdepth, TRUE, DEFAULT_RANGEDROWMAXDEPTH, 0, INT_MAX, NULL, NULL) );
16018  SCIP_CALL( SCIPaddIntParam(scip,
16019  "constraints/" CONSHDLR_NAME "/rangedrowfreq",
16020  "frequency for applying ranged row propagation",
16021  &conshdlrdata->rangedrowfreq, TRUE, DEFAULT_RANGEDROWFREQ, 1, INT_MAX, NULL, NULL) );
16023  "constraints/" CONSHDLR_NAME "/multaggrremove",
16024  "should multi-aggregations only be performed if the constraint can be removed afterwards?",
16025  &conshdlrdata->multaggrremove, TRUE, DEFAULT_MULTAGGRREMOVE, NULL, NULL) );
16026 
16027  return SCIP_OKAY;
16028 }
16029 
16030 /** includes a linear constraint update method into the linear constraint handler */
16032  SCIP* scip, /**< SCIP data structure */
16033  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
16034  int priority, /**< priority of upgrading method */
16035  const char* conshdlrname /**< name of the constraint handler */
16036  )
16037 {
16038  SCIP_CONSHDLR* conshdlr;
16039  SCIP_CONSHDLRDATA* conshdlrdata;
16040  SCIP_LINCONSUPGRADE* linconsupgrade;
16041  char paramname[SCIP_MAXSTRLEN];
16042  char paramdesc[SCIP_MAXSTRLEN];
16043 
16044  assert(scip != NULL);
16045  assert(linconsupgd != NULL);
16046  assert(conshdlrname != NULL );
16048  /* find the linear constraint handler */
16049  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
16050  if( conshdlr == NULL )
16051  {
16052  SCIPerrorMessage("linear constraint handler not found\n");
16053  return SCIP_PLUGINNOTFOUND;
16054  }
16055 
16056  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16057  assert(conshdlrdata != NULL);
16058 
16059  /* check if linear constraint update method already exists in constraint handler data */
16060  if( !conshdlrdataHasUpgrade(scip, conshdlrdata, linconsupgd, conshdlrname) )
16061  {
16062  /* create a linear constraint upgrade data object */
16063  SCIP_CALL( linconsupgradeCreate(scip, &linconsupgrade, linconsupgd, priority) );
16064 
16065  /* insert linear constraint update method into constraint handler data */
16066  SCIP_CALL( conshdlrdataIncludeUpgrade(scip, conshdlrdata, linconsupgrade) );
16067 
16068  /* adds parameter to turn on and off the upgrading step */
16069  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/linear/upgrade/%s", conshdlrname);
16070  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "enable linear upgrading for constraint handler <%s>", conshdlrname);
16072  paramname, paramdesc,
16073  &linconsupgrade->active, FALSE, TRUE, NULL, NULL) );
16074  }
16075 
16076  return SCIP_OKAY;
16077 }
16078 
16079 /** creates and captures a linear constraint
16080  *
16081  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
16082  */
16084  SCIP* scip, /**< SCIP data structure */
16085  SCIP_CONS** cons, /**< pointer to hold the created constraint */
16086  const char* name, /**< name of constraint */
16087  int nvars, /**< number of nonzeros in the constraint */
16088  SCIP_VAR** vars, /**< array with variables of constraint entries */
16089  SCIP_Real* vals, /**< array with coefficients of constraint entries */
16090  SCIP_Real lhs, /**< left hand side of constraint */
16091  SCIP_Real rhs, /**< right hand side of constraint */
16092  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
16093  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
16094  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
16095  * Usually set to TRUE. */
16096  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
16097  * TRUE for model constraints, FALSE for additional, redundant constraints. */
16098  SCIP_Bool check, /**< should the constraint be checked for feasibility?
16099  * TRUE for model constraints, FALSE for additional, redundant constraints. */
16100  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
16101  * Usually set to TRUE. */
16102  SCIP_Bool local, /**< is constraint only valid locally?
16103  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
16104  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
16105  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
16106  * adds coefficients to this constraint. */
16107  SCIP_Bool dynamic, /**< Is constraint subject to aging?
16108  * Usually set to FALSE. Set to TRUE for own cuts which
16109  * are separated as constraints. */
16110  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
16111  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
16112  SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
16113  * if it may be moved to a more global node?
16114  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
16115  )
16116 {
16117  SCIP_CONSHDLRDATA* conshdlrdata;
16118  SCIP_CONSHDLR* conshdlr;
16119  SCIP_CONSDATA* consdata;
16120 
16121  assert(scip != NULL);
16122  assert(cons != NULL);
16123 
16124  /* find the linear constraint handler */
16125  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
16126  if( conshdlr == NULL )
16127  {
16128  SCIPerrorMessage("linear constraint handler not found\n");
16129  return SCIP_PLUGINNOTFOUND;
16130  }
16131 
16132  /* check for event handler */
16133  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16134  assert(conshdlrdata != NULL);
16135  assert(conshdlrdata->eventhdlr != NULL);
16136 
16137  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
16138  * constraint after presolving we have to ensure that it holds active variables
16139  */
16140  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE && nvars > 0 )
16141  {
16142  SCIP_VAR** consvars;
16143  SCIP_Real* consvals;
16144  SCIP_Real constant = 0.0;
16145  int nconsvars;
16146  int requiredsize;
16147 
16148  nconsvars = nvars;
16149  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
16150  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
16151 
16152  /* get active variables for new constraint */
16153  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
16154 
16155  /* if space was not enough we need to resize the buffers */
16156  if( requiredsize > nconsvars )
16157  {
16158  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
16159  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
16160 
16161  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
16162  assert(requiredsize <= nconsvars);
16163  }
16164 
16165  /* adjust sides and check that we do not subtract infinity values */
16166  if( SCIPisInfinity(scip, REALABS(constant)) )
16167  {
16168  if( constant < 0.0 )
16169  {
16170  if( SCIPisInfinity(scip, lhs) )
16171  {
16172  SCIPfreeBufferArray(scip, &consvals);
16173  SCIPfreeBufferArray(scip, &consvars);
16174 
16175  SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", name);
16176 
16177  SCIPABORT();
16178  return SCIP_INVALIDDATA; /*lint !e527*/
16179  }
16180  if( SCIPisInfinity(scip, rhs) )
16181  {
16182  SCIPfreeBufferArray(scip, &consvals);
16183  SCIPfreeBufferArray(scip, &consvars);
16184 
16185  SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", name);
16186 
16187  SCIPABORT();
16188  return SCIP_INVALIDDATA; /*lint !e527*/
16189  }
16190 
16191  lhs = -SCIPinfinity(scip);
16192  rhs = -SCIPinfinity(scip);
16193  }
16194  else
16195  {
16196  if( SCIPisInfinity(scip, -lhs) )
16197  {
16198  SCIPfreeBufferArray(scip, &consvals);
16199  SCIPfreeBufferArray(scip, &consvars);
16200 
16201  SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", name);
16202 
16203  SCIPABORT();
16204  return SCIP_INVALIDDATA; /*lint !e527*/
16205  }
16206  if( SCIPisInfinity(scip, -rhs) )
16207  {
16208  SCIPfreeBufferArray(scip, &consvals);
16209  SCIPfreeBufferArray(scip, &consvars);
16210 
16211  SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", name);
16212 
16213  SCIPABORT();
16214  return SCIP_INVALIDDATA; /*lint !e527*/
16215  }
16216 
16217  lhs = SCIPinfinity(scip);
16218  rhs = SCIPinfinity(scip);
16219  }
16220  }
16221  else
16222  {
16223  if( !SCIPisInfinity(scip, REALABS(lhs)) )
16224  lhs -= constant;
16225  if( !SCIPisInfinity(scip, REALABS(rhs)) )
16226  rhs -= constant;
16227 
16228  if( SCIPisInfinity(scip, -lhs) )
16229  lhs = -SCIPinfinity(scip);
16230  else if( SCIPisInfinity(scip, lhs) )
16231  lhs = SCIPinfinity(scip);
16232 
16233  if( SCIPisInfinity(scip, rhs) )
16234  rhs = SCIPinfinity(scip);
16235  else if( SCIPisInfinity(scip, -rhs) )
16236  rhs = -SCIPinfinity(scip);
16237  }
16238 
16239  /* create constraint data */
16240  SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
16241  assert(consdata != NULL);
16242 
16243  SCIPfreeBufferArray(scip, &consvals);
16244  SCIPfreeBufferArray(scip, &consvars);
16245  }
16246  else
16247  {
16248  /* create constraint data */
16249  SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
16250  assert(consdata != NULL);
16251  }
16252 
16253  /* create constraint */
16254  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
16255  local, modifiable, dynamic, removable, stickingatnode) );
16256 
16257  if( SCIPisTransformed(scip) && needEvents(scip) )
16258  {
16259  /* catch bound change events of variables */
16260  SCIP_CALL( consCatchAllEvents(scip, *cons, conshdlrdata->eventhdlr) );
16261  assert(consdata->eventdata != NULL);
16262  }
16263 
16264  return SCIP_OKAY;
16265 }
16266 
16267 /** creates and captures a linear constraint
16268  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
16269  * method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
16270  *
16271  * @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
16272  *
16273  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
16274  */
16276  SCIP* scip, /**< SCIP data structure */
16277  SCIP_CONS** cons, /**< pointer to hold the created constraint */
16278  const char* name, /**< name of constraint */
16279  int nvars, /**< number of nonzeros in the constraint */
16280  SCIP_VAR** vars, /**< array with variables of constraint entries */
16281  SCIP_Real* vals, /**< array with coefficients of constraint entries */
16282  SCIP_Real lhs, /**< left hand side of constraint */
16283  SCIP_Real rhs /**< right hand side of constraint */
16284  )
16285 {
16286  assert(scip != NULL);
16287 
16288  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
16289  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
16290 
16291  return SCIP_OKAY;
16292 }
16293 
16294 /** creates by copying and captures a linear constraint */
16296  SCIP* scip, /**< target SCIP data structure */
16297  SCIP_CONS** cons, /**< pointer to store the created target constraint */
16298  SCIP* sourcescip, /**< source SCIP data structure */
16299  const char* name, /**< name of constraint */
16300  int nvars, /**< number of variables in source variable array */
16301  SCIP_VAR** sourcevars, /**< source variables of the linear constraints */
16302  SCIP_Real* sourcecoefs, /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
16303  SCIP_Real lhs, /**< left hand side of the linear constraint */
16304  SCIP_Real rhs, /**< right hand side of the linear constraint */
16305  SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
16306  * variables of the target SCIP */
16307  SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
16308  * target constraints */
16309  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
16310  SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
16311  SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
16312  SCIP_Bool check, /**< should the constraint be checked for feasibility? */
16313  SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
16314  SCIP_Bool local, /**< is constraint only valid locally? */
16315  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
16316  SCIP_Bool dynamic, /**< is constraint subject to aging? */
16317  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
16318  SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
16319  * if it may be moved to a more global node? */
16320  SCIP_Bool global, /**< create a global or a local copy? */
16321  SCIP_Bool* valid /**< pointer to store if the copying was valid */
16322  )
16323 {
16324  SCIP_VAR** vars;
16325  SCIP_Real* coefs;
16326 
16327  SCIP_Real constant;
16328  int requiredsize;
16329  int v;
16330 
16331  if( SCIPisGT(scip, lhs, rhs) )
16332  {
16333  *valid = FALSE;
16334  return SCIP_OKAY;
16335  }
16336 
16337  (*valid) = TRUE;
16338 
16339  if( nvars == 0 )
16340  {
16341  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
16342  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
16343  return SCIP_OKAY;
16344  }
16345 
16346  /* duplicate variable array */
16347  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, sourcevars, nvars) );
16348 
16349  /* duplicate coefficient array */
16350  if( sourcecoefs != NULL )
16351  {
16352  SCIP_CALL( SCIPduplicateBufferArray(scip, &coefs, sourcecoefs, nvars) );
16353  }
16354  else
16355  {
16356  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
16357  for( v = 0; v < nvars; ++v )
16358  coefs[v] = 1.0;
16359  }
16360 
16361  constant = 0.0;
16362 
16363  /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
16364  * the target SCIP
16365  */
16366  if( !SCIPvarIsOriginal(vars[0]) )
16367  {
16368  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize, TRUE) );
16369 
16370  if( requiredsize > nvars )
16371  {
16372  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
16373  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
16374 
16375  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize, TRUE) );
16376  assert(requiredsize <= nvars);
16377  }
16378  }
16379  else
16380  {
16381  for( v = 0; v < nvars; ++v )
16382  {
16383  assert(SCIPvarIsOriginal(vars[v]));
16384  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
16385  assert(vars[v] != NULL);
16386  }
16387  }
16388 
16389  /* map variables of the source constraint to variables of the target SCIP */
16390  for( v = 0; v < nvars && *valid; ++v )
16391  {
16392  SCIP_VAR* var;
16393  var = vars[v];
16394 
16395  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, valid) );
16396  assert(!(*valid) || vars[v] != NULL);
16397  }
16398 
16399  /* only create the target constraint, if all variables could be copied */
16400  if( *valid )
16401  {
16402  if( !SCIPisInfinity(scip, -lhs) )
16403  lhs -= constant;
16404 
16405  if( !SCIPisInfinity(scip, rhs) )
16406  rhs -= constant;
16407 
16408  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
16409  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
16410  }
16411 
16412  /* free buffer array */
16413  SCIPfreeBufferArray(scip, &coefs);
16414  SCIPfreeBufferArray(scip, &vars);
16415 
16416  return SCIP_OKAY;
16417 }
16418 
16419 /** adds coefficient to linear constraint (if it is not zero) */
16421  SCIP* scip, /**< SCIP data structure */
16422  SCIP_CONS* cons, /**< constraint data */
16423  SCIP_VAR* var, /**< variable of constraint entry */
16424  SCIP_Real val /**< coefficient of constraint entry */
16425  )
16426 {
16427  assert(scip != NULL);
16428  assert(cons != NULL);
16429  assert(var != NULL);
16430 
16431  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16432  {
16433  SCIPerrorMessage("constraint is not linear\n");
16434  return SCIP_INVALIDDATA;
16435  }
16437  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
16438  * constraint after presolving we have to ensure that it holds active variables
16439  */
16440  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE )
16441  {
16442  SCIP_CONSDATA* consdata;
16443  SCIP_VAR** consvars;
16444  SCIP_Real* consvals;
16445  SCIP_Real constant = 0.0;
16446  SCIP_Real rhs;
16447  SCIP_Real lhs;
16448  int nconsvars;
16449  int requiredsize;
16450  int v;
16451 
16452  nconsvars = 1;
16453  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
16454  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
16455  consvars[0] = var;
16456  consvals[0] = val;
16457 
16458  /* get active variables for new constraint */
16459  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
16460 
16461  /* if space was not enough we need to resize the buffers */
16462  if( requiredsize > nconsvars )
16463  {
16464  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
16465  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
16466 
16467  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
16468  assert(requiredsize <= nconsvars);
16469  }
16470 
16471  consdata = SCIPconsGetData(cons);
16472  assert(consdata != NULL);
16473 
16474  lhs = consdata->lhs;
16475  rhs = consdata->rhs;
16476 
16477  /* adjust sides and check that we do not subtract infinity values */
16478  /* constant is infinite */
16479  if( SCIPisInfinity(scip, REALABS(constant)) )
16480  {
16481  if( constant < 0.0 )
16482  {
16483  if( SCIPisInfinity(scip, lhs) )
16484  {
16485  SCIPfreeBufferArray(scip, &consvals);
16486  SCIPfreeBufferArray(scip, &consvars);
16487 
16488  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));
16489 
16490  SCIPABORT();
16491  return SCIP_INVALIDDATA; /*lint !e527*/
16492  }
16493  if( SCIPisInfinity(scip, rhs) )
16494  {
16495  SCIPfreeBufferArray(scip, &consvals);
16496  SCIPfreeBufferArray(scip, &consvars);
16497 
16498  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));
16499 
16500  SCIPABORT();
16501  return SCIP_INVALIDDATA; /*lint !e527*/
16502  }
16503 
16504  lhs = -SCIPinfinity(scip);
16505  rhs = -SCIPinfinity(scip);
16506  }
16507  else
16508  {
16509  if( SCIPisInfinity(scip, -lhs) )
16510  {
16511  SCIPfreeBufferArray(scip, &consvals);
16512  SCIPfreeBufferArray(scip, &consvars);
16513 
16514  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));
16515 
16516  SCIPABORT();
16517  return SCIP_INVALIDDATA; /*lint !e527*/
16518  }
16519  if( SCIPisInfinity(scip, -rhs) )
16520  {
16521  SCIPfreeBufferArray(scip, &consvals);
16522  SCIPfreeBufferArray(scip, &consvars);
16523 
16524  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));
16525 
16526  SCIPABORT();
16527  return SCIP_INVALIDDATA; /*lint !e527*/
16528  }
16529 
16530  lhs = SCIPinfinity(scip);
16531  rhs = SCIPinfinity(scip);
16532  }
16533  }
16534  /* constant is not infinite */
16535  else
16536  {
16537  if( !SCIPisInfinity(scip, REALABS(lhs)) )
16538  lhs -= constant;
16539  if( !SCIPisInfinity(scip, REALABS(rhs)) )
16540  rhs -= constant;
16541 
16542  if( SCIPisInfinity(scip, -lhs) )
16543  lhs = -SCIPinfinity(scip);
16544  else if( SCIPisInfinity(scip, lhs) )
16545  lhs = SCIPinfinity(scip);
16546 
16547  if( SCIPisInfinity(scip, rhs) )
16548  rhs = SCIPinfinity(scip);
16549  else if( SCIPisInfinity(scip, -rhs) )
16550  rhs = -SCIPinfinity(scip);
16551  }
16552 
16553  /* add all active variables to constraint */
16554  for( v = nconsvars - 1; v >= 0; --v )
16555  {
16556  SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
16557  }
16558 
16559  /* update left and right hand sides */
16560  SCIP_CALL( chgLhs(scip, cons, lhs));
16561  SCIP_CALL( chgRhs(scip, cons, rhs));
16562 
16563  SCIPfreeBufferArray(scip, &consvals);
16564  SCIPfreeBufferArray(scip, &consvars);
16565  }
16566  else
16567  {
16568  SCIP_CALL( addCoef(scip, cons, var, val) );
16569  }
16570 
16571  return SCIP_OKAY;
16572 }
16573 
16574 /** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
16575  * not yet contained in the constraint
16576  *
16577  * @note This method may only be called during problem creation stage for an original constraint and variable.
16578  *
16579  * @note This method requires linear time to search for occurences of the variable in the constraint data.
16580  */
16582  SCIP* scip, /**< SCIP data structure */
16583  SCIP_CONS* cons, /**< constraint data */
16584  SCIP_VAR* var, /**< variable of constraint entry */
16585  SCIP_Real val /**< new coefficient of constraint entry */
16586  )
16587 {
16588  SCIP_CONSDATA* consdata;
16589  SCIP_VAR** vars;
16590  SCIP_Bool found;
16591  int i;
16592 
16593  assert(scip != NULL);
16594  assert(cons != NULL);
16595  assert(var != NULL);
16596 
16598  {
16599  SCIPerrorMessage("constraint is not linear\n");
16600  return SCIP_INVALIDDATA;
16601  }
16602 
16603  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM || !SCIPconsIsOriginal(cons) || !SCIPvarIsOriginal(var) )
16604  {
16605  SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
16606  return SCIP_INVALIDDATA;
16607  }
16608 
16609  consdata = SCIPconsGetData(cons);
16610  assert(consdata != NULL);
16611 
16612  vars = consdata->vars;
16613  found = FALSE;
16614  i = 0;
16615  while( i < consdata->nvars )
16616  {
16617  if( vars[i] == var )
16618  {
16619  if( found || SCIPisZero(scip, val) )
16620  {
16621  SCIP_CALL( delCoefPos(scip, cons, i) );
16622 
16623  /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
16624  i--;
16625  }
16626  else
16627  {
16628  SCIP_CALL( chgCoefPos(scip, cons, i, val) );
16629  }
16630  found = TRUE;
16631  }
16632  i++;
16633  }
16634 
16635  if( !found && !SCIPisZero(scip, val) )
16636  {
16637  SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
16638  }
16639 
16640  return SCIP_OKAY;
16641 }
16642 
16643 /** deletes variable from linear constraint
16644  *
16645  * @note This method may only be called during problem creation stage for an original constraint and variable.
16646  *
16647  * @note This method requires linear time to search for occurences of the variable in the constraint data.
16648  */
16650  SCIP* scip, /**< SCIP data structure */
16651  SCIP_CONS* cons, /**< constraint data */
16652  SCIP_VAR* var /**< variable of constraint entry */
16653  )
16654 {
16655  assert(scip != NULL);
16656  assert(cons != NULL);
16657  assert(var != NULL);
16658 
16659  SCIP_CALL( SCIPchgCoefLinear(scip, cons, var, 0.0) );
16660 
16661  return SCIP_OKAY;
16662 }
16663 
16664 /** gets left hand side of linear constraint */
16666  SCIP* scip, /**< SCIP data structure */
16667  SCIP_CONS* cons /**< constraint data */
16668  )
16669 {
16670  SCIP_CONSDATA* consdata;
16671 
16672  assert(scip != NULL);
16673  assert(cons != NULL);
16674 
16675  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16676  {
16677  SCIPerrorMessage("constraint is not linear\n");
16678  SCIPABORT();
16679  return SCIP_INVALID; /*lint !e527*/
16680  }
16682  consdata = SCIPconsGetData(cons);
16683  assert(consdata != NULL);
16684 
16685  return consdata->lhs;
16686 }
16687 
16688 /** gets right hand side of linear constraint */
16690  SCIP* scip, /**< SCIP data structure */
16691  SCIP_CONS* cons /**< constraint data */
16692  )
16693 {
16694  SCIP_CONSDATA* consdata;
16695 
16696  assert(scip != NULL);
16697  assert(cons != NULL);
16698 
16699  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16700  {
16701  SCIPerrorMessage("constraint is not linear\n");
16702  SCIPABORT();
16703  return SCIP_INVALID; /*lint !e527*/
16704  }
16706  consdata = SCIPconsGetData(cons);
16707  assert(consdata != NULL);
16708 
16709  return consdata->rhs;
16710 }
16711 
16712 /** changes left hand side of linear constraint */
16714  SCIP* scip, /**< SCIP data structure */
16715  SCIP_CONS* cons, /**< constraint data */
16716  SCIP_Real lhs /**< new left hand side */
16717  )
16718 {
16719  assert(scip != NULL);
16720  assert(cons != NULL);
16721 
16722  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16723  {
16724  SCIPerrorMessage("constraint is not linear\n");
16725  return SCIP_INVALIDDATA;
16726  }
16727 
16728  SCIP_CALL( chgLhs(scip, cons, lhs) );
16730  return SCIP_OKAY;
16731 }
16732 
16733 /** changes right hand side of linear constraint */
16735  SCIP* scip, /**< SCIP data structure */
16736  SCIP_CONS* cons, /**< constraint data */
16737  SCIP_Real rhs /**< new right hand side */
16738  )
16739 {
16740  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16741  {
16742  SCIPerrorMessage("constraint is not linear\n");
16743  return SCIP_INVALIDDATA;
16744  }
16745 
16746  SCIP_CALL( chgRhs(scip, cons, rhs) );
16747 
16748  return SCIP_OKAY;
16749 }
16751 /** gets the number of variables in the linear constraint */
16752 int SCIPgetNVarsLinear(
16753  SCIP* scip, /**< SCIP data structure */
16754  SCIP_CONS* cons /**< constraint data */
16755  )
16756 {
16757  SCIP_CONSDATA* consdata;
16758 
16759  assert(scip != NULL);
16760  assert(cons != NULL);
16761 
16762  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16763  {
16764  SCIPerrorMessage("constraint is not linear\n");
16765  SCIPABORT();
16766  return -1; /*lint !e527*/
16767  }
16769  consdata = SCIPconsGetData(cons);
16770  assert(consdata != NULL);
16771 
16772  return consdata->nvars;
16773 }
16774 
16775 /** gets the array of variables in the linear constraint; the user must not modify this array! */
16777  SCIP* scip, /**< SCIP data structure */
16778  SCIP_CONS* cons /**< constraint data */
16779  )
16780 {
16781  SCIP_CONSDATA* consdata;
16782 
16783  assert(scip != NULL);
16784  assert(cons != NULL);
16785 
16786  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16787  {
16788  SCIPerrorMessage("constraint is not linear\n");
16789  SCIPABORT();
16790  return NULL; /*lint !e527*/
16791  }
16793  consdata = SCIPconsGetData(cons);
16794  assert(consdata != NULL);
16795 
16796  return consdata->vars;
16797 }
16798 
16799 /** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
16801  SCIP* scip, /**< SCIP data structure */
16802  SCIP_CONS* cons /**< constraint data */
16803  )
16804 {
16805  SCIP_CONSDATA* consdata;
16806 
16807  assert(scip != NULL);
16808  assert(cons != NULL);
16809 
16810  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16811  {
16812  SCIPerrorMessage("constraint is not linear\n");
16813  SCIPABORT();
16814  return NULL; /*lint !e527*/
16815  }
16817  consdata = SCIPconsGetData(cons);
16818  assert(consdata != NULL);
16819 
16820  return consdata->vals;
16821 }
16822 
16823 /** gets the activity of the linear constraint in the given solution
16824  *
16825  * @note if the solution contains values at infinity, this method will return SCIP_INVALID in case the activity
16826  * comprises positive and negative infinity contributions
16827  */
16829  SCIP* scip, /**< SCIP data structure */
16830  SCIP_CONS* cons, /**< constraint data */
16831  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
16832  )
16833 {
16834  SCIP_CONSDATA* consdata;
16835 
16836  assert(scip != NULL);
16837  assert(cons != NULL);
16838 
16839  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16840  {
16841  SCIPerrorMessage("constraint is not linear\n");
16842  SCIPABORT();
16843  return SCIP_INVALID; /*lint !e527*/
16844  }
16845 
16846  consdata = SCIPconsGetData(cons);
16847  assert(consdata != NULL);
16848 
16849  if( consdata->row != NULL )
16850  return SCIPgetRowSolActivity(scip, consdata->row, sol);
16851  else
16852  return consdataGetActivity(scip, consdata, sol);
16853 }
16854 
16855 /** gets the feasibility of the linear constraint in the given solution */
16857  SCIP* scip, /**< SCIP data structure */
16858  SCIP_CONS* cons, /**< constraint data */
16859  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
16860  )
16861 {
16862  SCIP_CONSDATA* consdata;
16863 
16864  assert(scip != NULL);
16865  assert(cons != NULL);
16866 
16867  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16868  {
16869  SCIPerrorMessage("constraint is not linear\n");
16870  SCIPABORT();
16871  return SCIP_INVALID; /*lint !e527*/
16872  }
16873 
16874  consdata = SCIPconsGetData(cons);
16875  assert(consdata != NULL);
16876 
16877  if( consdata->row != NULL )
16878  return SCIPgetRowSolFeasibility(scip, consdata->row, sol);
16879  else
16880  return consdataGetFeasibility(scip, consdata, sol);
16881 }
16882 
16883 /** gets the dual solution of the linear constraint in the current LP */
16885  SCIP* scip, /**< SCIP data structure */
16886  SCIP_CONS* cons /**< constraint data */
16887  )
16888 {
16889  SCIP_CONSDATA* consdata;
16890 
16891  assert(scip != NULL);
16892  assert(cons != NULL);
16893 
16894  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16895  {
16896  SCIPerrorMessage("constraint is not linear\n");
16897  SCIPABORT();
16898  return SCIP_INVALID; /*lint !e527*/
16899  }
16901  consdata = SCIPconsGetData(cons);
16902  assert(consdata != NULL);
16903 
16904  if( consdata->row != NULL )
16905  return SCIProwGetDualsol(consdata->row);
16906  else
16907  return 0.0;
16908 }
16909 
16910 /** gets the dual Farkas value of the linear constraint in the current infeasible LP */
16912  SCIP* scip, /**< SCIP data structure */
16913  SCIP_CONS* cons /**< constraint data */
16914  )
16915 {
16916  SCIP_CONSDATA* consdata;
16917 
16918  assert(scip != NULL);
16919  assert(cons != NULL);
16920 
16921  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16922  {
16923  SCIPerrorMessage("constraint is not linear\n");
16924  SCIPABORT();
16925  return SCIP_INVALID; /*lint !e527*/
16926  }
16928  consdata = SCIPconsGetData(cons);
16929  assert(consdata != NULL);
16930 
16931  if( consdata->row != NULL )
16932  return SCIProwGetDualfarkas(consdata->row);
16933  else
16934  return 0.0;
16935 }
16936 
16937 /** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
16938  * the user must not modify the row!
16939  */
16941  SCIP* scip, /**< SCIP data structure */
16942  SCIP_CONS* cons /**< constraint data */
16943  )
16944 {
16945  SCIP_CONSDATA* consdata;
16946 
16947  assert(scip != NULL);
16948  assert(cons != NULL);
16949 
16950  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16951  {
16952  SCIPerrorMessage("constraint is not linear\n");
16953  SCIPABORT();
16954  return NULL; /*lint !e527*/
16955  }
16957  consdata = SCIPconsGetData(cons);
16958  assert(consdata != NULL);
16959 
16960  return consdata->row;
16961 }
16962 
16963 /** tries to automatically convert a linear constraint into a more specific and more specialized constraint */
16965  SCIP* scip, /**< SCIP data structure */
16966  SCIP_CONS* cons, /**< source constraint to try to convert */
16967  SCIP_CONS** upgdcons /**< pointer to store upgraded constraint, or NULL if not successful */
16968  )
16969 {
16970  SCIP_CONSHDLR* conshdlr;
16971  SCIP_CONSHDLRDATA* conshdlrdata;
16972  SCIP_CONSDATA* consdata;
16973  SCIP_VAR* var;
16974  SCIP_Real val;
16975  SCIP_Real lb;
16976  SCIP_Real ub;
16977  SCIP_Real poscoeffsum;
16978  SCIP_Real negcoeffsum;
16979  SCIP_Bool integral;
16980  int nposbin;
16981  int nnegbin;
16982  int nposint;
16983  int nnegint;
16984  int nposimpl;
16985  int nnegimpl;
16986  int nposimplbin;
16987  int nnegimplbin;
16988  int nposcont;
16989  int nnegcont;
16990  int ncoeffspone;
16991  int ncoeffsnone;
16992  int ncoeffspint;
16993  int ncoeffsnint;
16994  int ncoeffspfrac;
16995  int ncoeffsnfrac;
16996  int i;
16997 
16998  assert(scip != NULL);
16999  assert(cons != NULL);
17000  assert(upgdcons != NULL);
17001 
17002  *upgdcons = NULL;
17003 
17004  /* we cannot upgrade a modifiable linear constraint, since we don't know what additional coefficients to expect */
17005  if( SCIPconsIsModifiable(cons) )
17006  return SCIP_OKAY;
17007 
17008  /* check for upgradability */
17009  if( SCIPconsGetNUpgradeLocks(cons) > 0 )
17010  return SCIP_OKAY;
17011 
17012  /* get the constraint handler and check, if it's really a linear constraint */
17013  conshdlr = SCIPconsGetHdlr(cons);
17014  if( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) != 0 )
17015  {
17016  SCIPerrorMessage("constraint is not linear\n");
17017  return SCIP_INVALIDDATA;
17018  }
17019 
17020  /* get constraint handler data and constraint data */
17021  conshdlrdata = SCIPconshdlrGetData(conshdlr);
17022  assert(conshdlrdata != NULL);
17023  consdata = SCIPconsGetData(cons);
17024  assert(consdata != NULL);
17025 
17026  /* check, if the constraint was already upgraded and will be deleted anyway after preprocessing */
17027  if( consdata->upgraded )
17028  return SCIP_OKAY;
17029 
17030  /* check, if the constraint is already stored as LP row */
17031  if( consdata->row != NULL )
17032  {
17033  if( SCIProwIsInLP(consdata->row) )
17034  {
17035  SCIPerrorMessage("cannot upgrade linear constraint that is already stored as row in the LP\n");
17036  return SCIP_INVALIDDATA;
17037  }
17038  else
17039  {
17040  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
17041  }
17042  }
17043 
17044  /* normalize constraint */
17045  SCIP_CALL( normalizeCons(scip, cons) );
17046 
17047 
17048  /*
17049  * calculate some statistics on linear constraint
17050  */
17051 
17052  nposbin = 0;
17053  nnegbin = 0;
17054  nposint = 0;
17055  nnegint = 0;
17056  nposimpl = 0;
17057  nnegimpl = 0;
17058  nposimplbin = 0;
17059  nnegimplbin = 0;
17060  nposcont = 0;
17061  nnegcont = 0;
17062  ncoeffspone = 0;
17063  ncoeffsnone = 0;
17064  ncoeffspint = 0;
17065  ncoeffsnint = 0;
17066  ncoeffspfrac = 0;
17067  ncoeffsnfrac = 0;
17068  integral = TRUE;
17069  poscoeffsum = 0.0;
17070  negcoeffsum = 0.0;
17071 
17072  for( i = 0; i < consdata->nvars; ++i )
17073  {
17074  var = consdata->vars[i];
17075  val = consdata->vals[i];
17076  lb = SCIPvarGetLbLocal(var);
17077  ub = SCIPvarGetUbLocal(var);
17078  assert(!SCIPisZero(scip, val));
17079 
17080  switch( SCIPvarGetType(var) )
17081  {
17082  case SCIP_VARTYPE_BINARY:
17083  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
17084  integral = integral && SCIPisIntegral(scip, val);
17085  if( val >= 0.0 )
17086  nposbin++;
17087  else
17088  nnegbin++;
17089  break;
17090  case SCIP_VARTYPE_INTEGER:
17091  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
17092  integral = integral && SCIPisIntegral(scip, val);
17093  if( val >= 0.0 )
17094  nposint++;
17095  else
17096  nnegint++;
17097  break;
17098  case SCIP_VARTYPE_IMPLINT:
17099  if( SCIPvarIsBinary(var) )
17100  {
17101  if( val >= 0.0 )
17102  nposimplbin++;
17103  else
17104  nnegimplbin++;
17105  }
17106  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
17107  integral = integral && SCIPisIntegral(scip, val);
17108  if( val >= 0.0 )
17109  nposimpl++;
17110  else
17111  nnegimpl++;
17112  break;
17114  integral = integral && SCIPisEQ(scip, lb, ub) && SCIPisIntegral(scip, val * lb);
17115  if( val >= 0.0 )
17116  nposcont++;
17117  else
17118  nnegcont++;
17119  break;
17120  default:
17121  SCIPerrorMessage("unknown variable type\n");
17122  return SCIP_INVALIDDATA;
17123  }
17124  if( SCIPisEQ(scip, val, 1.0) )
17125  ncoeffspone++;
17126  else if( SCIPisEQ(scip, val, -1.0) )
17127  ncoeffsnone++;
17128  else if( SCIPisIntegral(scip, val) )
17129  {
17130  if( SCIPisPositive(scip, val) )
17131  ncoeffspint++;
17132  else
17133  ncoeffsnint++;
17134  }
17135  else
17136  {
17137  if( SCIPisPositive(scip, val) )
17138  ncoeffspfrac++;
17139  else
17140  ncoeffsnfrac++;
17141  }
17142  if( SCIPisPositive(scip, val) )
17143  poscoeffsum += val;
17144  else
17145  negcoeffsum += val;
17146  }
17147 
17148 
17149  /*
17150  * call the upgrading methods
17151  */
17152 
17153  SCIPdebugMessage("upgrading linear constraint <%s> (%d upgrade methods):\n",
17154  SCIPconsGetName(cons), conshdlrdata->nlinconsupgrades);
17155  SCIPdebugMessage(" +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",
17156  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposcont, nnegcont,
17157  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
17158  poscoeffsum, negcoeffsum, integral);
17159 
17160  /* try all upgrading methods in priority order in case the upgrading step is enable */
17161  for( i = 0; i < conshdlrdata->nlinconsupgrades && *upgdcons == NULL; ++i )
17162  {
17163  if( conshdlrdata->linconsupgrades[i]->active )
17164  {
17165  SCIP_CALL( conshdlrdata->linconsupgrades[i]->linconsupgd(scip, cons, consdata->nvars,
17166  consdata->vars, consdata->vals, consdata->lhs, consdata->rhs,
17167  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposimplbin, nnegimplbin, nposcont, nnegcont,
17168  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
17169  poscoeffsum, negcoeffsum, integral,
17170  upgdcons) );
17171  }
17172  }
17173 
17174 #ifdef SCIP_DEBUG
17175  if( *upgdcons != NULL )
17176  {
17177  SCIPdebugPrintCons(scip, cons, NULL);
17178  SCIPdebugMessage(" -> upgraded to constraint type <%s>\n", SCIPconshdlrGetName(SCIPconsGetHdlr(*upgdcons)));
17179  SCIPdebugPrintCons(scip, *upgdcons, NULL);
17180  }
17181 #endif
17182 
17183  return SCIP_OKAY;
17184 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
#define EVENTHDLR_DESC
Definition: cons_linear.c:80
int SCIPgetNLPBranchCands(SCIP *scip)
Definition: scip.c:33158
#define CONSHDLR_DELAYSEPA
Definition: cons_linear.c:72
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip.c:22777
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41572
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)
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
Definition: var.c:16861
struct InferInfo INFERINFO
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:16883
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:41685
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip.c:28308
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:10698
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:5878
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20526
SCIP_Bool SCIPconsIsLocked(SCIP_CONS *cons)
Definition: cons.c:7939
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip.c:5588
static SCIP_RETCODE tightenVarBounds(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:6397
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:25588
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:846
static int inferInfoGetPos(INFERINFO inferinfo)
Definition: cons_linear.c:390
static SCIP_RETCODE consCatchEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linear.c:702
static SCIP_RETCODE chgCoefPos(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Real newval)
Definition: cons_linear.c:3701
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16443
static SCIP_RETCODE simplifyInequalities(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip.c:28285
static SCIP_Real consdataGetFeasibility(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:2891
#define DEFAULT_MAXAGGRNORMSCALE
Definition: cons_linear.c:103
#define DEFAULT_PRESOLPAIRWISE
Definition: cons_linear.c:91
#define SCIP_EVENTTYPE_VARFIXED
Definition: type_event.h:48
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.c:22886
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: scip.c:17373
#define CONSHDLR_NAME
Definition: cons_linear.c:61
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:20589
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:41648
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12033
#define CONSHDLR_MAXPREROUNDS
Definition: cons_linear.c:71
static void calculateMinvalAndMaxval(SCIP *scip, SCIP_Real side, SCIP_Real val, SCIP_Real minresactivity, SCIP_Real maxresactivity, SCIP_Real *minval, SCIP_Real *maxval)
#define BINWEIGHT
static void consdataUpdateSignatures(SCIP_CONSDATA *consdata, int pos)
Definition: cons_linear.c:2926
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1567
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip.h:20573
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:1440
#define DEFAULT_RANGEDROWFREQ
Definition: cons_linear.c:134
static void consdataRecomputeMaxActivityDelta(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1378
#define MAXSCALEDCOEF
Definition: cons_linear.c:141
static SCIP_Bool checkEqualObjective(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real *scale, SCIP_Real *offset)
Definition: cons_linear.c:9643
#define DEFAULT_CHECKRELMAXABS
Definition: cons_linear.c:100
static SCIP_RETCODE fixVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars)
Definition: cons_linear.c:7322
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:10378
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:11540
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16623
#define DEFAULT_MAXROUNDS
Definition: cons_linear.c:87
#define DEFAULT_SORTVARS
Definition: cons_linear.c:97
static SCIP_RETCODE convertUnaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *ndelconss)
Definition: cons_linear.c:8934
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1248
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, 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.c:15737
SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
Definition: cons.c:7899
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:5050
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41920
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:10653
#define SCIP_MAXSTRLEN
Definition: def.h:201
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip.c:5634
#define SCIP_DECL_CONSINITPRE(x)
Definition: type_cons.h:114
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.c:5246
static SCIP_RETCODE consDropAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:804
#define NULL
Definition: lpi_spx.cpp:130
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17113
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1125
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:42032
static void consdataUpdateActivitiesGlbUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldub, SCIP_Real newub, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:1871
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:940
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:7849
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:7681
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip.c:5334
SCIP_Real SCIPcutoffbounddelta(SCIP *scip)
Definition: scip.c:41202
SCIP_RETCODE SCIPupdateCutoffbound(SCIP *scip, SCIP_Real cutoffbound)
Definition: scip.c:38589
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17067
static SCIP_Real consdataGetMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2052
static SCIP_RETCODE linconsupgradeCreate(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority)
Definition: cons_linear.c:493
void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
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)
#define DEFAULT_MAXSEPACUTS
Definition: cons_linear.c:89
SCIP_RETCODE SCIPupdateLocalLowerbound(SCIP *scip, SCIP_Real newbound)
Definition: scip.c:12302
SCIP_Real SCIPgetHugeValue(SCIP *scip)
Definition: scip.c:41674
static void consdataRecomputeMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1172
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
Definition: scip.c:24320
#define DEFAULT_DETECTPARTIALOBJECTIVE
Definition: cons_linear.c:128
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip.c:17429
SCIP_Real SCIPgetDualfarkasLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip.c:5818
static void consdataGetGlbActivityBounds(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Bool goodrelax, SCIP_Real *glbminactivity, SCIP_Real *glbmaxactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
Definition: cons_linear.c:2608
static void permSortConsdata(SCIP_CONSDATA *consdata, int *perm, int nvars)
Definition: cons_linear.c:2984
#define DEFAULT_AGGREGATEVARIABLES
Definition: cons_linear.c:115
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:7909
#define FALSE
Definition: def.h:56
static SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
static SCIP_DECL_CONSEXITSOL(consExitsolLinear)
static void consdataInvalidateActivities(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1075
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:17169
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10743
static SCIP_DECL_CONSCOPY(consCopyLinear)
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip.c:7778
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:8174
SCIP_RETCODE SCIPincludeConshdlrLinear(SCIP *scip)
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 *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
Definition: cons_linear.c:2670
static SCIP_Bool conshdlrdataHasUpgrade(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_DECL_LINCONSUPGD((*linconsupgd)), const char *conshdlrname)
Definition: cons_linear.c:574
#define TRUE
Definition: def.h:55
#define DEFAULT_MAXCARDBOUNDDIST
Definition: cons_linear.c:109
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7640
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17648
enum Proprule PROPRULE
#define DEFAULT_NMINCOMPARISONS
Definition: cons_linear.c:93
#define SCIPstatisticMessage
Definition: pub_message.h:104
static SCIP_DECL_CONSINITLP(consInitlpLinear)
#define SCIP_PRESOLTIMING_EXHAUSTIVE
Definition: type_timing.h:45
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip.c:5795
#define SCIP_CALL(x)
Definition: def.h:266
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:7100
static SCIP_Bool consdataIsResidualIntegral(SCIP *scip, SCIP_CONSDATA *consdata, int pos, SCIP_Real val)
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:48
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)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:41972
SCIP_RETCODE SCIPconvertCutsToConss(SCIP *scip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition: scip.c:2823
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:53
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip.c:19590
static SCIP_DECL_CONSENFOPS(consEnfopsLinear)
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip.c:23083
SCIP_VAR ** SCIPgetLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
int SCIPconsGetNUpgradeLocks(SCIP_CONS *cons)
Definition: cons.c:7991
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.c:16332
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:42008
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:38561
SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:25786
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:27888
SCIP_Bool SCIPisSumGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41845
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip.h:20556
static SCIP_RETCODE tightenSides(SCIP *scip, SCIP_CONS *cons, int *nchgsides)
Definition: cons_linear.c:8423
SCIP_Real SCIPvarGetLbAtIndex(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:15737
#define SCIPdebugMessage
Definition: pub_message.h:77
#define DEFAULT_MINGAINPERNMINCOMP
Definition: cons_linear.c:94
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:34983
SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
Definition: misc.c:7620
SCIP_Bool SCIPisSumRelLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:42374
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:85
static SCIP_DECL_CONSEXITPRE(consExitpreLinear)
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16905
int SCIPgetNLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetRhsNonlinear(SCIP *scip, SCIP_CONS *cons)
void SCIPsortDownRealInt(SCIP_Real *realarray, int *intarray, int len)
enum Proprule PROPRULE
Definition: cons_linear.c:340
static SCIP_DECL_CONSRESPROP(consRespropLinear)
static SCIP_RETCODE detectRedundantConstraints(SCIP *scip, BMS_BLKMEM *blkmem, SCIP_CONS **conss, int nconss, int *firstchange, SCIP_Bool *cutoff, int *ndelconss, int *nchgsides)
int SCIPgetNContVars(SCIP *scip)
Definition: scip.c:10878
SCIP_RETCODE SCIPchgRowRhs(SCIP *scip, SCIP_ROW *row, SCIP_Real rhs)
Definition: scip.c:27783
SCIP_RETCODE SCIPsetConsPropagated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool propagate)
Definition: scip.c:25147
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:7839
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:7779
static INFERINFO getInferInfo(PROPRULE proprule, int pos)
Definition: cons_linear.c:399
static SCIP_RETCODE rangedRowPropagation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds, int *naddconss)
Definition: cons_linear.c:5437
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:26237
SCIP_RETCODE SCIPaddCut(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip.c:30967
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:24949
static SCIP_RETCODE consDropEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linear.c:738
#define checkMaxActivityDelta(scip, consdata)
Definition: cons_linear.c:1373
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:99
static SCIP_DECL_SORTINDCOMP(consdataCompVar)
Definition: cons_linear.c:2971
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:20554
int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
Definition: var.c:11206
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
Definition: scip.c:42044
#define DEFAULT_SEPARATEALL
Definition: cons_linear.c:112
#define DEFAULT_MAXSEPACUTSROOT
Definition: cons_linear.c:90
static SCIP_RETCODE addConflictFixedVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_BDCHGIDX *bdchgidx, int inferpos)
Definition: cons_linear.c:4720
SCIP_Real SCIPgetLhsNonlinear(SCIP *scip, SCIP_CONS *cons)
#define CONSHDLR_PRESOLTIMING
Definition: cons_linear.c:76
SCIP_Bool SCIPisLbBetter(SCIP *scip, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
Definition: scip.c:42255
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip.c:5359
SCIP_Real SCIPgetLowerbound(SCIP *scip)
Definition: scip.c:38393
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:7769
#define CONSHDLR_PROP_TIMING
Definition: cons_linear.c:77
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.c:20572
SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
Definition: var.c:16814
#define MAXMULTIAGGRQUOTIENT
Definition: cons_linear.c:9094
static SCIP_RETCODE rangedRowSimplify(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
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:1480
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
Definition: scip.c:24720
#define SCIP_EVENTTYPE_LBCHANGED
Definition: type_event.h:95
static SCIP_DECL_CONSFREE(consFreeLinear)
#define CONSHDLR_SEPAFREQ
Definition: cons_linear.c:66
SCIP_RETCODE SCIPsetConshdlrInit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINIT((*consinit)))
Definition: scip.c:5383
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.c:3547
#define MAXCONSPRESOLROUNDS
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16562
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.c:3573
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:23070
#define SCIP_EVENTTYPE_LBRELAXED
Definition: type_event.h:56
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16634
static SCIP_DECL_EVENTEXEC(eventExecLinear)
SCIP_Bool SCIPisUpdateUnreliable(SCIP *scip, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: scip.c:42455
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:7215
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:3917
static void linconsupgradeFree(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade)
Definition: cons_linear.c:514
static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons, SCIP_Bool reasonisrhs)
Definition: cons_linear.c:4928
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:6810
SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition: var.c:16792
SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17658
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip.c:36622
static SCIP_RETCODE checkParallelObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons_linear.c:9833
#define CONFLICTHDLR_NAME
Definition: cons_linear.c:82
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
Definition: event.c:1096
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)
Constraint handler for knapsack constraints of the form , x binary and .
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20542
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip)
Definition: scip.c:24342
SCIP_RETCODE SCIPincludeNonlinconsUpgrade(SCIP *scip, SCIP_DECL_NONLINCONSUPGD((*nonlinconsupgd)), SCIP_DECL_EXPRGRAPHNODEREFORM((*nodereform)), int priority, SCIP_Bool active, const char *conshdlrname)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41585
SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
Definition: var.c:16572
#define DEFAULT_DETECTCUTOFFBOUND
Definition: cons_linear.c:118
static SCIP_RETCODE updateCutoffbound(SCIP *scip, SCIP_CONS *cons, SCIP_Real primalbound)
Definition: cons_linear.c:9787
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:16585
SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:25560
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.c:1781
static SCIP_DECL_CONSDELETE(consDeleteLinear)
#define CONFLICTHDLR_PRIORITY
Definition: cons_linear.c:84
static SCIP_RETCODE addRelaxation(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *cutoff)
Definition: cons_linear.c:7051
SCIP_Real * SCIPgetLinearCoefsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:41984
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:4981
SCIP_ROW * SCIPgetRowLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:41709
static void getMaxActivity(SCIP *scip, SCIP_CONSDATA *consdata, int posinf, int neginf, int poshuge, int neghuge, SCIP_Real delta, SCIP_Bool global, SCIP_Bool goodrelax, SCIP_Real *maxactivity, SCIP_Bool *isrelax, SCIP_Bool *issettoinfinity)
Definition: cons_linear.c:2231
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip.c:17075
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:7879
int SCIPgetNLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNSepaRounds(SCIP *scip)
Definition: scip.c:37979
#define SCIPerrorMessage
Definition: pub_message.h:45
#define CONSHDLR_PROPFREQ
Definition: cons_linear.c:67
#define SCIPdebugPrintf
Definition: pub_message.h:80
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip.h:20574
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip.c:19526
SCIP_RETCODE SCIPupdateConsFlags(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1)
Definition: scip.c:25300
static SCIP_DECL_QUADCONSUPGD(upgradeConsQuadratic)
static SCIP_DECL_CONSENFOLP(consEnfolpLinear)
static void consdataGetActivityBounds(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Bool goodrelax, SCIP_Real *minactivity, SCIP_Real *maxactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax)
Definition: cons_linear.c:2330
SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
Definition: var.c:16803
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:41996
static SCIP_DECL_CONSSEPALP(consSepalpLinear)
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:3897
int SCIPcalcHashtableSize(int minsize)
Definition: misc.c:1157
SCIP_Real SCIPvarGetUbAtIndex(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:15859
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip.c:23050
SCIP_Real SCIPepsilon(SCIP *scip)
Definition: scip.c:41118
static void consdataCalcMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1278
SCIP_Bool SCIPvarIsInitial(SCIP_VAR *var)
Definition: var.c:16644
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41598
#define DEFAULT_MULTAGGRREMOVE
Definition: cons_linear.c:136
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip.c:5527
static SCIP_RETCODE chgRhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
Definition: cons_linear.c:3320
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip.c:19717
static SCIP_RETCODE conshdlrdataEnsureLinconsupgradesSize(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, int num)
Definition: cons_linear.c:433
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:41353
static void consdataUpdateDelCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:1934
static SCIP_RETCODE consdataSort(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:3057
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7620
SCIP_Bool SCIPvarIsRemovable(SCIP_VAR *var)
Definition: var.c:16654
static void consdataUpdateAddCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:1894
static int inferInfoGetProprule(INFERINFO inferinfo)
Definition: cons_linear.c:381
static SCIP_RETCODE consdataTightenCoefs(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
Definition: cons_linear.c:8508
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:83
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41907
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:16598
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:19126
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:41758
SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
Definition: var.c:16664
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:146
constraint handler for quadratic constraints
SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
Definition: scip.c:5503
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip.h:20562
SCIP_Bool SCIPisScalingIntegral(SCIP *scip, SCIP_Real val, SCIP_Real scalar)
Definition: scip.c:41733
SCIP_RETCODE SCIPincludeConflicthdlrBasic(SCIP *scip, SCIP_CONFLICTHDLR **conflicthdlrptr, const char *name, const char *desc, int priority, SCIP_DECL_CONFLICTEXEC((*conflictexec)), SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
Definition: scip.c:5962
static SCIP_RETCODE addConflictReasonVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR *var, SCIP_Real bound)
Definition: cons_linear.c:4784
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, int pos)
Definition: cons_linear.c:3585
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:4835
static int getInferInt(PROPRULE proprule, int pos)
Definition: cons_linear.c:418
SCIP_Real SCIPgetFeasibilityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
static SCIP_RETCODE checkPartialObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons_linear.c:9720
static SCIP_RETCODE conshdlrdataIncludeUpgrade(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_LINCONSUPGRADE *linconsupgrade)
Definition: cons_linear.c:604
#define SCIP_EVENTTYPE_UBRELAXED
Definition: type_event.h:58
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:16837
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3204
#define CONSHDLR_DELAYPROP
Definition: cons_linear.c:73
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:41637
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip.c:5292
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:55
static SCIP_Bool canTightenBounds(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:4952
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:26354
#define CONSHDLR_CHECKPRIORITY
Definition: cons_linear.c:65
static SCIP_RETCODE tightenVarBoundsEasy(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:5119
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.c:5192
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1719
static void getMinActivity(SCIP *scip, SCIP_CONSDATA *consdata, int posinf, int neginf, int poshuge, int neghuge, SCIP_Real delta, SCIP_Bool global, SCIP_Bool goodrelax, SCIP_Real *minactivity, SCIP_Bool *isrelax, SCIP_Bool *issettoinfinity)
Definition: cons_linear.c:2130
static SCIP_RETCODE scaleCons(SCIP *scip, SCIP_CONS *cons, SCIP_Real scalar)
Definition: cons_linear.c:3763
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip.c:32131
SCIP_VAR ** SCIPgetLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41946
int SCIPconshdlrGetPropFreq(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4761
static SCIP_DECL_CONSINIT(consInitLinear)
#define SCIPdebugGetSolVal(scip, var, val)
Definition: debug.h:264
SCIP_EXPRGRAPHNODE * SCIPgetExprgraphNodeNonlinear(SCIP *scip, SCIP_CONS *cons)
const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:706
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:50
static SCIP_DECL_CONSTRANS(consTransLinear)
#define SCIP_EVENTTYPE_BOUNDTIGHTENED
Definition: type_event.h:97
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:7650
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.c:23020
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip.c:16884
static SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip.c:11929
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
Definition: scip.c:41660
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.c:21682
#define SCIP_EVENTTYPE_UBCHANGED
Definition: type_event.h:96
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12080
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:7190
static void consdataUpdateChgCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldval, SCIP_Real newval, SCIP_Bool checkreliability)
Definition: cons_linear.c:1977
#define DEFAULT_DETECTLOWERBOUND
Definition: cons_linear.c:123
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip.c:17116
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41611
static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
Definition: cons_linear.c:1036
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:16873
SCIP_RETCODE SCIPsetConshdlrDelvars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELVARS((*consdelvars)))
Definition: scip.c:5749
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip.c:22681
void SCIPhashtablePrintStatistics(SCIP_HASHTABLE *hashtable, SCIP_MESSAGEHDLR *messagehdlr)
Definition: misc.c:1794
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:20193
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:16850
#define QUADCONSUPGD_PRIORITY
Definition: cons_linear.c:150
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17123
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip.c:997
public data structures and miscellaneous methods
static SCIP_RETCODE chgLhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
Definition: cons_linear.c:3205
unsigned int SCIP_EVENTTYPE
Definition: type_event.h:125
SCIP_RETCODE SCIPsetConshdlrInitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITPRE((*consinitpre)))
Definition: scip.c:5479
SCIP_Bool SCIPisPresolveFinished(SCIP *scip)
Definition: scip.c:1034
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.c:24772
SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip.c:21810
SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
Definition: scip.c:25097
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:16740
static SCIP_Longint getVarSignature(SCIP_VAR *var)
Definition: cons_linear.c:2912
#define SCIP_Bool
Definition: def.h:53
SCIP_RETCODE SCIPchgCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
#define CONSHDLR_NEEDSCONS
Definition: cons_linear.c:74
#define CONSHDLR_EAGERFREQ
Definition: cons_linear.c:68
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip.c:1216
#define MULTIPLIER
static SCIP_RETCODE performVarDeletions(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss)
Definition: cons_linear.c:3847
static const char * paramname[]
Definition: lpi_msk.c:4201
static void consdataRecomputeGlbMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1252
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:801
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:7859
static SCIP_Real consdataGetActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:2822
#define MAXTIGHTENROUNDS
Definition: cons_linear.c:6665
constraint handler for nonlinear constraints
static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
Definition: cons_linear.c:552
static SCIP_DECL_CONSPROP(consPropLinear)
#define DEFAULT_DUALPRESOLVING
Definition: cons_linear.c:117
#define MAX(x, y)
Definition: tclique_def.h:75
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:8245
SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
Definition: scip.c:24369
static SCIP_RETCODE mergeMultiples(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:4229
SCIP_Real SCIPgetLocalLowerbound(SCIP *scip)
Definition: scip.c:12191
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:17329
static SCIP_DECL_CONSDELVARS(consDelvarsLinear)
methods for debugging
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:7869
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:7739
static void consdataUpdateActivitiesGlbLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:1848
SCIP_Real * SCIPgetCoefsLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_Real consdataComputePseudoActivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1119
SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition: var.c:16894
static void consdataCalcActivities(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2070
#define NONLINCONSUPGD_PRIORITY
Definition: cons_linear.c:151
int SCIPgetNQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
static int getVarWeight(SCIP_VAR *var)
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:16825
int SCIPconsGetPos(SCIP_CONS *cons)
Definition: cons.c:7630
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip.c:5611
int SCIPgetNRuns(SCIP *scip)
Definition: scip.c:37318
#define SCIPreallocMemoryArray(scip, ptr, newnum)
Definition: scip.h:20534
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:89
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:16849
#define MAXDNOM
Definition: cons_linear.c:140
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:57
Constraint handler for linear constraints in their most general form, .
SCIP_RETCODE SCIPdelCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:1627
#define DEFAULT_MAXROUNDSROOT
Definition: cons_linear.c:88
#define SCIP_EVENTTYPE_GBDCHANGED
Definition: type_event.h:94
Proprule
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:38140
#define DEFAULT_TIGHTENBOUNDSFREQ
Definition: cons_linear.c:86
static SCIP_Bool needEvents(SCIP *scip)
Definition: cons_linear.c:835
#define SCIP_DECL_LINCONSUPGD(x)
Definition: cons_linear.h:81
static SCIP_RETCODE aggregateVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1298
#define DEFAULT_SIMPLIFYINEQUALITIES
Definition: cons_linear.c:116
static SCIP_RETCODE createRow(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:7027
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41624
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:1510
#define CONSHDLR_SEPAPRIORITY
Definition: cons_linear.c:63
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip.c:15966
#define SCIP_REAL_MAX
Definition: def.h:128
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.c:20469
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.c:20400
static void consdataGetReliableResidualActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *cancelvar, SCIP_Real *resactivity, SCIP_Bool isminresact, SCIP_Bool useglobalbounds)
Definition: cons_linear.c:2376
static void consdataRecomputeMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1199
SCIP_Bool SCIPisSumRelEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:42348
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip.c:36668
SCIP_RETCODE SCIPaddObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip.c:10040
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip.c:5565
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:11477
#define MAXSCALEDCOEFINTEGER
Definition: cons_linear.c:142
static SCIP_DECL_CONSCHECK(consCheckLinear)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16608
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:528
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
Definition: scip.c:41770
static void consdataCalcSignatures(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2951
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20585
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17057
static SCIP_DECL_CONSPARSE(consParseLinear)
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
static SCIP_RETCODE analyzeConflictRangedRow(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int nvars, SCIP_VAR *var, SCIP_Real bound)
Definition: cons_linear.c:5379
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:636
static SCIP_DECL_CONSGETVARS(consGetVarsLinear)
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip.c:5772
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:18935
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition: misc.c:3829
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 *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
Definition: cons_linear.c:2457
static SCIP_RETCODE fullDualPresolve(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool *cutoff, int *nchgbds)
SCIP_RETCODE SCIPsetConsSeparated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool separate)
Definition: scip.c:25072
static const SCIP_Real scalars[]
Definition: lp.c:5506
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1281
#define REALABS(x)
Definition: def.h:151
#define CONTWEIGHT
static SCIP_DECL_CONSLOCK(consLockLinear)
static void consdataCheckNonbinvar(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1302
static SCIP_RETCODE consCatchAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:772
#define SCIPfreeMemoryArrayNull(scip, ptr)
Definition: scip.h:20545
static SCIP_DECL_CONSSEPASOL(consSepasolLinear)
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:7457
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_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:41721
static SCIP_DECL_CONSPRINT(consPrintLinear)
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:20593
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
Definition: scip.c:5455
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:278
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41933
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip.c:19453
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16750
static SCIP_RETCODE convertBinaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:8990
static SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
#define CONFLICTHDLR_DESC
Definition: cons_linear.c:83
static SCIP_RETCODE normalizeCons(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:3906
SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:25812
#define SCIP_Real
Definition: def.h:127
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_CONS *cons, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
Definition: cons_linear.c:6669
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:7799
SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
Definition: scip.c:25047
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:20299
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition: type_event.h:49
static void getNewSidesAfterAggregation(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *slackvar, SCIP_Real slackcoef, SCIP_Real *newlhs, SCIP_Real *newrhs)
Definition: cons_linear.c:9048
SCIP_Bool SCIPisSumRelGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:42400
#define MIN(x, y)
Definition: memory.c:67
#define EVENTHDLR_NAME
Definition: cons_linear.c:79
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
SCIP_RETCODE SCIPcreateEmptyRowCons(SCIP *scip, SCIP_ROW **row, SCIP_CONSHDLR *conshdlr, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition: scip.c:27600
SCIP_Real SCIPgetDualsolLinear(SCIP *scip, SCIP_CONS *cons)
#define CONSHDLR_ENFOPRIORITY
Definition: cons_linear.c:64
static SCIP_RETCODE convertEquality(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9958
static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition: cons_linear.c:4300
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition: scip.c:28334
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41959
SCIP_RETCODE SCIPincludeQuadconsUpgrade(SCIP *scip, SCIP_DECL_QUADCONSUPGD((*quadconsupgd)), int priority, SCIP_Bool active, const char *conshdlrname)
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip.h:20568
#define SCIP_INVALID
Definition: def.h:147
SCIP_Real SCIPfeastol(SCIP *scip)
Definition: scip.c:41146
#define DEFAULT_RANGEDROWPROPAGATION
Definition: cons_linear.c:131
SCIP_Longint SCIPgetNConflictConssApplied(SCIP *scip)
Definition: scip.c:38114
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:3437
static SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip.c:27738
#define CONSHDLR_DESC
Definition: cons_linear.c:62
#define SCIP_Longint
Definition: def.h:112
SCIP_RETCODE SCIPupgradeConsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **upgdcons)
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip.c:3759
static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
Definition: cons_linear.c:458
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip.c:19685
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:917
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:20571
#define SCIPdebugAddSolVal(scip, var, val)
Definition: debug.h:263
static SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXIT((*consexit)))
Definition: scip.c:5407
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition: scip.c:19399
SCIP_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
#define MAX_CLIQUE_NONZEROS_PER_CONS
Definition: cons_linear.c:7390
static void consdataRecomputeGlbMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1226
SCIP_RETCODE SCIPincludeLinconsUpgrade(SCIP *scip, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority, const char *conshdlrname)
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:58
static SCIP_RETCODE convertLongEquality(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9104
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:49
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20597
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:16730
int SCIPgetNObjVars(SCIP *scip)
Definition: scip.c:10926
#define SCIPdebug(x)
Definition: pub_message.h:74
SCIP_RETCODE SCIPaddConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip.c:11999
static int inferInfoToInt(INFERINFO inferinfo)
Definition: cons_linear.c:372
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
#define MAXVALRECOMP
Definition: cons_linear.c:8472
static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:669
SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
Definition: scip.c:24436
static SCIP_DECL_CONSPRESOL(consPresolLinear)
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip.c:41422
#define DEFAULT_MAXEASYACTIVITYDELTA
Definition: cons_linear.c:106
SCIP_Real SCIPgetLhsQuadratic(SCIP *scip, SCIP_CONS *cons)
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:392
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:54
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:18948
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:41697
static SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
static SCIP_DECL_CONSEXIT(consExitLinear)
#define DEFAULT_RANGEDROWMAXDEPTH
Definition: cons_linear.c:133
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1120
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.c:3629
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip.c:5841
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:27864
#define SCIPABORT()
Definition: def.h:238
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:7789
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:7083
static INFERINFO intToInferInfo(int i)
Definition: cons_linear.c:359
int SCIPconsGetNLocksPos(SCIP_CONS *cons)
Definition: cons.c:7949
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:7819
int SCIPconsGetNLocksNeg(SCIP_CONS *cons)
Definition: cons.c:7959
#define INTWEIGHT
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)
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons.c:3927
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3149
SCIP_Real SCIPgetRhsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPchgRowLhs(SCIP *scip, SCIP_ROW *row, SCIP_Real lhs)
Definition: scip.c:27759
static SCIP_RETCODE addConflictBounds(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_BDCHGIDX *bdchgidx, int inferpos, SCIP_Bool reasonisrhs)
Definition: cons_linear.c:4541
SCIP_Longint SCIPcalcSmaComMul(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:7194
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition: scip.c:36834
#define SCIP_EVENTTYPE_VARDELETED
Definition: type_event.h:47
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:1798
SCIP_Bool SCIPisUbBetter(SCIP *scip, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
Definition: scip.c:42270
#define DEFAULT_PRESOLUSEHASHING
Definition: cons_linear.c:92
#define HASHSIZE_LINEARCONS
Definition: cons_linear.c:148
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:1823
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
Definition: cons_linear.c:1001
#define SCIP_EVENTTYPE_BOUNDRELAXED
Definition: type_event.h:98
#define DEFAULT_RANGEDROWARTCONS
Definition: cons_linear.c:132
static SCIP_RETCODE dualPresolve(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss)