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-2015 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 coefficents 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 /* checks ranged rows for possible solutions, it may detect infeasibility, fixings due to having only one possible
5403  * solution, boundtightening if having only two possible solutions or adds constraints which propagate a subset of
5404  * variables better
5405  *
5406  * e.g.
5407  * c1: 12 x1 + 9 x2 - x3 = 0 with x1, x2 free and 1 <= x3 <= 2
5408  *
5409  * x3 needs to be a multiple of 3, so it follows infeasibility
5410  *
5411  * e.g.
5412  * c1: 12 x1 + 9 x2 - x3 = 1 with x1, x2 free and 1 <= x3 <= 2
5413  *
5414  * only posible value for x3 is 2, so the variable will be fixed
5415  *
5416  * @todo add holes if possible
5417  */
5418 static
5420  SCIP* scip, /**< SCIP data structure */
5421  SCIP_CONS* cons, /**< linear constraint */
5422  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
5423  int* nfixedvars, /**< pointer to count number of fixed variables */
5424  int* nchgbds, /**< pointer to count the number of bound changes */
5425  int* naddconss /**< pointer to count number of added constraints */
5426  )
5427 {
5428  SCIP_CONSHDLRDATA* conshdlrdata;
5429  SCIP_CONSHDLR* conshdlr;
5430  SCIP_CONSDATA* consdata;
5431  SCIP_VAR** infcheckvars;
5432  SCIP_Real* infcheckvals;
5433  SCIP_Real minactinfvars;
5434  SCIP_Real maxactinfvars;
5436  SCIP_Real ub;
5437  SCIP_Real feastol;
5438  SCIP_Real fixedact;
5439  SCIP_Real lhs;
5440  SCIP_Real rhs;
5441  SCIP_Real absminbincoef;
5442  SCIP_Longint gcd;
5443  SCIP_Longint gcdtmp;
5444  SCIP_Bool minactinfvarsinvalid;
5445  SCIP_Bool maxactinfvarsinvalid;
5446  SCIP_Bool possiblegcd;
5447  SCIP_Bool gcdisone;
5448  SCIP_Bool addartconss;
5449  int ninfcheckvars;
5450  int nunfixedvars;
5451  int nfixedconsvars;
5452  int ncontvars;
5453  int contvarpos;
5454  int nposbinvars;
5455  int nnegbinvars;
5456  int pos;
5457  int v;
5458 
5459  assert(scip != NULL);
5460  assert(cons != NULL);
5461  assert(cutoff != NULL);
5462  assert(nfixedvars != NULL);
5463  assert(nchgbds != NULL);
5464  assert(naddconss != NULL);
5465 
5466  /* modifiable constraint can be changed so we do not have all necessary information */
5467  if( SCIPconsIsModifiable(cons) )
5468  return SCIP_OKAY;
5469 
5470  consdata = SCIPconsGetData(cons);
5471  assert(consdata != NULL);
5472 
5473  /* at least three variables are needed */
5474  if( consdata->nvars < 3 )
5475  return SCIP_OKAY;
5476 
5477  /* if we already presolved this constraint */
5478  if( consdata->rangedrowpropagation )
5479  return SCIP_OKAY;
5480 
5481  /* if we have too many continuous variables, so stop here */
5482  if( (consdata->sorted || consdata->binvarssorted) && SCIPvarGetType(consdata->vars[1]) == SCIP_VARTYPE_CONTINUOUS )
5483  return SCIP_OKAY;
5484 
5485  /* do nothing on normal inequalities */
5486  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
5487  return SCIP_OKAY;
5488 
5489  /* get constraint handler data */
5490  conshdlr = SCIPconsGetHdlr(cons);
5491  assert(conshdlr != NULL);
5492  conshdlrdata = SCIPconshdlrGetData(conshdlr);
5493  assert(conshdlrdata != NULL);
5494 
5495  addartconss = conshdlrdata->rangedrowartcons;
5496 
5497  fixedact = 0;
5498  nfixedconsvars = 0;
5499  /* calculate fixed activity and number of fixed variables */
5500  for( v = consdata->nvars - 1; v >= 0; --v )
5501  {
5502  /* all zero coefficients should be eliminated */
5503  assert(!SCIPisZero(scip, consdata->vals[v]));
5504 
5505  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5506  {
5507  fixedact += SCIPvarGetLbLocal(consdata->vars[v]) * consdata->vals[v];
5508  ++nfixedconsvars;
5509  }
5510  }
5511 
5512  /* do not work with huge fixed activities */
5513  if( SCIPisHugeValue(scip, REALABS(fixedact)) )
5514  return SCIP_OKAY;
5515 
5516  /* compute lhs and rhs for unfixed variables only and get number of unfixed variables */
5517  assert(!SCIPisInfinity(scip, -fixedact) && !SCIPisInfinity(scip, fixedact));
5518  lhs = consdata->lhs - fixedact;
5519  rhs = consdata->rhs - fixedact;
5520  nunfixedvars = consdata->nvars - nfixedconsvars;
5521 
5522  /* allocate temporary memory for variables and coefficients which may lead to infeasibility */
5523  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvars, nunfixedvars ));
5524  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvals, nunfixedvars ));
5525 
5526  absminbincoef = SCIP_REAL_MAX;
5527  nposbinvars = 0;
5528  nnegbinvars = 0;
5529  ncontvars = 0;
5530  contvarpos = -1;
5531  gcdisone = TRUE;
5532  possiblegcd = TRUE;
5533 
5534  /* we now partition all unfixed variables in two groups:
5535  *
5536  * the first one contains all integral variable with integral
5537  * coefficient so that all variables in this group will have a gcd greater than 1, this group will be implicitly
5538  * given
5539  *
5540  * the second group will contain all left unfixed variables and will be saved as infcheckvars with corresponding
5541  * coefficients as infcheckvals, the order of these variables should be the same as in the consdata object
5542  */
5543 
5544  /* find first integral variables with integral coefficient greater than 1, thereby collecting all other unfixed
5545  * variables
5546  */
5547  ninfcheckvars = 0;
5548  v = -1;
5549  pos = -1;
5550  do
5551  {
5552  ++v;
5553 
5554  /* partition the variables, do not change the order of collection, because it might be used later on */
5555  while( v < consdata->nvars && (SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5556  !SCIPisIntegral(scip, consdata->vals[v]) || SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0)) )
5557  {
5558  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5559  {
5560  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5561  {
5562  ++ncontvars;
5563  contvarpos = v;
5564  }
5565  else if( SCIPvarIsBinary(consdata->vars[v]) )
5566  {
5567  SCIP_Real absval = REALABS(consdata->vals[v]);
5568 
5569  if( consdata->vals[v] > 0.0 )
5570  ++nposbinvars;
5571  else
5572  ++nnegbinvars;
5573 
5574  if( absminbincoef > absval )
5575  absminbincoef = absval;
5576  }
5577 
5578  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5579  possiblegcd = FALSE;
5580  infcheckvars[ninfcheckvars] = consdata->vars[v];
5581  infcheckvals[ninfcheckvars] = consdata->vals[v];
5582  ++ninfcheckvars;
5583 
5584  if( pos == -1 )
5585  pos = v;
5586  }
5587  ++v;
5588  }
5589  } while( v < consdata->nvars && SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) );
5590 
5591  /* if the first group of variables is empty, we stop */
5592  /* @todo try to propagate/split up a constraint of the form:
5593  * x_1 + ... + x_m + a_1*y_1 + ... + a_n*y_n = k + c,
5594  * 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]
5595  */
5596  if( v == consdata->nvars )
5597  goto TERMINATE;
5598 
5599  assert(!SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])));
5600  assert(SCIPisIntegral(scip, consdata->vals[v]) && SCIPvarGetType(consdata->vars[v]) != SCIP_VARTYPE_CONTINUOUS && REALABS(consdata->vals[v]) > 1.5);
5601 
5602  feastol = SCIPfeastol(scip);
5603 
5604  gcd = (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol);
5605  assert(gcd >= 2);
5606  /* go on to partition the variables, do not change the order of collection, because it might be used later on;
5607  * calculate gcd over the first part of variables
5608  */
5609  for( ; v < consdata->nvars; ++v )
5610  {
5611  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5612  continue;
5613 
5614  if( SCIPvarIsBinary(consdata->vars[v]) )
5615  {
5616  SCIP_Real absval = REALABS(consdata->vals[v]);
5617 
5618  if( consdata->vals[v] > 0.0 )
5619  ++nposbinvars;
5620  else
5621  ++nnegbinvars;
5622 
5623  if( absminbincoef > absval )
5624  absminbincoef = absval;
5625  }
5626 
5627  if( !SCIPisIntegral(scip, consdata->vals[v]) || SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5628  SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0) )
5629  {
5630  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5631  {
5632  ++ncontvars;
5633  contvarpos = v;
5634  }
5635 
5636  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5637  possiblegcd = FALSE;
5638  infcheckvars[ninfcheckvars] = consdata->vars[v];
5639  infcheckvals[ninfcheckvars] = consdata->vals[v];
5640 
5641  ++ninfcheckvars;
5642 
5643  if( pos == -1 )
5644  pos = v;
5645  }
5646  else
5647  {
5648  assert(REALABS(consdata->vals[v]) > 1.5);
5649 
5650  gcdtmp = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol));
5651  assert(gcdtmp >= 1);
5652 
5653  if( gcdtmp == 1 )
5654  {
5655  infcheckvars[ninfcheckvars] = consdata->vars[v];
5656  infcheckvals[ninfcheckvars] = consdata->vals[v];
5657 
5658  ++ninfcheckvars;
5659 
5660  if( pos == -1 )
5661  pos = v;
5662  }
5663  else
5664  gcd = gcdtmp;
5665  }
5666  }
5667  assert(gcd >= 2);
5668 
5669  /* it should not happen that all variables are of integral type and have a gcd >= 2, this should be done by
5670  * normalizeCons()
5671  */
5672  if( ninfcheckvars == 0 )
5673  goto TERMINATE;
5674 
5675  assert(pos >= 0);
5676 
5677  minactinfvarsinvalid = FALSE;
5678  maxactinfvarsinvalid = FALSE;
5679  maxactinfvars = 0.0;
5680  minactinfvars = 0.0;
5681 
5682  /* calculate activities over all infcheckvars */
5683  for( v = ninfcheckvars - 1; v >= 0; --v )
5684  {
5685  lb = SCIPvarGetLbLocal(infcheckvars[v]);
5686  ub = SCIPvarGetUbLocal(infcheckvars[v]);
5687 
5688  if( SCIPisInfinity(scip, -lb) )
5689  {
5690  if( infcheckvals[v] < 0.0 )
5691  maxactinfvarsinvalid = TRUE;
5692  else
5693  minactinfvarsinvalid = TRUE;
5694  }
5695  else
5696  {
5697  if( infcheckvals[v] < 0.0 )
5698  maxactinfvars += infcheckvals[v] * lb;
5699  else
5700  minactinfvars += infcheckvals[v] * lb;
5701  }
5702 
5703  if( SCIPisInfinity(scip, ub) )
5704  {
5705  if( infcheckvals[v] > 0.0 )
5706  maxactinfvarsinvalid = TRUE;
5707  else
5708  minactinfvarsinvalid = TRUE;
5709  }
5710  else
5711  {
5712  if( infcheckvals[v] > 0.0 )
5713  maxactinfvars += infcheckvals[v] * ub;
5714  else
5715  minactinfvars += infcheckvals[v] * ub;
5716  }
5717 
5718  /* better abort on to big values */
5719  if( SCIPisHugeValue(scip, -minactinfvars) )
5720  minactinfvarsinvalid = TRUE;
5721  if( SCIPisHugeValue(scip, maxactinfvars) )
5722  maxactinfvarsinvalid = TRUE;
5723 
5724  if( minactinfvarsinvalid || maxactinfvarsinvalid )
5725  goto TERMINATE;
5726  }
5727  assert(!minactinfvarsinvalid && !maxactinfvarsinvalid);
5728 
5729  SCIPdebugMessage("minactinfvarsinvalid = %u, minactinfvars = %g, maxactinfvarsinvalid = %u, maxactinfvars = %g, gcd = %lld, ninfcheckvars = %d, ncontvars = %d\n", minactinfvarsinvalid, minactinfvars, maxactinfvarsinvalid, maxactinfvars, gcd, ninfcheckvars, ncontvars);
5730 
5731  /* @todo maybe we took the wrong variables as infcheckvars we could try to exchange integer variables */
5732  /* @todo if minactinfvarsinvalid or maxactinfvarsinvalid are true, try to exchange both partitions to maybe get valid
5733  * activities */
5734  /* @todo calculate minactivity and maxactivity for all non-intcheckvars, and use this for better bounding,
5735  * !!!note!!!
5736  * that therefore the conflict variables in addConflictFixedVars() need to be extended by all variables which
5737  * are not at their global bound
5738  */
5739 
5740  /* check if between left hand side and right hand side exist a feasible point, if not the constraint leads to
5741  * infeasibility */
5742  if( !SCIPisIntegral(scip, (lhs - maxactinfvars) / gcd) &&
5743  SCIPisGT(scip, SCIPceil(scip, (lhs - maxactinfvars) / gcd) * gcd, rhs - minactinfvars) )
5744  {
5745  SCIPdebugMessage("no feasible value exist, constraint <%s> lead to infeasibility", SCIPconsGetName(cons));
5746  SCIPdebugPrintCons(scip, cons, NULL);
5747 
5748  /* start conflict analysis */
5749  /* @todo improve conflict analysis by adding relaxed bounds */
5750  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
5751 
5752  *cutoff = TRUE;
5753  }
5754  else if( ncontvars == 0 )
5755  {
5756  SCIP_Longint gcdinfvars;
5757 
5758  gcdinfvars = -1;
5759 
5760  /* check for gcd over all infcheckvars */
5761  if( possiblegcd )
5762  {
5763  v = ninfcheckvars - 1;
5764  gcdinfvars = (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol);
5765  assert(gcdinfvars >= 2);
5766 
5767  for( ; v >= 0 && gcdinfvars >= 2; --v )
5768  {
5769  gcdinfvars = SCIPcalcGreComDiv(gcdinfvars, (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol));
5770  }
5771  }
5772  else if( gcdisone )
5773  gcdinfvars = 1;
5774 
5775  SCIPdebugMessage("gcdinfvars =%lld, possiblegcd = %u\n", gcdinfvars, possiblegcd);
5776 
5777  /* compute solutions for this ranged row, if all variables are of integral type with integral coefficients */
5778  if( gcdinfvars >= 1 )
5779  {
5780  SCIP_Real value;
5781  SCIP_Real value2;
5782  SCIP_Real minvalue;
5783  SCIP_Real maxvalue;
5784  int nsols;
5785 
5786  nsols = 0;
5787  value = minactinfvars;
5788  minvalue = SCIP_INVALID;
5789  maxvalue = SCIP_INVALID;
5790 
5791  /* check how many possible solutions exist */
5792  while( SCIPisLE(scip, value, maxactinfvars) )
5793  {
5794  value2 = value + gcd * (SCIPceil(scip, (lhs - value) / gcd));
5795 
5796  if( SCIPisGE(scip, value2, lhs) && SCIPisLE(scip, value2, rhs) )
5797  {
5798  ++nsols;
5799 
5800  /* early termination if we found more than two solutions */
5801  if( nsols == 3 )
5802  break;
5803 
5804  if( minvalue == SCIP_INVALID ) /*lint !e777*/
5805  minvalue = value;
5806 
5807  maxvalue = value;
5808  }
5809  value += gcdinfvars;
5810  }
5811  assert(nsols < 2 || minvalue <= maxvalue);
5812 
5813  /* determine last possible solution for better bounding */
5814  if( nsols == 3 )
5815  {
5816  value = maxactinfvars;
5817 
5818  /* check how many possible solutions exist */
5819  while( SCIPisGE(scip, value, minactinfvars) )
5820  {
5821  value2 = value + gcd * (SCIPfloor(scip, (rhs - value) / gcd));
5822 
5823  if( SCIPisGE(scip, value2, lhs) && SCIPisLE(scip, value2, rhs) )
5824  {
5825  maxvalue = value;
5826  assert(maxvalue > minvalue);
5827  break;
5828  }
5829  value -= gcdinfvars;
5830  }
5831  }
5832 
5833  SCIPdebugMessage("here nsols %s %d, minsolvalue = %g, maxsolvalue = %g, ninfcheckvars = %d, nunfixedvars = %d\n",
5834  nsols > 2 ? ">=" : "=", nsols, minvalue, maxvalue, ninfcheckvars, nunfixedvars);
5835 
5836  /* no possible solution found */
5837  if( nsols == 0 )
5838  {
5839  SCIPdebugMessage("gcdinfvars = %lld, gcd = %lld, correctedlhs = %g, correctedrhs = %g\n",
5840  gcdinfvars, gcd, lhs, rhs);
5841  SCIPdebugMessage("no solution found; constraint <%s> lead to infeasibility\n", SCIPconsGetName(cons));
5842  SCIPdebugPrintCons(scip, cons, NULL);
5843 
5844  /* start conflict analysis */
5845  /* @todo improve conflict analysis by adding relaxed bounds */
5846  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
5847 
5848  *cutoff = TRUE;
5849  }
5850  /* if only one solution exist we can extract a new constraint or fix variables */
5851  else if( nsols == 1 )
5852  {
5853  assert(minvalue == maxvalue); /*lint !e777*/
5854 
5855  /* we can fix the only variable in our second set of variables */
5856  if( ninfcheckvars == 1 )
5857  {
5858  SCIP_Bool fixed;
5859 
5860  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
5861 
5862  SCIPdebugMessage("fixing single variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
5863  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]),
5864  SCIPvarGetUbLocal(infcheckvars[0]), maxvalue/infcheckvals[0]);
5865 
5866  /* fix variable to only possible value */
5867  SCIP_CALL( SCIPinferVarFixCons(scip, infcheckvars[0], maxvalue/infcheckvals[0], cons,
5868  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &fixed) );
5869 
5870  if( *cutoff )
5871  {
5872  /* start conflict analysis */
5873  /* @todo improve conflict analysis by adding relaxed bounds */
5874  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
5875  }
5876 
5877  if( fixed )
5878  ++(*nfixedvars);
5879  }
5880  else
5881  {
5882  /* check for exactly one unfixed variable which is not part of the infcheckvars */
5883  if( ninfcheckvars == nunfixedvars - 1 )
5884  {
5885  SCIP_Real bound;
5886  SCIP_Bool foundvar;
5887  SCIP_Bool fixed;
5888  int w;
5889 
5890  assert(ninfcheckvars > 0);
5891 
5892  foundvar = FALSE;
5893  w = 0;
5894 
5895  /* find variable which is not an infcheckvar and fix it */
5896  for( v = 0; v < consdata->nvars - 1; ++v )
5897  {
5898  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5899  {
5900  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
5901  {
5902 #ifndef NDEBUG
5903  int v2 = v + 1;
5904  int w2 = w;
5905 
5906  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
5907 
5908  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
5909  {
5910  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
5911  continue;
5912 
5913  assert(consdata->vars[v2] == infcheckvars[w2]);
5914  ++w2;
5915  }
5916  assert(w2 == ninfcheckvars);
5917 #endif
5918  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
5919 
5920  foundvar = TRUE;
5921 
5922  if( consdata->vals[v] < 0 )
5923  {
5924  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
5925  }
5926  else
5927  {
5928  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
5929  }
5930 
5931  SCIPdebugMessage("fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
5932  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
5933  SCIPvarGetUbLocal(consdata->vars[v]), bound);
5934 
5935  /* fix variable to only possible value */
5936  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
5937  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
5938 
5939  if( *cutoff )
5940  {
5941  /* start conflict analysis */
5942  /* @todo improve conflict analysis by adding relaxed bounds */
5943  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
5944  consdata->vars[v], bound) );
5945  }
5946 
5947  if( fixed )
5948  ++(*nfixedvars);
5949 
5950  break;
5951  }
5952 
5953  ++w;
5954  }
5955  }
5956 
5957  /* maybe last variable was the not infcheckvar */
5958  if( !foundvar )
5959  {
5960  assert(v == consdata->nvars - 1);
5961  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
5962 
5963  if( consdata->vals[v] < 0 )
5964  {
5965  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
5966  }
5967  else
5968  {
5969  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
5970  }
5971 
5972  SCIPdebugMessage("fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
5973  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
5974  SCIPvarGetUbLocal(consdata->vars[v]), bound);
5975 
5976  /* fix variable to only possible value */
5977  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
5978  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
5979 
5980  if( *cutoff )
5981  {
5982  /* start conflict analysis */
5983  /* @todo improve conflict analysis by adding relaxed bounds */
5984  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
5985  consdata->vars[v], bound) );
5986  }
5987 
5988  if( fixed )
5989  ++(*nfixedvars);
5990  }
5991  }
5992  else if( !SCIPinProbing(scip) && SCIPgetDepth(scip) < 1 && !SCIPinRepropagation(scip) && addartconss &&
5993  (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
5994  {
5995  /* aggregation possible if we have two variables, but this will be done later on */
5996  SCIP_CONS* newcons;
5997  char name[SCIP_MAXSTRLEN];
5998 
5999  /* create, add, and release new artificial constraint */
6000  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6001  ++conshdlrdata->naddconss;
6002 
6003  SCIPdebugMessage("adding artificial constraint %s\n", name);
6004 
6005  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals,
6006  maxvalue, maxvalue, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6007  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6008 
6009  SCIPdebugPrintCons(scip, newcons, NULL);
6010 
6011  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6012 
6013  ++(*naddconss);
6014  }
6015  }
6016  }
6017  /* at least two solutions */
6018  else
6019  {
6020  /* @todo if we found more then one solution, we may reduced domains due to dualpresolving? */
6021 
6022  /* only one variable in the second set, so we can bound this variables */
6023  if( ninfcheckvars == 1 )
6024  {
6025  SCIP_Bool tightened;
6026  SCIP_Real newlb;
6027  SCIP_Real newub;
6028 
6029  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6030 
6031  if( infcheckvals[0] < 0 )
6032  {
6033  newlb = maxvalue/infcheckvals[0];
6034  newub = minvalue/infcheckvals[0];
6035  }
6036  else
6037  {
6038  newlb = minvalue/infcheckvals[0];
6039  newub = maxvalue/infcheckvals[0];
6040  }
6041  assert(newlb < newub);
6042 
6043  if( newlb > SCIPvarGetLbLocal(infcheckvars[0]) )
6044  {
6045  /* update lower bound of variable */
6046  SCIPdebugMessage("tightening lower bound of variable <%s> from %g to %g\n",
6047  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]), newlb);
6048 
6049  /* tighten variable lower bound to minimal possible value */
6050  SCIP_CALL( SCIPinferVarLbCons(scip, infcheckvars[0], newlb, 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  if( newub < SCIPvarGetUbLocal(infcheckvars[0]) )
6065  {
6066  /* update upper bound of variable */
6067  SCIPdebugMessage("tightening upper bound of variable <%s> from %g to %g\n",
6068  SCIPvarGetName(infcheckvars[0]), SCIPvarGetUbLocal(infcheckvars[0]), newub);
6069 
6070  /* tighten variable upper bound to maximal possible value */
6071  SCIP_CALL( SCIPinferVarUbCons(scip, infcheckvars[0], newub, cons,
6072  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6073 
6074  if( *cutoff )
6075  {
6076  /* start conflict analysis */
6077  /* @todo improve conflict analysis by adding relaxed bounds */
6078  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6079  }
6080 
6081  if( tightened )
6082  ++(*nchgbds);
6083  }
6084  }
6085  /* check if we have only one not infcheckvars, if so we can tighten this variable */
6086  else if( ninfcheckvars == nunfixedvars - 1 )
6087  {
6088  SCIP_Bool foundvar;
6089  SCIP_Bool tightened;
6090  SCIP_Real newlb;
6091  SCIP_Real newub;
6092  int w;
6093 
6094  assert(ninfcheckvars > 0);
6095  assert(minvalue < maxvalue);
6096 
6097  foundvar = FALSE;
6098  w = 0;
6099 
6100  /* find variable which is not an infcheckvar and fix it */
6101  for( v = 0; v < consdata->nvars - 1; ++v )
6102  {
6103  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6104  {
6105  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6106  {
6107 #ifndef NDEBUG
6108  int v2 = v + 1;
6109  int w2 = w;
6110 
6111  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6112 
6113  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6114  {
6115  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6116  continue;
6117 
6118  assert(consdata->vars[v2] == infcheckvars[w2]);
6119  ++w2;
6120  }
6121  assert(w2 == ninfcheckvars);
6122 #endif
6123 
6124  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6125  foundvar = TRUE;
6126 
6127  if( consdata->vals[v] < 0 )
6128  {
6129  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6130  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6131  }
6132  else
6133  {
6134  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6135  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6136  }
6137  assert(SCIPisLE(scip, newlb, newub));
6138 
6139  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6140  {
6141  /* update lower bound of variable */
6142  SCIPdebugMessage("tightening lower bound of variable <%s> from %g to %g\n",
6143  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6144 
6145  /* tighten variable lower bound to minimal possible value */
6146  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6147  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6148 
6149  if( *cutoff )
6150  {
6151  /* start conflict analysis */
6152  /* @todo improve conflict analysis by adding relaxed bounds */
6153  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6154  consdata->vars[v], newlb) );
6155  }
6156 
6157  if( tightened )
6158  ++(*nchgbds);
6159  }
6160 
6161  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6162  {
6163  /* update upper bound of variable */
6164  SCIPdebugMessage("tightening upper bound of variable <%s> from %g to %g\n",
6165  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6166 
6167  /* tighten variable upper bound to maximal possible value */
6168  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6169  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6170 
6171  if( *cutoff )
6172  {
6173  /* start conflict analysis */
6174  /* @todo improve conflict analysis by adding relaxed bounds */
6175  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6176  consdata->vars[v], newub) );
6177  }
6178 
6179  if( tightened )
6180  ++(*nchgbds);
6181  }
6182 
6183  break;
6184  }
6185 
6186  ++w;
6187  }
6188  }
6189 
6190  /* maybe last variable was the not infcheckvar */
6191  if( !foundvar )
6192  {
6193  assert(v == consdata->nvars - 1);
6194  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6195 
6196  if( consdata->vals[v] < 0 )
6197  {
6198  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6199  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6200  }
6201  else
6202  {
6203  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6204  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6205  }
6206  assert(SCIPisLE(scip, newlb, newub));
6207 
6208  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6209  {
6210  /* update lower bound of variable */
6211  SCIPdebugMessage("tightening lower bound of variable <%s> from %g to %g\n",
6212  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6213 
6214  /* tighten variable lower bound to minimal possible value */
6215  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6216  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6217 
6218  if( *cutoff )
6219  {
6220  /* start conflict analysis */
6221  /* @todo improve conflict analysis by adding relaxed bounds */
6222  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v],
6223  newlb) );
6224  }
6225 
6226  if( tightened )
6227  ++(*nchgbds);
6228  }
6229 
6230  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6231  {
6232  /* update upper bound of variable */
6233  SCIPdebugMessage("tightening upper bound of variable <%s> from %g to %g\n",
6234  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6235 
6236  /* tighten variable upper bound to maximal possible value */
6237  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6238  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6239 
6240  if( *cutoff )
6241  {
6242  /* start conflict analysis */
6243  /* @todo improve conflict analysis by adding relaxed bounds */
6244  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v],
6245  newub) );
6246  }
6247 
6248  if( tightened )
6249  ++(*nchgbds);
6250  }
6251  }
6252  }
6253  /* at least two solutions and more than one variable, so we add a new constraint which bounds the feasible
6254  * region for our infcheckvars, if possible
6255  */
6256  else if( !SCIPinProbing(scip) && SCIPgetDepth(scip) < 1 && !SCIPinRepropagation(scip) && addartconss &&
6257  (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6258  {
6259  SCIP_CONS* newcons;
6260  char name[SCIP_MAXSTRLEN];
6261  SCIP_Real newlhs;
6262  SCIP_Real newrhs;
6263 
6264  assert(maxvalue > minvalue);
6265 
6266  if( SCIPisGT(scip, minvalue, minactinfvars) )
6267  newlhs = minvalue;
6268  else
6269  newlhs = -SCIPinfinity(scip);
6270 
6271  if( SCIPisLT(scip, maxvalue, maxactinfvars) )
6272  newrhs = maxvalue;
6273  else
6274  newrhs = SCIPinfinity(scip);
6275 
6276  if( !SCIPisInfinity(scip, -newlhs) || !SCIPisInfinity(scip, newrhs) )
6277  {
6278  /* create, add, and release new artificial constraint */
6279  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons1_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6280  ++conshdlrdata->naddconss;
6281 
6282  SCIPdebugMessage("adding artificial constraint %s\n", name);
6283 
6284  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6285  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6286  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6287 
6288  SCIPdebugPrintCons(scip, newcons, NULL);
6289  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6290 
6291  ++(*naddconss);
6292  }
6293  /* @todo maybe add constraint for all variables which are not infcheckvars, lhs should be minvalue, rhs
6294  * should be maxvalue
6295  */
6296  }
6297  }
6298  }
6299  }
6300  else if( ncontvars == 1 )
6301  {
6302  /* try to improve bounds on the only continuous variable */
6303  if( nposbinvars + nnegbinvars == consdata->nvars - 1 )
6304  {
6305  SCIP_VAR* contvar;
6306  SCIP_Real contval;
6307  SCIP_Bool tightened;
6308  SCIP_Bool multiplied = FALSE;
6309  SCIP_Real binact = 0.0;
6310 
6311  assert(contvarpos >= 0 && contvarpos < consdata->nvars);
6312 
6313  contval = consdata->vals[contvarpos];
6314  contvar = consdata->vars[contvarpos];
6315  assert(SCIPvarGetType(contvar) == SCIP_VARTYPE_CONTINUOUS);
6316 
6317  /* convert representation to: lhs <= sum_i=1^n a_i*x_i - by <= rhs, b > 0 */
6318  if( contval > 0.0 )
6319  {
6320  SCIP_Real tmp;
6321 
6322  tmp = -lhs;
6323  lhs = -rhs;
6324  rhs = tmp;
6325  multiplied = TRUE;
6326  }
6327 
6328  contval = REALABS(contval);
6329 
6330  /* convert representation to: lhs <= sum_i=1^n a_i*x_i - by <= rhs, b > 0, for all i : a_i > 0 */
6331  if( nposbinvars != consdata->nvars - 1 || multiplied )
6332  {
6333  for( v = consdata->nvars - 1; v >= 0; --v )
6334  {
6335  if( v != contvarpos && !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6336  {
6337  if( !multiplied && consdata->vals[v] < 0.0 )
6338  {
6339  lhs -= consdata->vals[v];
6340  rhs -= consdata->vals[v];
6341  }
6342  else if( multiplied && consdata->vals[v] > 0.0 )
6343  {
6344  lhs += consdata->vals[v];
6345  rhs += consdata->vals[v];
6346  }
6347  }
6348  }
6349  }
6350 
6351  /* can we improve the lower bound? */
6352  if( SCIPisFeasNegative(scip, contval * SCIPvarGetLbLocal(contvar) + lhs) ||
6353  (SCIPisFeasPositive(scip, contval * SCIPvarGetLbLocal(contvar) + lhs) &&
6354  SCIPisFeasLT(scip, contval * SCIPvarGetLbLocal(contvar) + lhs, absminbincoef)) )
6355  {
6356  SCIP_Real newlb = SCIPisFeasNegative(scip, SCIPvarGetLbLocal(contvar) + lhs) ? -lhs : absminbincoef - lhs;
6357 
6358  newlb /= REALABS(contval);
6359 
6360  /* update lower bound of continuous variable */
6361  SCIPdebugMessage("tightening lower bound of variable <%s> from %g to %g\n",
6362  SCIPvarGetName(contvar), SCIPvarGetLbLocal(contvar), newlb);
6363 
6364  /* tighten variable lower bound to minimal possible value */
6365  SCIP_CALL( SCIPinferVarLbCons(scip, contvar, newlb, cons,
6366  getInferInt(PROPRULE_1_RANGEDROW, contvarpos), TRUE, cutoff, &tightened) );
6367 
6368  if( *cutoff )
6369  {
6370  /* start conflict analysis */
6371  /* @todo improve conflict analysis by adding relaxed bounds */
6372  SCIP_CALL( analyzeConflictRangedRow(scip, cons, NULL, 0, contvar,
6373  newlb) );
6374  }
6375 
6376  if( tightened )
6377  ++(*nchgbds);
6378  }
6379 
6380  /* compute binary activities in absolute value */
6381  for( v = consdata->nvars - 1; v >= 0; --v )
6382  {
6383  if( v != contvarpos && !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6384  {
6385  binact += REALABS(consdata->vals[v]);
6386  }
6387  }
6388 
6389  /* can we improve the upper bound? */
6390  if( SCIPisFeasLT(scip, contval * SCIPvarGetUbLocal(contvar), binact - rhs) &&
6391  SCIPisFeasGT(scip, contval * SCIPvarGetUbLocal(contvar), binact - absminbincoef - rhs) )
6392  {
6393  SCIP_Real newub = binact - absminbincoef - rhs;
6394 
6395  newub /= REALABS(contval);
6396 
6397  /* update lower bound of continuous variable */
6398  SCIPdebugMessage("tightening upper bound of variable <%s> from %g to %g\n",
6399  SCIPvarGetName(contvar), SCIPvarGetUbLocal(contvar), newub);
6400 
6401  /* tighten variable lower bound to minimal possible value */
6402  SCIP_CALL( SCIPinferVarUbCons(scip, contvar, newub, cons,
6403  getInferInt(PROPRULE_1_RANGEDROW, contvarpos), TRUE, cutoff, &tightened) );
6404 
6405  if( *cutoff )
6406  {
6407  /* start conflict analysis */
6408  /* @todo improve conflict analysis by adding relaxed bounds */
6409  SCIP_CALL( analyzeConflictRangedRow(scip, cons, NULL, 0, contvar,
6410  newub) );
6411  }
6412 
6413  if( tightened )
6414  ++(*nchgbds);
6415  }
6416  }
6417  }
6418  else if( ncontvars < ninfcheckvars && !SCIPinProbing(scip) && SCIPgetDepth(scip) < 1 )
6419  {
6420  SCIP_Real maxact = 0.0;
6421  SCIP_Real minact = 0.0;
6422  int w = 0;
6423 
6424  /* compute activities of non-infcheckvars */
6425  for( v = 0; v < consdata->nvars; ++v )
6426  {
6427  if( w < ninfcheckvars && consdata->vars[v] == infcheckvars[w] )
6428  {
6429  ++w;
6430  continue;
6431  }
6432 
6433  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6434  {
6435  if( SCIPvarIsBinary(consdata->vars[v]) )
6436  {
6437  if( consdata->vals[v] > 0.0 )
6438  maxact += consdata->vals[v];
6439  else
6440  minact += consdata->vals[v];
6441  }
6442  else
6443  {
6444  SCIP_Real tmpval;
6445 
6446  assert(SCIPvarIsIntegral(consdata->vars[v]));
6447 
6448  if( consdata->vals[v] > 0.0 )
6449  {
6450  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6451 
6452  if( SCIPisHugeValue(scip, -tmpval) )
6453  break;
6454 
6455  minact += tmpval;
6456 
6457  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6458 
6459  if( SCIPisHugeValue(scip, tmpval) )
6460  break;
6461 
6462  maxact += tmpval;
6463  }
6464  else
6465  {
6466  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6467 
6468  if( SCIPisHugeValue(scip, -tmpval) )
6469  break;
6470 
6471  minact += tmpval;
6472 
6473  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6474 
6475  if( SCIPisHugeValue(scip, tmpval) )
6476  break;
6477 
6478  maxact += tmpval;
6479  }
6480  }
6481  }
6482  }
6483  if( !SCIPinProbing(scip) && SCIPgetDepth(scip) < 1 && !SCIPinRepropagation(scip) && v == consdata->nvars
6484  && addartconss && !SCIPisHugeValue(scip, -minact) && !SCIPisHugeValue(scip, maxact) )
6485  {
6486  SCIP_CONS* newcons;
6487  char name[SCIP_MAXSTRLEN];
6488  SCIP_Real newlhs;
6489  SCIP_Real newrhs;
6490 
6491  assert(maxact > minact);
6492  assert(w == ninfcheckvars);
6493 
6494  newlhs = lhs - maxact;
6495  newrhs = rhs - minact;
6496  assert(newlhs < newrhs);
6497 
6498  /* create, add, and release new artificial constraint */
6499  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons2_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6500  ++conshdlrdata->naddconss;
6501 
6502  SCIPdebugMessage("adding artificial constraint %s\n", name);
6503 
6504  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6505  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6506  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6507 
6508  SCIPdebugPrintCons(scip, newcons, NULL);
6509  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6510 
6511  ++(*naddconss);
6512  }
6513  }
6514 
6515  TERMINATE:
6516  SCIPfreeBufferArray(scip, &infcheckvals);
6517  SCIPfreeBufferArray(scip, &infcheckvars);
6518 
6519  consdata->rangedrowpropagation = TRUE;
6520 
6521  return SCIP_OKAY;
6522 }
6523 
6524 /** tightens bounds of a single variable due to activity bounds */
6525 static
6527  SCIP* scip, /**< SCIP data structure */
6528  SCIP_CONS* cons, /**< linear constraint */
6529  int pos, /**< position of the variable in the vars array */
6530  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
6531  int* nchgbds, /**< pointer to count the total number of tightened bounds */
6532  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
6533  )
6534 {
6535  SCIP_CONSDATA* consdata;
6536  SCIP_VAR* var;
6537  SCIP_Real val;
6538  SCIP_Real lb;
6539  SCIP_Real ub;
6540  SCIP_Real minresactivity;
6541  SCIP_Real maxresactivity;
6543  SCIP_Real rhs;
6544  SCIP_Bool infeasible;
6545  SCIP_Bool tightened;
6546  SCIP_Bool minisrelax;
6547  SCIP_Bool maxisrelax;
6548  SCIP_Bool isminsettoinfinity;
6549  SCIP_Bool ismaxsettoinfinity;
6550 
6551  assert(scip != NULL);
6552  assert(cons != NULL);
6553  assert(cutoff != NULL);
6554  assert(nchgbds != NULL);
6555 
6556  /* we cannot tighten variables' bounds, if the constraint may be not complete */
6557  if( SCIPconsIsModifiable(cons) )
6558  return SCIP_OKAY;
6559 
6560  consdata = SCIPconsGetData(cons);
6561  assert(consdata != NULL);
6562  assert(0 <= pos && pos < consdata->nvars);
6563 
6564  *cutoff = FALSE;
6565 
6566  var = consdata->vars[pos];
6567 
6568  /* we cannot tighten bounds of multi-aggregated variables */
6570  return SCIP_OKAY;
6571 
6572  val = consdata->vals[pos];
6573  lhs = consdata->lhs;
6574  rhs = consdata->rhs;
6575  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
6576  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
6577  assert(var != NULL);
6578  assert(!SCIPisZero(scip, val));
6579  assert(!SCIPisInfinity(scip, lhs));
6580  assert(!SCIPisInfinity(scip, -rhs));
6581 
6582  lb = SCIPvarGetLbLocal(var);
6583  ub = SCIPvarGetUbLocal(var);
6584  assert(SCIPisLE(scip, lb, ub));
6585 
6586  if( val > 0.0 )
6587  {
6588  /* check, if we can tighten the variable's bounds */
6589  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6590  {
6591  SCIP_Real newub;
6592 
6593  newub = (rhs - minresactivity)/val;
6594 
6595  if( !SCIPisInfinity(scip, newub) &&
6596  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
6597  {
6598  SCIP_Bool activityunreliable;
6599  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6600 
6601  /* check minresactivities for reliability */
6602  if( activityunreliable )
6603  {
6604  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6605  newub = (rhs - minresactivity)/val;
6606  activityunreliable = SCIPisInfinity(scip, -minresactivity) ||
6607  (!SCIPisUbBetter(scip, newub, lb, ub) && (!SCIPisFeasLT(scip, newub, ub) || !SCIPvarIsIntegral(var))
6608  && (!force || !SCIPisLT(scip, newub, ub)));
6609  }
6610 
6611  if( !activityunreliable )
6612  {
6613  /* tighten upper bound */
6614  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
6615  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
6616  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6617  &infeasible, &tightened) );
6618  if( infeasible )
6619  {
6620  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6621  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
6622 
6623  /* analyze conflict */
6624  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6625 
6626  *cutoff = TRUE;
6627  return SCIP_OKAY;
6628  }
6629  if( tightened )
6630  {
6631  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6632  assert(SCIPisFeasLE(scip, ub, newub));
6633  (*nchgbds)++;
6634 
6635  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6636  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6637  }
6638  }
6639  }
6640  }
6641 
6642  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
6643  {
6644  SCIP_Real newlb;
6645 
6646  newlb = (lhs - maxresactivity)/val;
6647  if( !SCIPisInfinity(scip, -newlb) &&
6648  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6649  {
6650  /* check maxresactivities for reliability */
6651  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
6652  {
6653  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
6654  newlb = (lhs - maxresactivity)/val;
6655 
6656  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisLbBetter(scip, newlb, lb, ub)
6657  && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6658  && (!force || !SCIPisGT(scip, newlb, lb))) )
6659  return SCIP_OKAY;
6660  }
6661 
6662  /* tighten lower bound */
6663  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6664  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6665  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_LHS, pos), force,
6666  &infeasible, &tightened) );
6667  if( infeasible )
6668  {
6669  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6670  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6671 
6672  /* analyze conflict */
6673  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
6674 
6675  *cutoff = TRUE;
6676  return SCIP_OKAY;
6677  }
6678  if( tightened )
6679  {
6680  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6681  assert(SCIPisFeasGE(scip, lb, newlb));
6682  (*nchgbds)++;
6683  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6684  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6685  }
6686  }
6687  }
6688  }
6689  else
6690  {
6691  /* check, if we can tighten the variable's bounds */
6692  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6693  {
6694  SCIP_Real newlb;
6695 
6696  newlb = (rhs - minresactivity)/val;
6697  if( !SCIPisInfinity(scip, -newlb) &&
6698  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6699  {
6700  SCIP_Bool activityunreliable;
6701  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6702  /* check minresactivities for reliability */
6703  if( activityunreliable )
6704  {
6705  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6706  newlb = (rhs - minresactivity)/val;
6707 
6708  activityunreliable = SCIPisInfinity(scip, -minresactivity)
6709  || (!SCIPisLbBetter(scip, newlb, lb, ub) && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6710  && (!force || !SCIPisGT(scip, newlb, lb)));
6711  }
6712 
6713  if( !activityunreliable )
6714  {
6715  /* tighten lower bound */
6716  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6717  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6718  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6719  &infeasible, &tightened) );
6720  if( infeasible )
6721  {
6722  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6723  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6724 
6725  /* analyze conflict */
6726  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6727 
6728  *cutoff = TRUE;
6729  return SCIP_OKAY;
6730  }
6731  if( tightened )
6732  {
6733  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6734  assert(SCIPisFeasGE(scip, lb, newlb));
6735  (*nchgbds)++;
6736  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6737  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6738  }
6739  }
6740  }
6741  }
6742 
6743  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
6744  {
6745  SCIP_Real newub;
6746 
6747  newub = (lhs - maxresactivity)/val;
6748  if( !SCIPisInfinity(scip, newub) &&
6749  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
6750  {
6751  /* check maxresactivities for reliability */
6752  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
6753  {
6754  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
6755  newub = (lhs - maxresactivity)/val;
6756 
6757  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisUbBetter(scip, newub, lb, ub)
6758  && (!SCIPisFeasLT(scip, newub, ub) && !SCIPvarIsIntegral(var))
6759  && (!force || !SCIPisLT(scip, newub, ub))) )
6760  return SCIP_OKAY;
6761  }
6762 
6763  /* tighten upper bound */
6764  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g], newub=%.15g\n",
6765  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
6766  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_LHS, pos), force,
6767  &infeasible, &tightened) );
6768  if( infeasible )
6769  {
6770  SCIPdebugMessage("linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6771  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
6772 
6773  /* analyze conflict */
6774  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
6775 
6776  *cutoff = TRUE;
6777  return SCIP_OKAY;
6778  }
6779  if( tightened )
6780  {
6781  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6782  assert(SCIPisFeasLE(scip, ub, newub));
6783  (*nchgbds)++;
6784  SCIPdebugMessage("linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6785  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6786  }
6787  }
6788  }
6789  }
6790 
6791  return SCIP_OKAY;
6792 }
6793 
6794 #define MAXTIGHTENROUNDS 10
6795 
6796 /** tightens bounds of variables in constraint due to activity bounds */
6797 static
6799  SCIP* scip, /**< SCIP data structure */
6800  SCIP_CONS* cons, /**< linear constraint */
6801  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
6802  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
6803  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
6804  int* nchgbds /**< pointer to count the total number of tightened bounds */
6805  )
6806 {
6807  SCIP_CONSDATA* consdata;
6808  int nvars;
6809  int nrounds;
6810  int lastchange;
6811  int oldnchgbds;
6812  int v;
6813  SCIP_Bool force;
6814  SCIP_Bool easycase;
6815 
6816  assert(scip != NULL);
6817  assert(cons != NULL);
6818  assert(nchgbds != NULL);
6819  assert(cutoff != NULL);
6820 
6821  *cutoff = FALSE;
6822 
6823  /* we cannot tighten variables' bounds, if the constraint may be not complete */
6824  if( SCIPconsIsModifiable(cons) )
6825  return SCIP_OKAY;
6826 
6827  /* if a constraint was created after presolve, then it may hold fixed variables
6828  * if there are even multi-aggregated variables, then we cannot do bound tightening on these
6829  * thus, ensure here again that variable fixings have been applied
6830  */
6831  SCIP_CALL( applyFixings(scip, cons, cutoff) );
6832  if( *cutoff )
6833  return SCIP_OKAY;
6834 
6835  /* check if constraint has any chances of tightening bounds */
6836  if( !canTightenBounds(scip, cons) )
6837  return SCIP_OKAY;
6838 
6839  consdata = SCIPconsGetData(cons);
6840  assert(consdata != NULL);
6841 
6842  nvars = consdata->nvars;
6843  force = (nvars == 1) && !SCIPconsIsModifiable(cons);
6844 
6845  /* ensure that the variables are properly sorted */
6846  if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->binvarssorted )
6847  {
6848  SCIP_CALL( consdataSort(scip, consdata) );
6849  assert(consdata->binvarssorted);
6850  }
6851 
6852  /* update maximal activity delta if necessary */
6853  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
6854  consdataRecomputeMaxActivityDelta(scip, consdata);
6855 
6856  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
6857  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
6858  checkMaxActivityDelta(scip, consdata);
6859 
6860  /* this may happen if all variables are fixed */
6861  if( SCIPisFeasZero(scip, consdata->maxactdelta) )
6862  return SCIP_OKAY;
6863 
6864  if( !SCIPisInfinity(scip, consdata->maxactdelta) )
6865  {
6866  SCIP_Real slack;
6867  SCIP_Real surplus;
6868  SCIP_Real minactivity;
6869  SCIP_Real maxactivity;
6870  SCIP_Bool minisrelax;
6871  SCIP_Bool maxisrelax;
6872 
6873  /* use maximal activity delta to skip propagation (cannot deduce anything) */
6874  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minisrelax, &maxisrelax);
6875  assert(!SCIPisInfinity(scip, minactivity));
6876  assert(!SCIPisInfinity(scip, -maxactivity));
6877 
6878  slack = (SCIPisInfinity(scip, consdata->rhs) || SCIPisInfinity(scip, -minactivity)) ? SCIPinfinity(scip) : (consdata->rhs - minactivity);
6879  surplus = (SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, maxactivity)) ? SCIPinfinity(scip) : (maxactivity - consdata->lhs);
6880 
6881  /* check if the constraint will propagate */
6882  if( SCIPisLE(scip, consdata->maxactdelta, MIN(slack, surplus)) )
6883  return SCIP_OKAY;
6884  }
6885 
6886  /* check if we can use fast implementation for easy and numerically well behaved cases */
6887  easycase = SCIPisLT(scip, consdata->maxactdelta, maxeasyactivitydelta);
6888 
6889  /* as long as the bounds might be tightened again, try to tighten them; abort after a maximal number of rounds */
6890  lastchange = -1;
6891  for( nrounds = 0; (force || !consdata->boundstightened) && nrounds < MAXTIGHTENROUNDS; ++nrounds )
6892  {
6893  /* mark the constraint to have the variables' bounds tightened */
6894  consdata->boundstightened = TRUE;
6895 
6896  /* try to tighten the bounds of each variable in the constraint. During solving process, the binary variable
6897  * sorting enables skipping variables
6898  */
6899  v = 0;
6900  while( v < nvars && v != lastchange && !(*cutoff) )
6901  {
6902  oldnchgbds = *nchgbds;
6903 
6904  assert(!sortvars || SCIPgetStage(scip) < SCIP_STAGE_SOLVING || consdata->binvarssorted);
6905 
6906  if( easycase )
6907  {
6908  SCIP_CALL( tightenVarBoundsEasy(scip, cons, v, cutoff, nchgbds, force) );
6909  }
6910  else
6911  {
6912  SCIP_CALL( tightenVarBounds(scip, cons, v, cutoff, nchgbds, force) );
6913  }
6914 
6915  /* if there was no progress, skip the rest of the binary variables */
6916  if( *nchgbds > oldnchgbds )
6917  {
6918  lastchange = v;
6919  ++v;
6920  }
6921  else if( consdata->binvarssorted && v < consdata->nbinvars - 1
6922  && !SCIPisFeasEQ(scip, SCIPvarGetUbLocal(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v])) )
6923  v = consdata->nbinvars;
6924  else
6925  ++v;
6926  }
6927  }
6928 
6929 #ifndef NDEBUG
6930  if( force && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
6931  assert(*cutoff || SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->vars[0]), SCIPvarGetUbLocal(consdata->vars[0])));
6932 #endif
6933 
6934  return SCIP_OKAY;
6935 }
6936 
6937 /** checks linear constraint for feasibility of given solution or current solution */
6938 static
6940  SCIP* scip, /**< SCIP data structure */
6941  SCIP_CONS* cons, /**< linear constraint */
6942  SCIP_SOL* sol, /**< solution to be checked, or NULL for current solution */
6943  SCIP_Bool checklprows, /**< has linear constraint to be checked, if it is already in current LP? */
6944  SCIP_Bool checkrelmaxabs, /**< should the violation for a constraint with side 0.0 be checked relative
6945  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
6946  SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
6947  )
6948 {
6949  SCIP_CONSDATA* consdata;
6950  SCIP_Real activity;
6951 
6952  assert(scip != NULL);
6953  assert(cons != NULL);
6954  assert(violated != NULL);
6956  SCIPdebugMessage("checking linear constraint <%s>\n", SCIPconsGetName(cons));
6957  SCIPdebugPrintCons(scip, cons, NULL);
6958 
6959  consdata = SCIPconsGetData(cons);
6960  assert(consdata != NULL);
6961 
6962  *violated = FALSE;
6963 
6964  if( consdata->row != NULL )
6965  {
6966  if( !checklprows && SCIProwIsInLP(consdata->row) )
6967  return SCIP_OKAY;
6968  else if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
6969  activity = consdataComputePseudoActivity(scip, consdata);
6970  else
6971  activity = SCIPgetRowSolActivity(scip, consdata->row, sol);
6972  }
6973  else
6974  activity = consdataGetActivity(scip, consdata, sol);
6975 
6976  SCIPdebugMessage(" consdata activity=%.15g (lhs=%.15g, rhs=%.15g, row=%p, checklprows=%u, rowinlp=%u, sol=%p, hascurrentnodelp=%u)\n",
6977  activity, consdata->lhs, consdata->rhs, (void*)consdata->row, checklprows,
6978  consdata->row == NULL ? 0 : SCIProwIsInLP(consdata->row), (void*)sol,
6979  consdata->row == NULL ? FALSE : SCIPhasCurrentNodeLP(scip));
6980 
6981  /* the activity of pseudo solutions may be invalid if it comprises positive and negative infinity contributions; we
6982  * return infeasible for safety
6983  */
6984  if( activity == SCIP_INVALID ) /*lint !e777*/
6985  {
6986  assert(sol == NULL);
6987  *violated = TRUE;
6988 
6989  /* reset constraint age since we are in enforcement */
6990  SCIP_CALL( SCIPresetConsAge(scip, cons) );
6991  }
6992  else if( SCIPisFeasLT(scip, activity, consdata->lhs) || SCIPisFeasGT(scip, activity, consdata->rhs) )
6993  {
6994  /* the "normal" check: one of the two sides is violated */
6995  if( !checkrelmaxabs )
6996  {
6997  *violated = TRUE;
6998 
6999  /* only reset constraint age if we are in enforcement */
7000  if( sol == NULL )
7001  {
7002  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7003  }
7004  }
7005  /* the (much) more complicated check: we try to disregard random noise and violations of a 0.0 side which are
7006  * small compared to the absolute values occuring in the activity
7007  */
7008  else
7009  {
7010  SCIP_Real maxabs;
7011  SCIP_Real coef;
7012  SCIP_Real absval;
7013  SCIP_Real solval;
7014  int v;
7015 
7016  maxabs = 1.0;
7017 
7018  /* compute maximum absolute value */
7019  for( v = 0; v < consdata->nvars; ++v )
7020  {
7021  if( consdata->vals != NULL )
7022  {
7023  coef = consdata->vals[v];
7024  }
7025  else
7026  coef = 1.0;
7027 
7028  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
7029  absval = REALABS( coef * solval );
7030  maxabs = MAX( maxabs, absval );
7031  }
7032 
7033  /* regard left hand side, first */
7034  if( SCIPisFeasLT(scip, activity, consdata->lhs) )
7035  {
7036  /* check whether violation is random noise */
7037  if( (consdata->lhs - activity) <= (1e-15 * maxabs) )
7038  {
7039  SCIPdebugMessage(" lhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7040  consdata->lhs - activity, maxabs);
7041  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
7042 
7043  /* only increase constraint age if we are in enforcement */
7044  if( sol == NULL )
7045  {
7046  SCIP_CALL( SCIPincConsAge(scip, cons) );
7047  }
7048  }
7049  /* lhs is violated and lhs is 0.0: use relative tolerance w.r.t. largest absolute value */
7050  else if( SCIPisZero(scip, consdata->lhs) )
7051  {
7052  if( (consdata->lhs - activity) <= (SCIPfeastol(scip) * maxabs) )
7053  {
7054  SCIPdebugMessage(" lhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7055  consdata->lhs - activity, maxabs);
7056  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
7057 
7058  /* only increase constraint age if we are in enforcement */
7059  if( sol == NULL )
7060  {
7061  SCIP_CALL( SCIPincConsAge(scip, cons) );
7062  }
7063  }
7064  else
7065  {
7066  *violated = TRUE;
7067 
7068  /* only reset constraint age if we are in enforcement */
7069  if( sol == NULL )
7070  {
7071  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7072  }
7073  }
7074  }
7075  else
7076  {
7077  *violated = TRUE;
7078 
7079  /* only reset constraint age if we are in enforcement */
7080  if( sol == NULL )
7081  {
7082  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7083  }
7084  }
7085  }
7086 
7087  /* now regard right hand side */
7088  if( SCIPisFeasGT(scip, activity, consdata->rhs) )
7089  {
7090  /* check whether violation is random noise */
7091  if( (activity - consdata->rhs) <= (1e-15 * maxabs) )
7092  {
7093  SCIPdebugMessage(" rhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7094  activity - consdata->rhs, maxabs);
7095  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
7096 
7097  /* only increase constraint age if we are in enforcement */
7098  if( sol == NULL )
7099  {
7100  SCIP_CALL( SCIPincConsAge(scip, cons) );
7101  }
7102  }
7103  /* rhs is violated and rhs is 0.0, use relative tolerance w.r.t. largest absolute value */
7104  else if( SCIPisZero(scip, consdata->rhs) )
7105  {
7106  if( (activity - consdata->rhs) <= (SCIPfeastol(scip) * maxabs) )
7107  {
7108  SCIPdebugMessage(" rhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7109  activity - consdata->rhs, maxabs);
7110  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
7111 
7112  /* only increase constraint age if we are in enforcement */
7113  if( sol == NULL )
7114  {
7115  SCIP_CALL( SCIPincConsAge(scip, cons) );
7116  }
7117  }
7118  else
7119  {
7120  *violated = TRUE;
7121 
7122  /* only reset constraint age if we are in enforcement */
7123  if( sol == NULL )
7124  {
7125  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7126  }
7127  }
7128  }
7129  else
7130  {
7131  *violated = TRUE;
7132 
7133  /* only reset constraint age if we are in enforcement */
7134  if( sol == NULL )
7135  {
7136  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7137  }
7138  }
7139  }
7140  }
7141  }
7142  else
7143  {
7144  /* only increase constraint age if we are in enforcement */
7145  if( sol == NULL )
7146  {
7147  SCIP_CALL( SCIPincConsAge(scip, cons) );
7148  }
7149  }
7150 
7151  return SCIP_OKAY;
7152 }
7153 
7154 /** creates an LP row in a linear constraint data */
7155 static
7157  SCIP* scip, /**< SCIP data structure */
7158  SCIP_CONS* cons /**< linear constraint */
7159  )
7160 {
7161  SCIP_CONSDATA* consdata;
7162 
7163  assert(scip != NULL);
7164  assert(cons != NULL);
7165 
7166  consdata = SCIPconsGetData(cons);
7167  assert(consdata != NULL);
7168  assert(consdata->row == NULL);
7169 
7170  SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, SCIPconsGetHdlr(cons), SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
7173  SCIP_CALL( SCIPaddVarsToRow(scip, consdata->row, consdata->nvars, consdata->vars, consdata->vals) );
7174 
7175  return SCIP_OKAY;
7176 }
7177 
7178 /** adds linear constraint as cut to the LP */
7179 static
7181  SCIP* scip, /**< SCIP data structure */
7182  SCIP_CONS* cons, /**< linear constraint */
7183  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
7184  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7185  )
7186 {
7187  SCIP_CONSDATA* consdata;
7188 
7189  assert(scip != NULL);
7190  assert(cons != NULL);
7191 
7192  consdata = SCIPconsGetData(cons);
7193  assert(consdata != NULL);
7194 
7195  if( consdata->row == NULL )
7196  {
7197  /* convert consdata object into LP row */
7198  SCIP_CALL( createRow(scip, cons) );
7199  }
7200  assert(consdata->row != NULL);
7201 
7202  /* insert LP row as cut */
7203  if( !SCIProwIsInLP(consdata->row) )
7204  {
7205  SCIPdebugMessage("adding relaxation of linear constraint <%s>: ", SCIPconsGetName(cons));
7206  SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->row, NULL)) );
7207  /* if presolving is turned off, the row might be trivial */
7208  if ( ! SCIPisInfinity(scip, -consdata->lhs) || ! SCIPisInfinity(scip, consdata->rhs) )
7209  {
7210  SCIP_CALL( SCIPaddCut(scip, sol, consdata->row, FALSE, cutoff) );
7211  }
7212 #ifndef NDEBUG
7213  else
7214  {
7215  int pr;
7216  int cr;
7217  SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrounds", &pr) );
7218  SCIP_CALL( SCIPgetIntParam(scip, "constraints/linear/maxprerounds", &cr) );
7219  assert( pr == 0 || cr == 0 );
7220  }
7221 #endif
7222  }
7223 
7224  return SCIP_OKAY;
7225 }
7226 
7227 /** separates linear constraint: adds linear constraint as cut, if violated by given solution */
7228 static
7230  SCIP* scip, /**< SCIP data structure */
7231  SCIP_CONS* cons, /**< linear constraint */
7232  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
7233  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
7234  SCIP_Bool separatecards, /**< should knapsack cardinality cuts be generated? */
7235  SCIP_Bool separateall, /**< should all constraints be subject to cardinality cut generation instead of only
7236  * the ones with non-zero dual value? */
7237  int* ncuts, /**< pointer to add up the number of found cuts */
7238  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7239  )
7240 {
7241  SCIP_CONSDATA* consdata;
7242  SCIP_Bool violated;
7243  int oldncuts;
7244 
7245  assert(scip != NULL);
7246  assert(conshdlrdata != NULL);
7247  assert(cons != NULL);
7248  assert(cutoff != NULL);
7249 
7250  consdata = SCIPconsGetData(cons);
7251  assert(ncuts != NULL);
7252  assert(consdata != NULL);
7253 
7254  oldncuts = *ncuts;
7255  *cutoff = FALSE;
7256 
7257  SCIP_CALL( checkCons(scip, cons, sol, (sol != NULL), conshdlrdata->checkrelmaxabs, &violated) );
7258 
7259  if( violated )
7260  {
7261  /* insert LP row as cut */
7262  SCIP_CALL( addRelaxation(scip, cons, sol, cutoff) );
7263  (*ncuts)++;
7264  }
7265  else if( !SCIPconsIsModifiable(cons) && separatecards )
7266  {
7267  /* relax linear constraint into knapsack constraint and separate lifted cardinality cuts */
7268  if( !separateall && sol == NULL )
7269  {
7270  /* we only want to call the knapsack cardinality cut separator for rows that have a non-zero dual solution */
7271  if( consdata->row != NULL && SCIProwIsInLP(consdata->row) )
7272  {
7273  SCIP_Real dualsol;
7274 
7275  dualsol = SCIProwGetDualsol(consdata->row);
7276  if( SCIPisFeasNegative(scip, dualsol) )
7277  {
7278  if( !SCIPisInfinity(scip, consdata->rhs) )
7279  {
7280  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7281  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7282  }
7283  }
7284  else if( SCIPisFeasPositive(scip, dualsol) )
7285  {
7286  if( !SCIPisInfinity(scip, -consdata->lhs) )
7287  {
7288  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7289  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7290  }
7291  }
7292  }
7293  }
7294  else
7295  {
7296  if( !SCIPisInfinity(scip, consdata->rhs) )
7297  {
7298  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7299  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7300  }
7301  if( !SCIPisInfinity(scip, -consdata->lhs) )
7302  {
7303  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7304  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7305  }
7306  }
7307  }
7308 
7309  if( *ncuts > oldncuts )
7310  {
7311  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7312  }
7313 
7314  return SCIP_OKAY;
7315 }
7316 
7317 /** propagation method for linear constraints */
7318 static
7320  SCIP* scip, /**< SCIP data structure */
7321  SCIP_CONS* cons, /**< linear constraint */
7322  SCIP_Bool tightenbounds, /**< should the variable's bounds be tightened? */
7323  SCIP_Bool rangedrowpropagation,/**< should ranged row propagation be performed? */
7324  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7325  SCIP_Bool sortvars, /**< should variable sorting for faster propagation be used? */
7326  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
7327  int* nchgbds /**< pointer to count the total number of tightened bounds */
7328  )
7329 {
7330  SCIP_CONSDATA* consdata;
7331  SCIP_Real minactivity;
7332  SCIP_Real maxactivity;
7333  SCIP_Bool minactisrelax;
7334  SCIP_Bool maxactisrelax;
7336  assert(scip != NULL);
7337  assert(cons != NULL);
7338  assert(cutoff != NULL);
7339  assert(nchgbds != NULL);
7340 
7341  /*SCIPdebugMessage("propagating linear constraint <%s>\n", SCIPconsGetName(cons));*/
7342 
7343  consdata = SCIPconsGetData(cons);
7344  assert(consdata != NULL);
7345 
7346  *cutoff = FALSE;
7347 
7348  /* check, if constraint is already propagated */
7349  if( consdata->propagated && (!tightenbounds || consdata->boundstightened) )
7350  return SCIP_OKAY;
7351 
7352  /* mark constraint as propagated */
7353  consdata->propagated = TRUE;
7354 
7355  /* we can only infer activity bounds of the linear constraint, if it is not modifiable */
7356  if( !SCIPconsIsModifiable(cons) )
7357  {
7358  /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
7359  if( !SCIPinRepropagation(scip) )
7360  {
7361  SCIP_CALL( SCIPincConsAge(scip, cons) );
7362  }
7363 
7364  /* tighten the variable's bounds */
7365  if( tightenbounds )
7366  {
7367  int oldnchgbds;
7368 
7369  oldnchgbds = *nchgbds;
7370 
7371  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7372 
7373  if( *nchgbds > oldnchgbds )
7374  {
7375  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7376  }
7377  }
7378 
7379  /* propagate ranged rows */
7380  if( rangedrowpropagation && tightenbounds && !(*cutoff) )
7381  {
7382  int nfixedvars;
7383  int naddconss;
7384  int oldnchgbds;
7385 
7386  nfixedvars = 0;
7387  naddconss = 0;
7388  oldnchgbds = *nchgbds;
7389 
7390  SCIP_CALL( rangedRowPropagation(scip, cons, cutoff, &nfixedvars, nchgbds, &naddconss) );
7391 
7392  if( *cutoff )
7393  {
7394  SCIPdebugMessage("linear constraint <%s> is infeasible\n", SCIPconsGetName(cons));
7395  }
7396  else
7397  {
7398  SCIPdebugMessage("linear constraint <%s> found %d bound changes and %d fixings\n", SCIPconsGetName(cons), *nchgbds - oldnchgbds, nfixedvars);
7399  }
7400 
7401  if( nfixedvars > 0 )
7402  *nchgbds += 2*nfixedvars;
7403  }
7404 
7405  /* check constraint for infeasibility and redundancy */
7406  if( !(*cutoff) )
7407  {
7408  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
7409 
7410  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) )
7411  {
7412  SCIPdebugMessage("linear constraint <%s> is infeasible (rhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7413  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7414 
7415  /* analyze conflict */
7416  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
7417 
7418  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7419  *cutoff = TRUE;
7420  }
7421  else if( SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
7422  {
7423  SCIPdebugMessage("linear constraint <%s> is infeasible (lhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7424  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7425 
7426  /* analyze conflict */
7427  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7428 
7429  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7430  *cutoff = TRUE;
7431  }
7432  else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
7433  {
7434  SCIPdebugMessage("linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7435  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7436  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
7437  }
7438  }
7439  }
7440 
7441  return SCIP_OKAY;
7442 }
7443 
7444 
7445 /*
7446  * Presolving methods
7447  */
7448 
7449 /** converts all variables with fixed domain into FIXED variables */
7450 static
7452  SCIP* scip, /**< SCIP data structure */
7453  SCIP_CONS* cons, /**< linear constraint */
7454  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
7455  int* nfixedvars /**< pointer to count the total number of fixed variables */
7456  )
7457 {
7458  SCIP_CONSDATA* consdata;
7459  SCIP_VAR* var;
7460  SCIP_VARSTATUS varstatus;
7461  SCIP_Real lb;
7462  SCIP_Real ub;
7463  SCIP_Bool fixed;
7464  SCIP_Bool infeasible;
7465  int v;
7466 
7467  assert(scip != NULL);
7468  assert(cons != NULL);
7469  assert(cutoff != NULL);
7470  assert(nfixedvars != NULL);
7471 
7472  consdata = SCIPconsGetData(cons);
7473  assert(consdata != NULL);
7474 
7475  for( v = 0; v < consdata->nvars; ++v )
7476  {
7477  assert(consdata->vars != NULL);
7478  var = consdata->vars[v];
7479  varstatus = SCIPvarGetStatus(var);
7480 
7481  if( varstatus != SCIP_VARSTATUS_FIXED )
7482  {
7483  lb = SCIPvarGetLbGlobal(var);
7484  ub = SCIPvarGetUbGlobal(var);
7485  if( SCIPisEQ(scip, lb, ub) )
7486  {
7487  SCIP_Real fixval;
7488 
7489  fixval = SCIPselectSimpleValue(lb - 0.9 * SCIPepsilon(scip), ub + 0.9 * SCIPepsilon(scip), MAXDNOM);
7490  SCIPdebugMessage("converting variable <%s> with fixed bounds [%.15g,%.15g] into fixed variable fixed at %.15g\n",
7491  SCIPvarGetName(var), lb, ub, fixval);
7492  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
7493  if( infeasible )
7494  {
7495  SCIPdebugMessage(" -> infeasible fixing\n");
7496  *cutoff = TRUE;
7497  return SCIP_OKAY;
7498  }
7499  if( fixed )
7500  (*nfixedvars)++;
7501  }
7502  }
7503  }
7504 
7505  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
7506 
7507  if( infeasible )
7508  {
7509  SCIPdebugMessage(" -> infeasible fixing\n");
7510  *cutoff = TRUE;
7511  return SCIP_OKAY;
7512  }
7513 
7514  assert(consdata->removedfixings);
7515 
7516  return SCIP_OKAY;
7517 }
7518 
7519 #define MAX_CLIQUE_NONZEROS_PER_CONS 1000000
7520 
7521 /** extracts cliques of the constraint and adds them to SCIP
7522  *
7523  * The following clique extraction mechanism are implemeneted
7524  *
7525  * 1. collect binary variables and sort them in non increasing order, then
7526  *
7527  * a) if the constraint has a finite right hand side and the negative infinity counters for the minactivity are zero
7528  * then add the variables as a clique for which all successive pairs of coefficients fullfill the following
7529  * condition
7530  *
7531  * minactivity + vals[i] + vals[i+1] > rhs
7532  *
7533  * and also add the binary to binary implication also for non-successive variables for which the same argument
7534  * holds
7535  *
7536  * minactivity + vals[i] + vals[j] > rhs
7537  *
7538  * 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
7539  * binary to binary implications x1 = 1 => x4 = 0 and x2 = 1 => x4 = 0
7540  *
7541  * b) if the constraint has a finite left hand side and the positive infinity counters for the maxactivity are zero
7542  * then add the variables as a clique for which all successive pairs of coefficients fullfill the follwoing
7543  * condition
7544  *
7545  * maxactivity + vals[i] + vals[i-1] < lhs
7546  *
7547  * and also add the binary to binary implication also for non-successive variables for which the same argument
7548  * holds
7549  *
7550  * maxactivity + vals[i] + vals[j] < lhs
7551  *
7552  * e.g. you could multiply the above example by -1
7553  *
7554  * c) the constraint has a finite right hand side and a finite minactivity then add the variables as a negated
7555  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7556  * condition
7557  *
7558  * minactivity - vals[i] - vals[i-1] > rhs
7559  *
7560  * and also add the binary to binary implication also for non-successive variables for which the
7561  * same argument holds
7562  *
7563  * minactivity - vals[i] - vals[j] > rhs
7564  *
7565  * e.g. -4 x1 -3 x2 - 2 x3 + 2 x4 <= -4 would lead to the (negated) clique (~x1, ~x2) and the binary to binary
7566  * implication x1 = 0 => x3 = 1
7567  *
7568  * d) the constraint has a finite left hand side and a finite maxactivity then add the variables as a negated
7569  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7570  * condition
7571  *
7572  * maxactivity - vals[i] - vals[i+1] < lhs
7573  *
7574  * and also add the binary to binary implication also for non-successive variables for which the same argument
7575  * holds
7576  *
7577  * maxactivity - vals[i] - vals[j] < lhs
7578  *
7579  * e.g. you could multiply the above example by -1
7580  *
7581  * 2. if the linear constraint represents a set-packing or set-partitioning constraint, the whole constraint is added
7582  * as clique, (this part is done at the end of the method)
7583  *
7584  */
7585 static
7587  SCIP* scip, /**< SCIP data structure */
7588  SCIP_CONS* cons, /**< linear constraint */
7589  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7590  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
7591  int* nfixedvars, /**< pointer to count number of fixed variables */
7592  int* nchgbds, /**< pointer to count the total number of tightened bounds */
7593  SCIP_Bool* cutoff /**< pointer to store TRUE, if a cutoff was found */
7594  )
7595 {
7596  SCIP_VAR** vars;
7597  SCIP_Real* vals;
7598  SCIP_CONSDATA* consdata;
7599  SCIP_Bool lhsclique;
7600  SCIP_Bool rhsclique;
7601  SCIP_Bool finitelhs;
7602  SCIP_Bool finiterhs;
7603  SCIP_Bool finiteminact;
7604  SCIP_Bool finitemaxact;
7605  SCIP_Bool finitenegminact;
7606  SCIP_Bool finitenegmaxact;
7607  SCIP_Bool finiteposminact;
7608  SCIP_Bool finiteposmaxact;
7609  SCIP_Bool infeasible;
7610  SCIP_Bool stopped;
7611  int cliquenonzerosadded;
7612  int v;
7613  int i;
7614  int nposcoefs;
7615  int nnegcoefs;
7616  int nvars;
7617 
7618  assert(scip != NULL);
7619  assert(cons != NULL);
7620  assert(nfixedvars != NULL);
7621  assert(nchgbds != NULL);
7622  assert(cutoff != NULL);
7623  assert(!SCIPconsIsDeleted(cons));
7624 
7625  consdata = SCIPconsGetData(cons);
7626  assert(consdata != NULL);
7627 
7628  if( consdata->nvars < 2 )
7629  return SCIP_OKAY;
7630 
7631  /* add implications if posibble
7632  *
7633  * for now we only add binary to non-binary implications, and this is only done for the binary variable with the
7634  * maximal absolute contribution and also only if this variable would force all other variables to their bound
7635  * corresponding to the global minimal activity of the constraint
7636  */
7637  if( !consdata->implsadded )
7638  {
7639  /* sort variables by variable type */
7640  SCIP_CALL( consdataSort(scip, consdata) );
7641 
7642  /* @todo we might extract implications/cliques if SCIPvarIsBinary() variables exist and we have integer variables
7643  * up front, might change sorting correspondingly
7644  */
7645  /* fast abort if no binaries exist */
7646  if( !SCIPvarIsBinary(consdata->vars[0]) )
7647  return SCIP_OKAY;
7648 
7649  nvars = consdata->nvars;
7650  vars = consdata->vars;
7651  vals = consdata->vals;
7652 
7653  /* recompute activities if needed */
7654  if( !consdata->validactivities )
7655  consdataCalcActivities(scip, consdata);
7656  assert(consdata->validactivities);
7657 
7658  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
7659  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
7660  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
7661  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
7662  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
7663  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
7664  finiteminact = (finitenegminact && finiteposminact);
7665  finitemaxact = (finitenegmaxact && finiteposmaxact);
7666 
7667  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
7668  {
7669  SCIP_Real maxabscontrib = -1.0;
7670  SCIP_Bool posval = FALSE;
7671  SCIP_Bool allbinary = TRUE;
7672  int oldnchgbds = *nchgbds;
7673  int nbdchgs = 0;
7674  int nimpls = 0;
7675  int position = -1;
7676 
7677  /* we need a valid minimal/maximal activity to add cliques */
7678  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
7679  {
7680  consdataRecomputeGlbMinactivity(scip, consdata);
7681  assert(consdata->validglbminact);
7682  }
7683 
7684  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
7685  {
7686  consdataRecomputeGlbMaxactivity(scip, consdata);
7687  assert(consdata->validglbmaxact);
7688  }
7689  assert(consdata->validglbminact || consdata->validglbmaxact);
7690 
7691  /* @todo extend this to local/constraint probing */
7692 
7693  /* determine maximal contribution to the activity */
7694  for( v = nvars - 1; v >= 0; --v )
7695  {
7696  if( SCIPvarIsBinary(vars[v]) )
7697  {
7698  if( vals[v] > 0 )
7699  {
7700  SCIP_Real value = vals[v] * SCIPvarGetUbGlobal(vars[v]);
7701 
7702  if( value > maxabscontrib )
7703  {
7704  maxabscontrib = value;
7705  position = v;
7706  posval = TRUE;
7707  }
7708  }
7709  else
7710  {
7711  SCIP_Real value = vals[v] * SCIPvarGetLbGlobal(vars[v]);
7712 
7713  value = REALABS(value);
7714 
7715  if( value > maxabscontrib )
7716  {
7717  maxabscontrib = value;
7718  position = v;
7719  posval = FALSE;
7720  }
7721  }
7722  }
7723  else
7724  allbinary = FALSE;
7725  }
7726  assert(0 <= position && position < nvars);
7727 
7728  if( !SCIPisEQ(scip, maxabscontrib, 1.0) && !allbinary )
7729  {
7730  /* if the right hand side and the minimal activity are finite and changing the variable with the biggest
7731  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
7732  * implications
7733  */
7734  if( finiterhs && finiteminact && SCIPisEQ(scip, consdata->glbminactivity, consdata->rhs - maxabscontrib) )
7735  {
7736  for( v = nvars - 1; v >= 0; --v )
7737  {
7738  /* binary to binary implications will be collected when extrating cliques */
7739  if( !SCIPvarIsBinary(vars[v]) )
7740  {
7741  if( v != position )
7742  {
7743  if( vals[v] > 0 )
7744  {
7745  /* add implications */
7746  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
7747  ++nimpls;
7748  *nchgbds += nbdchgs;
7749  }
7750  else
7751  {
7752  /* add implications */
7753  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
7754  ++nimpls;
7755  *nchgbds += nbdchgs;
7756  }
7757 
7758  if( infeasible )
7759  {
7760  *cutoff = TRUE;
7761  break;
7762  }
7763  }
7764  }
7765  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
7766  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
7767  break;
7768  }
7769  }
7770 
7771  /* if the left hand side and the maximal activity are finite and changing the variable with the biggest
7772  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
7773  * implications
7774  */
7775  if( finitelhs && finitemaxact && SCIPisEQ(scip, consdata->glbmaxactivity, consdata->lhs - maxabscontrib) )
7776  {
7777  for( v = nvars - 1; v >= 0; --v )
7778  {
7779  /* binary to binary implications will be collected when extrating cliques */
7780  if( !SCIPvarIsBinary(vars[v]) )
7781  {
7782  if( v != position )
7783  {
7784  if( vals[v] > 0 )
7785  {
7786  /* add implications */
7787  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
7788  ++nimpls;
7789  *nchgbds += nbdchgs;
7790  }
7791  else
7792  {
7793  /* add implications */
7794  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
7795  ++nimpls;
7796  *nchgbds += nbdchgs;
7797  }
7798 
7799  if( infeasible )
7800  {
7801  *cutoff = TRUE;
7802  break;
7803  }
7804  }
7805  }
7806  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
7807  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
7808  break;
7809  }
7810  }
7811 
7812  /* did we find some implications */
7813  if( nimpls > 0 )
7814  {
7815  SCIPdebugMessage("extracted %d implications from constraint %s which led to %d bound changes, %scutoff detetcted\n", nimpls, SCIPconsGetName(cons), *nchgbds - oldnchgbds, *cutoff ? "" : "no ");
7816 
7817  if( *cutoff )
7818  return SCIP_OKAY;
7819 
7820  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
7821  if( *nchgbds - oldnchgbds > 0 )
7822  {
7823  /* check for fixed variables */
7824  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
7825  if( *cutoff )
7826  return SCIP_OKAY;
7827 
7828  /* tighten variable's bounds */
7829  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7830  if( *cutoff )
7831  return SCIP_OKAY;
7832 
7833  /* check for fixed variables */
7834  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
7835  if( *cutoff )
7836  return SCIP_OKAY;
7837  }
7838  }
7839  }
7840  }
7841 
7842  consdata->implsadded = TRUE;
7843  }
7844 
7845  /* check if we already added the cliques of this constraint */
7846  if( consdata->cliquesadded )
7847  return SCIP_OKAY;
7848 
7849  consdata->cliquesadded = TRUE;
7850  cliquenonzerosadded = 0;
7851  stopped = FALSE;
7852 
7853  /* sort variables by variable type */
7854  SCIP_CALL( consdataSort(scip, consdata) );
7855 
7856  nvars = consdata->nvars;
7857  vars = consdata->vars;
7858  vals = consdata->vals;
7859 
7860  /**@todo extract more cliques, implications and variable bounds from linear constraints */
7861 
7862  /* recompute activities if needed */
7863  if( !consdata->validactivities )
7864  consdataCalcActivities(scip, consdata);
7865  assert(consdata->validactivities);
7866 
7867  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
7868  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
7869  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
7870  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
7871  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
7872  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
7873  finiteminact = (finitenegminact && finiteposminact);
7874  finitemaxact = (finitenegmaxact && finiteposmaxact);
7875 
7876  /* 1. we wheck whether some variables do not fit together into this constraint and add the corresponding clique
7877  * information
7878  */
7879  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
7880  {
7881  SCIP_VAR** binvars;
7882  SCIP_Real* binvarvals;
7883  int nposbinvars = 0;
7884  int nnegbinvars = 0;
7885  int allonebinary = 0;
7886 
7887  SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nvars) );
7888  SCIP_CALL( SCIPallocBufferArray(scip, &binvarvals, nvars) );
7889 
7890  /* collect binary variables */
7891  for( i = 0; i < nvars; ++i )
7892  {
7893  if( SCIPvarIsBinary(vars[i]) )
7894  {
7895  assert(!SCIPisZero(scip, vals[i]));
7896 
7897  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
7898  ++allonebinary;
7899 
7900  binvars[nposbinvars + nnegbinvars] = vars[i];
7901  binvarvals[nposbinvars + nnegbinvars] = vals[i];
7902 
7903  if( SCIPisPositive(scip, vals[i]) )
7904  ++nposbinvars;
7905  else
7906  ++nnegbinvars;
7907 
7908  assert(nposbinvars + nnegbinvars <= nvars);
7909  }
7910  /* stop searching for binary variables, because the constraint data is sorted */
7911  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
7912  break;
7913  }
7914  assert(nposbinvars + nnegbinvars <= nvars);
7915 
7916  /* setppc constraints will be handled later; we need at least two binary variables with same sign to extract
7917  * cliques
7918  */
7919  if( allonebinary < nvars && (nposbinvars >= 2 || nnegbinvars >= 2) )
7920  {
7921  SCIP_Real threshold;
7922  int oldnchgbds = *nchgbds;
7923  int nbdchgs;
7924  int jstart;
7925  int j;
7926 
7927  /* we need a valid minimal/maximal activity to add cliques */
7928  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
7929  {
7930  consdataRecomputeGlbMinactivity(scip, consdata);
7931  assert(consdata->validglbminact);
7932  }
7933 
7934  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
7935  {
7936  consdataRecomputeGlbMaxactivity(scip, consdata);
7937  assert(consdata->validglbmaxact);
7938  }
7939  assert(consdata->validglbminact || consdata->validglbmaxact);
7940 
7941  /* sort coefficients non-increasing to be faster in the clique search */
7942  SCIPsortDownRealPtr(binvarvals, (void**) binvars, nposbinvars + nnegbinvars);
7943 
7944  /* case a) */
7945  if( finiterhs && finitenegminact && nposbinvars >= 2 )
7946  {
7947  /* compute value that needs to be exceeded */
7948  threshold = consdata->rhs - consdata->glbminactivity;
7949 
7950  i = 0;
7951  j = i + 1;
7952 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
7953  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
7954  assert(SCIPisFeasLE(scip, binvarvals[i], threshold));
7955 #endif
7956  /* check if at least two variables are in a clique */
7957  if( SCIPisFeasGT(scip, binvarvals[i] + binvarvals[j], threshold) )
7958  {
7959  ++j;
7960  /* check for extending the clique */
7961  while( j < nposbinvars )
7962  {
7963  if( !SCIPisFeasGT(scip, binvarvals[j-1] + binvarvals[j], threshold) )
7964  break;
7965  ++j;
7966  }
7967  assert(j >= 2);
7968 
7969  /* add clique with at least two variables */
7970  SCIP_CALL( SCIPaddClique(scip, &(binvars[i]), NULL, j - i, FALSE, &infeasible, &nbdchgs) );
7971 
7972  if( infeasible )
7973  *cutoff = TRUE;
7974 
7975  *nchgbds += nbdchgs;
7976 
7977  cliquenonzerosadded += j;
7978  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
7979  stopped = TRUE;
7980 
7981  /* exchange the last variable in the clique if possible and add all new ones */
7982  if( !stopped && !(*cutoff) && j < nposbinvars )
7983  {
7984  SCIP_VAR** clqvars;
7985  int lastfit = j - 2;
7986  assert(lastfit >= i);
7987 
7988  /* copy all 'main'-clique variables */
7989  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[i]), j - i) );
7990 
7991  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
7992  while( lastfit >= i && j < nposbinvars )
7993  {
7994  /* check if two variables are in a clique */
7995  if( SCIPisFeasGT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
7996  {
7997  clqvars[lastfit + 1] = binvars[j];
7998 
7999  /* add clique with at least two variables */
8000  SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, lastfit - i + 2, FALSE, &infeasible, &nbdchgs) );
8001 
8002  if( infeasible )
8003  {
8004  *cutoff = TRUE;
8005  break;
8006  }
8007 
8008  *nchgbds += nbdchgs;
8009 
8010  cliquenonzerosadded += (lastfit - i + 2);
8011  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8012  {
8013  stopped = TRUE;
8014  break;
8015  }
8016 
8017  ++j;
8018  }
8019  else
8020  --lastfit;
8021  }
8022 
8023  SCIPfreeBufferArray(scip, &clqvars);
8024  }
8025  }
8026  }
8027 
8028  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8029  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8030  {
8031  /* check for fixed variables */
8032  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8033 
8034  if( !*cutoff )
8035  {
8036  /* tighten variable's bounds */
8037  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8038 
8039  if( !*cutoff )
8040  {
8041  /* check for fixed variables */
8042  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8043 
8044  if( !*cutoff )
8045  {
8046  /* sort variables by variable type */
8047  SCIP_CALL( consdataSort(scip, consdata) );
8048 
8049  /* recompute activities if needed */
8050  if( !consdata->validactivities )
8051  consdataCalcActivities(scip, consdata);
8052  assert(consdata->validactivities);
8053 
8054  nvars = consdata->nvars;
8055  vars = consdata->vars;
8056  vals = consdata->vals;
8057  nposbinvars = 0;
8058  nnegbinvars = 0;
8059  allonebinary = 0;
8060 
8061  /* update binary variables */
8062  for( i = 0; i < nvars; ++i )
8063  {
8064  if( SCIPvarIsBinary(vars[i]) )
8065  {
8066  assert(!SCIPisZero(scip, vals[i]));
8067 
8068  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8069  ++allonebinary;
8070 
8071  binvars[nposbinvars + nnegbinvars] = vars[i];
8072  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8073 
8074  if( SCIPisPositive(scip, vals[i]) )
8075  ++nposbinvars;
8076  else
8077  ++nnegbinvars;
8078 
8079  assert(nposbinvars + nnegbinvars <= nvars);
8080  }
8081  /* stop searching for binary variables, because the constraint data is sorted */
8082  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8083  break;
8084  }
8085  assert(nposbinvars + nnegbinvars <= nvars);
8086  }
8087  }
8088  }
8089 
8090  oldnchgbds = *nchgbds;
8091  }
8092 
8093  /* case b) */
8094  if( !stopped && !(*cutoff) && finitelhs && finiteposmaxact && nnegbinvars >= 2 )
8095  {
8096  /* compute value that needs to be deceeded */
8097  threshold = consdata->lhs - consdata->glbmaxactivity;
8098 
8099  i = nposbinvars + nnegbinvars - 1;
8100  j = i - 1;
8101 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8102  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8103  assert(SCIPisFeasGE(scip, binvarvals[i], threshold));
8104 #endif
8105  /* check if two variables are in a clique */
8106  if( SCIPisFeasLT(scip, binvarvals[i] + binvarvals[j], threshold) )
8107  {
8108  --j;
8109  /* check for extending the clique */
8110  while( j >= nposbinvars )
8111  {
8112  if( !SCIPisFeasLT(scip, binvarvals[j+1] + binvarvals[j], threshold) )
8113  break;
8114  --j;
8115  }
8116  jstart = j;
8117 
8118  assert(i - j >= 2);
8119  /* add clique with at least two variables */
8120  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), NULL, i - j, FALSE, &infeasible, &nbdchgs) );
8121 
8122  if( infeasible )
8123  *cutoff = TRUE;
8124 
8125  *nchgbds += nbdchgs;
8126 
8127  cliquenonzerosadded += (i - j);
8128  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8129  stopped = TRUE;
8130 
8131  /* exchange the last variable in the clique if possible and add all new ones */
8132  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8133  {
8134  SCIP_VAR** clqvars;
8135  int lastfit = jstart + 1;
8136  assert(lastfit < i);
8137 
8138  /* copy all 'main'-clique variables */
8139  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8140  ++lastfit;
8141 
8142  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8143  while( lastfit <= i && j >= nposbinvars )
8144  {
8145  /* check if two variables are in a clique */
8146  if( SCIPisFeasLT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8147  {
8148  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8149  clqvars[lastfit - jstart - 2] = binvars[j];
8150 
8151  assert(i - lastfit + 2 >= 2);
8152  /* add clique with at least two variables */
8153  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), NULL, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8154 
8155  if( infeasible )
8156  {
8157  *cutoff = TRUE;
8158  break;
8159  }
8160 
8161  *nchgbds += nbdchgs;
8162 
8163  cliquenonzerosadded += (i - lastfit + 2);
8164  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8165  {
8166  stopped = TRUE;
8167  break;
8168  }
8169 
8170  --j;
8171  }
8172  else
8173  ++lastfit;
8174  }
8175 
8176  SCIPfreeBufferArray(scip, &clqvars);
8177  }
8178  }
8179  }
8180 
8181  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8182  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8183  {
8184  /* check for fixed variables */
8185  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8186 
8187  if( !*cutoff )
8188  {
8189  /* tighten variable's bounds */
8190  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8191 
8192  if( !*cutoff )
8193  {
8194  /* check for fixed variables */
8195  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8196 
8197  if( !*cutoff )
8198  {
8199  /* sort variables by variable type */
8200  SCIP_CALL( consdataSort(scip, consdata) );
8201 
8202  /* recompute activities if needed */
8203  if( !consdata->validactivities )
8204  consdataCalcActivities(scip, consdata);
8205  assert(consdata->validactivities);
8206 
8207  nvars = consdata->nvars;
8208  vars = consdata->vars;
8209  vals = consdata->vals;
8210  nposbinvars = 0;
8211  nnegbinvars = 0;
8212  allonebinary = 0;
8213 
8214  /* update binary variables */
8215  for( i = 0; i < nvars; ++i )
8216  {
8217  if( SCIPvarIsBinary(vars[i]) )
8218  {
8219  assert(!SCIPisZero(scip, vals[i]));
8220 
8221  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8222  ++allonebinary;
8223 
8224  binvars[nposbinvars + nnegbinvars] = vars[i];
8225  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8226 
8227  if( SCIPisPositive(scip, vals[i]) )
8228  ++nposbinvars;
8229  else
8230  ++nnegbinvars;
8231 
8232  assert(nposbinvars + nnegbinvars <= nvars);
8233  }
8234  /* stop searching for binary variables, because the constraint data is sorted */
8235  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8236  break;
8237  }
8238  assert(nposbinvars + nnegbinvars <= nvars);
8239  }
8240  }
8241  }
8242 
8243  oldnchgbds = *nchgbds;
8244  }
8245 
8246  /* case c) */
8247  if( !(*cutoff) && finiterhs && finiteminact && nnegbinvars >= 2 )
8248  {
8249  SCIP_Bool* values;
8250 
8251  /* initialize clique values array for adding a negated clique */
8252  SCIP_CALL( SCIPallocBufferArray(scip, &values, nnegbinvars) );
8253  BMSclearMemoryArray(values, nnegbinvars);
8254 
8255  /* compute value that needs to be exceeded */
8256  threshold = consdata->rhs - consdata->glbminactivity;
8257 
8258  i = nposbinvars + nnegbinvars - 1;
8259  j = i - 1;
8260 
8261 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8262  /* check if the variable should not have already been fixed to one */
8263  assert(!SCIPisFeasGT(scip, binvarvals[i], threshold));
8264 #endif
8265 
8266  if( SCIPisFeasGT(scip, -binvarvals[i] - binvarvals[j], threshold) )
8267  {
8268  --j;
8269  /* check for extending the clique */
8270  while( j >= nposbinvars )
8271  {
8272  if( !SCIPisFeasGT(scip, -binvarvals[j+1] - binvarvals[j], threshold) )
8273  break;
8274  --j;
8275  }
8276  jstart = j;
8277 
8278  assert(i - j >= 2);
8279  /* add negated clique with at least two variables */
8280  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), values, i - j, FALSE, &infeasible, &nbdchgs) );
8281 
8282  if( infeasible )
8283  *cutoff = TRUE;
8284 
8285  *nchgbds += nbdchgs;
8286 
8287  cliquenonzerosadded += (i - j);
8288  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8289  stopped = TRUE;
8290 
8291  /* exchange the last variable in the clique if possible and add all new ones */
8292  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8293  {
8294  SCIP_VAR** clqvars;
8295  int lastfit = j + 1;
8296  assert(lastfit < i);
8297 
8298  /* copy all 'main'-clique variables */
8299  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8300  ++lastfit;
8301 
8302  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8303  while( lastfit <= i && j >= nposbinvars )
8304  {
8305  /* check if two variables are in a negated clique */
8306  if( SCIPisFeasGT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8307  {
8308  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8309  clqvars[lastfit - jstart - 2] = binvars[j];
8310 
8311  assert(i - lastfit + 2 >= 2);
8312  /* add clique with at least two variables */
8313  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), values, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8314 
8315  if( infeasible )
8316  {
8317  *cutoff = TRUE;
8318  break;
8319  }
8320 
8321  *nchgbds += nbdchgs;
8322 
8323  cliquenonzerosadded += (i - lastfit + 2);
8324  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8325  {
8326  stopped = TRUE;
8327  break;
8328  }
8329 
8330  --j;
8331  }
8332  else
8333  ++lastfit;
8334  }
8335 
8336  SCIPfreeBufferArray(scip, &clqvars);
8337  }
8338  }
8339 
8340  SCIPfreeBufferArray(scip, &values);
8341  }
8342 
8343  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8344  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8345  {
8346  /* check for fixed variables */
8347  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8348 
8349  if( !*cutoff )
8350  {
8351  /* tighten variable's bounds */
8352  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8353 
8354  if( !*cutoff )
8355  {
8356  /* check for fixed variables */
8357  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8358 
8359  if( !*cutoff )
8360  {
8361  /* sort variables by variable type */
8362  SCIP_CALL( consdataSort(scip, consdata) );
8363 
8364  /* recompute activities if needed */
8365  if( !consdata->validactivities )
8366  consdataCalcActivities(scip, consdata);
8367  assert(consdata->validactivities);
8368 
8369  nvars = consdata->nvars;
8370  vars = consdata->vars;
8371  vals = consdata->vals;
8372  nposbinvars = 0;
8373  nnegbinvars = 0;
8374  allonebinary = 0;
8375 
8376  /* update binary variables */
8377  for( i = 0; i < nvars; ++i )
8378  {
8379  if( SCIPvarIsBinary(vars[i]) )
8380  {
8381  assert(!SCIPisZero(scip, vals[i]));
8382 
8383  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8384  ++allonebinary;
8385 
8386  binvars[nposbinvars + nnegbinvars] = vars[i];
8387  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8388 
8389  if( SCIPisPositive(scip, vals[i]) )
8390  ++nposbinvars;
8391  else
8392  ++nnegbinvars;
8393 
8394  assert(nposbinvars + nnegbinvars <= nvars);
8395  }
8396  /* stop searching for binary variables, because the constraint data is sorted */
8397  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8398  break;
8399  }
8400  assert(nposbinvars + nnegbinvars <= nvars);
8401  }
8402  }
8403  }
8404  }
8405 
8406  /* case d) */
8407  if( !stopped && !(*cutoff) && finitelhs && finitemaxact && nposbinvars >= 2 )
8408  {
8409  SCIP_Bool* values;
8410 
8411  /* initialize clique values array for adding a negated clique */
8412  SCIP_CALL( SCIPallocBufferArray(scip, &values, nposbinvars) );
8413  BMSclearMemoryArray(values, nposbinvars);
8414 
8415  /* compute value that needs to be exceeded */
8416  threshold = consdata->lhs - consdata->glbmaxactivity;
8417 
8418  i = 0;
8419  j = i + 1;
8420 
8421 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8422  /* check if the variable should not have already been fixed to one */
8423  assert(!SCIPisFeasLT(scip, -binvarvals[i], threshold));
8424 #endif
8425 
8426  if( SCIPisFeasLT(scip, -binvarvals[i] - binvarvals[j], threshold) )
8427  {
8428  ++j;
8429  /* check for extending the clique */
8430  while( j < nposbinvars )
8431  {
8432  if( !SCIPisFeasLT(scip, -binvarvals[j-1] - binvarvals[j], threshold) )
8433  break;
8434  ++j;
8435  }
8436  assert(j >= 2);
8437 
8438  /* add negated clique with at least two variables */
8439  SCIP_CALL( SCIPaddClique(scip, &(binvars[i]), values, j - i, FALSE, &infeasible, &nbdchgs) );
8440 
8441  if( infeasible )
8442  *cutoff = TRUE;
8443 
8444  *nchgbds += nbdchgs;
8445 
8446  cliquenonzerosadded += j;
8447  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8448  stopped = TRUE;
8449 
8450  /* exchange the last variable in the clique if possible and add all new ones */
8451  if( !stopped && !(*cutoff) && j < nposbinvars )
8452  {
8453  SCIP_VAR** clqvars;
8454  int lastfit = j - 2;
8455  assert(lastfit >= i);
8456 
8457  /* copy all 'main'-clique variables */
8458  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[i]), j - i) );
8459 
8460  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8461  while( lastfit >= i && j < nposbinvars )
8462  {
8463  /* check if two variables are in a negated clique */
8464  if( SCIPisFeasLT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8465  {
8466  clqvars[lastfit + 1] = binvars[j];
8467 
8468  /* add clique with at least two variables */
8469  SCIP_CALL( SCIPaddClique(scip, clqvars, values, lastfit - i + 2, FALSE, &infeasible, &nbdchgs) );
8470 
8471  if( infeasible )
8472  {
8473  *cutoff = TRUE;
8474  break;
8475  }
8476 
8477  *nchgbds += nbdchgs;
8478 
8479  cliquenonzerosadded += (lastfit - i + 2);
8480  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8481  break;
8482 
8483  ++j;
8484  }
8485  else
8486  --lastfit;
8487  }
8488 
8489  SCIPfreeBufferArray(scip, &clqvars);
8490  }
8491  }
8492 
8493  SCIPfreeBufferArray(scip, &values);
8494  }
8495  }
8496 
8497  SCIPfreeBufferArray(scip, &binvarvals);
8498  SCIPfreeBufferArray(scip, &binvars);
8499 
8500  if( *cutoff )
8501  return SCIP_OKAY;
8502  }
8503 
8504  /* 2. we only check if the constraint is a set packing / partitioning constraint */
8505 
8506  /* check if all variables are binary, if the coefficients are +1 or -1, and if the right hand side is equal
8507  * to 1 - number of negative coefficients, or if the left hand side is equal to number of positive coefficients - 1
8508  */
8509  nposcoefs = 0;
8510  nnegcoefs = 0;
8511  for( i = 0; i < nvars; ++i )
8512  {
8513  if( !SCIPvarIsBinary(vars[i]) )
8514  return SCIP_OKAY;
8515  else if( SCIPisEQ(scip, vals[i], +1.0) )
8516  nposcoefs++;
8517  else if( SCIPisEQ(scip, vals[i], -1.0) )
8518  nnegcoefs++;
8519  else
8520  return SCIP_OKAY;
8521  }
8522 
8523  lhsclique = SCIPisEQ(scip, consdata->lhs, (SCIP_Real)nposcoefs - 1.0);
8524  rhsclique = SCIPisEQ(scip, consdata->rhs, 1.0 - (SCIP_Real)nnegcoefs);
8525 
8526  if( lhsclique || rhsclique )
8527  {
8528  SCIP_Bool* values;
8529  int nbdchgs;
8530 
8531  SCIPdebugMessage("linear constraint <%s>: adding clique with %d vars (%d pos, %d neg)\n",
8532  SCIPconsGetName(cons), nvars, nposcoefs, nnegcoefs);
8533  SCIP_CALL( SCIPallocBufferArray(scip, &values, nvars) );
8534 
8535  for( i = 0; i < nvars; ++i )
8536  values[i] = (rhsclique == (vals[i] > 0.0));
8537 
8538  SCIP_CALL( SCIPaddClique(scip, vars, values, nvars, SCIPisEQ(scip, consdata->lhs, consdata->rhs), &infeasible, &nbdchgs) );
8539 
8540  if( infeasible )
8541  *cutoff = TRUE;
8542 
8543  *nchgbds += nbdchgs;
8544  SCIPfreeBufferArray(scip, &values);
8545  }
8546 
8547  return SCIP_OKAY;
8548 }
8549 
8550 /** tightens left and right hand side of constraint due to integrality */
8551 static
8553  SCIP* scip, /**< SCIP data structure */
8554  SCIP_CONS* cons, /**< linear constraint */
8555  int* nchgsides /**< pointer to count number of side changes */
8556  )
8557 {
8558  SCIP_CONSDATA* consdata;
8559  SCIP_Bool integral;
8560  int i;
8561 
8562  assert(scip != NULL);
8563  assert(cons != NULL);
8564  assert(nchgsides != NULL);
8565 
8566  consdata = SCIPconsGetData(cons);
8567  assert(consdata != NULL);
8569  if( !SCIPisIntegral(scip, consdata->lhs) || !SCIPisIntegral(scip, consdata->rhs) )
8570  {
8571  integral = TRUE;
8572  for( i = 0; i < consdata->nvars && integral; ++i )
8573  {
8574  integral = SCIPisIntegral(scip, consdata->vals[i])
8575  && (SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS);
8576  }
8577  if( integral )
8578  {
8579  SCIPdebugMessage("linear constraint <%s>: make sides integral: sides=[%.15g,%.15g]\n",
8580  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
8581  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisIntegral(scip, consdata->lhs) )
8582  {
8583  SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
8584  if( !consdata->upgraded )
8585  (*nchgsides)++;
8586  }
8587  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisIntegral(scip, consdata->rhs) )
8588  {
8589  SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
8590  if( !consdata->upgraded )
8591  (*nchgsides)++;
8592  }
8593  SCIPdebugMessage("linear constraint <%s>: new integral sides: sides=[%.15g,%.15g]\n",
8594  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
8595  }
8596  }
8597 
8598  return SCIP_OKAY;
8599 }
8600 
8601 #define MAXVALRECOMP 1e+06
8602 
8603 /** tightens coefficients of binary, integer, and implicit integer variables due to activity bounds in presolving:
8604  * given an inequality lhs <= a*x + ai*xi <= rhs, with a non-continuous variable li <= xi <= ui
8605  * let minact := min{a*x + ai*xi}, maxact := max{a*x + ai*xi}
8606  * (i) ai >= 0:
8607  * if minact + ai >= lhs and maxact - ai <= rhs: (**)
8608  * - a deviation from the lower/upper bound of xi would make the left/right hand side redundant
8609  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
8610  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
8611  * - change coefficients:
8612  * ai' := max(lhs - minact, maxact - rhs)
8613  * lhs' := lhs - (ai - ai')*li
8614  * rhs' := rhs - (ai - ai')*ui
8615  * (ii) ai < 0:
8616  * if minact - ai >= lhs and maxact + ai <= rhs: (***)
8617  * - a deviation from the upper/lower bound of xi would make the left/right hand side redundant
8618  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
8619  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
8620  * - change coefficients:
8621  * ai' := min(rhs - maxact, minact - lhs)
8622  * lhs' := lhs - (ai - ai')*ui
8623  * rhs' := rhs - (ai - ai')*li
8624  *
8625  * We further try to remove redundant variable from the constraint;
8626  * Variables which fulfill conditions (**) or (***) are called surely non-redundant variables.
8627  * A deviation of only one from their bound makes the lhs/rhs feasible (i.e., redundant), even if all other
8628  * variables are set to their "worst" bound. If all variables which are not surely non-redundant cannot make
8629  * the lhs/rhs redundant, even if they are set to their "best" bound, they can be removed from the constraint.
8630  * 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
8631  * suffices to fulfill the inequality, whereas the x_i do not contribute to feasibility and can be removed.
8632  *
8633  * @todo use also some tightening procedures for (knapsack) constraints with non-integer coefficients, see
8634  * cons_knapsack.c the following methods detectRedundantVars() and tightenWeights()
8635  */
8636 static
8638  SCIP* scip, /**< SCIP data structure */
8639  SCIP_CONS* cons, /**< linear constraint */
8640  int* nchgcoefs, /**< pointer to count total number of changed coefficients */
8641  int* nchgsides /**< pointer to count number of side changes */
8642  )
8643 {
8644  SCIP_CONSDATA* consdata;
8645  SCIP_VAR* var;
8646  SCIP_Real minactivity; /* minimal value w.r.t. the variable's local bounds for the constraint's
8647  * activity, ignoring the coefficients contributing with infinite value */
8648  SCIP_Real maxactivity; /* maximal value w.r.t. the variable's local bounds for the constraint's
8649  * activity, ignoring the coefficients contributing with infinite value */
8650  SCIP_Bool minactisrelax; /* do huge finite values contribute to the minactivity? */
8651  SCIP_Bool maxactisrelax; /* do huge finite values contribute to the maxactivity? */
8652  SCIP_Real minleftactivity; /* minimal activity without surely non-redundant variables. */
8653  SCIP_Real maxleftactivity; /* maximal activity without surely non-redundant variables. */
8654  SCIP_Real aggrlhs; /* lhs without minimal activity of surely non-redundant variables. */
8655  SCIP_Real aggrrhs; /* rhs without maximal activity of surely non-redundant variables. */
8656  SCIP_Real lval; /* candidate for new value arising from considering the left hand side */
8657  SCIP_Real rval; /* candidate for new value arising from considering the left hand side */
8658  SCIP_Real val;
8659  SCIP_Real newval;
8660  SCIP_Real newlhs;
8661  SCIP_Real newrhs;
8662  SCIP_Real lb;
8663  SCIP_Real ub;
8664  int i;
8665 
8666  assert(scip != NULL);
8667  assert(cons != NULL);
8668  assert(nchgcoefs != NULL);
8669  assert(nchgsides != NULL);
8670 
8671  consdata = SCIPconsGetData(cons);
8672  assert(consdata != NULL);
8673 
8674  /* @todo Is this still needed with automatic recomputation of activities? */
8675  /* if the maximal coefficient is too large, recompute the activities */
8676  if( consdata->validmaxabsval && consdata->maxabsval > MAXVALRECOMP )
8677  {
8678  consdataRecomputeMinactivity(scip, consdata);
8679  consdataRecomputeMaxactivity(scip, consdata);
8680  }
8681 
8682  /* get the minimal and maximal activity of the constraint */
8683  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8684 
8685  minleftactivity = 0.0;
8686  maxleftactivity = 0.0;
8687 
8688  /* try to tighten each coefficient */
8689  i = 0;
8690  while( i < consdata->nvars )
8691  {
8692  var = consdata->vars[i];
8693 
8694  /* get coefficient and variable's bounds */
8695  lb = SCIPvarGetLbLocal(var);
8696  ub = SCIPvarGetUbLocal(var);
8697  val = consdata->vals[i];
8698  assert(!SCIPisZero(scip, val));
8699 
8700  /* check sign of coefficient */
8701  if( val >= 0.0 )
8702  {
8703  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
8705  SCIPisGE(scip, minactivity + val, consdata->lhs) && SCIPisLE(scip, maxactivity - val, consdata->rhs) )
8706  {
8707  /* change coefficients:
8708  * ai' := max(lhs - minact, maxact - rhs)
8709  * lhs' := lhs - (ai - ai')*li
8710  * rhs' := rhs - (ai - ai')*ui
8711  */
8712 
8713  lval = consdata->lhs - minactivity;
8714  rval = maxactivity - consdata->rhs;
8715 
8716  /* Try to avoid cancellation, if there are only two variables */
8717  if( consdata->nvars == 2 )
8718  {
8719  SCIP_Real otherval;
8720  otherval = consdata->vals[1-i];
8721 
8722  if( !SCIPisInfinity(scip, -consdata->lhs) && consdata->minactivityneginf + consdata->minactivityneginf == 0 )
8723  {
8724  lval = consdata->lhs - val*lb;
8725  lval -= otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
8726  }
8727 
8728  if( !SCIPisInfinity(scip,consdata->rhs) && consdata->maxactivityneginf + consdata->maxactivityneginf == 0 )
8729  {
8730  rval = val*ub - consdata->rhs;
8731  rval += otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
8732  }
8733  }
8734 
8735  newval = MAX(lval, rval);
8736  assert(SCIPisSumRelLE(scip, newval, val));
8737 
8738  /* Try to avoid cancellation in computation of lhs/rhs */
8739  newlhs = consdata->lhs - val * lb;
8740  newlhs += newval * lb;
8741  newrhs = consdata->rhs - val * ub;
8742  newrhs += newval * ub;
8743 
8744  if( !SCIPisSumRelEQ(scip, newval, val) )
8745  {
8746  SCIPdebugMessage("linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
8747  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
8748  minactivity, maxactivity, consdata->lhs, consdata->rhs);
8749 
8750  /* update the coefficient and the activity bounds */
8751  if( SCIPisZero(scip, newval) )
8752  {
8753  SCIP_CALL( delCoefPos(scip, cons, i) );
8754  i--;
8755  }
8756  else
8757  {
8758  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
8759  }
8760  (*nchgcoefs)++;
8761 
8762  /* get the new minimal and maximal activity of the constraint */
8763  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8764 
8765  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
8766  {
8767  SCIPdebugMessage("linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
8768 
8769  SCIP_CALL( chgLhs(scip, cons, newlhs) );
8770  (*nchgsides)++;
8771  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
8772  }
8773 
8774  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
8775  {
8776  SCIPdebugMessage("linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
8777 
8778  SCIP_CALL( chgRhs(scip, cons, newrhs) );
8779  (*nchgsides)++;
8780  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
8781  }
8782  }
8783  }
8784  else
8785  {
8786  if( !SCIPisInfinity(scip, -minleftactivity) )
8787  {
8788  assert(!SCIPisInfinity(scip, val));
8789  assert(!SCIPisInfinity(scip, lb));
8790  if( SCIPisInfinity(scip, -lb) )
8791  minleftactivity = -SCIPinfinity(scip);
8792  else
8793  minleftactivity += val * lb;
8794  }
8795 
8796  if( !SCIPisInfinity(scip, maxleftactivity) )
8797  {
8798  assert(!SCIPisInfinity(scip, val));
8799  assert(!SCIPisInfinity(scip, -ub));
8800  if( SCIPisInfinity(scip,ub) )
8801  maxleftactivity = SCIPinfinity(scip);
8802  else
8803  maxleftactivity += val * ub;
8804  }
8805  }
8806  }
8807  else
8808  {
8809  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
8811  SCIPisGE(scip, minactivity - val, consdata->lhs) && SCIPisLE(scip, maxactivity + val, consdata->rhs) )
8812  {
8813  /* change coefficients:
8814  * ai' := min(rhs - maxact, minact - lhs)
8815  * lhs' := lhs - (ai - ai')*ui
8816  * rhs' := rhs - (ai - ai')*li
8817  */
8818 
8819  lval = minactivity - consdata->lhs;
8820  rval = consdata->rhs - maxactivity;
8821 
8822  /* Try to avoid cancellation, if there are only two variables */
8823  if( consdata->nvars == 2 )
8824  {
8825  SCIP_Real otherval;
8826  otherval = consdata->vals[1-i];
8827 
8828  if( !SCIPisInfinity(scip,-consdata->lhs) && consdata->minactivityneginf + consdata->minactivityneginf == 0 )
8829  {
8830  lval = val*ub - consdata->lhs;
8831  lval += otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
8832  }
8833 
8834  if( !SCIPisInfinity(scip,consdata->rhs) && consdata->maxactivityneginf + consdata->maxactivityneginf == 0 )
8835  {
8836  rval = consdata->rhs - val*lb;
8837  rval -= otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
8838  }
8839  }
8840 
8841  newval = MIN(lval, rval);
8842  assert(SCIPisSumRelGE(scip, newval, val));
8843 
8844  /* Try to avoid cancellation in computation of lhs/rhs */
8845  newlhs = consdata->lhs - val * ub;
8846  newlhs += newval * ub;
8847  newrhs = consdata->rhs - val * lb;
8848  newrhs += newval * lb;
8849 
8850  if( !SCIPisSumRelEQ(scip, newval, val) )
8851  {
8852  SCIPdebugMessage("linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
8853  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
8854  minactivity, maxactivity, consdata->lhs, consdata->rhs);
8855 
8856  /* update the coefficient and the activity bounds */
8857  if( SCIPisZero(scip, newval) )
8858  {
8859  SCIP_CALL( delCoefPos(scip, cons, i) );
8860  i--;
8861  }
8862  else
8863  {
8864  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
8865  }
8866  (*nchgcoefs)++;
8867 
8868  /* get the new minimal and maximal activity of the constraint */
8869  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8870 
8871  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
8872  {
8873  SCIPdebugMessage("linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
8874 
8875  SCIP_CALL( chgLhs(scip, cons, newlhs) );
8876  (*nchgsides)++;
8877  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
8878  }
8879 
8880  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
8881  {
8882  SCIPdebugMessage("linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
8883 
8884  SCIP_CALL( chgRhs(scip, cons, newrhs) );
8885  (*nchgsides)++;
8886  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
8887  }
8888  }
8889  }
8890  else
8891  {
8892  if( !SCIPisInfinity(scip, -minleftactivity) )
8893  {
8894  assert(!SCIPisInfinity(scip, -val));
8895  assert(!SCIPisInfinity(scip, -ub));
8896  if( SCIPisInfinity(scip, ub) )
8897  minleftactivity = -SCIPinfinity(scip);
8898  else
8899  minleftactivity += val * ub;
8900  }
8901 
8902  if( !SCIPisInfinity(scip, maxleftactivity) )
8903  {
8904  assert(!SCIPisInfinity(scip, -val));
8905  assert(!SCIPisInfinity(scip, lb));
8906  if( SCIPisInfinity(scip, -lb) )
8907  maxleftactivity = SCIPinfinity(scip);
8908  else
8909  maxleftactivity += val * lb;
8910  }
8911  }
8912  }
8913  ++i;
8914  }
8915 
8916  SCIPdebugMessage("minleftactivity = %.15g, rhs = %.15g\n",
8917  minleftactivity, consdata->rhs);
8918  SCIPdebugMessage("maxleftactivity = %.15g, lhs = %.15g\n",
8919  maxleftactivity, consdata->lhs);
8920 
8921  /* minleft == \infty ==> minactivity == \infty */
8922  assert(!SCIPisInfinity(scip, -minleftactivity) || SCIPisInfinity(scip, -minactivity));
8923  assert(!SCIPisInfinity(scip, maxleftactivity) || SCIPisInfinity(scip, maxactivity));
8924 
8925  /* if the lhs is finite, we will check in the following whether the not non-redundant variables can make lhs feasible;
8926  * this is not valid, if the minactivity is -\infty (aggrlhs would be minus infinity in the following computation)
8927  * or if huge values contributed to the minactivity, because the minactivity is then just a relaxation
8928  * (<= the exact minactivity), and we might falsely claim variables to be redundant in the following
8929  */
8930  assert(!SCIPisInfinity(scip, minactivity));
8931  if( !SCIPisInfinity(scip, -consdata->lhs) && (SCIPisInfinity(scip, -minactivity) || minactisrelax) )
8932  return SCIP_OKAY;
8933 
8934  /* if the rhs is finite, we will check in the following whether the not non-redundant variables can make rhs feasible;
8935  * this is not valid, if the maxactivity is \infty (aggrrhs would be infinity in the following computation)
8936  * or if huge values contributed to the maxactivity, because the maxactivity is then just a relaxation
8937  * (>= the exact maxactivity), and we might falsely claim variables to be redundant in the following
8938  */
8939  assert(!SCIPisInfinity(scip, -maxactivity));
8940  if( !SCIPisInfinity(scip, consdata->rhs) && (SCIPisInfinity(scip, maxactivity) || maxactisrelax) )
8941  return SCIP_OKAY;
8942 
8943  /* correct lhs and rhs by min/max activity of surely non-redundant variables
8944  * surely non-redundant variables are all those where a deviation from the bound makes the lhs/rhs redundant
8945  */
8946  aggrlhs = consdata->lhs - minactivity + minleftactivity;
8947  aggrrhs = consdata->rhs - maxactivity + maxleftactivity;
8948 
8949  /* check if the constraint contains variables which are redundant. The reasoning is the following:
8950  * Each non-redundant variable can make the lhs/rhs feasible with a deviation of only one in the bound.
8951  * If _all_ variables which are not non-redundant together cannot make lhs/rhs feasible,
8952  * they can be removed from the constraint.
8953  * aggrrhs may contain some near-infinity value, but only if rhs is infinity.
8954  */
8955  if( (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasLT(scip, maxleftactivity, aggrlhs))
8956  && (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasGT(scip, minleftactivity, aggrrhs)) )
8957  {
8958  SCIP_Real minleftactivitypart;
8959  SCIP_Real maxleftactivitypart;
8960 
8961  assert(!SCIPisInfinity(scip, -consdata->lhs) || !SCIPisInfinity(scip, consdata->rhs));
8962 
8963  /* try to remove redundant variables from constraint */
8964  i = 0;
8965  while( i < consdata->nvars )
8966  {
8967  var = consdata->vars[i];
8968  minleftactivitypart = 0.0;
8969  maxleftactivitypart = 0.0;
8970  lb = SCIPvarGetLbLocal(var);
8971  ub = SCIPvarGetUbLocal(var);
8972 
8973  /* get coefficient and variable's bounds */
8974  val = consdata->vals[i];
8975  assert(!SCIPisZero(scip, val));
8976 
8977  /* check sign of coefficient */
8978  if( val >= 0.0 )
8979  {
8980  /* negation of condition above in case of positive val */
8981  if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ||
8982  SCIPisLT(scip, minactivity + val, consdata->lhs) || SCIPisGT(scip, maxactivity - val, consdata->rhs) )
8983  {
8984  SCIPdebugMessage("minactivity = %g\tval = %g\tlhs = %g\n", minactivity, val, consdata->lhs);
8985  SCIPdebugMessage("maxactivity = %g\tval = %g\trhs = %g\n", maxactivity, val, consdata->rhs);
8986  SCIPdebugMessage("linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
8987  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
8988 
8989  minleftactivitypart = val * lb;
8990  maxleftactivitypart = val * ub;
8991 
8992  SCIP_CALL( delCoefPos(scip, cons, i) );
8993  i--;
8994 
8995  /* get the new minimal and maximal activity of the constraint */
8996  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8997 
8998  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
8999  * huge contributions
9000  */
9001  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9002  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9003  }
9004  }
9005  else
9006  {
9007  /* negation of condition above in case of negative val */
9008  if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ||
9009  SCIPisLT(scip, minactivity - val, consdata->lhs) || SCIPisGT(scip, maxactivity + val, consdata->rhs) )
9010  {
9011  SCIPdebugMessage("linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9012  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9013 
9014  minleftactivitypart = val * ub;
9015  maxleftactivitypart = val * lb;
9016 
9017  SCIP_CALL( delCoefPos(scip, cons, i) );
9018  i--;
9019 
9020  /* get the new minimal and maximal activity of the constraint */
9021  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
9022 
9023  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9024  * huge contributions
9025  */
9026  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9027  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9028  }
9029  }
9030 
9031  /* the following update step is needed in every iteration cause otherwise it is possible that the surely none-
9032  * redundant variables could get deleted,
9033  * e.g. y_1 + 16y_2 >= 25, y1 with bounds [9,12], y2 with bounds [0,2], minactivity would be 9, it follows that
9034  * y_2 is surely not redundant and y_1 is redundant so we would first delete y1 and without updating the sides
9035  * we would also delete y2 and as a result we would have gotten infeasibility */
9036  /* adjust lhs and right hand side */
9037  newlhs = consdata->lhs - minleftactivitypart;
9038  newrhs = consdata->rhs - maxleftactivitypart;
9039 
9040  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisFeasEQ(scip, newlhs, consdata->lhs) )
9041  {
9042  SCIPdebugMessage("linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9043  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9044  ++(*nchgsides);
9045  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9046  }
9047  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisFeasEQ(scip, newrhs, consdata->rhs) )
9048  {
9049  SCIPdebugMessage("linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9050  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9051  ++(*nchgsides);
9052  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9053  }
9054  ++i;
9055  }
9056  }
9057 
9058  return SCIP_OKAY;
9059 }
9060 
9061 /* processes equality with only one variable by fixing the variable and deleting the constraint */
9062 static
9064  SCIP* scip, /**< SCIP data structure */
9065  SCIP_CONS* cons, /**< linear constraint */
9066  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9067  int* nfixedvars, /**< pointer to count number of fixed variables */
9068  int* ndelconss /**< pointer to count number of deleted constraints */
9069  )
9070 {
9071  SCIP_CONSDATA* consdata;
9072  SCIP_VAR* var;
9073  SCIP_Real val;
9074  SCIP_Real fixval;
9075  SCIP_Bool infeasible;
9076  SCIP_Bool fixed;
9077 
9078  assert(scip != NULL);
9079  assert(cons != NULL);
9080  assert(cutoff != NULL);
9081  assert(nfixedvars != NULL);
9082  assert(ndelconss != NULL);
9083 
9084  consdata = SCIPconsGetData(cons);
9085  assert(consdata != NULL);
9086  assert(consdata->nvars == 1);
9087  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9088 
9089  /* calculate the value to fix the variable to */
9090  var = consdata->vars[0];
9091  val = consdata->vals[0];
9092  assert(!SCIPisZero(scip, val));
9093  fixval = SCIPselectSimpleValue(consdata->lhs/val - 0.9 * SCIPepsilon(scip),
9094  consdata->rhs/val + 0.9 * SCIPepsilon(scip), MAXDNOM);
9095  SCIPdebugMessage("linear equality <%s>: fix <%s> == %.15g\n",
9096  SCIPconsGetName(cons), SCIPvarGetName(var), fixval);
9097 
9098  /* fix variable */
9099  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
9100  if( infeasible )
9101  {
9102  SCIPdebugMessage(" -> infeasible fixing\n");
9103  *cutoff = TRUE;
9104  return SCIP_OKAY;
9105  }
9106  if( fixed )
9107  (*nfixedvars)++;
9108 
9109  /* disable constraint */
9110  SCIP_CALL( SCIPdelCons(scip, cons) );
9111  if( !consdata->upgraded )
9112  (*ndelconss)++;
9113 
9114  return SCIP_OKAY;
9115 }
9116 
9117 /* processes equality with exactly two variables by aggregating one of the variables and deleting the constraint */
9118 static
9120  SCIP* scip, /**< SCIP data structure */
9121  SCIP_CONS* cons, /**< linear constraint */
9122  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9123  int* naggrvars, /**< pointer to count number of aggregated variables */
9124  int* ndelconss /**< pointer to count number of deleted constraints */
9125  )
9126 {
9127  SCIP_CONSDATA* consdata;
9128  SCIP_Bool infeasible;
9129  SCIP_Bool redundant;
9130  SCIP_Bool aggregated;
9131 
9132  assert(scip != NULL);
9133  assert(cons != NULL);
9134  assert(cutoff != NULL);
9135  assert(naggrvars != NULL);
9136  assert(ndelconss != NULL);
9137 
9138  consdata = SCIPconsGetData(cons);
9139  assert(consdata != NULL);
9140  assert(consdata->nvars == 2);
9141  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9142 
9143  SCIPdebugMessage("linear constraint <%s>: aggregate %.15g<%s> + %.15g<%s> == %.15g\n",
9144  SCIPconsGetName(cons), consdata->vals[0], SCIPvarGetName(consdata->vars[0]),
9145  consdata->vals[1], SCIPvarGetName(consdata->vars[1]), consdata->rhs);
9146 
9147  /* aggregate the equality */
9148  SCIP_CALL( SCIPaggregateVars(scip, consdata->vars[0], consdata->vars[1], consdata->vals[0], consdata->vals[1],
9149  consdata->rhs, &infeasible, &redundant, &aggregated) );
9150 
9151  /* check for infeasibility of aggregation */
9152  if( infeasible )
9153  {
9154  SCIPdebugMessage(" -> infeasible aggregation\n");
9155  *cutoff = TRUE;
9156  return SCIP_OKAY;
9157  }
9158 
9159  /* count the aggregation */
9160  if( aggregated )
9161  (*naggrvars)++;
9162 
9163  /* delete the constraint, if it is redundant */
9164  if( redundant )
9165  {
9166  SCIP_CALL( SCIPdelCons(scip, cons) );
9167 
9168  if( !consdata->upgraded )
9169  (*ndelconss)++;
9170  }
9171 
9172  return SCIP_OKAY;
9173 }
9174 
9175 /** calculates the new lhs and rhs of the constraint after the given variable is aggregated out */
9176 static
9178  SCIP* scip, /**< SCIP data structure */
9179  SCIP_CONSDATA* consdata, /**< linear constraint data */
9180  SCIP_VAR* slackvar, /**< variable to be aggregated out */
9181  SCIP_Real slackcoef, /**< coefficient of variable in constraint */
9182  SCIP_Real* newlhs, /**< pointer to store new lhs of constraint */
9183  SCIP_Real* newrhs /**< pointer to store new rhs of constraint */
9184  )
9185 {
9186  SCIP_Real slackvarlb;
9187  SCIP_Real slackvarub;
9188 
9189  assert(scip != NULL);
9190  assert(consdata != NULL);
9191  assert(newlhs != NULL);
9192  assert(newrhs != NULL);
9193  assert(!SCIPisInfinity(scip, -consdata->lhs));
9194  assert(!SCIPisInfinity(scip, consdata->rhs));
9195 
9196  slackvarlb = SCIPvarGetLbGlobal(slackvar);
9197  slackvarub = SCIPvarGetUbGlobal(slackvar);
9198  if( slackcoef > 0.0 )
9199  {
9200  if( SCIPisInfinity(scip, -slackvarlb) )
9201  *newrhs = SCIPinfinity(scip);
9202  else
9203  *newrhs = consdata->rhs - slackcoef * slackvarlb;
9204  if( SCIPisInfinity(scip, slackvarub) )
9205  *newlhs = -SCIPinfinity(scip);
9206  else
9207  *newlhs = consdata->lhs - slackcoef * slackvarub;
9208  }
9209  else
9210  {
9211  if( SCIPisInfinity(scip, -slackvarlb) )
9212  *newlhs = -SCIPinfinity(scip);
9213  else
9214  *newlhs = consdata->rhs - slackcoef * slackvarlb;
9215  if( SCIPisInfinity(scip, slackvarub) )
9216  *newrhs = SCIPinfinity(scip);
9217  else
9218  *newrhs = consdata->lhs - slackcoef * slackvarub;
9219  }
9220  assert(SCIPisLE(scip, *newlhs, *newrhs));
9221 }
9222 
9223 #define MAXMULTIAGGRQUOTIENT 1e+03
9224 
9225 /* processes equality with more than two variables by multi-aggregating one of the variables and converting the equality
9226  * into an inequality; if multi-aggregation is not possible, tries to identify one continuous or integer variable that
9227  * is implicitly integral by this constraint
9228  *
9229  * @todo Check whether a more clever way of avoiding aggregation of variables containing implicitly integer variables
9230  * can help.
9231  */
9232 static
9234  SCIP* scip, /**< SCIP data structure */
9235  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
9236  SCIP_CONS* cons, /**< linear constraint */
9237  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9238  int* naggrvars, /**< pointer to count number of aggregated variables */
9239  int* ndelconss /**< pointer to count number of deleted constraints */
9240  )
9241 {
9242  SCIP_CONSDATA* consdata;
9243  SCIP_VAR** vars;
9244  SCIP_Real* vals;
9245  SCIP_VARTYPE bestslacktype;
9246  SCIP_VARTYPE slacktype;
9247  SCIP_Real lhs;
9248  SCIP_Real rhs;
9249  SCIP_Real bestslackdomrng;
9250  SCIP_Real minabsval;
9251  SCIP_Real maxabsval;
9252  SCIP_Bool bestremovescons;
9253  SCIP_Bool coefszeroone;
9254  SCIP_Bool coefsintegral;
9255  SCIP_Bool varsintegral;
9256  SCIP_Bool infeasible;
9257  SCIP_Bool samevar;
9258  int supinf; /* counter for infinite contributions to the supremum of a possible
9259  * multi-aggregation
9260  */
9261  int infinf; /* counter for infinite contributions to the infimum of a possible
9262  * multi-aggregation
9263  */
9264  int maxnlocksstay;
9265  int maxnlocksremove;
9266  int bestslackpos;
9267  int bestnlocks;
9268  int ncontvars;
9269  int contvarpos;
9270  int nintvars;
9271  int nimplvars;
9272  int intvarpos;
9273  int v;
9274 
9275  assert(scip != NULL);
9276  assert(cons != NULL);
9277  assert(cutoff != NULL);
9278  assert(naggrvars != NULL);
9279 
9280  consdata = SCIPconsGetData(cons);
9281  assert(consdata != NULL);
9282  assert(consdata->nvars > 2);
9283  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9284 
9285  SCIPdebugMessage("linear constraint <%s>: try to multi-aggregate equality\n", SCIPconsGetName(cons));
9286 
9287  /* We do not want to increase the total number of non-zeros due to the multi-aggregation.
9288  * Therefore, we have to restrict the number of locks of a variable that is aggregated out.
9289  * maxnlocksstay: maximal sum of lock numbers if the constraint does not become redundant after the aggregation
9290  * maxnlocksremove: maximal sum of lock numbers if the constraint can be deleted after the aggregation
9291  */
9292  lhs = consdata->lhs;
9293  rhs = consdata->rhs;
9294  maxnlocksstay = 0;
9295  if( consdata->nvars == 3 )
9296  {
9297  /* If the constraint becomes redundant, 3 non-zeros are removed, and we get 1 additional non-zero for each
9298  * constraint the variable appears in. Thus, the variable must appear in at most 3 other constraints.
9299  */
9300  maxnlocksremove = 3;
9301  }
9302  else if( consdata->nvars == 4 )
9303  {
9304  /* If the constraint becomes redundant, 4 non-zeros are removed, and we get 2 additional non-zeros for each
9305  * constraint the variable appears in. Thus, the variable must appear in at most 2 other constraints.
9306  */
9307  maxnlocksremove = 2;
9308  }
9309  else
9310  {
9311  /* If the constraint is redundant but has more than 4 variables, we can only accept one other constraint. */
9312  maxnlocksremove = 1;
9313  }
9314 
9315  /* the locks on this constraint can be ignored */
9316  if( SCIPconsIsChecked(cons) )
9317  {
9318  if( !SCIPisInfinity(scip, -lhs) )
9319  {
9320  maxnlocksstay++;
9321  maxnlocksremove++;
9322  }
9323  if( !SCIPisInfinity(scip, rhs) )
9324  {
9325  maxnlocksstay++;
9326  maxnlocksremove++;
9327  }
9328  }
9329 
9330  /* look for a slack variable s to convert a*x + s == b into lhs <= a*x <= rhs */
9331  vars = consdata->vars;
9332  vals = consdata->vals;
9333  bestslackpos = -1;
9334  bestslacktype = SCIP_VARTYPE_BINARY;
9335  bestnlocks = INT_MAX;
9336  bestremovescons = FALSE;
9337  bestslackdomrng = 0.0;
9338  coefszeroone = TRUE;
9339  coefsintegral = TRUE;
9340  varsintegral = TRUE;
9341  ncontvars = 0;
9342  contvarpos = -1;
9343  nintvars = 0;
9344  nimplvars = 0;
9345  intvarpos = -1;
9346  minabsval = SCIPinfinity(scip);
9347  maxabsval = -1.0;
9348  for( v = 0; v < consdata->nvars; ++v )
9349  {
9350  SCIP_VAR* var;
9351  SCIP_Real val;
9352  SCIP_Real absval;
9353  SCIP_Real varlb;
9354  SCIP_Real varub;
9355  SCIP_Bool iscont;
9356  int nlocks;
9357 
9358  assert(vars != NULL);
9359  assert(vals != NULL);
9360 
9361  var = vars[v];
9362  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksDown(var) >= 1); /* because variable is locked in this equality */
9363  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksUp(var) >= 1);
9364  varlb = SCIPvarGetLbGlobal(var);
9365  varub = SCIPvarGetUbGlobal(var);
9366 
9367  val = vals[v];
9368  absval = REALABS(val);
9369  assert(SCIPisPositive(scip, absval));
9370 
9371  /* calculate minimal and maximal absolute value */
9372  if( absval < minabsval )
9373  minabsval = absval;
9374  if( absval > maxabsval )
9375  maxabsval = absval;
9376 
9377  /* do not try to multi aggregate, when numerical bad */
9378  if( maxabsval / minabsval > MAXMULTIAGGRQUOTIENT )
9379  return SCIP_OKAY;
9380 
9381  slacktype = SCIPvarGetType(var);
9382  coefszeroone = coefszeroone && SCIPisEQ(scip, absval, 1.0);
9383  coefsintegral = coefsintegral && SCIPisIntegral(scip, val);
9384  varsintegral = varsintegral && (slacktype != SCIP_VARTYPE_CONTINUOUS);
9385  iscont = (slacktype == SCIP_VARTYPE_CONTINUOUS || slacktype == SCIP_VARTYPE_IMPLINT);
9386 
9387  /* update candidates for continuous -> implint and integer -> implint conversion */
9388  if( slacktype == SCIP_VARTYPE_CONTINUOUS )
9389  {
9390  ncontvars++;
9391  contvarpos = v;
9392  }
9393  else if( slacktype == SCIP_VARTYPE_IMPLINT )
9394  {
9395  ++nimplvars;
9396  }
9397  else if( slacktype == SCIP_VARTYPE_INTEGER )
9398  {
9399  nintvars++;
9400  intvarpos = v;
9401  }
9402 
9403  /* check, if variable is already fixed or aggregated */
9404  if( !SCIPvarIsActive(var) )
9405  continue;
9406 
9407  /* check, if variable is used in too many other constraints, even if this constraint could be deleted */
9408  nlocks = SCIPvarGetNLocksDown(var) + SCIPvarGetNLocksUp(var);
9409 
9410  if( nlocks > maxnlocksremove )
9411  continue;
9412 
9413  /* check, if variable can be used as a slack variable */
9414  if( (iscont || (coefsintegral && varsintegral && SCIPisEQ(scip, absval, 1.0))) &&
9415  !SCIPdoNotMultaggrVar(scip, var) )
9416  {
9417  SCIP_Bool better;
9418  SCIP_Bool equal;
9419  SCIP_Real slackdomrng;
9420 
9421  if( SCIPisInfinity(scip, varub) || SCIPisInfinity(scip, -varlb) )
9422  slackdomrng = SCIPinfinity(scip);
9423  /* we do not want to perform multi-aggregation due to numerics, if the bounds are huge */
9424  else if( SCIPisHugeValue(scip, varub) || SCIPisHugeValue(scip, -varlb) )
9425  return SCIP_OKAY;
9426  else
9427  {
9428  slackdomrng = (varub - varlb)*absval;
9429  assert(!SCIPisInfinity(scip, slackdomrng));
9430  }
9431  equal = FALSE;
9432  better = (slacktype > bestslacktype) || (bestslackpos == -1);
9433  if( !better && slacktype == bestslacktype )
9434  {
9435  better = (nlocks < bestnlocks);
9436  if( nlocks == bestnlocks && !bestremovescons )
9437  {
9438  better = SCIPisGT(scip, slackdomrng, bestslackdomrng);
9439  equal = !better && SCIPisGE(scip, slackdomrng, bestslackdomrng);
9440  }
9441  }
9442 
9443  if( better || equal )
9444  {
9445  SCIP_Real minresactivity;
9446  SCIP_Real maxresactivity;
9447  SCIP_Real newlhs;
9448  SCIP_Real newrhs;
9449  SCIP_Bool removescons;
9450  SCIP_Bool minisrelax;
9451  SCIP_Bool maxisrelax;
9452  SCIP_Bool isminsettoinfinity;
9453  SCIP_Bool ismaxsettoinfinity;
9454 
9455  /* check if the constraint becomes redundant after multi-aggregation */
9456  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
9457  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
9458 
9459  /* do not perform the multi-aggregation due to numerics, if we have huge contributions in the residual
9460  * activity
9461  */
9462  if( minisrelax || maxisrelax )
9463  continue;
9464 
9465  getNewSidesAfterAggregation(scip, consdata, var, val, &newlhs, &newrhs);
9466  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9467 
9468  /* check resactivities for reliability */
9469  if( removescons )
9470  {
9471  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
9472  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
9473 
9474  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity)
9475  && SCIPisFeasLE(scip, newlhs, minresactivity))
9476  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
9477 
9478  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9479  }
9480 
9481  /* if parameter multaggrremove is set to TRUE, only aggregate when this removes constraint */
9482  if( conshdlrdata->multaggrremove && !removescons )
9483  continue;
9484 
9485  /* prefer variables that make the constraints redundant */
9486  if( bestremovescons && !removescons )
9487  continue;
9488 
9489  /* if the constraint does not become redundant, only accept the variable if it does not appear in
9490  * other constraints
9491  */
9492  if( !removescons && nlocks > maxnlocksstay )
9493  continue;
9494 
9495  better = better || (!bestremovescons && removescons);
9496  if( better )
9497  {
9498  bestslackpos = v;
9499  bestslacktype = slacktype;
9500  bestnlocks = nlocks;
9501  bestslackdomrng = slackdomrng;
9502  bestremovescons = removescons;
9503  }
9504  }
9505  }
9506  }
9507 
9508  /* if all coefficients and variables are integral, the right hand side must also be integral */
9509  if( coefsintegral && varsintegral && !SCIPisFeasIntegral(scip, consdata->rhs) )
9510  {
9511  SCIPdebugMessage("linear equality <%s> is integer infeasible\n", SCIPconsGetName(cons));
9512  SCIPdebugPrintCons(scip, cons, NULL);
9513  *cutoff = TRUE;
9514  return SCIP_OKAY;
9515  }
9516 
9517  supinf = 0;
9518  infinf = 0;
9519  samevar = FALSE;
9520 
9521  /* check whether the the infimum and the supremum of the multi-aggregation can be get infinite */
9522  for( v = 0; v < consdata->nvars; ++v )
9523  {
9524  if( v != bestslackpos )
9525  {
9526  if( SCIPisPositive(scip, consdata->vals[v]) )
9527  {
9528  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9529  {
9530  ++supinf;
9531  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9532  {
9533  ++infinf;
9534  samevar = TRUE;
9535  }
9536  }
9537  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9538  ++infinf;
9539 
9540  }
9541  else if( SCIPisNegative(scip, consdata->vals[v]) )
9542  {
9543  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9544  {
9545  ++supinf;
9546  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9547  {
9548  ++infinf;
9549  samevar = TRUE;
9550  }
9551  }
9552  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9553  ++infinf;
9554  }
9555  }
9556  }
9557  assert(!samevar || (supinf > 0 && infinf > 0));
9558 
9559  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
9560  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
9561  if( (samevar && (supinf > 1 || infinf > 1)) || (!samevar && supinf > 0 && infinf > 0) )
9562  {
9563  SCIPdebugMessage("do not perform multi-aggregation: infimum and supremum are both infinite\n");
9564  return SCIP_OKAY;
9565  }
9566 
9567  /* if the slack variable is of integer type, and the constraint itself may take fractional values,
9568  * we cannot aggregate the variable, because the integrality condition would get lost
9569  * Similarly, if there are implicitly integral variables we cannot aggregate, since we might
9570  * loose the integrality condition for this variable.
9571  */
9572  if( bestslackpos >= 0
9573  && (bestslacktype == SCIP_VARTYPE_CONTINUOUS || bestslacktype == SCIP_VARTYPE_IMPLINT
9574  || (coefsintegral && varsintegral && nimplvars == 0)) )
9575  {
9576  SCIP_VAR* slackvar;
9577  SCIP_Real* scalars;
9578  SCIP_Real slackcoef;
9579  SCIP_Real aggrconst;
9580  SCIP_Real newlhs;
9581  SCIP_Real newrhs;
9582  SCIP_Bool aggregated;
9583 
9584  /* we found a slack variable that only occurs in at most one other constraint:
9585  * a_1*x_1 + ... + a_k*x_k + a'*s == rhs -> s == rhs - a_1/a'*x_1 - ... - a_k/a'*x_k
9586  */
9587  assert(bestslackpos < consdata->nvars);
9588 
9589  /* do not multi aggregate binary variables */
9590  if( SCIPvarIsBinary(vars[bestslackpos]) )
9591  return SCIP_OKAY;
9592 
9593  /* convert equality into inequality by deleting the slack variable:
9594  * x + a*s == b, l <= s <= u -> b - a*u <= x <= b - a*l
9595  */
9596  slackvar = vars[bestslackpos];
9597  slackcoef = vals[bestslackpos];
9598  assert(!SCIPisZero(scip, slackcoef));
9599  aggrconst = consdata->rhs/slackcoef;
9600 
9601  getNewSidesAfterAggregation(scip, consdata, slackvar, slackcoef, &newlhs, &newrhs);
9602  assert(SCIPisLE(scip, newlhs, newrhs));
9603  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9604  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9605  SCIP_CALL( delCoefPos(scip, cons, bestslackpos) );
9606 
9607  /* allocate temporary memory */
9608  SCIP_CALL( SCIPallocBufferArray(scip, &scalars, consdata->nvars) );
9609 
9610  /* set up the multi-aggregation */
9611  SCIPdebugMessage("linear constraint <%s>: multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(slackvar));
9612  for( v = 0; v < consdata->nvars; ++v )
9613  {
9614  scalars[v] = -consdata->vals[v]/slackcoef;
9615  SCIPdebugPrintf(" %+.15g<%s>", scalars[v], SCIPvarGetName(vars[v]));
9616  }
9617  SCIPdebugPrintf(" %+.15g, bounds of <%s>: [%.15g,%.15g], nlocks=%d, maxnlocks=%d, removescons=%u\n",
9618  aggrconst, SCIPvarGetName(slackvar), SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar),
9619  bestnlocks, bestremovescons ? maxnlocksremove : maxnlocksstay, bestremovescons);
9620 
9621  /* perform the multi-aggregation */
9622  SCIP_CALL( SCIPmultiaggregateVar(scip, slackvar, consdata->nvars, vars, scalars, aggrconst,
9623  &infeasible, &aggregated) );
9624  assert(aggregated);
9625 
9626  /* free temporary memory */
9627  SCIPfreeBufferArray(scip, &scalars);
9628 
9629  /* check for infeasible aggregation */
9630  if( infeasible )
9631  {
9632  SCIPdebugMessage("linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
9633  *cutoff = TRUE;
9634  return SCIP_OKAY;
9635  }
9636 
9637  (*naggrvars)++;
9638 
9639  /* delete the constraint if it became redundant */
9640  if( bestremovescons )
9641  {
9642  SCIPdebugMessage("linear constraint <%s>: redundant after multi-aggregation\n", SCIPconsGetName(cons));
9643  SCIP_CALL( SCIPdelCons(scip, cons) );
9644 
9645  if( !consdata->upgraded )
9646  (*ndelconss)++;
9647  }
9648  }
9649  else if( ncontvars == 1 )
9650  {
9651  SCIP_VAR* var;
9652 
9653  assert(0 <= contvarpos && contvarpos < consdata->nvars);
9654  var = vars[contvarpos];
9655  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
9656 
9657  if( coefsintegral && SCIPisFeasIntegral(scip, consdata->rhs) )
9658  {
9659  /* upgrade continuous variable to an implicit one, if the absolute value of the coefficient is one */
9660  if( SCIPisEQ(scip, REALABS(vals[contvarpos]), 1.0) )
9661  {
9662  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
9663  SCIPdebugMessage("linear constraint <%s>: converting continuous variable <%s> to implicit integer variable\n",
9664  SCIPconsGetName(cons), SCIPvarGetName(var));
9665  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
9666  if( infeasible )
9667  {
9668  SCIPdebugMessage("infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
9669  *cutoff = TRUE;
9670 
9671  return SCIP_OKAY;
9672  }
9673  }
9674  /* aggregate continuous variable to an implicit one, if the absolute value of the coefficient is unequal to one */
9675  /* @todo check if the aggregation coefficient should be in some range(, which is not too big) */
9676  else if( !SCIPdoNotAggr(scip) )
9677  {
9678  SCIP_VAR* newvar;
9679  SCIP_Real absval;
9680  char newvarname[SCIP_MAXSTRLEN];
9681  SCIP_Bool redundant;
9682  SCIP_Bool aggregated;
9683 
9684  absval = REALABS(vals[contvarpos]);
9685 
9686  (void) SCIPsnprintf(newvarname, SCIP_MAXSTRLEN, "%s_impl", SCIPvarGetName(var));
9687 
9688  /* create new implicit variable for aggregation */
9689  SCIP_CALL( SCIPcreateVar(scip, &newvar, newvarname, -SCIPinfinity(scip), SCIPinfinity(scip), 0.0,
9691 
9692  /* add new variable to problem */
9693  SCIP_CALL( SCIPaddVar(scip, newvar) );
9694 
9695 #ifdef SCIP_DEBUG_SOLUTION
9696  if( SCIPdebugIsMainscip(scip) )
9697  {
9698  SCIP_Real varval;
9699  SCIP_CALL( SCIPdebugGetSolVal(scip, var, &varval) );
9700  SCIP_CALL( SCIPdebugAddSolVal(scip, newvar, absval * varval) );
9701  }
9702 #endif
9703 
9704  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
9705  SCIPdebugMessage("linear constraint <%s>: aggregating continuous variable <%s> to newly created implicit integer variable <%s>, aggregation factor = %g\n",
9706  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetName(newvar), absval);
9707 
9708  /* aggregate continuous and implicit variable */
9709  SCIP_CALL( SCIPaggregateVars(scip, var, newvar, absval, -1.0, 0.0, &infeasible, &redundant, &aggregated) );
9710 
9711  if( infeasible )
9712  {
9713  SCIPdebugMessage("infeasible aggregation of variable <%s> to implicit variable <%s>, domain is empty\n",
9714  SCIPvarGetName(var), SCIPvarGetName(newvar));
9715  *cutoff = TRUE;
9716 
9717  /* release implicit variable */
9718  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
9719 
9720  return SCIP_OKAY;
9721  }
9722 
9723  if( aggregated )
9724  (*naggrvars)++;
9725 
9726  /* release implicit variable */
9727  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
9728  }
9729 
9730  /* we do not have any event on vartype changes, so we need to manually force this constraint to be presolved
9731  * again
9732  */
9733  consdata->boundstightened = FALSE;
9734  consdata->presolved = FALSE;
9735  }
9736  }
9737  else if( ncontvars == 0 && nimplvars == 0 && nintvars == 1 && !coefszeroone )
9738  {
9739  SCIP_VAR* var;
9740 
9741  /* this seems to help for rococo instances, but does not for rout (where all coefficients are +/- 1.0)
9742  * -> we don't convert integers into implints if the row is a 0/1-row
9743  */
9744  assert(varsintegral);
9745  assert(0 <= intvarpos && intvarpos < consdata->nvars);
9746  var = vars[intvarpos];
9747  assert(SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER);
9748 
9749  if( coefsintegral
9750  && SCIPisEQ(scip, REALABS(vals[intvarpos]), 1.0)
9751  && SCIPisFeasIntegral(scip, consdata->rhs) )
9752  {
9753  /* convert the integer variable with coefficient 1.0 into an implicit integer variable */
9754  SCIPdebugMessage("linear constraint <%s>: converting integer variable <%s> to implicit integer variable\n",
9755  SCIPconsGetName(cons), SCIPvarGetName(var));
9756  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
9757  if( infeasible )
9758  {
9759  SCIPdebugMessage("infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
9760  *cutoff = TRUE;
9761 
9762  return SCIP_OKAY;
9763  }
9764  }
9765  }
9766 
9767  return SCIP_OKAY;
9768 }
9769 
9770 /** checks if the given variables and their coefficient are equal (w.r.t. scaling factor) to the objective function */
9771 static
9773  SCIP* scip, /**< SCIP data structure */
9774  SCIP_CONSDATA* consdata, /**< linear constraint data */
9775  SCIP_Real* scale, /**< pointer to store the scaling factor between the constraint and the
9776  * objective function
9777  */
9778  SCIP_Real* offset /**< pointer to store the offset of the objective function resulting by
9779  * this constraint
9780  */
9781  )
9782 {
9783  SCIP_VAR** vars;
9784  SCIP_VAR* var;
9785  SCIP_Real objval;
9786  SCIP_Bool negated;
9787  int nvars;
9788  int v;
9789 
9790  vars = consdata->vars;
9791  nvars = consdata->nvars;
9792  assert(vars != NULL);
9793 
9794  for( v = 0; v < nvars; ++v )
9795  {
9796  negated = FALSE;
9797  var = vars[v];
9798  assert(vars != NULL);
9799 
9800  if( SCIPvarIsNegated(var) )
9801  {
9802  negated = TRUE;
9803  var = SCIPvarGetNegatedVar(var);
9804  assert(var != NULL);
9805  }
9806 
9807  objval = SCIPvarGetObj(var);
9808 
9809  /* if a variable has a zero objective coefficient the linear constraint is not a subset of the objective
9810  * function
9811  */
9812  if( SCIPisZero(scip, objval) )
9813  return FALSE;
9814  else
9815  {
9816  SCIP_Real val;
9817 
9818  val = consdata->vals[v];
9819 
9820  if( negated )
9821  {
9822  if( v == 0 )
9823  {
9824  /* the first variable defines the scale */
9825  (*scale) = val / -objval;
9826 
9827  (*offset) += val;
9828  }
9829  else if( SCIPisEQ(scip, -objval * (*scale), val) )
9830  (*offset) += val;
9831  else
9832  return FALSE;
9833  }
9834  else if( v == 0 )
9835  {
9836  /* the first variable defines the scale */
9837  (*scale) = val / objval;
9838  }
9839  else if( !SCIPisEQ(scip, objval * (*scale), val) )
9840  return FALSE;
9841  }
9842  }
9843 
9844  return TRUE;
9845 }
9846 
9847 /** check if the linear equality constraint is equal to a subset of the objective function; if so we can remove the
9848  * objective coefficients and add an objective offset
9849  */
9850 static
9852  SCIP* scip, /**< SCIP data structure */
9853  SCIP_CONS* cons, /**< linear equation constraint */
9854  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
9855  )
9856 {
9857  SCIP_CONSDATA* consdata;
9858  SCIP_Real offset;
9859  SCIP_Real scale;
9860  SCIP_Bool applicable;
9861  int nobjvars;
9862  int nvars;
9863  int v;
9864 
9865  assert(scip != NULL);
9866  assert(cons != NULL);
9867  assert(conshdlrdata != NULL);
9868 
9869  consdata = SCIPconsGetData(cons);
9870  assert(consdata != NULL);
9871  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9872 
9873  nvars = consdata->nvars;
9874  nobjvars = SCIPgetNObjVars(scip);
9875 
9876  /* check if the linear equality constraints does not have more variables than the objective function */
9877  if( nvars > nobjvars || nvars == 0 )
9878  return SCIP_OKAY;
9879 
9880  /* check for allowance of algorithm */
9881  if( (nvars < nobjvars && !conshdlrdata->detectpartialobjective) ||
9882  (nvars == nobjvars && (!conshdlrdata->detectcutoffbound || !conshdlrdata->detectlowerbound)) )
9883  return SCIP_OKAY;
9884 
9885  offset = consdata->rhs;
9886  scale = 1.0;
9887 
9888  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
9889  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
9890 
9891  if( applicable )
9892  {
9893  SCIP_VAR** vars;
9894 
9895  vars = consdata->vars;
9896  assert(vars != NULL);
9897 
9898  offset /= scale;
9899 
9900  SCIPdebugMessage("linear equality constraint <%s> == %g (offset %g) is a subset of the objective function\n",
9901  SCIPconsGetName(cons), consdata->rhs, offset);
9902 
9903  /* set all objective coefficient to zero */
9904  for( v = 0; v < nvars; ++v )
9905  {
9906  SCIP_CALL( SCIPchgVarObj(scip, vars[v], 0.0) );
9907  }
9908 
9909  /* add an objective offset */
9910  SCIP_CALL( SCIPaddObjoffset(scip, offset) );
9911  }
9912 
9913  return SCIP_OKAY;
9914 }
9915 
9916 /** updates the cutoff if the given primal bound (which is implied by the given constraint) is better */
9917 static
9919  SCIP* scip, /**< SCIP data structure */
9920  SCIP_CONS* cons, /**< constraint */
9921  SCIP_Real primalbound /**< feasible primal bound */
9922  )
9923 {
9924  SCIP_Real cutoffbound;
9925 
9926  /* increase the cutoff bound value by an epsilon to ensue that solution with the value of the cutoff bound are still
9927  * accepted
9928  */
9929  cutoffbound = primalbound + SCIPcutoffbounddelta(scip);
9930 
9931  if( cutoffbound < SCIPgetCutoffbound(scip) )
9932  {
9933  SCIPdebugMessage("update cutoff bound <%g>\n", cutoffbound);
9935  SCIP_CALL( SCIPupdateCutoffbound(scip, cutoffbound) );
9936  }
9937  else
9938  {
9939  SCIP_CONSDATA* consdata;
9940 
9941  consdata = SCIPconsGetData(cons);
9942  assert(consdata != NULL);
9943 
9944  /* we cannot disable the enforcement and propagation on ranged rows, because the cutoffbound could only have
9945  * resulted from one side
9946  */
9947  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
9948  {
9949  /* in case the cutoff bound is worse then the currently known one, we additionally avoid enforcement and
9950  * propagation
9951  */
9952  SCIP_CALL( SCIPsetConsEnforced(scip, cons, FALSE) );
9953  SCIP_CALL( SCIPsetConsPropagated(scip, cons, FALSE) );
9954  }
9955  }
9956 
9957  return SCIP_OKAY;
9958 }
9959 
9960 /** check if the linear constraint is parallel to objective function; if so update the cutoff bound and avoid that the
9961  * constraint enters the LP by setting the initial and separated flag to FALSE
9962  */
9963 static
9965  SCIP* scip, /**< SCIP data structure */
9966  SCIP_CONS* cons, /**< linear constraint */
9967  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
9968  )
9969 {
9970  SCIP_CONSDATA* consdata;
9971  SCIP_Real offset;
9972  SCIP_Real scale;
9973  SCIP_Bool applicable;
9974  int nobjvars;
9975  int nvars;
9976 
9977  assert(scip != NULL);
9978  assert(cons != NULL);
9979  assert(conshdlrdata != NULL);
9981  consdata = SCIPconsGetData(cons);
9982  assert(consdata != NULL);
9983 
9984  /* ignore equalities since these are covert by the method checkPartialObjective() */
9985  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
9986  return SCIP_OKAY;
9987 
9988  nvars = consdata->nvars;
9989  nobjvars = SCIPgetNObjVars(scip);
9990 
9991  /* check if the linear inequality constraints has the same number of variables as the objective function and if the
9992  * initial and/or separated flag is set to FALSE
9993  */
9994  if( nvars != nobjvars || (!SCIPconsIsInitial(cons) && !SCIPconsIsSeparated(cons)) )
9995  return SCIP_OKAY;
9996 
9997  offset = 0.0;
9998  scale = 1.0;
9999 
10000  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
10001  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
10002 
10003  if( applicable )
10004  {
10005  SCIP_Bool rhsfinite = !SCIPisInfinity(scip, consdata->rhs);
10006  SCIP_Bool lhsfinite = !SCIPisInfinity(scip, -consdata->lhs);
10007 
10008  if( SCIPisPositive(scip, scale) )
10009  {
10010  if( conshdlrdata->detectcutoffbound && rhsfinite )
10011  {
10012  SCIP_Real primalbound;
10013 
10014  primalbound = (consdata->rhs - offset) / scale;
10015 
10016  SCIPdebugMessage("constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10017  SCIPconsGetName(cons), primalbound);
10018 
10019  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10020  }
10021 
10022  if( conshdlrdata->detectlowerbound && lhsfinite )
10023  {
10024  SCIP_Real lowerbound;
10025 
10026  lowerbound = (consdata->lhs - offset) / scale;
10027 
10028  SCIPdebugMessage("constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10029  SCIPconsGetName(cons), lowerbound);
10030 
10031  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10032  }
10033 
10034  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !lhsfinite)) ||
10035  (conshdlrdata->detectlowerbound && !rhsfinite) )
10036  {
10037  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10038  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10039  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10040  }
10041  }
10042  else
10043  {
10044  if( conshdlrdata->detectlowerbound && rhsfinite )
10045  {
10046  SCIP_Real lowerbound;
10047 
10048  lowerbound = (consdata->rhs - offset) / scale;
10049 
10050  SCIPdebugMessage("constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10051  SCIPconsGetName(cons), lowerbound);
10052 
10053  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10054  }
10055 
10056  if( conshdlrdata->detectcutoffbound && lhsfinite )
10057  {
10058  SCIP_Real primalbound;
10059 
10060  primalbound = (consdata->lhs - offset) / scale;
10061 
10062  SCIPdebugMessage("constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10063  SCIPconsGetName(cons), primalbound);
10064 
10065  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10066  }
10067 
10068  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !rhsfinite)) ||
10069  (conshdlrdata->detectlowerbound && !lhsfinite) )
10070  {
10071  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10072  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10073  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10074  }
10075  }
10076  }
10077 
10078  return SCIP_OKAY;
10079 }
10080 
10081 /** converts special equalities */
10082 static
10084  SCIP* scip, /**< SCIP data structure */
10085  SCIP_CONS* cons, /**< linear constraint */
10086  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
10087  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10088  int* nfixedvars, /**< pointer to count number of fixed variables */
10089  int* naggrvars, /**< pointer to count number of aggregated variables */
10090  int* ndelconss /**< pointer to count number of deleted constraints */
10091  )
10092 {
10093  SCIP_CONSDATA* consdata;
10094 
10095  assert(scip != NULL);
10096  assert(cons != NULL);
10097  assert(conshdlrdata != NULL);
10098  assert(cutoff != NULL);
10099  assert(nfixedvars != NULL);
10100  assert(naggrvars != NULL);
10101  assert(ndelconss != NULL);
10102 
10103  consdata = SCIPconsGetData(cons);
10104  assert(consdata != NULL);
10105  assert(consdata->removedfixings);
10106 
10107  /* do nothing on inequalities */
10108  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10109  return SCIP_OKAY;
10110 
10111  /* depending on the number of variables, call a special conversion method */
10112  if( consdata->nvars == 1 )
10113  {
10114  /* fix variable */
10115  SCIP_CALL( convertUnaryEquality(scip, cons, cutoff, nfixedvars, ndelconss) );
10116  }
10117  else if( consdata->nvars == 2 )
10118  {
10119  /* aggregate one of the variables */
10120  SCIP_CALL( convertBinaryEquality(scip, cons, cutoff, naggrvars, ndelconss) );
10121  }
10122  else
10123  {
10124  /* check if the equality is part of the objective function */
10125  SCIP_CALL( checkPartialObjective(scip, cons, conshdlrdata) );
10126 
10127  /* try to multi-aggregate one of the variables */
10128  SCIP_CALL( convertLongEquality(scip, conshdlrdata, cons, cutoff, naggrvars, ndelconss) );
10129  }
10130 
10131  return SCIP_OKAY;
10132 }
10133 
10134 /** returns whether the linear sum of all variables/coefficients except the given one divided by the given value is always
10135  * integral
10136  */
10137 static
10139  SCIP* scip, /**< SCIP data structure */
10140  SCIP_CONSDATA* consdata, /**< linear constraint */
10141  int pos, /**< position of variable to be left out */
10142  SCIP_Real val /**< value to divide the coefficients by */
10143  )
10144 {
10145  int v;
10146 
10147  assert(scip != NULL);
10148  assert(consdata != NULL);
10149  assert(0 <= pos && pos < consdata->nvars);
10150 
10151  for( v = 0; v < consdata->nvars; ++v )
10152  {
10153  if( v != pos && (!SCIPvarIsIntegral(consdata->vars[v]) || !SCIPisIntegral(scip, consdata->vals[v]/val)) )
10154  return FALSE;
10155  }
10156 
10157  return TRUE;
10158 }
10159 
10160 /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i
10161  * check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i
10162  */
10163 static
10165  SCIP* scip, /**< SCIP data structure */
10166  SCIP_Real side, /**< lhs or rhs */
10167  SCIP_Real val, /**< coefficient */
10168  SCIP_Real minresactivity, /**< minimal residual activity */
10169  SCIP_Real maxresactivity, /**< maximal residual activity */
10170  SCIP_Real* minval, /**< pointer to store calculated minval */
10171  SCIP_Real* maxval /**< pointer to store calculated maxval */
10172  )
10173 {
10174  assert(scip != NULL);
10175  assert(minval != NULL);
10176  assert(maxval != NULL);
10177 
10178  if( val > 0.0 )
10179  {
10180  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10181  *minval = -maxresactivity;
10182  else
10183  *minval = (side - maxresactivity)/val;
10184 
10185  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10186  *maxval = -minresactivity;
10187  else
10188  *maxval = (side - minresactivity)/val;
10189  }
10190  else
10191  {
10192  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10193  *minval = minresactivity;
10194  else
10195  *minval = (side - minresactivity)/val;
10196 
10197  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10198  *maxval = maxresactivity;
10199  else
10200  *maxval = (side - maxresactivity)/val;
10201  }
10202 }
10203 
10204 
10205 /* applies dual presolving for variables that are locked only once in a direction, and this locking is due to a
10206  * linear inequality
10207  */
10208 static
10210  SCIP* scip, /**< SCIP data structure */
10211  SCIP_CONS* cons, /**< linear constraint */
10212  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10213  int* nfixedvars, /**< pointer to count number of fixed variables */
10214  int* naggrvars, /**< pointer to count number of aggregated variables */
10215  int* ndelconss /**< pointer to count number of deleted constraints */
10216  )
10217 {
10218  SCIP_CONSDATA* consdata;
10219  SCIP_Bool lhsexists;
10220  SCIP_Bool rhsexists;
10221  SCIP_Bool bestisint;
10222  SCIP_Bool bestislhs;
10223  int bestpos;
10224  int i;
10225  int maxotherlocks;
10226 
10227  assert(scip != NULL);
10228  assert(cons != NULL);
10229  assert(cutoff != NULL);
10230  assert(nfixedvars != NULL);
10231  assert(naggrvars != NULL);
10232  assert(ndelconss != NULL);
10233 
10234  /* only process checked constraints (for which the locks are increased);
10235  * otherwise we would have to check for variables with nlocks == 0, and these are already processed by the
10236  * dualfix presolver
10237  */
10238  if( !SCIPconsIsChecked(cons) )
10239  return SCIP_OKAY;
10240 
10241  consdata = SCIPconsGetData(cons);
10242  assert(consdata != NULL);
10243 
10244  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
10245  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
10246 
10247  /* search for a single-locked variable which can be multi-aggregated; if a valid continuous variable was found, we
10248  * can use it safely for aggregation and break the search loop
10249  */
10250  bestpos = -1;
10251  bestisint = TRUE;
10252  bestislhs = FALSE;
10253 
10254  /* We only want to multi-aggregate variables, if they appear in maximal one additional constraint,
10255  * everything else would produce fill-in. Exceptions:
10256  * - If there are only two variables in the constraint from which the multi-aggregation arises, no fill-in will be
10257  * produced.
10258  * - If there are three variables in the constraint, multi-aggregation in three additional constraints will remove
10259  * six nonzeros (three from the constraint and the three entries of the multi-aggregated variable) and add
10260  * six nonzeros (two variables per substitution).
10261  * - If there at most four variables in the constraint, multi-aggregation in two additional constraints will remove
10262  * six nonzeros (four from the constraint and the two entries of the multi-aggregated variable) and add
10263  * six nonzeros (three variables per substitution). God exists!
10264  */
10265  if( consdata->nvars <= 2 )
10266  maxotherlocks = INT_MAX;
10267  else if( consdata->nvars == 3 )
10268  maxotherlocks = 3;
10269  else if( consdata->nvars == 4 )
10270  maxotherlocks = 2;
10271  else
10272  maxotherlocks = 1;
10273 
10274  /* if this constraint has both sides, it also provides a lock for the other side and thus we can allow one more lock */
10275  if( lhsexists && rhsexists )
10276  maxotherlocks++;
10277 
10278  for( i = 0; i < consdata->nvars && bestisint; ++i )
10279  {
10280  SCIP_VAR* var;
10281  SCIP_Bool isint;
10282  SCIP_Real val;
10283  SCIP_Real obj;
10284  SCIP_Real lb;
10285  SCIP_Real ub;
10286  SCIP_Bool agglhs;
10287  SCIP_Bool aggrhs;
10288 
10289  var = consdata->vars[i];
10291 
10292  /* if we already found a candidate, skip integers */
10293  if( bestpos >= 0 && isint )
10294  continue;
10295 
10296  /* better do not multi-aggregate binary variables, since most plugins rely on their binary variables to be either
10297  * active, fixed, or single-aggregated with another binary variable
10298  */
10299  if( SCIPvarIsBinary(var) && consdata->nvars > 2 )
10300  continue;
10301 
10302  if ( SCIPdoNotMultaggrVar(scip, var) )
10303  continue;
10304 
10305  val = consdata->vals[i];
10306  obj = SCIPvarGetObj(var);
10307  lb = SCIPvarGetLbGlobal(var);
10308  ub = SCIPvarGetUbGlobal(var);
10309 
10310  /* lhs <= a_0 * x_0 + a_1 * x_1 + ... + a_{n-1} * x_{n-1} <= rhs
10311  *
10312  * a_i >= 0, c_i >= 0, lhs exists, nlocksdown(x_i) == 1:
10313  * - constraint is the only one that forbids fixing the variable to its lower bound
10314  * - 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
10315  *
10316  * a_i <= 0, c_i <= 0, lhs exists, nlocksup(x_i) == 1:
10317  * - constraint is the only one that forbids fixing the variable to its upper bound
10318  * - 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
10319  *
10320  * a_i >= 0, c_i <= 0, rhs exists, nlocksup(x_i) == 1:
10321  * - constraint is the only one that forbids fixing the variable to its upper bound
10322  * - 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
10323  *
10324  * a_i <= 0, c_i >= 0, rhs exists, nlocksdown(x_i) == 1:
10325  * - constraint is the only one that forbids fixing the variable to its lower bound
10326  * - 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
10327  *
10328  * but: all this is only applicable, if the aggregated value is inside x_i's bounds for all possible values
10329  * of all x_j
10330  * furthermore: we only want to apply this, if no fill-in will be produced
10331  */
10332  agglhs = lhsexists
10333  && ((val > 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDown(var) == 1
10334  && SCIPvarGetNLocksUp(var) <= maxotherlocks)
10335  || (val < 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUp(var) == 1
10336  && SCIPvarGetNLocksDown(var) <= maxotherlocks));
10337  aggrhs = rhsexists
10338  && ((val > 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUp(var) == 1
10339  && SCIPvarGetNLocksDown(var) <= maxotherlocks)
10340  || (val < 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDown(var) == 1
10341  && SCIPvarGetNLocksUp(var) <= maxotherlocks));
10342  if( agglhs || aggrhs )
10343  {
10344  SCIP_Real minresactivity;
10345  SCIP_Real maxresactivity;
10346  SCIP_Real minval;
10347  SCIP_Real maxval;
10348  SCIP_Bool minisrelax;
10349  SCIP_Bool maxisrelax;
10350  SCIP_Bool isminsettoinfinity;
10351  SCIP_Bool ismaxsettoinfinity;
10352 
10353  /* calculate bounds for \sum_{j \neq i} a_j * x_j */
10354  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
10355  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
10356  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10357 
10358  /* We called consdataGetActivityResiduals() saying that we do not need a good relaxation,
10359  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
10360  * This is needed, because we do not want to rely on relaxed finite resactivities.
10361  */
10362  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
10363 
10364  if( agglhs )
10365  {
10366  /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10367  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10368 
10369  assert(SCIPisLE(scip, minval, maxval));
10370  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10371  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10372  {
10373  SCIP_Real oldmaxresactivity;
10374  SCIP_Real oldminresactivity;
10375  SCIP_Bool recalculated;
10376 
10377  recalculated = FALSE;
10378  oldmaxresactivity = maxresactivity;
10379  oldminresactivity = minresactivity;
10380 
10381  /* check minresactivity for reliability */
10382  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10383  {
10384  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10385  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10386  isminsettoinfinity = TRUE; /* here it means only that it was even calculated */
10387  }
10388 
10389  /* check maxresactivity for reliability */
10390  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10391  {
10392  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10393  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10394  ismaxsettoinfinity = TRUE; /* here it means only that it was even calculated */
10395  }
10396 
10397  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10398  if( recalculated )
10399  {
10400  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10401 
10402  /* check again if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10403  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10404 
10405  assert(SCIPisLE(scip, minval, maxval));
10406  }
10407 
10408  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10409  {
10410  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10411  * in the multi-aggregation
10412  */
10413  if( !isint || (SCIPisIntegral(scip, consdata->lhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10414  {
10415  bestpos = i;
10416  bestisint = isint;
10417  bestislhs = TRUE;
10418  continue; /* no need to also look at the right hand side */
10419  }
10420  }
10421  }
10422  }
10423 
10424  if( aggrhs )
10425  {
10426  /* check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10427  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10428 
10429  assert(SCIPisLE(scip,minval,maxval));
10430  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10431  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10432  {
10433  SCIP_Real oldmaxresactivity;
10434  SCIP_Real oldminresactivity;
10435  SCIP_Bool recalculated;
10436 
10437  recalculated = FALSE;
10438  oldmaxresactivity = maxresactivity;
10439  oldminresactivity = minresactivity;
10440 
10441  /* check minresactivity for reliability */
10442  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10443  {
10444  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10445  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10446  }
10447 
10448  /* check maxresactivity for reliability */
10449  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10450  {
10451  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10452  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10453  }
10454 
10455  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10456  if( recalculated )
10457  {
10458  /* check again if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10459  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10460  assert(SCIPisLE(scip,minval,maxval));
10461  }
10462 
10463  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10464  {
10465  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10466  * in the multi-aggregation
10467  */
10468  if( !isint || (SCIPisIntegral(scip, consdata->rhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10469  {
10470  bestpos = i;
10471  bestisint = isint;
10472  bestislhs = FALSE;
10473  }
10474  }
10475  }
10476  }
10477  }
10478  }
10479 
10480  if( bestpos >= 0 )
10481  {
10482  SCIP_VAR** aggrvars;
10483  SCIP_Real* aggrcoefs;
10484  SCIP_Real aggrconst;
10485  SCIP_VAR* bestvar;
10486  SCIP_Real bestval;
10487  int naggrs;
10488  int j;
10489  SCIP_Bool infeasible;
10490  SCIP_Bool aggregated;
10491  SCIP_Bool samevar;
10492  int supinf; /* counter for infinite contributions to the supremum of a possible
10493  * multi-aggregation
10494  */
10495  int infinf; /* counter for infinite contributions to the infimum of a possible
10496  * multi-aggregation
10497  */
10498 
10499  assert(!bestislhs || lhsexists);
10500  assert(bestislhs || rhsexists);
10501 
10502  bestvar = consdata->vars[bestpos];
10503  bestval = consdata->vals[bestpos];
10504  assert(bestisint ==
10506 
10507  /* allocate temporary memory */
10508  SCIP_CALL( SCIPallocBufferArray(scip, &aggrvars, consdata->nvars-1) );
10509  SCIP_CALL( SCIPallocBufferArray(scip, &aggrcoefs, consdata->nvars-1) );
10510 
10511  /* set up the multi-aggregation */
10512  SCIPdebugPrintCons(scip, cons, NULL);
10513  SCIPdebugMessage("linear constraint <%s> (dual): multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(bestvar));
10514  naggrs = 0;
10515  supinf = 0;
10516  infinf = 0;
10517  samevar = FALSE;
10518 
10519  for( j = 0; j < consdata->nvars; ++j )
10520  {
10521  if( j != bestpos )
10522  {
10523  aggrvars[naggrs] = consdata->vars[j];
10524  aggrcoefs[naggrs] = -consdata->vals[j]/consdata->vals[bestpos];
10525  SCIPdebugPrintf(" %+.15g<%s>", aggrcoefs[naggrs], SCIPvarGetName(aggrvars[naggrs]));
10526  if( bestisint )
10527  {
10528  /* coefficient must be integral: round it to exact integral value */
10529  assert(SCIPisIntegral(scip, aggrcoefs[naggrs]));
10530  aggrcoefs[naggrs] = SCIPfloor(scip, aggrcoefs[naggrs]+0.5);
10531  }
10532 
10533  if( SCIPisPositive(scip, aggrcoefs[naggrs]) )
10534  {
10535  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
10536  {
10537  ++supinf;
10538  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
10539  {
10540  ++infinf;
10541  samevar = TRUE;
10542  }
10543  }
10544  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
10545  ++infinf;
10546  }
10547  else if( SCIPisNegative(scip, aggrcoefs[naggrs]) )
10548  {
10549  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
10550  {
10551  ++supinf;
10552  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
10553  {
10554  ++infinf;
10555  samevar = TRUE;
10556  }
10557  }
10558  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
10559  ++infinf;
10560  }
10561 
10562  naggrs++;
10563  }
10564  }
10565  assert(!samevar || (supinf > 0 && infinf > 0));
10566 
10567  aggrconst = (bestislhs ? consdata->lhs/bestval : consdata->rhs/bestval);
10568  SCIPdebugPrintf(" %+.15g, bounds of <%s>: [%.15g,%.15g]\n", aggrconst, SCIPvarGetName(bestvar),
10569  SCIPvarGetLbGlobal(bestvar), SCIPvarGetUbGlobal(bestvar));
10570  assert(naggrs == consdata->nvars-1);
10571 
10572  /* right hand side must be integral: round it to exact integral value */
10573  if( bestisint )
10574  {
10575  assert(SCIPisIntegral(scip, aggrconst));
10576  aggrconst = SCIPfloor(scip, aggrconst+0.5);
10577  }
10578 
10579  aggregated = FALSE;
10580  infeasible = FALSE;
10581 
10582  /* perform the multi-aggregation */
10583  if( (samevar && supinf == 1 && infinf == 1) || (!samevar && (supinf == 0 || infinf == 0)) )
10584  {
10585  /* @todo if multi-aggregate makes them numerical trouble, avoid them if the coefficients differ to much, see
10586  * also convertLongEquality() early termination due to coefficients
10587  */
10588  SCIP_CALL( SCIPmultiaggregateVar(scip, bestvar, naggrs, aggrvars, aggrcoefs, aggrconst, &infeasible, &aggregated) );
10589  }
10590  else
10591  {
10592  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
10593  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
10594  SCIPdebugMessage("do not perform multi-aggregation: infimum and supremum are both infinite\n");
10595  }
10596  /* free temporary memory */
10597  SCIPfreeBufferArray(scip, &aggrcoefs);
10598  SCIPfreeBufferArray(scip, &aggrvars);
10599 
10600  /* check for infeasible aggregation */
10601  if( infeasible )
10602  {
10603  SCIPdebugMessage("linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
10604  *cutoff = TRUE;
10605  return SCIP_OKAY;
10606  }
10607 
10608  /* delete the constraint, if the aggregation was successful */
10609  if( aggregated )
10610  {
10611  SCIP_CALL( SCIPdelCons(scip, cons) );
10612 
10613  if( !consdata->upgraded )
10614  (*ndelconss)++;
10615  (*naggrvars)++;
10616  }
10617  else
10618  {
10619  SCIPdebugMessage("aggregation non successful!\n");
10620  }
10621  }
10622 
10623  return SCIP_OKAY;
10624 }
10625 
10626 #define BINWEIGHT 1
10627 #define INTWEIGHT 4
10628 #define CONTWEIGHT 8
10629 
10630 /** gets weight for variable in a "weighted number of variables" sum */
10631 static
10632 int getVarWeight(
10633  SCIP_VAR* var /**< variable to get weight for */
10634  )
10635 {
10636  switch( SCIPvarGetType(var) )
10637  {
10638  case SCIP_VARTYPE_BINARY:
10639  return BINWEIGHT;
10640  case SCIP_VARTYPE_INTEGER:
10641  case SCIP_VARTYPE_IMPLINT:
10642  return INTWEIGHT;
10644  return CONTWEIGHT;
10645  default:
10646  SCIPerrorMessage("invalid variable type\n");
10647  SCIPABORT();
10648  return 0; /*lint !e527*/
10649  }
10650 }
10651 
10652 /** tries to aggregate variables in equations a^Tx = lhs
10653  * in case there are at most two binary variables with an odd coefficient and all other
10654  * variables are not continuous and have an even coefficient then:
10655  * - exactly one odd binary variables
10656  * this binary variables y can be fixed to 0 if the lhs is even and to 1 if the lhs is odd
10657  * - lhs is odd -> y = 1
10658  * - lhs is even -> y = 0
10659  * - exactly two odd binary variables
10660  * aggregate the two binary variables with odd coefficient
10661  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
10662  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
10663  */
10664 static
10666  SCIP* scip, /**< SCIP data structure */
10667  SCIP_CONS* cons, /**< linear constraint */
10668  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10669  int* nfixedvars, /**< pointer to count number of fixed variables */
10670  int* naggrvars, /**< pointer to count number of aggregated variables */
10671  int* ndelconss /**< pointer to count number of deleted constraints */
10672  )
10673 { /*lint --e{715}*/
10674  SCIP_CONSDATA* consdata;
10675  SCIP_Bool success;
10676 
10677  assert( scip != NULL );
10678  assert( cons != NULL );
10679 
10680  consdata = SCIPconsGetData(cons);
10681  assert( consdata != NULL );
10682 
10683  /* check if the linear constraint is an equation with integral right hand side */
10684  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) || !SCIPisIntegral(scip, consdata->lhs) )
10685  return SCIP_OKAY;
10686 
10687  /* try to fix and aggregated variables until nothing is possible anymore */
10688  do
10689  {
10690  int v;
10691  int nvars;
10692  SCIP_VAR** vars;
10693  SCIP_Real* vals;
10694  SCIP_Real lhs;
10695  SCIP_Bool lhsodd;
10696 
10697  SCIP_Bool infeasible;
10698  SCIP_Bool fixed;
10699  SCIP_Bool aggregated;
10700  SCIP_Bool redundant;
10701 
10702  SCIP_VAR* var1;
10703  SCIP_VAR* var2;
10704  int noddvars;
10705 
10706  success = FALSE;
10707 
10708  lhs = consdata->lhs;
10709  vars = consdata->vars;
10710  vals = consdata->vals;
10711  nvars = consdata->nvars;
10712 
10713  assert( !SCIPisInfinity(scip, ABS(lhs)) );
10714 
10715  var1 = NULL;
10716  var2 = NULL;
10717  noddvars = 0;
10718 
10719  /* search for binary variables with an odd coefficient */
10720  for( v = 0; v < nvars && noddvars < 3; ++v )
10721  {
10722  SCIP_Longint val;
10723 
10724  /* all coefficients and variables have to be integral */
10725  if( !SCIPisIntegral(scip, vals[v]) || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
10726  return SCIP_OKAY;
10727 
10728  val = (SCIP_Longint)SCIPfeasFloor(scip, vals[v]);
10729  if( val % 2 != 0 )
10730  {
10731  /* the odd values have to belong to binary variables */
10732  if( !SCIPvarIsBinary(vars[v]) )
10733  return SCIP_OKAY;
10734 
10735  if( noddvars == 0 )
10736  var1 = vars[v];
10737  else
10738  var2 = vars[v];
10739 
10740  noddvars++;
10741  }
10742  }
10743 
10744  /* check lhs is odd or even */
10745  lhsodd = (((SCIP_Longint)SCIPfeasFloor(scip, lhs)) % 2 != 0);
10746 
10747  if( noddvars == 1 )
10748  {
10749  assert( var1 != NULL );
10750 
10751  SCIPdebugMessage("linear constraint <%s>: try fixing variable <%s> to <%g>\n",
10752  SCIPconsGetName(cons), SCIPvarGetName(var1), lhsodd ? 1.0 : 0.0);
10753 
10754  SCIP_CALL( SCIPfixVar(scip, var1, lhsodd? 1.0 : 0.0, &infeasible, &fixed) );
10755 
10756  /* check for infeasibility of fixing */
10757  if( infeasible )
10758  {
10759  SCIPdebugMessage(" -> infeasible fixing\n");
10760  *cutoff = TRUE;
10761  return SCIP_OKAY;
10762  }
10763 
10764  if( fixed )
10765  {
10766  SCIPdebugMessage(" -> feasible fixing\n");
10767  (*nfixedvars)++;
10768  success = TRUE;
10769  }
10770  }
10771  else if( noddvars == 2 )
10772  {
10773  assert( var1 != NULL );
10774  assert( var2 != NULL );
10775 
10776  /* aggregate the two variables with odd coefficient
10777  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
10778  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
10779  */
10780  SCIPdebugMessage("linear constraint <%s>: try aggregation of variables <%s> and <%s>\n",
10781  SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
10782 
10783  SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, lhsodd ? 1.0 : -1.0,
10784  lhsodd ? 1.0 : 0.0, &infeasible, &redundant, &aggregated) );
10785 
10786  /* check for infeasibility of aggregation */
10787  if( infeasible )
10788  {
10789  SCIPdebugMessage(" -> infeasible aggregation\n");
10790  *cutoff = TRUE;
10791  return SCIP_OKAY;
10792  }
10793 
10794  /* count the aggregation */
10795  if( aggregated )
10796  {
10797  SCIPdebugMessage(" -> feasible aggregation\n");
10798  (*naggrvars)++;
10799  success = TRUE;
10800  }
10801  }
10802 
10803  if( success )
10804  {
10805  /* apply fixings and aggregation to successfully rerun this presolving step */
10806  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
10807 
10808  if( infeasible )
10809  {
10810  SCIPdebugMessage(" -> infeasible fixing\n");
10811  *cutoff = TRUE;
10812  return SCIP_OKAY;
10813  }
10814 
10815  /* normalize constraint */
10816  SCIP_CALL( normalizeCons(scip, cons) );
10817  }
10818  }
10819  while( success );
10820 
10821  return SCIP_OKAY;
10822 }
10823 
10824 
10825 
10826 /** sorting method for constraint data, compares two variables on given indices, continuous variables will be sorted to
10827  * the end and for all other variables the sortation will be in non-increasing order of their absolute value of the
10828  * coefficients
10829  */
10830 static
10831 SCIP_DECL_SORTINDCOMP(consdataCompSim)
10832 { /*lint --e{715}*/
10833  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
10834  SCIP_VARTYPE vartype1;
10835  SCIP_VARTYPE vartype2;
10836  SCIP_Real value;
10837 
10838  assert(consdata != NULL);
10839  assert(0 <= ind1 && ind1 < consdata->nvars);
10840  assert(0 <= ind2 && ind2 < consdata->nvars);
10841 
10842  vartype1 = SCIPvarGetType(consdata->vars[ind1]);
10843  vartype2 = SCIPvarGetType(consdata->vars[ind2]);
10844 
10845  if( vartype1 == SCIP_VARTYPE_CONTINUOUS )
10846  {
10847  /* continuous varibles will be sorted to the back */
10848  if( vartype2 != vartype1 )
10849  return +1;
10850  /* both variables are continuous */
10851  else
10852  return 0;
10853  }
10854  /* continuous variables will be sorted to the back */
10855  else if( vartype2 == SCIP_VARTYPE_CONTINUOUS )
10856  return -1;
10857 
10858  value = REALABS(consdata->vals[ind2]) - REALABS(consdata->vals[ind1]);
10859 
10860  /* for all non-continuous variables, the variables are sorted after decreasing absolute coefficients */
10861  return (value > 0 ? +1 : (value < 0 ? -1 : 0));
10862 }
10863 
10864 /** tries to simplify coefficients and delete variables in ranged row of the form lhs <= a^Tx <= rhs, e.g. using the greatest
10865  * common divisor
10866  *
10867  * 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
10868  * constraint to 1^Tx = 1
10869  */
10870 static
10872  SCIP* scip, /**< SCIP data structure */
10873  SCIP_CONS* cons, /**< linear constraint */
10874  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
10875  int* nchgsides /**< pointer to store the amount of changed sides */
10876  )
10877 {
10878  SCIP_CONSDATA* consdata;
10879  SCIP_VAR** vars;
10880  SCIP_Real* vals;
10881  SCIP_Real minval;
10882  SCIP_Real secondminval;
10883  SCIP_Real maxval;
10884  SCIP_Real lhs;
10885  SCIP_Real rhs;
10886  int nvars;
10887  int v;
10888 
10889  /* we must not change a modifiable constraint in any way */
10890  if( SCIPconsIsModifiable(cons) )
10891  return SCIP_OKAY;
10892 
10893  if( SCIPconsIsDeleted(cons) )
10894  return SCIP_OKAY;
10895 
10896  consdata = SCIPconsGetData(cons);
10897  assert(consdata != NULL);
10898 
10899  nvars = consdata->nvars;
10900 
10901  /* do not check empty or bound-constraints */
10902  if( nvars < 2 )
10903  return SCIP_OKAY;
10904 
10905  vals = consdata->vals;
10906  vars = consdata->vars;
10907  assert(vars != NULL);
10908  assert(vals != NULL);
10909 
10910  lhs = consdata->lhs;
10911  rhs = consdata->rhs;
10912  assert(!SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs));
10913  assert(!SCIPisNegative(scip, rhs));
10914 
10915  minval = SCIP_INVALID;
10916  secondminval = SCIP_INVALID;
10917  maxval = -SCIP_INVALID;
10918 
10919  for( v = nvars - 1; v >= 0; --v )
10920  {
10921  if( SCIPvarIsBinary(vars[v]) )
10922  {
10923  if( minval > vals[v] || minval == SCIP_INVALID ) /*lint !e777*/
10924  {
10925  secondminval = minval;
10926  minval = vals[v];
10927  }
10928  else if( secondminval > vals[v] || secondminval == SCIP_INVALID ) /*lint !e777*/
10929  secondminval = vals[v];
10930 
10931  if( maxval < vals[v] || maxval == -SCIP_INVALID ) /*lint !e777*/
10932  maxval = vals[v];
10933  }
10934  else
10935  break;
10936  }
10937 
10938  /* check if all variables are binary */
10939  if( v == -1 )
10940  {
10941  if( SCIPisEQ(scip, minval, maxval) && SCIPisEQ(scip, lhs, rhs) )
10942  return SCIP_OKAY;
10943 
10944  /* check if we can and need to choose exactly one binary variable */
10945  if( SCIPisGE(scip, minval, lhs) && SCIPisLE(scip, maxval, rhs) && SCIPisGT(scip, minval + secondminval, rhs) )
10946  {
10947  /* change all coefficients to 1.0 */
10948  for( v = nvars - 1; v >= 0; --v )
10949  {
10950  SCIP_CALL( chgCoefPos(scip, cons, v, 1.0) );
10951  }
10952  (*nchgcoefs) += nvars;
10953 
10954  /* replace old right and left hand side with 1.0 */
10955  SCIP_CALL( chgRhs(scip, cons, 1.0) );
10956  SCIP_CALL( chgLhs(scip, cons, 1.0) );
10957  (*nchgsides) += 2;
10958  }
10959  }
10960 
10961  return SCIP_OKAY;
10962 }
10963 
10964 /** tries to simplify coefficients and delete variables in constraints of the form lhs <= a^Tx <= rhs
10965  * for equations @see rangedRowSimplify() will be called
10966  *
10967  * there are several different coefficient reduction steps which will be applied
10968  *
10969  * 1. We try to determine parts of the constraint which will not change anything on (in-)feasibility of the constraint
10970  *
10971  * e.g. 5x1 + 5x2 + 3z1 <= 8 => 3z1 is redundant if all x are binary and -2 < 3z1 <= 3
10972  *
10973  * 2. We try to remove redundant fractional parts in a constraint
10974  *
10975  * e.g. 5.2x1 + 5.1x2 + 3x3 <= 8.3 => will be changed to 5x1 + 5x2 + 3x3 <= 8 if all x are binary
10976  *
10977  * 3. We are using the greatest common divisor for further reductions
10978  *
10979  * e.g. 10x1 + 5y2 + 5x3 + 3x4 <= 15 => will be changed to 2x1 + y2 + x3 + x4 <= 3 if all xi are binary and y2 is
10980  * integral
10981  */
10982 static
10984  SCIP* scip, /**< SCIP data structure */
10985  SCIP_CONS* cons, /**< linear constraint */
10986  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
10987  int* nchgsides /**< pointer to store the amount of changed sides */
10988  )
10989 {
10990  SCIP_CONSDATA* consdata;
10991  SCIP_VAR** vars;
10992  SCIP_Real* vals;
10993  int* perm;
10994  SCIP_Real minactsub;
10995  SCIP_Real maxactsub;
10996  SCIP_Real siderest;
10997  SCIP_Real feastol;
10998  SCIP_Real newcoef;
10999  SCIP_Real absval;
11000  SCIP_Real side;
11001  SCIP_Real lhs;
11002  SCIP_Real rhs;
11003  SCIP_Real lb;
11004  SCIP_Real ub;
11005  SCIP_Longint restcoef;
11006  SCIP_Longint oldgcd;
11007  SCIP_Longint rest;
11008  SCIP_Longint gcd;
11009  SCIP_Bool isminsettoinfinity;
11010  SCIP_Bool ismaxsettoinfinity;
11011  SCIP_Bool isminrelax;
11012  SCIP_Bool ismaxrelax;
11013  SCIP_Bool allcoefintegral;
11014  SCIP_Bool onlybin;
11015  SCIP_Bool hasrhs;
11016  SCIP_Bool haslhs;
11017  int oldnchgcoefs;
11018  int oldnchgsides;
11019  int foundbin;
11020  int candpos;
11021  int candpos2;
11022  int offsetv;
11023  int nvars;
11024  int v;
11025  int w;
11026 
11027  assert(scip != NULL);
11028  assert(cons != NULL);
11029  assert(nchgcoefs != NULL);
11030  assert(nchgsides != NULL);
11031 
11032  /* we must not change a modifiable constraint in any way */
11033  if( SCIPconsIsModifiable(cons) )
11034  return SCIP_OKAY;
11035 
11036  if( SCIPconsIsDeleted(cons) )
11037  return SCIP_OKAY;
11038 
11039  consdata = SCIPconsGetData(cons);
11040  assert(consdata != NULL);
11041 
11042  nvars = consdata->nvars;
11043 
11044  /* do not check empty or bound-constraints */
11045  if( nvars <= 2 )
11046  return SCIP_OKAY;
11047 
11048  /* update maximal activity delta if necessary */
11049  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
11050  consdataRecomputeMaxActivityDelta(scip, consdata);
11051 
11052  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
11053  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
11054  checkMaxActivityDelta(scip, consdata);
11055 
11056  /* @todo the following might be too hard, check which steps can be applied and what code must be corrected
11057  * accordingly
11058  */
11059  /* can only work with valid non-infinity activities per variable */
11060  if( SCIPisInfinity(scip, consdata->maxactdelta) )
11061  return SCIP_OKAY;
11062 
11063  /* @todo: change the following: due to vartype changes, the status of the normalization can be wrong, need an event
11064  * but the eventsystem seems to be full
11065  */
11066  consdata->normalized = FALSE;
11067 
11068  /* normalize constraint */
11069  SCIP_CALL( normalizeCons(scip, cons) );
11070  assert(consdata->normalized);
11071  assert(nvars == consdata->nvars);
11072 
11073  lhs = consdata->lhs;
11074  rhs = consdata->rhs;
11075  assert(!SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs));
11076  assert(!SCIPisNegative(scip, rhs));
11077 
11078  if( !SCIPisInfinity(scip, -lhs) )
11079  haslhs = TRUE;
11080  else
11081  haslhs = FALSE;
11082 
11083  if( !SCIPisInfinity(scip, rhs) )
11084  hasrhs = TRUE;
11085  else
11086  hasrhs = FALSE;
11087 
11088  oldnchgcoefs = *nchgcoefs;
11089  oldnchgsides = *nchgsides;
11090 
11091  /* @todo also work on ranged rows */
11092  if( haslhs && hasrhs )
11093  {
11094  SCIP_CALL( rangedRowSimplify(scip, cons, nchgcoefs, nchgsides ) );
11095 
11096  return SCIP_OKAY;
11097  }
11098  assert(haslhs != hasrhs);
11099 
11100  /* if we have a normalized inequality (not ranged) the one side should be positive, @see normalizeCons() */
11101  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11102  assert(!haslhs || !SCIPisNegative(scip, lhs));
11103 
11104  /* get temporary memory to store the sorted permutation */
11105  SCIP_CALL( SCIPallocBufferArray(scip, &perm, nvars) );
11106 
11107  /* call sorting method, order continuous variables to the end and all other variables after non-increasing absolute
11108  * value of their coefficients
11109  */
11110  SCIPsort(perm, consdataCompSim, (void*)consdata, nvars);
11111 
11112  /* perform sorting after permutation array */
11113  permSortConsdata(consdata, perm, nvars);
11114  consdata->sorted = FALSE;
11115  consdata->binvarssorted = FALSE;
11116 
11117  vars = consdata->vars;
11118  vals = consdata->vals;
11119  assert(vars != NULL);
11120  assert(vals != NULL);
11121  assert(consdata->validmaxabsval ? (SCIPisFeasEQ(scip, consdata->maxabsval, REALABS(vals[0])) || SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS) : TRUE);
11122 
11123  /* free temporary memory */
11124  SCIPfreeBufferArray(scip, &perm);
11125 
11126  /* only check constraints with at least two non continuous variables */
11127  if( SCIPvarGetType(vars[1]) == SCIP_VARTYPE_CONTINUOUS )
11128  return SCIP_OKAY;
11129 
11130  /* do not process constraints when all coefficients are 1.0 */
11131  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) && ((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs))) )
11132  return SCIP_OKAY;
11133 
11134  feastol = SCIPfeastol(scip);
11135 
11136  SCIPdebugMessage("starting simplification of coeffcients\n");
11137  SCIPdebugPrintCons(scip, cons, NULL);
11138 
11139  /* get global activities */
11140  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minactsub, &maxactsub,
11141  &isminrelax, &ismaxrelax, &isminsettoinfinity, &ismaxsettoinfinity);
11142 
11143  /* cannot work with infinite activities */
11144  if( isminsettoinfinity || ismaxsettoinfinity )
11145  return SCIP_OKAY;
11146 
11147  assert(!isminrelax);
11148  assert(!ismaxrelax);
11149  assert(maxactsub > minactsub);
11150  assert(!SCIPisInfinity(scip, -minactsub));
11151  assert(!SCIPisInfinity(scip, maxactsub));
11152 
11153  v = 0;
11154  offsetv = -1;
11155  side = haslhs ? lhs : rhs;
11156 
11157  /* we now determine coefficients as large as the side of the constraint to might retrieve a better reduction were we
11158  * do not need to look at the large coefficients
11159  *
11160  * e.g. all x are binary, z are positive integer
11161  * c1: +5x1 + 5x2 + 3x3 + 3x4 + x5 >= 5 (x5 is redundant and does not change (in-)feasibility of this constraint)
11162  * c2: +4x1 + 4x2 + 3x3 + 3x4 + x5 >= 4 (gcd (without the coefficient of x5) after the large coefficients is 3
11163  * c3: +30x1 + 29x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 30 (gcd (without the coefficient of x2) after the large coefficients is 7
11164  *
11165  * can be changed to
11166  *
11167  * c1: +6x1 + 6x2 + 3x3 + 3x4 >= 6 (will be changed to c1: +2x1 + 2x2 + x3 + x4 >= 2)
11168  * c2: +6x1 + 6x2 + 3x3 + 3x4 + 3x5 >= 6 (will be changed to c2: +2x1 + 2x2 + x3 + x4 + x5 >= 2)
11169  * c3: +28x1 + 28x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 28 (will be changed to c3: +4x1 + 4x2 + 2x3 + 2z1 + x5 + x6 <= 4)
11170  */
11171 
11172  /* if the minimal activity is negative and we found more than one variable with a coefficient bigger than the left
11173  * hand side, we cannot apply the extra reduction step and need to reset v
11174  *
11175  * e.g. 7x1 + 7x2 - 4x3 - 4x4 >= 7 => xi = 1 forall i is not a solution, but if we would do a change on the
11176  * coeffcients due to the gcd on the "small" coeffcients we would get 8x1 + 8x2 - 4x3 - 4x4 >= 8 were xi = 1
11177  * forall i is a solution
11178  *
11179  * also redundancy of variables would not be correct determined in such a case
11180  */
11181  if( nvars > 2 && SCIPisEQ(scip, vals[0], side) && !SCIPisNegative(scip, minactsub) )
11182  {
11183  ++v;
11184 
11185  while( SCIPisEQ(scip, side, vals[v]) )
11186  {
11187  /* if we have integer variable with "side"-coefficients but also with a lower bound greater than 0 we stop this
11188  * extra step, which might have worked
11189  */
11190  if( SCIPvarGetLbGlobal(vars[v]) > 0.5 )
11191  {
11192  v = 0;
11193  break;
11194  }
11195 
11196  ++v;
11197  assert(v < nvars);
11198  }
11199 
11200  /* cannot work with continuous variables which have a big coefficient */
11201  if( v > 0 && SCIPvarGetType(vars[v - 1]) == SCIP_VARTYPE_CONTINUOUS )
11202  return SCIP_OKAY;
11203 
11204  /* big negative coefficient, do not try to use the extra coefficient reduction step */
11205  if( SCIPisEQ(scip, side, -vals[v]) )
11206  v = 0;
11207 
11208  /* all but one variable are processed or the next variables is continuous we cannot perform the extra coefficient
11209  * reduction
11210  */
11211  if( v == nvars - 1 || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11212  v = 0;
11213 
11214  if( v > 0 )
11215  {
11216  assert(v < nvars);
11217 
11218  offsetv = v - 1;
11219 
11220  for( w = 0; w < v; ++w )
11221  {
11222  lb = SCIPvarGetLbGlobal(vars[w]);
11223  ub = SCIPvarGetUbGlobal(vars[w]);
11224 
11225  assert(vals[w] > 0);
11226 
11227  /* update residual activities */
11228  maxactsub -= ub * vals[w];
11229  minactsub -= lb * vals[w];
11230  assert(maxactsub > minactsub);
11231  }
11232  }
11233  }
11234 
11235  /* find and remove redundant variables which do not interact with the (in-)feasible of a constraints
11236  *
11237  * e.g. assume all x are binary and y1 is continuous with bounds [-3,1] then we can reduce
11238  *
11239  * 15x1 + 15x2 + 7x3 + 3x4 + y1 <= 26
11240  * to
11241  * 15x1 + 15x2 <= 26 <=> x1 + x2 <= 1
11242  */
11243  if( nvars > 2 && SCIPisIntegral(scip, vals[v]) )
11244  {
11245  SCIP_Bool redundant = FALSE;
11246 
11247  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11248  assert(gcd >= 1);
11249 
11250  if( v == 0 )
11251  {
11252  lb = SCIPvarGetLbGlobal(vars[0]);
11253  ub = SCIPvarGetUbGlobal(vars[0]);
11254 
11255  /* update residual activities */
11256  if( vals[0] > 0 )
11257  {
11258  maxactsub -= ub * vals[0];
11259  minactsub -= lb * vals[0];
11260  }
11261  else
11262  {
11263  maxactsub -= lb * vals[0];
11264  minactsub -= ub * vals[0];
11265  }
11266  assert(maxactsub > minactsub);
11267  ++v;
11268  }
11269 
11270  siderest = -SCIP_INVALID;
11271  allcoefintegral = TRUE;
11272 
11273  /* check if some variables always fit into the given constraint */
11274  for( ; v < nvars - 1; ++v )
11275  {
11276  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11277  break;
11278 
11279  if( !SCIPisIntegral(scip, vals[v]) )
11280  {
11281  allcoefintegral = FALSE;
11282  break;
11283  }
11284 
11285  /* calculate greatest common divisor for all general and binary variables */
11286  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11287 
11288  if( gcd == 1 )
11289  break;
11290 
11291  lb = SCIPvarGetLbGlobal(vars[v]);
11292  ub = SCIPvarGetUbGlobal(vars[v]);
11293 
11294  assert(!SCIPisInfinity(scip, -lb));
11295  assert(!SCIPisInfinity(scip, ub));
11296 
11297  /* update residual activities */
11298  if( vals[v] > 0 )
11299  {
11300  maxactsub -= ub * vals[v];
11301  minactsub -= lb * vals[v];
11302  }
11303  else
11304  {
11305  maxactsub -= lb * vals[v];
11306  minactsub -= ub * vals[v];
11307  }
11308  assert(SCIPisGE(scip, maxactsub, minactsub));
11309 
11310  if( hasrhs )
11311  {
11312  /* determine the remainder of the right hand side and the gcd */
11313  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11314  }
11315  else
11316  {
11317  /* determine the remainder of the left hand side and the gcd */
11318  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11319  if( SCIPisZero(scip, siderest) )
11320  siderest = gcd;
11321  }
11322 
11323  /* early termination if the activities deceed the gcd */
11324  if( (offsetv == -1 && hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd)) || (haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd) )
11325  {
11326  redundant = TRUE;
11327  break;
11328  }
11329  }
11330  assert(v < nvars || (offsetv >= 0 && gcd > 1));
11331 
11332  if( !redundant )
11333  {
11334  if( hasrhs )
11335  {
11336  /* determine the remainder of the right hand side and the gcd */
11337  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11338  }
11339  else
11340  {
11341  /* determine the remainder of the left hand side and the gcd */
11342  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11343  if( SCIPisZero(scip, siderest) )
11344  siderest = gcd;
11345  }
11346  }
11347  else
11348  ++v;
11349 
11350  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);
11351 
11352  /* check if we can remove redundant variables */
11353  if( v < nvars && (redundant ||
11354  (offsetv == -1 && hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd)) ||
11355  (haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd)) )
11356  {
11357  SCIP_Real oldcoef;
11358 
11359  /* double check the redundancy */
11360 #ifndef NDEBUG
11361  SCIP_Real tmpminactsub = 0.0;
11362  SCIP_Real tmpmaxactsub = 0.0;
11363 
11364  /* recompute residual activities */
11365  for( w = v; w < nvars; ++w )
11366  {
11367  lb = SCIPvarGetLbGlobal(vars[w]);
11368  ub = SCIPvarGetUbGlobal(vars[w]);
11369 
11370  assert(!SCIPisInfinity(scip, -lb));
11371  assert(!SCIPisInfinity(scip, ub));
11372 
11373  /* update residual activities */
11374  if( vals[w] > 0 )
11375  {
11376  tmpmaxactsub += ub * vals[w];
11377  tmpminactsub += lb * vals[w];
11378  }
11379  else
11380  {
11381  tmpmaxactsub += lb * vals[w];
11382  tmpminactsub += ub * vals[w];
11383  }
11384  assert(tmpmaxactsub >= tmpminactsub);
11385  }
11386 
11387  if( hasrhs )
11388  {
11389  assert(offsetv == -1);
11390 
11391  /* determine the remainder of the right hand side and the gcd */
11392  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11393  }
11394  else
11395  {
11396  /* determine the remainder of the left hand side and the gcd */
11397  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11398  if( SCIPisZero(scip, siderest) )
11399  siderest = gcd;
11400  }
11401 
11402  /* does the redundancy really is fulfilled */
11403  assert((hasrhs && SCIPisLE(scip, tmpmaxactsub, siderest) && tmpminactsub > siderest - gcd) || (haslhs && tmpmaxactsub < siderest && SCIPisGE(scip, tmpminactsub, siderest - gcd)));
11404 #endif
11405 
11406  SCIPdebugMessage("removing %d last variables from constraint <%s>, because they never change anything on the feasibility of this constraint\n", nvars - v, SCIPconsGetName(cons));
11407 
11408  /* remove redundant variables */
11409  for( w = nvars - 1; w >= v; --w )
11410  {
11411  SCIP_CALL( delCoefPos(scip, cons, w) );
11412  }
11413  (*nchgcoefs) += (nvars - v);
11414 
11415  assert(w >= 0);
11416 
11417  oldcoef = vals[w];
11418 
11419  /* normalize constraint */
11420  SCIP_CALL( normalizeCons(scip, cons) );
11421  assert(vars == consdata->vars);
11422  assert(vals == consdata->vals);
11423  assert(w < consdata->nvars);
11424 
11425  /* compute new greatest common divisor due to normalization */
11426  gcd = (SCIP_Longint)(gcd / (oldcoef/vals[w]) + feastol);
11427  assert(gcd >= 1);
11428 
11429  /* update side */
11430  if( hasrhs )
11431  {
11432  /* replace old with new right hand side */
11433  SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
11434  rhs = consdata->rhs;
11435  }
11436  else
11437  {
11438  if( SCIPisFeasGT(scip, oldcoef/vals[w], 1.0) )
11439  {
11440  SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
11441  lhs = consdata->lhs;
11442  }
11443  else
11444  assert(offsetv == -1 || SCIPisEQ(scip, vals[offsetv], consdata->lhs));
11445  }
11446  ++(*nchgsides);
11447 
11448  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11449  assert(!haslhs || !SCIPisNegative(scip, lhs));
11450 
11451  /* get new constraint data */
11452  nvars = consdata->nvars;
11453  assert(nvars >= 2);
11454 
11455  allcoefintegral = TRUE;
11456 
11457 #ifndef NDEBUG
11458  /* check integrality */
11459  for( w = offsetv + 1; w < nvars; ++w )
11460  {
11461  assert(SCIPisIntegral(scip, vals[w]));
11462  }
11463 #endif
11464  SCIPdebugPrintCons(scip, cons, NULL);
11465  }
11466 
11467  /* try to find a better gcd, when having large coefficients */
11468  if( offsetv >= 0 && gcd == 1 )
11469  {
11470  /* calculate greatest common divisor for all general variables */
11471  gcd = (SCIP_Longint)(REALABS(vals[nvars - 1]) + feastol);
11472 
11473  if( gcd > 1 )
11474  {
11475  gcd = -1;
11476  candpos = -1;
11477 
11478  for( v = nvars - 1; v > offsetv; --v )
11479  {
11480  assert(!SCIPisZero(scip, vals[v]));
11481  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11482  break;
11483 
11484  if( !SCIPisIntegral(scip, vals[v]) )
11485  {
11486  allcoefintegral = FALSE;
11487  break;
11488  }
11489 
11490  oldgcd = gcd;
11491 
11492  if( gcd == -1 )
11493  {
11494  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11495  assert(gcd >= 1);
11496  }
11497  else
11498  {
11499  /* calculate greatest common divisor for all general and binary variables */
11500  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11501  }
11502 
11503  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
11504  * can stop searching
11505  */
11506  if( gcd == 1 )
11507  {
11508  if( !SCIPvarIsBinary(vars[v]) )
11509  break;
11510 
11511  /* found candidate */
11512  if( candpos == -1 )
11513  {
11514  gcd = oldgcd;
11515  candpos = v;
11516  }
11517  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
11518  else
11519  break;
11520  }
11521  }
11522  assert(v > offsetv || candpos > offsetv);
11523  }
11524  else
11525  candpos = -1;
11526  }
11527  else
11528  candpos = nvars - 1;
11529 
11530  /* check last coefficient for integrality */
11531  if( gcd > 1 && allcoefintegral && !redundant )
11532  {
11533  if( !SCIPisIntegral(scip, vals[nvars - 1]) )
11534  allcoefintegral = FALSE;
11535  }
11536 
11537  /* check for further necessary coefficient adjustments */
11538  if( offsetv >= 0 && gcd > 1 && allcoefintegral )
11539  {
11540  assert(offsetv + 1 < nvars);
11541  assert(0 <= candpos && candpos < nvars);
11542 
11543  if( SCIPvarGetType(vars[candpos]) != SCIP_VARTYPE_CONTINUOUS )
11544  {
11545  SCIP_Bool notchangable = FALSE;
11546 
11547 #ifndef NDEBUG
11548  /* check integrality */
11549  for( w = offsetv + 1; w < nvars; ++w )
11550  {
11551  assert(SCIPisIntegral(scip, vals[w]));
11552  }
11553 #endif
11554 
11555  if( vals[candpos] > 0 && SCIPvarIsBinary(vars[candpos]) &&
11556  SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) < gcd )
11557  {
11558  /* determine the remainder of the side and the gcd */
11559  if( hasrhs )
11560  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
11561  else
11562  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
11563  assert(rest >= 0);
11564  assert(rest < gcd);
11565 
11566  /* determine the remainder of the coefficient candidate and the gcd */
11567  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
11568  assert(restcoef >= 1);
11569  assert(restcoef < gcd);
11570 
11571  if( hasrhs )
11572  {
11573  /* calculate new coefficient */
11574  if( restcoef > rest )
11575  newcoef = vals[candpos] - restcoef + gcd;
11576  else
11577  newcoef = vals[candpos] - restcoef;
11578  }
11579  else
11580  {
11581  /* calculate new coefficient */
11582  if( rest == 0 || restcoef < rest )
11583  newcoef = vals[candpos] - restcoef;
11584  else
11585  newcoef = vals[candpos] - restcoef + gcd;
11586  }
11587 
11588 
11589  /* done */
11590 
11591  /* new coeffcient must not be zero if we would loose the implication that a variable needs to be 0 if
11592  * another with the big coefficient was set to 1
11593  */
11594  if( hasrhs && SCIPisZero(scip, newcoef) )
11595  {
11596  notchangable = TRUE;
11597  }
11598  else if( SCIPisZero(scip, newcoef) )
11599  {
11600  /* delete old redundant coefficient */
11601  SCIP_CALL( delCoefPos(scip, cons, candpos) );
11602  ++(*nchgcoefs);
11603  }
11604  else
11605  {
11606  /* replace old with new coefficient */
11607  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
11608  ++(*nchgcoefs);
11609  }
11610  }
11611  else if( vals[candpos] < 0 || !SCIPvarIsBinary(vars[candpos]) )
11612  {
11613  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol));
11614  }
11615 
11616  /* correct side and big coefficients */
11617  if( (!notchangable && hasrhs && ((!SCIPisFeasIntegral(scip, rhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(rhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd))) ||
11618  ( haslhs && (!SCIPisFeasIntegral(scip, lhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(lhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd)) )
11619  {
11620  if( haslhs )
11621  {
11622  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasCeil(scip, lhs/gcd) * gcd + feastol));
11623 
11624  SCIP_CALL( chgLhs(scip, cons, newcoef) );
11625  ++(*nchgsides);
11626  }
11627  else
11628  {
11629  assert(hasrhs);
11630  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasFloor(scip, rhs/gcd) * gcd + feastol));
11631 
11632  SCIP_CALL( chgRhs(scip, cons, newcoef) );
11633  ++(*nchgsides);
11634  }
11635 
11636  /* correct coefficients up front */
11637  for( w = offsetv; w >= 0; --w )
11638  {
11639  assert(vals[w] > 0);
11640 
11641  SCIP_CALL( chgCoefPos(scip, cons, w, newcoef) );
11642  }
11643  (*nchgcoefs) += (offsetv + 1);
11644  }
11645 
11646  if( !notchangable )
11647  {
11648  /* normalize constraint */
11649  SCIP_CALL( normalizeCons(scip, cons) );
11650  assert(vars == consdata->vars);
11651  assert(vals == consdata->vals);
11652 
11653  /* get new constraint data */
11654  nvars = consdata->nvars;
11655  assert(nvars >= 2);
11656 
11657  SCIPdebugPrintCons(scip, cons, NULL);
11658 
11659  lhs = consdata->lhs;
11660  rhs = consdata->rhs;
11661  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11662  assert(!haslhs || !SCIPisNegative(scip, lhs));
11663  }
11664  }
11665  }
11666  }
11667 
11668  /* @todo we still can remove continuous variables if they are redundant due to the non-integrality argument */
11669  /* no continuous variables are left over */
11670  if( SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS )
11671  return SCIP_OKAY;
11672 
11673  onlybin = TRUE;
11674  allcoefintegral = TRUE;
11675  /* check if all variables are of binary type */
11676  for( v = nvars - 1; v >= 0; --v )
11677  {
11678  if( !SCIPvarIsBinary(vars[v]) )
11679  onlybin = FALSE;
11680  if( !SCIPisIntegral(scip, vals[v]) )
11681  allcoefintegral = FALSE;
11682  }
11683 
11684  /* check if the non-integrality part of all integral variables is smaller than the non-inegrality part of the right
11685  * hand side or bigger than the left hand side respectively, so we can make all of them integral
11686  *
11687  * @todo there are some steps missing ....
11688  */
11689  if( (hasrhs && !SCIPisFeasIntegral(scip, rhs)) || (haslhs && !SCIPisFeasIntegral(scip, lhs)) )
11690  {
11691  SCIP_Real val;
11692  SCIP_Real newval;
11693  SCIP_Real frac = 0.0;
11694  SCIP_Bool found = FALSE;
11695 
11696  if( hasrhs )
11697  {
11698  if( allcoefintegral )
11699  {
11700  /* replace old with new right hand side */
11701  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
11702  ++(*nchgsides);
11703  }
11704  else
11705  {
11706  siderest = rhs - SCIPfloor(scip, rhs);
11707 
11708  /* try to round down all non-integral coefficients */
11709  for( v = nvars - 1; v >= 0; --v )
11710  {
11711  val = vals[v];
11712 
11713  /* add up all possible fractional parts */
11714  if( !SCIPisIntegral(scip, val) )
11715  {
11716  lb = SCIPvarGetLbGlobal(vars[v]);
11717  ub = SCIPvarGetUbGlobal(vars[v]);
11718 
11719  /* at least one bound need to be at zero */
11720  if( !onlybin && !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
11721  return SCIP_OKAY;
11722 
11723  /* swap bounds for 'standard' form */
11724  if( !SCIPisFeasZero(scip, lb) )
11725  {
11726  SCIP_Real tmp = lb;
11727  lb = ub;
11728  ub = tmp;
11729  val *= -1;
11730  }
11731 
11732  found = TRUE;
11733 
11734  frac += (val - SCIPfloor(scip, val)) * ub;
11735 
11736  /* if we exceed the fractional part of the right hand side, we cannot tighten the coefficients
11737  *
11738  * e.g. 1.1x1 + 1.1x2 + 1.4x3 + 1.02x4 <= 2.4, here we cannot floor all fractionals because
11739  * x3, x4 set to 1 would be infeasible but feasible after flooring
11740  */
11741  if( SCIPisGT(scip, frac, siderest) )
11742  return SCIP_OKAY;
11743  }
11744  }
11745  assert(v == -1);
11746 
11747  SCIPdebugMessage("rounding all non-integral coefficients and the right hand side down\n");
11748 
11749  /* round rhs and coefficients to integral values */
11750  if( found )
11751  {
11752  for( v = nvars - 1; v >= 0; --v )
11753  {
11754  val = vals[v];
11755 
11756  /* add the whole fractional part */
11757  if( !SCIPisIntegral(scip, val) )
11758  {
11759  lb = SCIPvarGetLbGlobal(vars[v]);
11760 
11761  if( SCIPisFeasZero(scip, lb) )
11762  newval = SCIPfloor(scip, val);
11763  else
11764  newval = SCIPceil(scip, val);
11765 
11766  if( SCIPisZero(scip, newval) )
11767  {
11768  /* delete old redundant coefficient */
11769  SCIP_CALL( delCoefPos(scip, cons, v) );
11770  ++(*nchgcoefs);
11771  }
11772  else
11773  {
11774  /* replace old with new coefficient */
11775  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
11776  ++(*nchgcoefs);
11777  }
11778  }
11779  }
11780  }
11781 
11782  /* replace old with new right hand side */
11783  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
11784  ++(*nchgsides);
11785  }
11786  }
11787  else
11788  {
11789  if( allcoefintegral )
11790  {
11791  /* replace old with new left hand side */
11792  SCIP_CALL( chgLhs(scip, cons, SCIPceil(scip, lhs)) );
11793  ++(*nchgsides);
11794  }
11795  else
11796  {
11797  /* cannot floor left hand side to zero */
11798  if( SCIPisLT(scip, lhs, 1.0) )
11799  return SCIP_OKAY;
11800 
11801  siderest = lhs - SCIPfloor(scip, lhs);
11802 
11803  /* try to round down all non-integral coefficients */
11804  for( v = nvars - 1; v >= 0; --v )
11805  {
11806  val = vals[v];
11807 
11808  /* add up all possible fractional parts */
11809  if( !SCIPisIntegral(scip, val) )
11810  {
11811  lb = SCIPvarGetLbGlobal(vars[v]);
11812  ub = SCIPvarGetUbGlobal(vars[v]);
11813 
11814  /* at least one bound need to be at zero */
11815  if( !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
11816  return SCIP_OKAY;
11817 
11818  /* swap bounds for 'standard' form */
11819  if( !SCIPisFeasZero(scip, lb) )
11820  {
11821  SCIP_Real tmp = lb;
11822  lb = ub;
11823  ub = tmp;
11824  val *= -1;
11825  }
11826 
11827  /* cannot floor to zero */
11828  if( SCIPisLT(scip, val, 1.0) )
11829  return SCIP_OKAY;
11830 
11831  /* the fractional part on each variable need to exceed the fractional part on the left hand side */
11832  if( SCIPisLT(scip, val - SCIPfloor(scip, val), siderest) )
11833  return SCIP_OKAY;
11834 
11835  found = TRUE;
11836 
11837  frac += (val - SCIPfloor(scip, val)) * ub;
11838 
11839  /* if we exceed the fractional part of the left hand side plus one by summing up all maximal
11840  * fractional parts of the variables, we cannot tighten the coefficients
11841  *
11842  * e.g. 4.3x1 + 1.3x2 + 1.3x3 + 1.6x4 >= 4.2, here we cannot floor all fractionals because
11843  * x2-x4 set to 1 would be feasible but not after flooring
11844  */
11845  if( SCIPisGE(scip, frac, 1 + siderest) )
11846  return SCIP_OKAY;
11847  }
11848  /* all coefficients need to be integral, otherwise we might do an invalid reduction */
11849  else
11850  return SCIP_OKAY;
11851  }
11852  assert(v == -1);
11853 
11854  SCIPdebugMessage("rounding all non-integral coefficients and the left hand side down\n");
11855 
11856  /* round lhs and coefficients to integral values */
11857  if( found )
11858  {
11859  for( v = nvars - 1; v >= 0; --v )
11860  {
11861  val = vals[v];
11862 
11863  /* add the whole fractional part */
11864  if( !SCIPisIntegral(scip, val) )
11865  {
11866  lb = SCIPvarGetLbGlobal(vars[v]);
11867 
11868  if( SCIPisFeasZero(scip, lb) )
11869  newval = SCIPfloor(scip, val);
11870  else
11871  newval = SCIPceil(scip, val);
11872 
11873  if( SCIPisZero(scip, newval) )
11874  {
11875  /* delete old redundant coefficient */
11876  SCIP_CALL( delCoefPos(scip, cons, v) );
11877  ++(*nchgcoefs);
11878  }
11879  else
11880  {
11881  /* replace old with new coefficient */
11882  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
11883  ++(*nchgcoefs);
11884  }
11885  }
11886  }
11887  }
11888 
11889  /* replace old with new left hand side */
11890  SCIP_CALL( chgLhs(scip, cons, SCIPfloor(scip, lhs)) );
11891  ++(*nchgsides);
11892  }
11893  }
11894 
11895  /* normalize constraint */
11896  SCIP_CALL( normalizeCons(scip, cons) );
11897  assert(vars == consdata->vars);
11898  assert(vals == consdata->vals);
11899 
11900  rhs = consdata->rhs;
11901  lhs = consdata->lhs;
11902 
11903  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11904  assert(!haslhs || !SCIPisNegative(scip, lhs));
11905 
11906  SCIPdebugPrintCons(scip, cons, NULL);
11907 
11908  nvars = consdata->nvars;
11909  if( nvars < 2 )
11910  return SCIP_OKAY;
11911 
11912  allcoefintegral = TRUE;
11913 #ifndef NDEBUG
11914  /* debug check if all coefficients are really integral */
11915  for( v = nvars - 1; v >= 0; --v )
11916  assert(SCIPisIntegral(scip, vals[v]));
11917 #endif
11918  }
11919 
11920  /* @todo following can also work on non integral coefficients, need more investigation */
11921  /* only check constraints with integral coefficients on all integral variables */
11922  if( !allcoefintegral )
11923  return SCIP_OKAY;
11924 
11925  /* we want to avoid numerical troubles, therefore we do not change non-integral sides */
11926  if( (hasrhs && !SCIPisIntegral(scip, rhs)) || (haslhs && !SCIPisIntegral(scip, lhs)) )
11927  return SCIP_OKAY;
11928 
11929  /* maximal absolute value of coefficients in constraint is one, so we cannot tighten it further */
11930  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) )
11931  return SCIP_OKAY;
11932 
11933  /* stop if the last coeffcients is one in absolute value and the variable is not binary */
11934  if( !SCIPvarIsBinary(vars[nvars - 1]) && SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) )
11935  return SCIP_OKAY;
11936 
11937  assert(nvars >= 2);
11938 
11939  /* start gcd procedure for all variables */
11940 
11941  do
11942  {
11943  oldnchgcoefs = *nchgcoefs;
11944  oldnchgsides = *nchgsides;
11945 
11946  /* stop if we have two coeffcients which are one in absolute value */
11947  if( SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) && SCIPisEQ(scip, REALABS(vals[nvars - 2]), 1.0) )
11948  return SCIP_OKAY;
11949 
11950  gcd = -1;
11951 
11952  /* calculate greatest common divisor over all integer variables */
11953  if( !onlybin )
11954  {
11955  foundbin = -1;
11956 
11957  for( v = nvars - 1; v >= 0; --v )
11958  {
11959  assert(!SCIPisZero(scip, vals[v]));
11960  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS);
11961 
11962  if( SCIPvarIsBinary(vars[v]) )
11963  {
11964  if( foundbin == -1 )
11965  foundbin = v;
11966  continue;
11967  }
11968 
11969  absval = REALABS(vals[v]);
11970  assert(SCIPisIntegral(scip, absval));
11971 
11972  if( gcd == -1 )
11973  {
11974  gcd = (SCIP_Longint)(absval + feastol);
11975  assert(gcd >= 1);
11976  }
11977  else
11978  {
11979  /* calculate greatest common divisor for all general variables */
11980  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(absval + feastol));
11981  }
11982  if( gcd == 1 )
11983  break;
11984  }
11985  }
11986  else
11987  foundbin = nvars - 1;
11988 
11989  /* we need at least one binary variable and a gcd greater than 1 to try to perform further coefficient changes */
11990  if( gcd == 1 || foundbin == -1)
11991  return SCIP_OKAY;
11992 
11993  assert((onlybin && gcd == -1) || (!onlybin && gcd > 1));
11994 
11995  candpos = -1;
11996  candpos2 = -1;
11997 
11998  /* calculate greatest common divisor over all integer and binary variables and determine the candidate where we might
11999  * change the coefficient
12000  */
12001  for( v = foundbin; v >= 0; --v )
12002  {
12003  if( onlybin || SCIPvarIsBinary(vars[v]) )
12004  {
12005  absval = REALABS(vals[v]);
12006  assert(SCIPisIntegral(scip, absval));
12007 
12008  oldgcd = gcd;
12009 
12010  if( gcd == -1 )
12011  {
12012  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
12013  assert(gcd >= 1);
12014  }
12015  else
12016  {
12017  /* calculate greatest common divisor for all general and binary variables */
12018  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12019  }
12020 
12021  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
12022  * can terminate
12023  */
12024  if( gcd == 1 )
12025  {
12026  /* found candidate */
12027  if( candpos == -1 )
12028  {
12029  gcd = oldgcd;
12030  candpos = v;
12031 
12032  /* if we have only binary variables and both first coefficients have a gcd of 1, both are candidates for
12033  * the coefficient change
12034  */
12035  if( onlybin && v == foundbin - 1 )
12036  candpos2 = foundbin;
12037  }
12038  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
12039  else
12040  {
12041  if( onlybin && candpos == v + 1 && candpos2 == v + 2 )
12042  {
12043  assert(candpos2 == nvars - 1);
12044 
12045  /* take new candidates */
12046  candpos = candpos2;
12047 
12048  /* recalculate gcd from scratch */
12049  gcd = (SCIP_Longint)(REALABS(vals[v+1]) + feastol);
12050  assert(gcd >= 1);
12051 
12052  /* calculate greatest common divisor for all general and binary variables */
12053  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12054  if( gcd == 1 )
12055  return SCIP_OKAY;
12056  }
12057  else
12058  /* cannot determine a possible coefficient for reduction */
12059  return SCIP_OKAY;
12060  }
12061  }
12062  }
12063  }
12064  assert(gcd >= 2);
12065 
12066  /* we should have found one coefficient, that led to a gcd of 1, otherwise we could normalize the constraint
12067  * further
12068  */
12069  assert(candpos >= 0 && candpos < nvars);
12070 
12071  /* all variables and all coefficients are integral, so the side should be too */
12072  assert((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs)));
12073 
12074  /* check again, if we have a normalized inequality (not ranged) the one side should be positive,
12075  * @see normalizeCons()
12076  */
12077  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12078  assert(!haslhs || !SCIPisNegative(scip, lhs));
12079 
12080  /* determine the remainder of the side and the gcd */
12081  if( hasrhs )
12082  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
12083  else
12084  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
12085  assert(rest >= 0);
12086  assert(rest < gcd);
12087 
12088  /* determine the remainder of the coefficient candidate and the gcd */
12089  if( vals[candpos] < 0 )
12090  {
12091  restcoef = ((SCIP_Longint)(vals[candpos] - feastol)) % gcd;
12092  assert(restcoef <= -1);
12093  restcoef += gcd;
12094  }
12095  else
12096  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
12097  assert(restcoef >= 1);
12098  assert(restcoef < gcd);
12099 
12100  if( hasrhs )
12101  {
12102  if( rest > 0 )
12103  {
12104  /* replace old with new right hand side */
12105  SCIP_CALL( chgRhs(scip, cons, rhs - rest) );
12106  ++(*nchgsides);
12107  }
12108 
12109  /* calculate new coefficient */
12110  if( restcoef > rest )
12111  newcoef = vals[candpos] - restcoef + gcd;
12112  else
12113  newcoef = vals[candpos] - restcoef;
12114  }
12115  else
12116  {
12117  if( rest > 0 )
12118  {
12119  /* replace old with new left hand side */
12120  SCIP_CALL( chgLhs(scip, cons, lhs - rest + gcd) );
12121  ++(*nchgsides);
12122  }
12123 
12124  /* calculate new coefficient */
12125  if( rest == 0 || restcoef < rest )
12126  newcoef = vals[candpos] - restcoef;
12127  else
12128  newcoef = vals[candpos] - restcoef + gcd;
12129  }
12130  assert(SCIPisZero(scip, newcoef) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(newcoef) + feastol)) == gcd);
12131 
12132  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));
12133 
12134  if( SCIPisZero(scip, newcoef) )
12135  {
12136  /* delete redundant coefficient */
12137  SCIP_CALL( delCoefPos(scip, cons, candpos) );
12138  }
12139  else
12140  {
12141  /* replace old with new coefficient */
12142  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12143  }
12144  ++(*nchgcoefs);
12145 
12146  /* now constraint can be normalized, might be directly done by dividing it by the gcd */
12147  SCIP_CALL( normalizeCons(scip, cons) );
12148  assert(vars == consdata->vars);
12149  assert(vals == consdata->vals);
12150 
12151  SCIPdebugPrintCons(scip, cons, NULL);
12152 
12153  rhs = consdata->rhs;
12154  lhs = consdata->lhs;
12155  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12156  assert(!haslhs || !SCIPisNegative(scip, lhs));
12157 
12158  nvars = consdata->nvars;
12159 
12160  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));
12161  }
12162  while( nvars >= 2 );
12163 
12164  return SCIP_OKAY;
12165 }
12166 
12167 
12168 /* tries to aggregate an (in)equality and an equality in order to decrease the number of variables in the (in)equality:
12169  * cons0 := a * cons0 + b * cons1,
12170  * where a = val1[v] and b = -val0[v] for common variable v which removes most variable weight;
12171  * for numerical stability, we will only accept integral a and b;
12172  * the variable weight is a weighted sum over all included variables, where each binary variable weighs BINWEIGHT,
12173  * each integer or implicit integer variable weighs INTWEIGHT and each continuous variable weighs CONTWEIGHT
12174  */
12175 static
12177  SCIP* scip, /**< SCIP data structure */
12178  SCIP_CONS* cons0, /**< (in)equality to modify */
12179  SCIP_CONS* cons1, /**< equality to use for aggregation of cons0 */
12180  int* commonidx0, /**< array with indices of variables in cons0, that appear also in cons1 */
12181  int* commonidx1, /**< array with indices of variables in cons1, that appear also in cons0 */
12182  int* diffidx0minus1, /**< array with indices of variables in cons0, that don't appear in cons1 */
12183  int* diffidx1minus0, /**< array with indices of variables in cons1, that don't appear in cons0 */
12184  int nvarscommon, /**< number of variables, that appear in both constraints */
12185  int commonidxweight, /**< variable weight sum of common variables */
12186  int diffidx0minus1weight, /**< variable weight sum of variables in cons0, that don't appear in cons1 */
12187  int diffidx1minus0weight, /**< variable weight sum of variables in cons1, that don't appear in cons0 */
12188  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
12189  int* nchgcoefs, /**< pointer to count the number of changed coefficients */
12190  SCIP_Bool* aggregated /**< pointer to store whether an aggregation was made */
12191  )
12193  SCIP_CONSDATA* consdata0;
12194  SCIP_CONSDATA* consdata1;
12195  SCIP_Real a;
12196  SCIP_Real b;
12197  SCIP_Real aggrcoef;
12198  SCIP_Real scalarsum;
12199  SCIP_Real bestscalarsum;
12200  SCIP_Bool betterscalarsum;
12201  SCIP_Bool commonvarlindependent; /* indicates whether coefficient vector of common variables in linearly dependent */
12202  int varweight;
12203  int nvars;
12204  int bestvarweight;
12205  int bestnvars;
12206  int bestv;
12207  int v;
12208  int i;
12209 
12210  assert(scip != NULL);
12211  assert(cons0 != NULL);
12212  assert(cons1 != NULL);
12213  assert(commonidx0 != NULL);
12214  assert(commonidx1 != NULL);
12215  assert(diffidx0minus1 != NULL);
12216  assert(diffidx1minus0 != NULL);
12217  assert(nvarscommon >= 1);
12218  assert(commonidxweight >= nvarscommon);
12219  assert(nchgcoefs != NULL);
12220  assert(aggregated != NULL);
12221 
12222  assert(SCIPconsIsActive(cons0));
12223  assert(SCIPconsIsActive(cons1));
12224 
12225  SCIPdebugMessage("try aggregation of <%s> and <%s>\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12226 
12227  /* cons0 is an (in)equality */
12228  consdata0 = SCIPconsGetData(cons0);
12229  assert(consdata0 != NULL);
12230  assert(consdata0->nvars >= 1);
12231  assert(SCIPisLE(scip, consdata0->lhs, consdata0->rhs));
12232  assert(diffidx0minus1weight >= consdata0->nvars - nvarscommon);
12233 
12234  /* cons1 is an equality */
12235  consdata1 = SCIPconsGetData(cons1);
12236  assert(consdata1 != NULL);
12237  assert(consdata1->nvars >= 1);
12238  assert(SCIPisEQ(scip, consdata1->lhs, consdata1->rhs));
12239  assert(diffidx1minus0weight >= consdata1->nvars - nvarscommon);
12240 
12241  *aggregated = FALSE;
12242 
12243  /* search for the best common variable such that
12244  * val1[var] * consdata0 - val0[var] * consdata1
12245  * has least weighted number of variables
12246  */
12247  bestvarweight = commonidxweight + diffidx0minus1weight;
12248  bestnvars = consdata0->nvars;
12249  bestv = -1;
12250  bestscalarsum = 0.0;
12251  commonvarlindependent = TRUE;
12252  for( v = 0; v < nvarscommon; ++v )
12253  {
12254  assert(consdata0->vars[commonidx0[v]] == consdata1->vars[commonidx1[v]]);
12255  a = consdata1->vals[commonidx1[v]];
12256  b = -consdata0->vals[commonidx0[v]];
12257 
12258  /* only try aggregation, if coefficients are integral (numerical stability) */
12259  if( SCIPisIntegral(scip, a) && SCIPisIntegral(scip, b) )
12260  {
12261  /* count the number of variables in the potential new constraint a * consdata0 + b * consdata1 */
12262  varweight = diffidx0minus1weight + diffidx1minus0weight;
12263  nvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12264  scalarsum = REALABS(a) + REALABS(b);
12265  betterscalarsum = (scalarsum < bestscalarsum);
12266  for( i = 0; i < nvarscommon
12267  && (varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum)); ++i )
12268  {
12269  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12270  if( !SCIPisZero(scip, aggrcoef) )
12271  {
12272  varweight += getVarWeight(consdata0->vars[commonidx0[i]]);
12273  nvars++;
12274  }
12275  }
12276  if( varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum) )
12277  {
12278  bestv = v;
12279  bestvarweight = varweight;
12280  bestnvars = nvars;
12281  bestscalarsum = scalarsum;
12282  }
12283  }
12284 
12285  /* update commonvarlindependent flag, if still TRUE:
12286  * 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
12287  */
12288  if( commonvarlindependent && v > 0 )
12289  commonvarlindependent = SCIPisEQ(scip,
12290  consdata1->vals[commonidx1[v]] * consdata0->vals[commonidx0[0]],
12291  consdata1->vals[commonidx1[0]] * consdata0->vals[commonidx0[v]]);
12292  }
12293 
12294  /* if better aggregation was found, create new constraint and delete old one */
12295  if( (bestv != -1 || commonvarlindependent) && SCIPconsGetNUpgradeLocks(cons0) == 0 )
12296  {
12297  SCIP_CONS* newcons;
12298  SCIP_CONSDATA* newconsdata;
12299  SCIP_VAR** newvars;
12300  SCIP_Real* newvals;
12301  SCIP_Real newlhs;
12302  SCIP_Real newrhs;
12303  int newnvars;
12304 
12305  if( bestv != -1 )
12306  {
12307  /* choose multipliers such that the multiplier for the (in)equality cons0 is positive */
12308  if( consdata1->vals[commonidx1[bestv]] > 0.0 )
12309  {
12310  a = consdata1->vals[commonidx1[bestv]];
12311  b = -consdata0->vals[commonidx0[bestv]];
12312  }
12313  else
12314  {
12315  a = -consdata1->vals[commonidx1[bestv]];
12316  b = consdata0->vals[commonidx0[bestv]];
12317  }
12318  assert(SCIPisIntegral(scip, a));
12319  assert(SCIPisPositive(scip, a));
12320  assert(SCIPisIntegral(scip, b));
12321  assert(!SCIPisZero(scip, b));
12322  }
12323  else
12324  {
12325  assert(commonvarlindependent);
12326  if( consdata1->vals[commonidx1[0]] > 0.0 )
12327  {
12328  a = consdata1->vals[commonidx1[0]];
12329  b = -consdata0->vals[commonidx0[0]];
12330  }
12331  else
12332  {
12333  a = -consdata1->vals[commonidx1[0]];
12334  b = consdata0->vals[commonidx0[0]];
12335  }
12336  assert(SCIPisPositive(scip, a));
12337  assert(!SCIPisZero(scip, b));
12338 
12339  /* if a/b is integral, then we can easily choose integer multipliers */
12340  if( SCIPisIntegral(scip, a/b) )
12341  {
12342  if( a/b > 0 )
12343  {
12344  a /= b;
12345  b = 1.0;
12346  }
12347  else
12348  {
12349  a /= -b;
12350  b = -1.0;
12351  }
12352  }
12353 
12354  /* setup best* variables that were not setup above because we are in the commonvarlindependent case */
12355  bestvarweight = diffidx0minus1weight + diffidx1minus0weight;
12356  bestnvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12357  }
12358 
12359  SCIPdebugMessage("aggregate linear constraints <%s> := %.15g*<%s> + %.15g*<%s> -> nvars: %d -> %d, weight: %d -> %d\n",
12360  SCIPconsGetName(cons0), a, SCIPconsGetName(cons0), b, SCIPconsGetName(cons1),
12361  consdata0->nvars, bestnvars, commonidxweight + diffidx0minus1weight, bestvarweight);
12362  SCIPdebugPrintCons(scip, cons0, NULL);
12363  SCIPdebugPrintCons(scip, cons1, NULL);
12364 
12365  /* get temporary memory for creating the new linear constraint */
12366  SCIP_CALL( SCIPallocBufferArray(scip, &newvars, bestnvars) );
12367  SCIP_CALL( SCIPallocBufferArray(scip, &newvals, bestnvars) );
12368 
12369  /* calculate the common coefficients, if we have not recognized linear dependency */
12370  newnvars = 0;
12371  if( !commonvarlindependent )
12372  {
12373  for( i = 0; i < nvarscommon; ++i )
12374  {
12375  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12376  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12377 
12378  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12379  if( !SCIPisZero(scip, aggrcoef) )
12380  {
12381  assert(newnvars < bestnvars);
12382  newvars[newnvars] = consdata0->vars[commonidx0[i]];
12383  newvals[newnvars] = aggrcoef;
12384  newnvars++;
12385  }
12386  }
12387  }
12388  else
12389  {
12390  /* if we recognized linear dependency of the common coefficients, then the aggregation coefficient should be 0.0 for every common variable */
12391 #ifndef NDEBUG
12392  for( i = 0; i < nvarscommon; ++i )
12393  {
12394  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12395  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12396 
12397  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12398  assert(SCIPisZero(scip, aggrcoef));
12399  }
12400 #endif
12401  }
12402 
12403  /* calculate the coefficients appearing in cons0 but not in cons1 */
12404  for( i = 0; i < consdata0->nvars - nvarscommon; ++i )
12405  {
12406  assert(0 <= diffidx0minus1[i] && diffidx0minus1[i] < consdata0->nvars);
12407 
12408  aggrcoef = a * consdata0->vals[diffidx0minus1[i]];
12409  assert(!SCIPisZero(scip, aggrcoef));
12410  assert(newnvars < bestnvars);
12411  newvars[newnvars] = consdata0->vars[diffidx0minus1[i]];
12412  newvals[newnvars] = aggrcoef;
12413  newnvars++;
12414  }
12415 
12416  /* calculate the coefficients appearing in cons1 but not in cons0 */
12417  for( i = 0; i < consdata1->nvars - nvarscommon; ++i )
12418  {
12419  assert(0 <= diffidx1minus0[i] && diffidx1minus0[i] < consdata1->nvars);
12420 
12421  aggrcoef = b * consdata1->vals[diffidx1minus0[i]];
12422  assert(!SCIPisZero(scip, aggrcoef));
12423  assert(newnvars < bestnvars);
12424  newvars[newnvars] = consdata1->vars[diffidx1minus0[i]];
12425  newvals[newnvars] = aggrcoef;
12426  newnvars++;
12427  }
12428  assert(newnvars == bestnvars);
12429 
12430  /* calculate the new left and right hand side of the (in)equality */
12431  assert(!SCIPisInfinity(scip, -consdata1->lhs));
12432  assert(!SCIPisInfinity(scip, consdata1->rhs));
12433  if( SCIPisInfinity(scip, -consdata0->lhs) )
12434  newlhs = -SCIPinfinity(scip);
12435  else
12436  newlhs = a * consdata0->lhs + b * consdata1->lhs;
12437  if( SCIPisInfinity(scip, consdata0->rhs) )
12438  newrhs = SCIPinfinity(scip);
12439  else
12440  newrhs = a * consdata0->rhs + b * consdata1->rhs;
12441 
12442  /* create the new linear constraint */
12443  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, SCIPconsGetName(cons0), newnvars, newvars, newvals, newlhs, newrhs,
12445  SCIPconsIsChecked(cons0), SCIPconsIsPropagated(cons0),
12446  SCIPconsIsLocal(cons0), SCIPconsIsModifiable(cons0),
12448 
12449  newconsdata = SCIPconsGetData(newcons);
12450  assert(newconsdata != NULL);
12451 
12452  /* copy the upgraded flag from the old cons0 to the new constraint */
12453  newconsdata->upgraded = consdata0->upgraded;
12454 
12455  /* normalize the new constraint */
12456  SCIP_CALL( normalizeCons(scip, newcons) );
12457 
12458  /* check, if we really want to use the new constraint instead of the old one:
12459  * use the new one, if the maximum norm doesn't grow too much
12460  */
12461  if( consdataGetMaxAbsval(SCIPconsGetData(newcons)) <= maxaggrnormscale * consdataGetMaxAbsval(consdata0) )
12462  {
12463  SCIPdebugMessage(" -> aggregated to <%s>\n", SCIPconsGetName(newcons));
12464  SCIPdebugPrintCons(scip, newcons, NULL);
12465 
12466  /* update the statistics: we changed all coefficients */
12467  if( !consdata0->upgraded )
12468  (*nchgcoefs) += consdata0->nvars + consdata1->nvars - nvarscommon;
12469  *aggregated = TRUE;
12470 
12471  /* delete the old constraint, and add the new linear constraint to the problem */
12472  SCIP_CALL( SCIPdelCons(scip, cons0) );
12473  SCIP_CALL( SCIPaddCons(scip, newcons) );
12474  }
12475 
12476  /* release the new constraint */
12477  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
12478 
12479  /* free temporary memory */
12480  SCIPfreeBufferArray(scip, &newvals);
12481  SCIPfreeBufferArray(scip, &newvars);
12482  }
12483 
12484  return SCIP_OKAY;
12485 }
12486 
12487 /** gets the key of the given element */
12488 static
12489 SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
12490 { /*lint --e{715}*/
12491  /* the key is the element itself */
12492  return elem;
12493 }
12494 
12495 /** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables and the
12496  * coefficients are either equal or negated
12497  */
12498 static
12499 SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
12500 {
12501  SCIP* scip;
12502  SCIP_CONSDATA* consdata1;
12503  SCIP_CONSDATA* consdata2;
12504  SCIP_Bool coefsequal;
12505  SCIP_Bool coefsnegated;
12506  int i;
12507 
12508  assert(key1 != NULL);
12509  assert(key2 != NULL);
12510  consdata1 = SCIPconsGetData((SCIP_CONS*)key1);
12511  consdata2 = SCIPconsGetData((SCIP_CONS*)key2);
12512  assert(consdata1->sorted);
12513  assert(consdata2->sorted);
12514 
12515  scip = (SCIP*)userptr;
12516  assert(scip != NULL);
12517 
12518  /* checks trivial case */
12519  if( consdata1->nvars != consdata2->nvars )
12520  return FALSE;
12521 
12522  coefsequal = TRUE;
12523  coefsnegated = TRUE;
12524 
12525  for( i = 0; i < consdata1->nvars && (coefsequal || coefsnegated); ++i )
12526  {
12527  SCIP_Real val1;
12528  SCIP_Real val2;
12529 
12530  /* tests if variables are equal */
12531  if( consdata1->vars[i] != consdata2->vars[i] )
12532  {
12533  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 1 ||
12534  SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == -1);
12535  coefsequal = FALSE;
12536  coefsnegated = FALSE;
12537  break;
12538  }
12539  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 0);
12540 
12541  /* tests if coefficients are either equal or negated */
12542  val1 = consdata1->vals[i];
12543  val2 = consdata2->vals[i];
12544  coefsequal = coefsequal && SCIPisEQ(scip, val1, val2);
12545  coefsnegated = coefsnegated && SCIPisEQ(scip, val1, -val2);
12546  }
12547 
12548  return (coefsequal || coefsnegated);
12549 }
12550 
12551 #define MULTIPLIER 2048
12552 /** returns the hash value of the key */
12553 static
12554 SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
12555 {
12556  SCIP_CONSDATA* consdata;
12557  SCIP_Real maxabsrealval;
12558  unsigned int hashval;
12559  int minidx;
12560  int mididx;
12561  int maxidx;
12562  int addval;
12563 #ifndef NDEBUG
12564  SCIP* scip;
12565 
12566  scip = (SCIP*)userptr;
12567  assert(scip != NULL);
12568 #endif
12569 
12570  assert(key != NULL);
12571  consdata = SCIPconsGetData((SCIP_CONS*)key);
12572  assert(consdata != NULL);
12573  assert(consdata->nvars > 0);
12574 
12575  assert(consdata->sorted);
12576 
12577  minidx = SCIPvarGetIndex(consdata->vars[0]);
12578  mididx = SCIPvarGetIndex(consdata->vars[consdata->nvars / 2]);
12579  maxidx = SCIPvarGetIndex(consdata->vars[consdata->nvars - 1]);
12580  assert(minidx >= 0 && minidx <= maxidx);
12581 
12582  addval = (int) REALABS(consdata->vals[0]);
12583  addval += (((int) REALABS(consdata->vals[consdata->nvars / 2])) << 4); /*lint !e701*/
12584  addval += (((int) REALABS(consdata->vals[consdata->nvars - 1])) << 8); /*lint !e701*/
12585 
12586  maxabsrealval = consdataGetMaxAbsval(consdata);
12587  /* hash value depends on vectors of variable indices */
12588  if( maxabsrealval < (SCIP_Real) INT_MAX )
12589  {
12590  if( maxabsrealval < 1.0 )
12591  addval += (int) (MULTIPLIER * maxabsrealval);
12592  else
12593  addval += (int) maxabsrealval;
12594  }
12595 
12596  hashval = (consdata->nvars << 29) + (minidx << 22) + (mididx << 11) + maxidx + addval; /*lint !e701*/
12597 
12598  return hashval;
12599 }
12600 
12601 /** compares each constraint with all other constraints for possible redundancy and removes or changes constraint
12602  * accordingly; in contrast to preprocessConstraintPairs(), it uses a hash table
12603  */
12604 static
12606  SCIP* scip, /**< SCIP data structure */
12607  BMS_BLKMEM* blkmem, /**< block memory */
12608  SCIP_CONS** conss, /**< constraint set */
12609  int nconss, /**< number of constraints in constraint set */
12610  int* firstchange, /**< pointer to store first changed constraint */
12611  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
12612  int* ndelconss, /**< pointer to count number of deleted constraints */
12613  int* nchgsides /**< pointer to count number of changed left/right hand sides */
12614  )
12615 {
12616  SCIP_HASHTABLE* hashtable;
12617  int hashtablesize;
12618  int c;
12619 
12620  assert(scip != NULL);
12621  assert(blkmem != NULL);
12622  assert(conss != NULL);
12623  assert(firstchange != NULL);
12624  assert(cutoff != NULL);
12625  assert(ndelconss != NULL);
12626  assert(nchgsides != NULL);
12627 
12628  /* create a hash table for the constraint set */
12629  hashtablesize = SCIPcalcHashtableSize(10*nconss);
12630  hashtablesize = MAX(hashtablesize, HASHSIZE_LINEARCONS);
12631  SCIP_CALL( SCIPhashtableCreate(&hashtable, blkmem, hashtablesize,
12632  hashGetKeyLinearcons, hashKeyEqLinearcons, hashKeyValLinearcons, (void*) scip) );
12633 
12634  /* check all constraints in the given set for redundancy */
12635  for( c = 0; c < nconss; ++c )
12636  {
12637  SCIP_CONS* cons0;
12638  SCIP_CONS* cons1;
12639  SCIP_CONSDATA* consdata0;
12640 
12641  cons0 = conss[c];
12642 
12643  if( !SCIPconsIsActive(cons0) || SCIPconsIsModifiable(cons0) )
12644  continue;
12645 
12646  /* check for interuption */
12647  if( c % 1000 == 0 && SCIPisStopped(scip) )
12648  break;
12649 
12650  /* sorts the constraint */
12651  consdata0 = SCIPconsGetData(cons0);
12652  assert(consdata0 != NULL);
12653  SCIP_CALL( consdataSort(scip, consdata0) );
12654  assert(consdata0->sorted);
12655 
12656  /* get constraint from current hash table with same variables as cons0 and with coefficients either equal or negated
12657  * to the ones of cons0 */
12658  cons1 = (SCIP_CONS*)(SCIPhashtableRetrieve(hashtable, (void*)cons0));
12659 
12660  if( cons1 != NULL )
12661  {
12662  SCIP_CONS* consstay;
12663  SCIP_CONS* consdel;
12664  SCIP_CONSDATA* consdatastay;
12665  SCIP_CONSDATA* consdatadel;
12666  SCIP_CONSDATA* consdata1;
12667 
12668  SCIP_Real lhs;
12669  SCIP_Real rhs;
12670 
12671  assert(SCIPconsIsActive(cons1));
12672  assert(!SCIPconsIsModifiable(cons1));
12673 
12674  /* constraint found: create a new constraint with same coefficients and best left and right hand side;
12675  * delete old constraints afterwards
12676  */
12677  consdata1 = SCIPconsGetData(cons1);
12678 
12679  assert(consdata1 != NULL);
12680  assert(consdata0->nvars >= 1 && consdata0->nvars == consdata1->nvars);
12681 
12682  assert(consdata1->sorted);
12683  assert(consdata0->vars[0] == consdata1->vars[0]);
12684 
12685  if( SCIPisEQ(scip, consdata0->vals[0], consdata1->vals[0]) )
12686  {
12687  /* the coefficients of both constraints are equal */
12688  assert(consdata0->nvars < 2 || SCIPisEQ(scip, consdata0->vals[1], consdata1->vals[1]));
12689  SCIPdebugMessage("aggregate linear constraints <%s> and <%s> with equal coefficients into single ranged row\n",
12690  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12691  SCIPdebugPrintCons(scip, cons0, NULL);
12692  SCIPdebugPrintCons(scip, cons1, NULL);
12693 
12694  lhs = MAX(consdata1->lhs, consdata0->lhs);
12695  rhs = MIN(consdata1->rhs, consdata0->rhs);
12696  }
12697  else
12698  {
12699  /* the coefficients of both rows are negations */
12700  assert(SCIPisEQ(scip, consdata0->vals[0], -(consdata1->vals[0])));
12701  assert(consdata0->nvars < 2 || SCIPisEQ(scip, consdata0->vals[1], -(consdata1->vals[1])));
12702  SCIPdebugMessage("aggregate linear constraints <%s> and <%s> with negated coefficients into single ranged row\n",
12703  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12704  SCIPdebugPrintCons(scip, cons0, NULL);
12705  SCIPdebugPrintCons(scip, cons1, NULL);
12706 
12707  lhs = MAX(consdata1->lhs, -consdata0->rhs);
12708  rhs = MIN(consdata1->rhs, -consdata0->lhs);
12709  }
12710 
12711  if( SCIPisFeasLT(scip, rhs, lhs) )
12712  {
12713  SCIPdebugMessage("aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons1));
12714  *cutoff = TRUE;
12715  break;
12716  }
12717 
12718  /* ensure that lhs <= rhs holds without tolerances as we only allow such rows to enter the LP */
12719  if( lhs > rhs )
12720  {
12721  rhs = (lhs + rhs)/2;
12722  lhs = rhs;
12723  }
12724 
12725  /* check which constraint has to stay;
12726  * changes applied to an upgraded constraint will not be considered in the instance */
12727  if( consdata1->upgraded && !consdata0->upgraded )
12728  {
12729  consstay = cons0;
12730  consdatastay = consdata0;
12731  consdel = cons1;
12732  consdatadel = consdata1;
12733 
12734  /* exchange consdel with consstay in hashtable */
12735  SCIP_CALL( SCIPhashtableRemove(hashtable, (void*) consdel) );
12736  SCIP_CALL( SCIPhashtableInsert(hashtable, (void*) consstay) );
12737  }
12738  else
12739  {
12740  consstay = cons1;
12741  consdatastay = consdata1;
12742  consdel = cons0;
12743  consdatadel = consdata0;
12744  }
12745 
12746  /* update lhs and rhs of consstay */
12747  SCIP_CALL( chgLhs(scip, consstay, lhs) );
12748  SCIP_CALL( chgRhs(scip, consstay, rhs) );
12749 
12750  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
12751  SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
12752 
12753  /* delete consdel */
12754  assert(!consdatastay->upgraded || (consdatastay->upgraded && consdatadel->upgraded));
12755  SCIP_CALL( SCIPdelCons(scip, consdel) );
12756  if( !consdatadel->upgraded )
12757  (*ndelconss)++;
12758 
12759  /* update the first changed constraint to begin the next aggregation round with */
12760  if( consdatastay->changed && SCIPconsGetPos(consstay) < *firstchange )
12761  *firstchange = SCIPconsGetPos(consstay);
12762 
12763  assert(SCIPconsIsActive(consstay));
12764  }
12765  else
12766  {
12767  /* no such constraint in current hash table: insert cons0 into hash table */
12768  SCIP_CALL( SCIPhashtableInsert(hashtable, (void*) cons0) );
12769  }
12770  }
12771 #ifdef SCIP_MORE_DEBUG
12772  SCIPinfoMessage(scip, NULL, "linear pairwise comparison hashtable statistics:\n");
12774 #endif
12775 
12776  /* free hash table */
12777  SCIPhashtableFree(&hashtable);
12778 
12779  return SCIP_OKAY;
12780 }
12781 
12782 /** compares constraint with all prior constraints for possible redundancy or aggregation,
12783  * and removes or changes constraint accordingly
12784  */
12785 static
12787  SCIP* scip, /**< SCIP data structure */
12788  SCIP_CONS** conss, /**< constraint set */
12789  int firstchange, /**< first constraint that changed since last pair preprocessing round */
12790  int chkind, /**< index of constraint to check against all prior indices upto startind */
12791  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
12792  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
12793  int* ndelconss, /**< pointer to count number of deleted constraints */
12794  int* nchgsides, /**< pointer to count number of changed left/right hand sides */
12795  int* nchgcoefs /**< pointer to count number of changed coefficients */
12796  )
12797 {
12798  SCIP_CONS* cons0;
12799  SCIP_CONSDATA* consdata0;
12800  int* commonidx0;
12801  int* commonidx1;
12802  int* diffidx0minus1;
12803  int* diffidx1minus0;
12804  SCIP_Longint possignature0;
12805  SCIP_Longint negsignature0;
12806  SCIP_Bool cons0changed;
12807  SCIP_Bool cons0isequality;
12808  int diffidx1minus0size;
12809  int c;
12810  SCIP_Real cons0lhs;
12811  SCIP_Real cons0rhs;
12812  SCIP_Bool cons0upgraded;
12813 
12814  assert(scip != NULL);
12815  assert(conss != NULL);
12816  assert(firstchange <= chkind);
12817  assert(cutoff != NULL);
12818  assert(ndelconss != NULL);
12819  assert(nchgsides != NULL);
12820  assert(nchgcoefs != NULL);
12821 
12822  /* get the constraint to be checked against all prior constraints */
12823  cons0 = conss[chkind];
12824  assert(cons0 != NULL);
12825  assert(SCIPconsIsActive(cons0));
12826  assert(!SCIPconsIsModifiable(cons0));
12827 
12828  consdata0 = SCIPconsGetData(cons0);
12829  assert(consdata0 != NULL);
12830  assert(consdata0->nvars >= 1);
12831  cons0isequality = SCIPisEQ(scip, consdata0->lhs, consdata0->rhs);
12832 
12833  /* sort the constraint */
12834  SCIP_CALL( consdataSort(scip, consdata0) );
12835 
12836  /* calculate bit signatures of cons0 for potentially positive and negative coefficients */
12837  consdataCalcSignatures(consdata0);
12838  possignature0 = consdata0->possignature;
12839  negsignature0 = consdata0->negsignature;
12840 
12841  /* get temporary memory for indices of common variables */
12842  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx0, consdata0->nvars) );
12843  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx1, consdata0->nvars) );
12844  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx0minus1, consdata0->nvars) );
12845  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx1minus0, consdata0->nvars) );
12846  diffidx1minus0size = consdata0->nvars;
12847 
12848  cons0lhs = consdata0->lhs;
12849  cons0rhs = consdata0->rhs;
12850  cons0upgraded = consdata0->upgraded;
12851 
12852  /* check constraint against all prior constraints */
12853  cons0changed = consdata0->changed;
12854  consdata0->changed = FALSE;
12855  for( c = (cons0changed ? 0 : firstchange); c < chkind && !(*cutoff) && conss[chkind] != NULL; ++c )
12856  {
12857  SCIP_CONS* cons1;
12858  SCIP_CONSDATA* consdata1;
12859  SCIP_Longint possignature1;
12860  SCIP_Longint negsignature1;
12861  SCIP_Bool cons0dominateslhs;
12862  SCIP_Bool cons1dominateslhs;
12863  SCIP_Bool cons0dominatesrhs;
12864  SCIP_Bool cons1dominatesrhs;
12865  SCIP_Bool cons1isequality;
12866  SCIP_Bool coefsequal;
12867  SCIP_Bool coefsnegated;
12868  SCIP_Bool tryaggregation;
12869  int nvarscommon;
12870  int nvars0minus1;
12871  int nvars1minus0;
12872  int commonidxweight;
12873  int diffidx0minus1weight;
12874  int diffidx1minus0weight;
12875  int v0;
12876  int v1;
12877 
12878  assert(cons0lhs == consdata0->lhs); /*lint !e777*/
12879  assert(cons0rhs == consdata0->rhs); /*lint !e777*/
12880  assert(cons0upgraded == consdata0->upgraded);
12881 
12882  cons1 = conss[c];
12883 
12884  /* cons1 has become inactive during presolving of constraint pairs */
12885  if( cons1 == NULL )
12886  continue;
12887 
12888  assert(SCIPconsIsActive(cons0) && !SCIPconsIsModifiable(cons0));
12889  assert(SCIPconsIsActive(cons1) && !SCIPconsIsModifiable(cons1));
12890 
12891  consdata1 = SCIPconsGetData(cons1);
12892  assert(consdata1 != NULL);
12893 
12894  /* SCIPdebugMessage("preprocess linear constraint pair <%s>[chgd:%d, upgd:%d] and <%s>[chgd:%d, upgd:%d]\n",
12895  SCIPconsGetName(cons0), cons0changed, cons0upgraded,
12896  SCIPconsGetName(cons1), consdata1->changed, consdata1->upgraded); */
12897 
12898  /* if both constraints didn't change since last pair processing, we can ignore the pair */
12899  if( !cons0changed && !consdata1->changed )
12900  continue;
12901 
12902  /* if both constraints are already upgraded, skip the pair;
12903  * because changes on these constraints cannot be applied to the instance anymore */
12904  if( cons0upgraded && consdata1->upgraded )
12905  continue;
12906 
12907  assert(consdata1->nvars >= 1);
12908 
12909  /* sort the constraint */
12910  SCIP_CALL( consdataSort(scip, consdata1) );
12911 
12912  /* calculate bit signatures of cons1 for potentially positive and negative coefficients */
12913  consdataCalcSignatures(consdata1);
12914  possignature1 = consdata1->possignature;
12915  negsignature1 = consdata1->negsignature;
12916 
12917  /* the signatures give a quick test to check for domination and equality of coefficients */
12918  coefsequal = (possignature0 == possignature1) && (negsignature0 == negsignature1);
12919  coefsnegated = (possignature0 == negsignature1) && (negsignature0 == possignature1);
12920  cons0dominateslhs = SCIPisGE(scip, cons0lhs, consdata1->lhs)
12921  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
12922  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
12923  cons1dominateslhs = SCIPisGE(scip, consdata1->lhs, cons0lhs)
12924  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
12925  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
12926  cons0dominatesrhs = SCIPisLE(scip, cons0rhs, consdata1->rhs)
12927  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
12928  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
12929  cons1dominatesrhs = SCIPisLE(scip, consdata1->rhs, cons0rhs)
12930  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
12931  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
12932  cons1isequality = SCIPisEQ(scip, consdata1->lhs, consdata1->rhs);
12933  tryaggregation = (cons0isequality || cons1isequality) && (maxaggrnormscale > 0.0);
12934  if( !cons0dominateslhs && !cons1dominateslhs && !cons0dominatesrhs && !cons1dominatesrhs
12935  && !coefsequal && !coefsnegated && !tryaggregation )
12936  continue;
12937 
12938  /* make sure, we have enough memory for the index set of V_1 \ V_0 */
12939  if( tryaggregation && consdata1->nvars > diffidx1minus0size )
12940  {
12941  SCIP_CALL( SCIPreallocBufferArray(scip, &diffidx1minus0, consdata1->nvars) );
12942  diffidx1minus0size = consdata1->nvars;
12943  }
12944 
12945  /* check consdata0 against consdata1:
12946  * - if lhs0 >= lhs1 and for each variable v and each solution value x_v val0[v]*x_v <= val1[v]*x_v,
12947  * consdata0 dominates consdata1 w.r.t. left hand side
12948  * - if rhs0 <= rhs1 and for each variable v and each solution value x_v val0[v]*x_v >= val1[v]*x_v,
12949  * consdata0 dominates consdata1 w.r.t. right hand side
12950  * - if val0[v] == -val1[v] for all variables v, the two inequalities can be replaced by a single
12951  * ranged row (or equality)
12952  * - if at least one constraint is an equality, count the weighted number of common variables W_c
12953  * and the weighted number of variable in the difference sets W_0 = w(V_0 \ V_1), W_1 = w(V_1 \ V_0),
12954  * where the weight of each variable depends on its type, such that aggregations in order to remove the
12955  * number of continuous and integer variables are preferred:
12956  * - if W_c > W_1, try to aggregate consdata0 := a * consdata0 + b * consdata1 in order to decrease the
12957  * variable weight in consdata0, where a = +/- val1[v] and b = -/+ val0[v] for common v which leads to
12958  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
12959  * to be positive to not switch the sense of the (in)equality cons0
12960  * - if W_c > W_0, try to aggregate consdata1 := a * consdata1 + b * consdata0 in order to decrease the
12961  * variable weight in consdata1, where a = +/- val0[v] and b = -/+ val1[v] for common v which leads to
12962  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
12963  * to be positive to not switch the sense of the (in)equality cons1
12964  */
12965 
12966  /* check consdata0 against consdata1 for redundancy, or ranged row accumulation */
12967  nvarscommon = 0;
12968  commonidxweight = 0;
12969  nvars0minus1 = 0;
12970  diffidx0minus1weight = 0;
12971  nvars1minus0 = 0;
12972  diffidx1minus0weight = 0;
12973  v0 = 0;
12974  v1 = 0;
12975  while( (v0 < consdata0->nvars || v1 < consdata1->nvars)
12976  && (cons0dominateslhs || cons1dominateslhs || cons0dominatesrhs || cons1dominatesrhs
12977  || coefsequal || coefsnegated || tryaggregation) )
12978  {
12979  SCIP_VAR* var;
12980  SCIP_Real val0;
12981  SCIP_Real val1;
12982  int varcmp;
12983 
12984  /* test, if variable appears in only one or in both constraints */
12985  if( v0 < consdata0->nvars && v1 < consdata1->nvars )
12986  varcmp = SCIPvarCompare(consdata0->vars[v0], consdata1->vars[v1]);
12987  else if( v0 < consdata0->nvars )
12988  varcmp = -1;
12989  else
12990  varcmp = +1;
12991 
12992  switch( varcmp )
12993  {
12994  case -1:
12995  /* variable doesn't appear in consdata1 */
12996  var = consdata0->vars[v0];
12997  val0 = consdata0->vals[v0];
12998  val1 = 0.0;
12999  if( tryaggregation )
13000  {
13001  diffidx0minus1[nvars0minus1] = v0;
13002  nvars0minus1++;
13003  diffidx0minus1weight += getVarWeight(var);
13004  }
13005  v0++;
13006  coefsequal = FALSE;
13007  coefsnegated = FALSE;
13008  break;
13009 
13010  case +1:
13011  /* variable doesn't appear in consdata0 */
13012  var = consdata1->vars[v1];
13013  val0 = 0.0;
13014  val1 = consdata1->vals[v1];
13015  if( tryaggregation )
13016  {
13017  diffidx1minus0[nvars1minus0] = v1;
13018  nvars1minus0++;
13019  diffidx1minus0weight += getVarWeight(var);
13020  }
13021  v1++;
13022  coefsequal = FALSE;
13023  coefsnegated = FALSE;
13024  break;
13025 
13026  case 0:
13027  /* variable appears in both constraints */
13028  assert(consdata0->vars[v0] == consdata1->vars[v1]);
13029  var = consdata0->vars[v0];
13030  val0 = consdata0->vals[v0];
13031  val1 = consdata1->vals[v1];
13032  if( tryaggregation )
13033  {
13034  commonidx0[nvarscommon] = v0;
13035  commonidx1[nvarscommon] = v1;
13036  nvarscommon++;
13037  commonidxweight += getVarWeight(var);
13038  }
13039  v0++;
13040  v1++;
13041  coefsequal = coefsequal && (SCIPisEQ(scip, val0, val1));
13042  coefsnegated = coefsnegated && (SCIPisEQ(scip, val0, -val1));
13043  break;
13044 
13045  default:
13046  SCIPerrorMessage("invalid comparison result\n");
13047  var = NULL;
13048  val0 = 0.0;
13049  val1 = 0.0;
13050  SCIPABORT();
13051  }
13052  assert(var != NULL);
13053 
13054  /* update domination criteria w.r.t. the coefficient and the variable's bounds */
13055  if( SCIPisGT(scip, val0, val1) )
13056  {
13057  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13058  {
13059  cons0dominatesrhs = FALSE;
13060  cons1dominateslhs = FALSE;
13061  }
13062  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13063  {
13064  cons0dominateslhs = FALSE;
13065  cons1dominatesrhs = FALSE;
13066  }
13067  }
13068  else if( SCIPisLT(scip, val0, val1) )
13069  {
13070  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13071  {
13072  cons0dominateslhs = FALSE;
13073  cons1dominatesrhs = FALSE;
13074  }
13075  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13076  {
13077  cons0dominatesrhs = FALSE;
13078  cons1dominateslhs = FALSE;
13079  }
13080  }
13081  }
13082 
13083  /* check for disaggregated ranged rows */
13084  if( coefsequal || coefsnegated )
13085  {
13086  SCIP_CONS* consstay;
13087  SCIP_CONS* consdel;
13088 #ifndef NDEBUG
13089  SCIP_CONSDATA* consdatastay;
13090 #endif
13091  SCIP_CONSDATA* consdatadel;
13092  SCIP_Real lhs;
13093  SCIP_Real rhs;
13094  int consinddel;
13095 
13096  /* the coefficients in both rows are either equal or negated: create a new constraint with same coefficients and
13097  * best left and right hand sides; delete the old constraints afterwards
13098  */
13099  SCIPdebugMessage("aggregate linear constraints <%s> and <%s> with %s coefficients into single ranged row\n",
13100  SCIPconsGetName(cons0), SCIPconsGetName(cons1), coefsequal ? "equal" : "negated");
13101  SCIPdebugPrintCons(scip, cons0, NULL);
13102  SCIPdebugPrintCons(scip, cons1, NULL);
13103 
13104  if( coefsequal )
13105  {
13106  /* the coefficients of both rows are equal */
13107  lhs = MAX(consdata0->lhs, consdata1->lhs);
13108  rhs = MIN(consdata0->rhs, consdata1->rhs);
13109  }
13110  else
13111  {
13112  /* the coefficients of both rows are negations */
13113  lhs = MAX(consdata0->lhs, -consdata1->rhs);
13114  rhs = MIN(consdata0->rhs, -consdata1->lhs);
13115  }
13116  if( SCIPisFeasLT(scip, rhs, lhs) )
13117  {
13118  SCIPdebugMessage("aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
13119  *cutoff = TRUE;
13120  break;
13121  }
13122 
13123  /* check which constraint has to stay;
13124  * changes applied to an upgraded constraint will not be considered in the instance */
13125  if( consdata0->upgraded )
13126  {
13127  assert(!consdata1->upgraded);
13128  consstay = cons1;
13129 #ifndef NDEBUG
13130  consdatastay = consdata1;
13131 #endif
13132 
13133  consdel = cons0;
13134  consdatadel = consdata0;
13135  consinddel = chkind;
13136  }
13137  else
13138  {
13139  consstay = cons0;
13140 #ifndef NDEBUG
13141  consdatastay = consdata0;
13142 #endif
13143 
13144  consdel = cons1;
13145  consdatadel = consdata1;
13146  consinddel = c;
13147  }
13148 
13149  /* update the sides of consstay */
13150  SCIP_CALL( chgLhs(scip, consstay, lhs) );
13151  SCIP_CALL( chgRhs(scip, consstay, rhs) );
13152  if( !consdata0->upgraded )
13153  {
13154  assert(consstay == cons0);
13155  cons0lhs = consdata0->lhs;
13156  cons0rhs = consdata0->rhs;
13157  }
13158 
13159  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13160  SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
13161 
13162  assert( !consdatastay->upgraded );
13163  /* delete consdel */
13164  SCIP_CALL( SCIPdelCons(scip, consdel) );
13165  conss[consinddel] = NULL;
13166  if( !consdatadel->upgraded )
13167  (*ndelconss)++;
13168  continue;
13169  }
13170 
13171  /* check for domination: remove dominated sides, but don't touch equalities as long as they are not totally
13172  * redundant
13173  */
13174  if( cons1dominateslhs && (!cons0isequality || cons1dominatesrhs || SCIPisInfinity(scip, consdata0->rhs) ) )
13175  {
13176  /* left hand side is dominated by consdata1: delete left hand side of consdata0 */
13177  SCIPdebugMessage("left hand side of linear constraint <%s> is dominated by <%s>:\n",
13178  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13179  SCIPdebugPrintCons(scip, cons0, NULL);
13180  SCIPdebugPrintCons(scip, cons1, NULL);
13181 
13182  /* check for infeasibility */
13183  if( SCIPisFeasGT(scip, consdata1->lhs, consdata0->rhs) )
13184  {
13185  SCIPdebugMessage("linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13186  *cutoff = TRUE;
13187  break;
13188  }
13189 
13190  /* remove redundant left hand side */
13191  if( !SCIPisInfinity(scip, -consdata0->lhs) )
13192  {
13193  SCIP_CALL( chgLhs(scip, cons0, -SCIPinfinity(scip)) );
13194  cons0lhs = consdata0->lhs;
13195  cons0isequality = FALSE;
13196  if( !consdata0->upgraded )
13197  {
13198  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13199  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13200 
13201  (*nchgsides)++;
13202  }
13203  }
13204  }
13205  else if( cons0dominateslhs && (!cons1isequality || cons0dominatesrhs || SCIPisInfinity(scip, consdata1->rhs)) )
13206  {
13207  /* left hand side is dominated by consdata0: delete left hand side of consdata1 */
13208  SCIPdebugMessage("left hand side of linear constraint <%s> is dominated by <%s>:\n",
13209  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13210  SCIPdebugPrintCons(scip, cons1, NULL);
13211  SCIPdebugPrintCons(scip, cons0, NULL);
13212 
13213  /* check for infeasibility */
13214  if( SCIPisFeasGT(scip, consdata0->lhs, consdata1->rhs) )
13215  {
13216  SCIPdebugMessage("linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13217  *cutoff = TRUE;
13218  break;
13219  }
13220 
13221  /* remove redundant left hand side */
13222  if( !SCIPisInfinity(scip, -consdata1->lhs) )
13223  {
13224  SCIP_CALL( chgLhs(scip, cons1, -SCIPinfinity(scip)) );
13225  cons1isequality = FALSE;
13226  if( !consdata1->upgraded )
13227  {
13228  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13229  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13230 
13231  (*nchgsides)++;
13232  }
13233  }
13234  }
13235  if( cons1dominatesrhs && (!cons0isequality || cons1dominateslhs || SCIPisInfinity(scip, -consdata0->lhs)) )
13236  {
13237  /* right hand side is dominated by consdata1: delete right hand side of consdata0 */
13238  SCIPdebugMessage("right hand side of linear constraint <%s> is dominated by <%s>:\n",
13239  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13240  SCIPdebugPrintCons(scip, cons0, NULL);
13241  SCIPdebugPrintCons(scip, cons1, NULL);
13242 
13243  /* check for infeasibility */
13244  if( SCIPisFeasLT(scip, consdata1->rhs, consdata0->lhs) )
13245  {
13246  SCIPdebugMessage("linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13247  *cutoff = TRUE;
13248  break;
13249  }
13250 
13251  /* remove redundant right hand side */
13252  if( !SCIPisInfinity(scip, consdata0->rhs) )
13253  {
13254  SCIP_CALL( chgRhs(scip, cons0, SCIPinfinity(scip)) );
13255  cons0rhs = consdata0->rhs;
13256  cons0isequality = FALSE;
13257  if( !consdata0->upgraded )
13258  {
13259  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13260  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13261 
13262  (*nchgsides)++;
13263  }
13264  }
13265  }
13266  else if( cons0dominatesrhs && (!cons1isequality || cons0dominateslhs || SCIPisInfinity(scip, -consdata1->lhs)) )
13267  {
13268  /* right hand side is dominated by consdata0: delete right hand side of consdata1 */
13269  SCIPdebugMessage("right hand side of linear constraint <%s> is dominated by <%s>:\n",
13270  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13271  SCIPdebugPrintCons(scip, cons1, NULL);
13272  SCIPdebugPrintCons(scip, cons0, NULL);
13273 
13274  /* check for infeasibility */
13275  if( SCIPisFeasLT(scip, consdata0->rhs, consdata1->lhs) )
13276  {
13277  SCIPdebugMessage("linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13278  *cutoff = TRUE;
13279  break;
13280  }
13281 
13282  /* remove redundant right hand side */
13283  if( !SCIPisInfinity(scip, consdata1->rhs) )
13284  {
13285  SCIP_CALL( chgRhs(scip, cons1, SCIPinfinity(scip)) );
13286  cons1isequality = FALSE;
13287  if( !consdata1->upgraded )
13288  {
13289  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13290  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13291 
13292  (*nchgsides)++;
13293  }
13294  }
13295  }
13296 
13297  /* check for now redundant constraints */
13298  if( SCIPisInfinity(scip, -consdata0->lhs) && SCIPisInfinity(scip, consdata0->rhs) )
13299  {
13300  /* consdata0 became redundant */
13301  SCIPdebugMessage("linear constraint <%s> is redundant\n", SCIPconsGetName(cons0));
13302  SCIP_CALL( SCIPdelCons(scip, cons0) );
13303  conss[chkind] = NULL;
13304  if( !consdata0->upgraded )
13305  {
13306  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13307  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13308 
13309  (*ndelconss)++;
13310  }
13311  continue;
13312  }
13313  if( SCIPisInfinity(scip, -consdata1->lhs) && SCIPisInfinity(scip, consdata1->rhs) )
13314  {
13315  /* consdata1 became redundant */
13316  SCIPdebugMessage("linear constraint <%s> is redundant\n", SCIPconsGetName(cons1));
13317  SCIP_CALL( SCIPdelCons(scip, cons1) );
13318  conss[c] = NULL;
13319  if( !consdata1->upgraded )
13320  {
13321  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13322  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13323 
13324  (*ndelconss)++;
13325  }
13326  continue;
13327  }
13328 
13329  /* check, if we want to aggregate an (in)equality with an equality:
13330  * consdata0 := a * consdata0 + b * consdata1 or consdata1 := a * consdata1 + b * consdata0
13331  */
13332  if( tryaggregation )
13333  {
13334  SCIP_Bool aggregated;
13335 
13336  assert(consdata0->nvars == nvarscommon + nvars0minus1);
13337  assert(consdata1->nvars == nvarscommon + nvars1minus0);
13338 
13339  aggregated = FALSE;
13340  if( cons1isequality && !consdata0->upgraded && commonidxweight > diffidx1minus0weight )
13341  {
13342  /* W_c > W_1: try to aggregate consdata0 := a * consdata0 + b * consdata1 */
13343  SCIP_CALL( aggregateConstraints(scip, cons0, cons1, commonidx0, commonidx1, diffidx0minus1, diffidx1minus0,
13344  nvarscommon, commonidxweight, diffidx0minus1weight, diffidx1minus0weight, maxaggrnormscale,
13345  nchgcoefs, &aggregated) );
13346 
13347  /* update array of active constraints */
13348  if( aggregated )
13349  {
13350  assert(!SCIPconsIsActive(cons0));
13351  assert(SCIPconsIsActive(cons1));
13352  conss[chkind] = NULL;
13353  }
13354  }
13355  if( !aggregated && cons0isequality && !consdata1->upgraded && commonidxweight > diffidx0minus1weight )
13356  {
13357  /* W_c > W_0: try to aggregate consdata1 := a * consdata1 + b * consdata0 */
13358  SCIP_CALL( aggregateConstraints(scip, cons1, cons0, commonidx1, commonidx0, diffidx1minus0, diffidx0minus1,
13359  nvarscommon, commonidxweight, diffidx1minus0weight, diffidx0minus1weight, maxaggrnormscale,
13360  nchgcoefs, &aggregated) );
13361 
13362  /* update array of active constraints */
13363  if( aggregated )
13364  {
13365  assert(!SCIPconsIsActive(cons1));
13366  assert(SCIPconsIsActive(cons0));
13367  conss[c] = NULL;
13368  }
13369  }
13370  }
13371  }
13372 
13373  /* free temporary memory */
13374  SCIPfreeBufferArray(scip, &diffidx1minus0);
13375  SCIPfreeBufferArray(scip, &diffidx0minus1);
13376  SCIPfreeBufferArray(scip, &commonidx1);
13377  SCIPfreeBufferArray(scip, &commonidx0);
13378 
13379  return SCIP_OKAY;
13380 }
13381 
13382 /** applies full dual presolving on variables that only appear in linear constraints */
13383 static
13385  SCIP* scip, /**< SCIP data structure */
13386  SCIP_CONS** conss, /**< constraint set */
13387  int nconss, /**< number of constraints */
13388  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
13389  int* nchgbds /**< pointer to count the number of bound changes */
13390  )
13391 {
13392  SCIP_Real* redlb;
13393  SCIP_Real* redub;
13394  int* nlocksdown;
13395  int* nlocksup;
13396  SCIP_Bool* isimplint;
13397  SCIP_VAR** origvars;
13398  SCIP_VAR** vars;
13399  SCIP_VAR** conscontvars;
13400  int nvars;
13401  int nbinvars;
13402  int nintvars;
13403  int ncontvars;
13404  int v;
13405  int c;
13406 
13407  /* we calculate redundancy bounds with the following meaning:
13408  * redlb[v] == k : if x_v >= k, we can always round x_v down to x_v == k without violating any constraint
13409  * redub[v] == k : if x_v <= k, we can always round x_v up to x_v == k without violating any constraint
13410  * then:
13411  * c_v >= 0 : x_v <= redlb[v] is feasible due to optimality
13412  * c_v <= 0 : x_v >= redub[v] is feasible due to optimality
13413  */
13414 
13415  /* Additionally, we detect continuous variables that are implicitly integral.
13416  * A continuous variable j is implicit integral if it only has only +/-1 coefficients,
13417  * and all constraints (including the bounds as trivial constraints) in which:
13418  * c_j > 0: the variable is down-locked,
13419  * c_j < 0: the variable is up-locked,
13420  * c_j = 0: the variable appears
13421  * have, apart from j, only integer variables with integral coefficients and integral sides.
13422  * This is because then, the value of the variable is either determined by one of its bounds or
13423  * by one of these constraints, and in all cases, the value of the variable is integral.
13424  */
13425 
13426  assert(scip != NULL);
13427  assert(nconss == 0 || conss != NULL);
13428  assert(nchgbds != NULL);
13429  assert(!SCIPinProbing(scip));
13430 
13431  /* get active variables */
13432  nvars = SCIPgetNVars(scip);
13433  origvars = SCIPgetVars(scip);
13434 
13435  /* if the problem is a pure binary program, nothing can be achieved by full dual presolve */
13436  nbinvars = SCIPgetNBinVars(scip);
13437  if( nbinvars == nvars )
13438  return SCIP_OKAY;
13439 
13440  /* get number of continuous variables */
13441  ncontvars = SCIPgetNContVars(scip);
13442  nintvars = nvars - ncontvars;
13443 
13444  /* copy the variable array since this array might change during the curse of this algorithm */
13445  nvars = nvars - nbinvars;
13446  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &(origvars[nbinvars]), nvars) );
13447 
13448  /* allocate temporary memory */
13449  SCIP_CALL( SCIPallocBufferArray(scip, &redlb, nvars) );
13450  SCIP_CALL( SCIPallocBufferArray(scip, &redub, nvars) );
13451  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksdown, nvars) );
13452  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksup, nvars) );
13453  SCIP_CALL( SCIPallocBufferArray(scip, &isimplint, ncontvars) );
13454  SCIP_CALL( SCIPallocBufferArray(scip, &conscontvars, ncontvars) );
13455 
13456  /* initialize redundancy bounds */
13457  for( v = 0; v < nvars; ++v )
13458  {
13459  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
13460  redlb[v] = SCIPvarGetLbGlobal(vars[v]);
13461  redub[v] = SCIPvarGetUbGlobal(vars[v]);
13462  }
13463  BMSclearMemoryArray(nlocksdown, nvars);
13464  BMSclearMemoryArray(nlocksup, nvars);
13465 
13466  /* Initialize isimplint array: variable may be implied integer if rounded to their best bound they are integral.
13467  * We better not use SCIPisFeasIntegral() in these checks.
13468  */
13469  for( v = 0; v < ncontvars; v++ )
13470  {
13471  SCIP_VAR* var;
13472  SCIP_Real obj;
13473  SCIP_Real lb;
13474  SCIP_Real ub;
13475 
13476  var = vars[v + nintvars - nbinvars];
13477  lb = SCIPvarGetLbGlobal(var);
13478  ub = SCIPvarGetUbGlobal(var);
13479 
13480  obj = SCIPvarGetObj(var);
13481  if( SCIPisZero(scip, obj) )
13482  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb)) && (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
13483  else
13484  {
13485  if( SCIPisPositive(scip, obj) )
13486  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb));
13487  else
13488  {
13489  assert(SCIPisNegative(scip, obj));
13490  isimplint[v] = (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
13491  }
13492  }
13493  }
13494 
13495  /* scan all constraints */
13496  for( c = 0; c < nconss; ++c )
13497  {
13498  /* we only need to consider constraints that have been locked (i.e., checked constraints or constraints that are
13499  * part of checked disjunctions)
13500  */
13501  if( SCIPconsIsLocked(conss[c]) )
13502  {
13503  SCIP_CONSDATA* consdata;
13504  SCIP_Bool lhsexists;
13505  SCIP_Bool rhsexists;
13506  SCIP_Bool hasimpliedpotential;
13507  SCIP_Bool integralcoefs;
13508  int nlockspos;
13509  int contvarpos;
13510  int nconscontvars;
13511  int i;
13512 
13513  consdata = SCIPconsGetData(conss[c]);
13514  assert(consdata != NULL);
13515 
13516  /* get number of times the constraint was locked */
13517  nlockspos = SCIPconsGetNLocksPos(conss[c]);
13518 
13519  /* we do not want to include constraints with locked negation (this would be too weird) */
13520  if( SCIPconsGetNLocksNeg(conss[c]) > 0 )
13521  {
13522  /* mark all continuous variables as not being implicit integral */
13523  for( i = 0; i < consdata->nvars; ++i )
13524  {
13525  SCIP_VAR* var;
13526 
13527  var = consdata->vars[i];
13529  {
13530  int contv;
13531  contv = SCIPvarGetProbindex(var) - nintvars;
13532  assert(0 <= contv && contv < ncontvars); /* variable should be active due to applyFixings() */
13533  isimplint[contv] = FALSE;
13534  }
13535  }
13536  continue;
13537  }
13538 
13539  /* check for existing sides */
13540  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
13541  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
13542 
13543  /* count locks and update redundancy bounds */
13544  contvarpos = -1;
13545  nconscontvars = 0;
13546  hasimpliedpotential = FALSE;
13547  integralcoefs = !SCIPconsIsModifiable(conss[c]);
13548 
13549  for( i = 0; i < consdata->nvars; ++i )
13550  {
13551  SCIP_VAR* var;
13552  SCIP_Real val;
13553  SCIP_Real minresactivity;
13554  SCIP_Real maxresactivity;
13555  SCIP_Real newredlb;
13556  SCIP_Real newredub;
13557  SCIP_Bool minisrelax;
13558  SCIP_Bool maxisrelax;
13559  SCIP_Bool isminsettoinfinity;
13560  SCIP_Bool ismaxsettoinfinity;
13561  int arrayindex;
13562 
13563  var = consdata->vars[i];
13564  val = consdata->vals[i];
13565 
13566  /* check if still all integer variables have integral coefficients */
13567  if( SCIPvarIsIntegral(var) )
13568  integralcoefs = integralcoefs && SCIPisIntegral(scip, val);
13569 
13570  /* we do not need to process binary variables */
13571  if( SCIPvarIsBinary(var) )
13572  continue;
13573 
13574  if( SCIPconsIsModifiable(conss[c]) )
13575  {
13576  minresactivity = -SCIPinfinity(scip);
13577  maxresactivity = SCIPinfinity(scip);
13578  isminsettoinfinity = TRUE;
13579  ismaxsettoinfinity = TRUE;
13580  }
13581  else
13582  {
13583  /* calculate residual activity bounds if variable would be fixed to zero */
13584  consdataGetGlbActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
13585  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
13586 
13587  /* We called consdataGetGlbActivityResiduals() saying that we do not need a good relaxation,
13588  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
13589  * This is needed, because we do not want to rely on relaxed finite resactivities.
13590  */
13591  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
13592 
13593  /* check minresactivity for reliability */
13594  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
13595  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, TRUE);
13596 
13597  /* check maxresactivity for reliability */
13598  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
13599  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, TRUE);
13600  }
13601 
13602  arrayindex = SCIPvarGetProbindex(var) - nbinvars;
13603 
13604  assert(0 <= arrayindex && arrayindex < nvars); /* variable should be active due to applyFixings() */
13605 
13606  newredlb = redlb[arrayindex];
13607  newredub = redub[arrayindex];
13608  if( val > 0.0 )
13609  {
13610  if( lhsexists )
13611  {
13612  /* lhs <= d*x + a*y, d > 0 -> redundant in y if x >= (lhs - min{a*y})/d */
13613  nlocksdown[arrayindex] += nlockspos;
13614  newredlb = (isminsettoinfinity ? SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
13615  }
13616  if( rhsexists )
13617  {
13618  /* d*x + a*y <= rhs, d > 0 -> redundant in y if x <= (rhs - max{a*y})/d */
13619  nlocksup[arrayindex] += nlockspos;
13620  newredub = (ismaxsettoinfinity ? -SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
13621  }
13622  }
13623  else
13624  {
13625  if( lhsexists )
13626  {
13627  /* lhs <= d*x + a*y, d < 0 -> redundant in y if x <= (lhs - min{a*y})/d */
13628  nlocksup[arrayindex] += nlockspos;
13629  newredub = (isminsettoinfinity ? -SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
13630  }
13631  if( rhsexists )
13632  {
13633  /* d*x + a*y <= rhs, d < 0 -> redundant in y if x >= (rhs - max{a*y})/d */
13634  nlocksdown[arrayindex] += nlockspos;
13635  newredlb = (ismaxsettoinfinity ? SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
13636  }
13637  }
13638 
13639  /* if the variable is integer, we have to round the value to the next integral value */
13640  if( SCIPvarIsIntegral(var) )
13641  {
13642  if( !SCIPisInfinity(scip, newredlb) )
13643  newredlb = SCIPceil(scip, newredlb);
13644  if( !SCIPisInfinity(scip, -newredub) )
13645  newredub = SCIPfloor(scip, newredub);
13646  }
13647 
13648  /* update redundancy bounds */
13649  redlb[arrayindex] = MAX(redlb[arrayindex], newredlb);
13650  redub[arrayindex] = MIN(redub[arrayindex], newredub);
13651 
13652  /* collect the continuous variables of the constraint */
13654  {
13655  int contv;
13656 
13657  assert(nconscontvars < ncontvars);
13658  contvarpos = i;
13659  conscontvars[nconscontvars] = var;
13660  nconscontvars++;
13661 
13662  contv = SCIPvarGetProbindex(var) - nintvars;
13663  assert(0 <= contv && contv < ncontvars);
13664  hasimpliedpotential = hasimpliedpotential || isimplint[contv];
13665  }
13666  }
13667 
13668  /* update implied integer status of continuous variables */
13669  if( hasimpliedpotential )
13670  {
13671  if( nconscontvars > 1 || !integralcoefs )
13672  {
13673  /* there is more than one continuous variable or the integer variables have fractional coefficients:
13674  * none of the continuous variables is implied integer
13675  */
13676  for( i = 0; i < nconscontvars; i++ )
13677  {
13678  int contv;
13679  contv = SCIPvarGetProbindex(conscontvars[i]) - nintvars;
13680  assert(0 <= contv && contv < ncontvars);
13681  isimplint[contv] = FALSE;
13682  }
13683  }
13684  else
13685  {
13686  SCIP_VAR* var;
13687  SCIP_Real val;
13688  SCIP_Real absval;
13689  int contv;
13690 
13691  /* there is exactly one continuous variable and the integer variables have integral coefficients:
13692  * this is the interesting case, and we have to check whether the coefficient is +/-1 and the corresponding
13693  * side(s) of the constraint is integral
13694  */
13695  assert(nconscontvars == 1);
13696  assert(0 <= contvarpos && contvarpos < consdata->nvars);
13697  var = consdata->vars[contvarpos];
13698  val = consdata->vals[contvarpos];
13699  contv = SCIPvarGetProbindex(var) - nintvars;
13700  assert(0 <= contv && contv < ncontvars);
13701  assert(isimplint[contv]);
13702 
13703  absval = REALABS(val);
13704  if( !SCIPisEQ(scip, absval, 1.0) )
13705  isimplint[contv] = FALSE;
13706  else
13707  {
13708  SCIP_Real obj;
13709 
13710  obj = SCIPvarGetObj(var);
13711  if( obj * val >= 0.0 && lhsexists )
13712  {
13713  /* the variable may be blocked by the constraint's left hand side */
13714  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->lhs);
13715  }
13716  if( obj * val <= 0.0 && rhsexists )
13717  {
13718  /* the variable may be blocked by the constraint's left hand side */
13719  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->rhs);
13720  }
13721  }
13722  }
13723  }
13724  }
13725  }
13726 
13727  /* check if any bounds can be tightened due to optimality */
13728  for( v = 0; v < nvars; ++v )
13729  {
13730  SCIP_VAR* var;
13731  SCIP_Real obj;
13732  SCIP_Bool infeasible;
13733  SCIP_Bool tightened;
13734 
13735  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
13736  assert(SCIPvarGetNLocksDown(vars[v]) >= nlocksdown[v]);
13737  assert(SCIPvarGetNLocksUp(vars[v]) >= nlocksup[v]);
13738 
13739  var = vars[v];
13740  obj = SCIPvarGetObj(var);
13741  if( obj >= 0.0 )
13742  {
13743  /* making the variable as small as possible does not increase the objective:
13744  * check if all down locks of the variables are due to linear constraints;
13745  * if largest bound to make constraints redundant is -infinity, we better do nothing for numerical reasons
13746  */
13747  if( SCIPvarGetNLocksDown(var) == nlocksdown[v]
13748  && !SCIPisInfinity(scip, -redlb[v])
13749  && redlb[v] < SCIPvarGetUbGlobal(var) )
13750  {
13751  SCIP_Real ub;
13752 
13753  /* if x_v >= redlb[v], we can always round x_v down to x_v == redlb[v] without violating any constraint
13754  * -> tighten upper bound to x_v <= redlb[v]
13755  */
13756  SCIPdebugMessage("variable <%s> only locked down in linear constraints: dual presolve <%s>[%.15g,%.15g] <= %.15g\n",
13758  redlb[v]);
13759  SCIP_CALL( SCIPtightenVarUb(scip, var, redlb[v], FALSE, &infeasible, &tightened) );
13760  assert(!infeasible);
13761 
13762  ub = SCIPvarGetUbGlobal(var);
13763  redub[v] = MIN(redub[v], ub);
13764  if( tightened )
13765  (*nchgbds)++;
13766  }
13767  }
13768  if( obj <= 0.0 )
13769  {
13770  /* making the variable as large as possible does not increase the objective:
13771  * check if all up locks of the variables are due to linear constraints;
13772  * if smallest bound to make constraints redundant is +infinity, we better do nothing for numerical reasons
13773  */
13774  if( SCIPvarGetNLocksUp(var) == nlocksup[v]
13775  && !SCIPisInfinity(scip, redub[v])
13776  && redub[v] > SCIPvarGetLbGlobal(var) )
13777  {
13778  SCIP_Real lb;
13779 
13780  /* if x_v <= redub[v], we can always round x_v up to x_v == redub[v] without violating any constraint
13781  * -> tighten lower bound to x_v >= redub[v]
13782  */
13783  SCIPdebugMessage("variable <%s> only locked up in linear constraints: dual presolve <%s>[%.15g,%.15g] >= %.15g\n",
13785  redub[v]);
13786  SCIP_CALL( SCIPtightenVarLb(scip, var, redub[v], FALSE, &infeasible, &tightened) );
13787  assert(!infeasible);
13788 
13789  lb = SCIPvarGetLbGlobal(var);
13790  redlb[v] = MAX(redlb[v], lb);
13791  if( tightened )
13792  (*nchgbds)++;
13793  }
13794  }
13795  }
13796 
13797  /* upgrade continuous variables to implied integers */
13798  for( v = nintvars - nbinvars; v < nvars; ++v )
13799  {
13800  SCIP_VAR* var;
13801  SCIP_Bool infeasible;
13802 
13803  var = vars[v];
13804  assert(var != NULL);
13805 
13806  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
13807  assert(SCIPvarGetNLocksDown(var) >= nlocksdown[v]);
13808  assert(SCIPvarGetNLocksUp(var) >= nlocksup[v]);
13809  assert(0 <= v - nintvars + nbinvars && v - nintvars + nbinvars < ncontvars);
13810 
13811  /* we can only conclude implied integrality if the variable appears in no other constraint */
13812  if( isimplint[v - nintvars + nbinvars]
13813  && SCIPvarGetNLocksDown(var) == nlocksdown[v]
13814  && SCIPvarGetNLocksUp(var) == nlocksup[v] )
13815  {
13816 
13817  /* since we locally copied the variable array we can change the variable type immediately */
13818  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
13819 
13820  if( infeasible )
13821  {
13822  SCIPdebugMessage("infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
13823  *cutoff = TRUE;
13824 
13825  break;
13826  }
13827 
13828  SCIPdebugMessage("dual presolve: converting continuous variable <%s>[%g,%g] to implicit integer\n",
13830  }
13831  }
13832 
13833  /* free temporary memory */
13834  SCIPfreeBufferArray(scip, &conscontvars);
13835  SCIPfreeBufferArray(scip, &isimplint);
13836  SCIPfreeBufferArray(scip, &nlocksup);
13837  SCIPfreeBufferArray(scip, &nlocksdown);
13838  SCIPfreeBufferArray(scip, &redub);
13839  SCIPfreeBufferArray(scip, &redlb);
13840 
13841  SCIPfreeBufferArray(scip, &vars);
13842 
13843  return SCIP_OKAY;
13844 }
13845 
13846 
13847 /*
13848  * Callback methods of constraint handler
13849  */
13850 
13851 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
13852 static
13853 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
13854 { /*lint --e{715}*/
13855  assert(scip != NULL);
13856  assert(conshdlr != NULL);
13857  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
13858 
13859  /* call inclusion method of constraint handler */
13861 
13862  *valid = TRUE;
13863 
13864  return SCIP_OKAY;
13865 }
13866 
13867 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
13868 static
13869 SCIP_DECL_CONSFREE(consFreeLinear)
13870 { /*lint --e{715}*/
13871  SCIP_CONSHDLRDATA* conshdlrdata;
13872 
13873  assert(scip != NULL);
13874  assert(conshdlr != NULL);
13875  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
13876 
13877  /* free constraint handler data */
13878  conshdlrdata = SCIPconshdlrGetData(conshdlr);
13879  assert(conshdlrdata != NULL);
13880 
13881  conshdlrdataFree(scip, &conshdlrdata);
13882 
13883  SCIPconshdlrSetData(conshdlr, NULL);
13884 
13885  return SCIP_OKAY;
13886 }
13887 
13888 
13889 /** initialization method of constraint handler (called after problem was transformed) */
13890 static
13891 SCIP_DECL_CONSINIT(consInitLinear)
13892 {
13893  SCIP_CONSHDLRDATA* conshdlrdata;
13894  int c;
13895 
13896  assert(scip != NULL);
13897 
13898  /* check for event handler */
13899  conshdlrdata = SCIPconshdlrGetData(conshdlr);
13900  assert(conshdlrdata != NULL);
13901  assert(conshdlrdata->eventhdlr != NULL);
13902  assert(nconss == 0 || conss != NULL);
13903 
13904  /* catch events for the constraints */
13905  for( c = 0; c < nconss; ++c )
13906  {
13907  /* catch all events */
13908  SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
13909  }
13910 
13911  return SCIP_OKAY;
13912 }
13913 
13914 
13915 /** deinitialization method of constraint handler (called before transformed problem is freed) */
13916 static
13917 SCIP_DECL_CONSEXIT(consExitLinear)
13918 {
13919  SCIP_CONSHDLRDATA* conshdlrdata;
13920  int c;
13921 
13922  assert(scip != NULL);
13923 
13924  /* check for event handler */
13925  conshdlrdata = SCIPconshdlrGetData(conshdlr);
13926  assert(conshdlrdata != NULL);
13927  assert(conshdlrdata->eventhdlr != NULL);
13928 
13929  /* drop events for the constraints */
13930  for( c = nconss - 1; c >= 0; --c )
13931  {
13932  SCIP_CONSDATA* consdata;
13934  consdata = SCIPconsGetData(conss[c]);
13935  assert(consdata != NULL);
13936 
13937  if( consdata->eventdata != NULL )
13938  {
13939  /* drop all events */
13940  SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
13941  assert(consdata->eventdata == NULL);
13942  }
13943  }
13944 
13945  return SCIP_OKAY;
13946 
13947 }
13948 
13949 #ifdef WITH_PRINTORIGCONSTYPES
13950 
13951 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
13952 static
13953 SCIP_Bool isRangedRow(
13954  SCIP* scip, /**< SCIP data structure */
13955  SCIP_CONS* cons /**< constraint */
13956  )
13957 {
13958  assert(scip != NULL);
13959  assert(cons != NULL);
13960  assert(SCIPconsGetData(cons) != NULL);
13961 
13962  return !(SCIPisEQ(scip, SCIPconsGetData(cons)->lhs, SCIPconsGetData(cons)->rhs)
13963  || SCIPisInfinity(scip, -SCIPconsGetData(cons)->lhs) || SCIPisInfinity(scip, SCIPconsGetData(cons)->rhs) );
13964 }
13965 
13966 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
13967 static
13968 SCIP_Bool isFiniteNonnegativeIntegral(
13969  SCIP* scip, /**< SCIP data structure */
13970  SCIP_Real x /**< value */
13971  )
13972 {
13973  assert(scip != NULL);
13974 
13975  return (!SCIPisInfinity(scip, x) && !SCIPisNegative(scip, x) && SCIPisIntegral(scip, x));
13976 }
13977 
13978 /** presolving initialization method of constraint handler (called when presolving is about to begin) */
13979 static
13980 SCIP_DECL_CONSINITPRE(consInitpreLinear)
13981 { /*lint --e{715}*/
13982  int counter[(int)SCIP_CONSTYPE_GENERAL + 1];
13983  int c;
13984 
13985  assert(scip != NULL);
13986 
13987  /* initialize counter for constraint types to zero */
13988  BMSclearMemoryArray(counter, (int)SCIP_CONSTYPE_GENERAL + 1);
13989 
13990  /* loop through all constraints */
13991  for( c = 0; c < nconss; c++ )
13992  {
13993  SCIP_CONS* cons;
13994  SCIP_CONSDATA* consdata;
13995  int i;
13996 
13997  /* get constraint */
13998  cons = conss[c];
13999  assert(cons != NULL);
14000 
14001  /* get constraint data */
14002  consdata = SCIPconsGetData(cons);
14003  assert(consdata != NULL);
14004 
14005  /* merge multiples and delete variables with zero coefficient */
14006  SCIP_CALL( mergeMultiples(scip, cons) );
14007  for( i = 0; i < consdata->nvars; i++ )
14008  {
14009  assert(!SCIPisZero(scip, consdata->vals[i]));
14010  }
14011 
14012  /* is constraint of type SCIP_CONSTYPE_EMPTY? */
14013  if( consdata->nvars == 0 )
14014  {
14015  SCIPdebugMessage("classified as EMPTY: ");
14016  SCIPdebugPrintCons(scip, cons, NULL);
14017  counter[SCIP_CONSTYPE_EMPTY]++;
14018  continue;
14019  }
14020 
14021  /* is constraint of type SCIP_CONSTYPE_FREE? */
14022  if( SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, -consdata->lhs) )
14023  {
14024  SCIPdebugMessage("classified as FREE: ");
14025  SCIPdebugPrintCons(scip, cons, NULL);
14026  counter[SCIP_CONSTYPE_FREE]++;
14027  continue;
14028  }
14029 
14030  /* is constraint of type SCIP_CONSTYPE_SINGLETON? */
14031  if( consdata->nvars == 1 )
14032  {
14033  SCIPdebugMessage("classified as SINGLETON: ");
14034  SCIPdebugPrintCons(scip, cons, NULL);
14035  counter[SCIP_CONSTYPE_SINGLETON] += isRangedRow(scip, cons) ? 2 : 1;
14036  continue;
14037  }
14038 
14039  /* is constraint of type SCIP_CONSTYPE_AGGREGATION? */
14040  if( consdata->nvars == 2 && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
14041  {
14042  SCIPdebugMessage("classified as AGGREGATION: ");
14043  SCIPdebugPrintCons(scip, cons, NULL);
14044  counter[SCIP_CONSTYPE_AGGREGATION]++;
14045  continue;
14046  }
14047 
14048  /* is constraint of type SCIP_CONSTYPE_{VARBOUND}? */
14049  if( consdata->nvars == 2 )
14050  {
14051  SCIPdebugMessage("classified as VARBOUND: ");
14052  SCIPdebugPrintCons(scip, cons, NULL);
14053  counter[SCIP_CONSTYPE_VARBOUND] += isRangedRow(scip, cons) ? 2 : 1;
14054  continue;
14055  }
14056 
14057  /* is constraint of type SCIP_CONSTYPE_{SETPARTITION, SETPACKING, SETCOVERING, CARDINALITY, INVKNAPSACK}? */
14058  {
14059  SCIP_Real scale;
14060  SCIP_Real b;
14061  SCIP_Bool unmatched;
14062  int nnegbinvars;
14063 
14064  unmatched = FALSE;
14065  nnegbinvars = 0;
14066 
14067  scale = REALABS(consdata->vals[0]);
14068  for( i = 0; i < consdata->nvars && !unmatched; i++ )
14069  {
14070  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
14071  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
14072  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
14073  unmatched = unmatched || !SCIPisEQ(scip, REALABS(consdata->vals[i]), scale);
14074 
14075  if( consdata->vals[i] < 0.0 )
14076  nnegbinvars++;
14077  }
14078 
14079  if( !unmatched )
14080  {
14081  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
14082  {
14083  b = consdata->rhs/scale + nnegbinvars;
14084  if( SCIPisEQ(scip, 1.0, b) )
14085  {
14086  SCIPdebugMessage("classified as SETPARTITION: ");
14087  SCIPdebugPrintCons(scip, cons, NULL);
14088  counter[SCIP_CONSTYPE_SETPARTITION]++;
14089  continue;
14090  }
14091  else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
14092  {
14093  SCIPdebugMessage("classified as CARDINALITY: ");
14094  SCIPdebugPrintCons(scip, cons, NULL);
14095  counter[SCIP_CONSTYPE_CARDINALITY]++;
14096  continue;
14097  }
14098  }
14099 
14100  b = consdata->rhs/scale + nnegbinvars;
14101  if( SCIPisEQ(scip, 1.0, b) )
14102  {
14103  SCIPdebugMessage("classified as SETPACKING: ");
14104  SCIPdebugPrintCons(scip, cons, NULL);
14105  counter[SCIP_CONSTYPE_SETPACKING]++;
14106  consdata->rhs = SCIPinfinity(scip);
14107  }
14108  else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
14109  {
14110  SCIPdebugMessage("classified as INVKNAPSACK: ");
14111  SCIPdebugPrintCons(scip, cons, NULL);
14112  counter[SCIP_CONSTYPE_INVKNAPSACK]++;
14113  consdata->rhs = SCIPinfinity(scip);
14114  }
14115 
14116  b = consdata->lhs/scale + nnegbinvars;
14117  if( SCIPisEQ(scip, 1.0, b) )
14118  {
14119  SCIPdebugMessage("classified as SETCOVERING: ");
14120  SCIPdebugPrintCons(scip, cons, NULL);
14121  counter[SCIP_CONSTYPE_SETCOVERING]++;
14122  consdata->lhs = -SCIPinfinity(scip);
14123  }
14124 
14125  if( SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, consdata->rhs) )
14126  continue;
14127  }
14128  }
14129 
14130  /* is constraint of type SCIP_CONSTYPE_{EQKNAPSACK, BINPACKING, KNAPSACK}? */
14131  /* @todo If coefficients or rhs are not integral, we currently do not check
14132  * if the constraint could be scaled (finitely), such that they are.
14133  */
14134  {
14135  SCIP_Real b;
14136  SCIP_Bool unmatched;
14137 
14138  b = consdata->rhs;
14139  unmatched = FALSE;
14140  for( i = 0; i < consdata->nvars && !unmatched; i++ )
14141  {
14142  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
14143  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
14144  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
14145  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
14146 
14147  if( SCIPisNegative(scip, consdata->vals[i]) )
14148  b -= consdata->vals[i];
14149  }
14150  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
14151 
14152  if( !unmatched )
14153  {
14154  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
14155  {
14156  SCIPdebugMessage("classified as EQKNAPSACK: ");
14157  SCIPdebugPrintCons(scip, cons, NULL);
14158  counter[SCIP_CONSTYPE_EQKNAPSACK]++;
14159  continue;
14160  }
14161  else
14162  {
14163  SCIP_Bool matched;
14164 
14165  matched = FALSE;
14166  for( i = 0; i < consdata->nvars && !matched; i++ )
14167  {
14168  matched = matched || SCIPisEQ(scip, b, REALABS(consdata->vals[i]));
14169  }
14170 
14171  SCIPdebugMessage("classified as %s: ", matched ? "BINPACKING" : "KNAPSACK");
14172  SCIPdebugPrintCons(scip, cons, NULL);
14173  counter[matched ? SCIP_CONSTYPE_BINPACKING : SCIP_CONSTYPE_KNAPSACK]++;
14174  }
14175 
14176  if( SCIPisInfinity(scip, -consdata->lhs) )
14177  continue;
14178  else
14179  consdata->rhs = SCIPinfinity(scip);
14180  }
14181  }
14182 
14183  /* is constraint of type SCIP_CONSTYPE_{INTKNAPSACK}? */
14184  {
14185  SCIP_Real b;
14186  SCIP_Bool unmatched;
14187 
14188  unmatched = FALSE;
14189 
14190  b = consdata->rhs;
14191  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
14192 
14193  for( i = 0; i < consdata->nvars && !unmatched; i++ )
14194  {
14195  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
14196  unmatched = unmatched || SCIPisNegative(scip, SCIPvarGetLbGlobal(consdata->vars[i]));
14197  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
14198  unmatched = unmatched || SCIPisNegative(scip, consdata->vals[i]);
14199  }
14200 
14201  if( !unmatched )
14202  {
14203  SCIPdebugMessage("classified as INTKNAPSACK: ");
14204  SCIPdebugPrintCons(scip, cons, NULL);
14205  counter[SCIP_CONSTYPE_INTKNAPSACK]++;
14206 
14207  if( SCIPisInfinity(scip, -consdata->lhs) )
14208  continue;
14209  else
14210  consdata->rhs = SCIPinfinity(scip);
14211  }
14212  }
14213 
14214  /* is constraint of type SCIP_CONSTYPE_{MIXEDBINARY}? */
14215  {
14216  SCIP_Bool unmatched;
14217 
14218  unmatched = FALSE;
14219  for( i = 0; i < consdata->nvars && !unmatched; i++ )
14220  {
14221  if( SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS
14222  && (SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0)
14223  || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0)) )
14224  unmatched = TRUE;
14225  }
14226 
14227  if( !unmatched )
14228  {
14229  SCIPdebugMessage("classified as MIXEDBINARY (%d): ", isRangedRow(scip, cons) ? 2 : 1);
14230  SCIPdebugPrintCons(scip, cons, NULL);
14231  counter[SCIP_CONSTYPE_MIXEDBINARY] += isRangedRow(scip, cons) ? 2 : 1;
14232  continue;
14233  }
14234  }
14235 
14236  /* no special structure detected */
14237  SCIPdebugMessage("classified as GENERAL: ");
14238  SCIPdebugPrintCons(scip, cons, NULL);
14239  counter[SCIP_CONSTYPE_GENERAL] += isRangedRow(scip, cons) ? 2 : 1;
14240  }
14241 
14242  /* print statistics */
14243  SCIPinfoMessage(scip, NULL, "\n");
14244  SCIPinfoMessage(scip, NULL, "Number of constraints according to type:\n");
14245  SCIPinfoMessage(scip, NULL, "----------------------------------------\n");
14246  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_EMPTY %6d\n", 0, counter[ 0]);
14247  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_FREE %6d\n", 1, counter[ 1]);
14248  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SINGLETON %6d\n", 2, counter[ 2]);
14249  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_AGGREGATION %6d\n", 3, counter[ 3]);
14250  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_VARBOUND %6d\n", 4, counter[ 4]);
14251  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SETPARTITION %6d\n", 5, counter[ 5]);
14252  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SETPACKING %6d\n", 6, counter[ 6]);
14253  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SETCOVERING %6d\n", 7, counter[ 7]);
14254  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_CARDINALITY %6d\n", 8, counter[ 8]);
14255  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_INVKNAPSACK %6d\n", 9, counter[ 9]);
14256  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_EQKNAPSACK %6d\n", 10, counter[10]);
14257  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_BINPACKING %6d\n", 11, counter[11]);
14258  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_KNAPSACK %6d\n", 12, counter[12]);
14259  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_INTKNAPSACK %6d\n", 13, counter[13]);
14260  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_MIXEDBINARY %6d\n", 14, counter[14]);
14261  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_GENERAL %6d\n", 15, counter[15]);
14262  SCIPinfoMessage(scip, NULL, "----------------------------------------\n\n");
14263 
14264  SCIPinfoMessage(scip, NULL, " EMPTY");
14265  SCIPinfoMessage(scip, NULL, " FREE");
14266  SCIPinfoMessage(scip, NULL, " SING");
14267  SCIPinfoMessage(scip, NULL, " AGGR");
14268  SCIPinfoMessage(scip, NULL, " VARBD");
14269  SCIPinfoMessage(scip, NULL, " SETPART");
14270  SCIPinfoMessage(scip, NULL, " SETPACK");
14271  SCIPinfoMessage(scip, NULL, " SETCOV");
14272  SCIPinfoMessage(scip, NULL, " CARD");
14273  SCIPinfoMessage(scip, NULL, " INVKNAP");
14274  SCIPinfoMessage(scip, NULL, " EQKNAP");
14275  SCIPinfoMessage(scip, NULL, " BINPACK");
14276  SCIPinfoMessage(scip, NULL, " KNAP");
14277  SCIPinfoMessage(scip, NULL, " INTKNAP");
14278  SCIPinfoMessage(scip, NULL, " MIXBIN");
14279  SCIPinfoMessage(scip, NULL, " GEN\n");
14280  for( c = 0; c <= (int)SCIP_CONSTYPE_GENERAL; c++ )
14281  {
14282  SCIPinfoMessage(scip, NULL, "%9d", counter[c]);
14283  }
14284 
14285  SCIPinfoMessage(scip, NULL, "\n\n");
14286  SCIPinfoMessage(scip, NULL, "----------------------------------------\n\n");
14287 
14288  return SCIP_OKAY;
14289 }
14290 #endif
14291 
14292 
14293 /** presolving deinitialization method of constraint handler (called after presolving has been finished) */
14294 static
14295 SCIP_DECL_CONSEXITPRE(consExitpreLinear)
14296 { /*lint --e{715}*/
14297  int c;
14298 #ifdef SCIP_STATISTIC
14299  SCIP_CONSHDLRDATA* conshdlrdata;
14300  int ngoodconss;
14301  int nallconss;
14302 #endif
14303 
14304  /* delete all linear constraints that were upgraded to a more specific constraint type;
14305  * make sure, only active variables remain in the remaining constraints
14306  */
14307  assert(scip != NULL);
14308 
14309 #ifdef SCIP_STATISTIC
14310  /* count number of well behaved linear constraints */
14311  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14312  assert(conshdlrdata != NULL);
14313 
14314  ngoodconss = 0;
14315  nallconss = 0;
14316 
14317  for( c = 0; c < nconss; ++c )
14318  {
14319  SCIP_CONSDATA* consdata;
14320 
14321  if( SCIPconsIsDeleted(conss[c]) )
14322  continue;
14323 
14324  consdata = SCIPconsGetData(conss[c]);
14325  assert(consdata != NULL);
14326 
14327  if( consdata->upgraded )
14328  continue;
14329 
14330  nallconss++;
14331 
14332  consdataRecomputeMaxActivityDelta(scip, consdata);
14333 
14334  if( SCIPisLT(scip, consdata->maxactdelta, conshdlrdata->maxeasyactivitydelta) )
14335  ngoodconss++;
14336  }
14337  if( nallconss )
14338  {
14339  SCIPstatisticMessage("below threshold: %d / %d ratio= %g\n", ngoodconss, nallconss, (100.0 * ngoodconss / nallconss));
14340  }
14341 #endif
14342 
14343  for( c = 0; c < nconss; ++c )
14344  {
14345  SCIP_CONSDATA* consdata;
14346 
14347  if( SCIPconsIsDeleted(conss[c]) )
14348  continue;
14349 
14350  consdata = SCIPconsGetData(conss[c]);
14351  assert(consdata != NULL);
14352 
14353  if( consdata->upgraded )
14354  {
14355  /* this is no problem reduction, because the upgraded constraint was added to the problem before, and the
14356  * (redundant) linear constraint was only kept in order to support presolving the the linear constraint handler
14357  */
14358  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
14359  }
14360  else
14361  {
14362  /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
14363  SCIP_CALL( applyFixings(scip, conss[c], NULL) );
14364  }
14365  }
14366 
14367  return SCIP_OKAY;
14368 }
14369 
14370 
14371 /** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
14372 static
14373 SCIP_DECL_CONSEXITSOL(consExitsolLinear)
14374 { /*lint --e{715}*/
14375  int c;
14376 
14377  assert(scip != NULL);
14378 
14379  /* release the rows of all constraints */
14380  for( c = 0; c < nconss; ++c )
14381  {
14382  SCIP_CONSDATA* consdata;
14383 
14384  consdata = SCIPconsGetData(conss[c]);
14385  assert(consdata != NULL);
14386 
14387  if( consdata->row != NULL )
14388  {
14389  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
14390  }
14391  }
14392 
14393  /* if this is a restart, convert cutpool rows into linear constraints */
14394  if( restart )
14395  {
14396  int ncutsadded;
14397 
14398  ncutsadded = 0;
14399 
14400  /* create out of all active cuts in cutpool linear constraints */
14401  SCIP_CALL( SCIPconvertCutsToConss(scip, NULL, NULL, TRUE, &ncutsadded) );
14402 
14403  if( ncutsadded > 0 )
14404  {
14406  "(restart) converted %d cuts from the global cut pool into linear constraints\n", ncutsadded);
14407  /* an extra blank line should be printed separately since the buffer message handler only handles up to one
14408  * line correctly
14409  */
14411  }
14412  }
14413 
14414  return SCIP_OKAY;
14415 }
14416 
14417 
14418 /** frees specific constraint data */
14419 static
14420 SCIP_DECL_CONSDELETE(consDeleteLinear)
14421 { /*lint --e{715}*/
14422  SCIP_CONSHDLRDATA* conshdlrdata;
14423 
14424  assert(scip != NULL);
14425  assert(conshdlr != NULL);
14426  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14427 
14428  /* check for event handler */
14429  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14430  assert(conshdlrdata != NULL);
14431  assert(conshdlrdata->eventhdlr != NULL);
14432 
14433  /* free event datas */
14434  if( (*consdata)->eventdata != NULL )
14435  {
14436  /* drop bound change events of variables */
14437  SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
14438  }
14439  assert((*consdata)->eventdata == NULL);
14440 
14441  /* free linear constraint */
14442  SCIP_CALL( consdataFree(scip, consdata) );
14443 
14444  return SCIP_OKAY;
14445 }
14446 
14447 
14448 /** transforms constraint data into data belonging to the transformed problem */
14449 static
14450 SCIP_DECL_CONSTRANS(consTransLinear)
14451 { /*lint --e{715}*/
14452  SCIP_CONSHDLRDATA* conshdlrdata;
14453  SCIP_CONSDATA* sourcedata;
14454  SCIP_CONSDATA* targetdata;
14455 
14456  /*debugMessage("Trans method of linear constraints\n");*/
14457 
14458  assert(scip != NULL);
14459  assert(conshdlr != NULL);
14460  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14461  assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
14462  assert(sourcecons != NULL);
14463  assert(targetcons != NULL);
14464 
14465  sourcedata = SCIPconsGetData(sourcecons);
14466  assert(sourcedata != NULL);
14467  assert(sourcedata->row == NULL); /* in original problem, there cannot be LP rows */
14468 
14469  /* check for event handler */
14470  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14471  assert(conshdlrdata != NULL);
14472  assert(conshdlrdata->eventhdlr != NULL);
14473 
14474  /* create linear constraint data for target constraint */
14475  SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs, sourcedata->rhs) );
14476 
14477  /* create target constraint */
14478  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
14479  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
14480  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
14481  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
14482  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
14483 
14484  if( SCIPisTransformed(scip) && needEvents(scip) )
14485  {
14486  /* catch bound change events of variables */
14487  SCIP_CALL( consCatchAllEvents(scip, *targetcons, conshdlrdata->eventhdlr) );
14488  assert(targetdata->eventdata != NULL);
14489  }
14490 
14491  return SCIP_OKAY;
14492 }
14493 
14494 
14495 /** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
14496 static
14497 SCIP_DECL_CONSINITLP(consInitlpLinear)
14498 { /*lint --e{715}*/
14499  SCIP_Bool cutoff;
14500  int c;
14501 
14502  assert(scip != NULL);
14503  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14504 
14505  for( c = 0; c < nconss; ++c )
14506  {
14507  assert(SCIPconsIsInitial(conss[c]));
14508  SCIP_CALL( addRelaxation(scip, conss[c], NULL, &cutoff) );
14509  /* cannot use cutoff here, since initlp has no return value */
14510  }
14511 
14512  return SCIP_OKAY;
14514 
14515 
14516 /** separation method of constraint handler for LP solutions */
14517 static
14518 SCIP_DECL_CONSSEPALP(consSepalpLinear)
14519 { /*lint --e{715}*/
14520  SCIP_CONSHDLRDATA* conshdlrdata;
14521  SCIP_Real loclowerbound;
14522  SCIP_Real glblowerbound;
14523  SCIP_Real cutoffbound;
14524  SCIP_Real maxbound;
14525  SCIP_Bool separatecards;
14526  SCIP_Bool cutoff;
14527  int c;
14528  int depth;
14529  int nrounds;
14530  int maxsepacuts;
14531  int ncuts;
14532 
14533  assert(scip != NULL);
14534  assert(conshdlr != NULL);
14535  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14536  assert(result != NULL);
14537 
14538  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14539  assert(conshdlrdata != NULL);
14540  depth = SCIPgetDepth(scip);
14541  nrounds = SCIPgetNSepaRounds(scip);
14542 
14543  /*debugMessage("Sepa method of linear constraints\n");*/
14544 
14545  *result = SCIP_DIDNOTRUN;
14546 
14547  /* only call the separator a given number of times at each node */
14548  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
14549  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
14550  return SCIP_OKAY;
14551 
14552  /* get the maximal number of cuts allowed in a separation round */
14553  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
14554 
14555  /* check if we want to produce knapsack cardinality cuts at this node */
14556  loclowerbound = SCIPgetLocalLowerbound(scip);
14557  glblowerbound = SCIPgetLowerbound(scip);
14558  cutoffbound = SCIPgetCutoffbound(scip);
14559  maxbound = glblowerbound + conshdlrdata->maxcardbounddist * (cutoffbound - glblowerbound);
14560  separatecards = SCIPisLE(scip, loclowerbound, maxbound);
14561  separatecards = separatecards && (SCIPgetNLPBranchCands(scip) > 0);
14562 
14563  *result = SCIP_DIDNOTFIND;
14564  ncuts = 0;
14565  cutoff = FALSE;
14566 
14567  /* check all useful linear constraints for feasibility */
14568  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
14569  {
14570  /*debugMessage("separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
14571  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, separatecards, conshdlrdata->separateall, &ncuts, &cutoff) );
14572  }
14573 
14574  /* adjust return value */
14575  if( cutoff )
14576  *result = SCIP_CUTOFF;
14577  else if( ncuts > 0 )
14578  *result = SCIP_SEPARATED;
14579 
14580  /* combine linear constraints to get more cuts */
14581  /**@todo further cuts of linear constraints */
14582 
14583  return SCIP_OKAY;
14584 }
14585 
14586 
14587 /** separation method of constraint handler for arbitrary primal solutions */
14588 static
14589 SCIP_DECL_CONSSEPASOL(consSepasolLinear)
14590 { /*lint --e{715}*/
14591  SCIP_CONSHDLRDATA* conshdlrdata;
14592  int c;
14593  int depth;
14594  int nrounds;
14595  int maxsepacuts;
14596  int ncuts;
14597  SCIP_Bool cutoff;
14598 
14599  assert(scip != NULL);
14600  assert(conshdlr != NULL);
14601  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14602  assert(result != NULL);
14603 
14604  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14605  assert(conshdlrdata != NULL);
14606  depth = SCIPgetDepth(scip);
14607  nrounds = SCIPgetNSepaRounds(scip);
14608 
14609  /*debugMessage("Sepa method of linear constraints\n");*/
14610 
14611  *result = SCIP_DIDNOTRUN;
14612 
14613  /* only call the separator a given number of times at each node */
14614  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
14615  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
14616  return SCIP_OKAY;
14617 
14618  /* get the maximal number of cuts allowed in a separation round */
14619  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
14620 
14621  *result = SCIP_DIDNOTFIND;
14622  ncuts = 0;
14623  cutoff = FALSE;
14624 
14625  /* check all useful linear constraints for feasibility */
14626  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
14627  {
14628  /*debugMessage("separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
14629  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, TRUE, conshdlrdata->separateall, &ncuts, &cutoff) );
14630  }
14631 
14632  /* adjust return value */
14633  if( cutoff )
14634  *result = SCIP_CUTOFF;
14635  else if( ncuts > 0 )
14636  *result = SCIP_SEPARATED;
14637 
14638  /* combine linear constraints to get more cuts */
14639  /**@todo further cuts of linear constraints */
14640 
14641  return SCIP_OKAY;
14642 }
14643 
14644 
14645 /** constraint enforcing method of constraint handler for LP solutions */
14646 static
14647 SCIP_DECL_CONSENFOLP(consEnfolpLinear)
14648 { /*lint --e{715}*/
14649  SCIP_CONSHDLRDATA* conshdlrdata;
14650  SCIP_Bool checkrelmaxabs;
14651  SCIP_Bool violated;
14652  SCIP_Bool cutoff;
14653  int c;
14654 
14655  assert(scip != NULL);
14656  assert(conshdlr != NULL);
14657  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14658  assert(result != NULL);
14659 
14660  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14661  assert(conshdlrdata != NULL);
14662 
14663  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
14664 
14665  /*SCIPdebugMessage("Enfolp method of linear constraints\n");*/
14666 
14667  /* check for violated constraints
14668  * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
14669  */
14670  *result = SCIP_FEASIBLE;
14671 
14672  /* check all useful linear constraints for feasibility */
14673  for( c = 0; c < nusefulconss; ++c )
14674  {
14675  SCIP_CALL( checkCons(scip, conss[c], NULL, FALSE, checkrelmaxabs, &violated) );
14676 
14677  if( violated )
14678  {
14679  /* insert LP row as cut */
14680  SCIP_CALL( addRelaxation(scip, conss[c], NULL, &cutoff) );
14681  if ( cutoff )
14682  *result = SCIP_CUTOFF;
14683  else
14684  *result = SCIP_SEPARATED;
14685  }
14686  }
14687 
14688  /* check all obsolete linear constraints for feasibility */
14689  for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
14690  {
14691  SCIP_CALL( checkCons(scip, conss[c], NULL, FALSE, checkrelmaxabs, &violated) );
14692 
14693  if( violated )
14694  {
14695  /* insert LP row as cut */
14696  SCIP_CALL( addRelaxation(scip, conss[c], NULL, &cutoff) );
14697  if ( cutoff )
14698  *result = SCIP_CUTOFF;
14699  else
14700  *result = SCIP_SEPARATED;
14701  }
14702  }
14703 
14704  return SCIP_OKAY;
14705 }
14706 
14707 
14708 /** constraint enforcing method of constraint handler for pseudo solutions */
14709 static
14710 SCIP_DECL_CONSENFOPS(consEnfopsLinear)
14711 { /*lint --e{715}*/
14712  SCIP_CONSHDLRDATA* conshdlrdata;
14713  SCIP_Bool checkrelmaxabs;
14714  SCIP_Bool violated;
14715  int c;
14716 
14717  assert(scip != NULL);
14718  assert(conshdlr != NULL);
14719  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14720  assert(result != NULL);
14721 
14722  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14723  assert(conshdlrdata != NULL);
14724 
14725  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
14727  SCIPdebugMessage("Enfops method of linear constraints\n");
14728 
14729  /* if the solution is infeasible anyway due to objective value, skip the enforcement */
14730  if( objinfeasible )
14731  {
14732  SCIPdebugMessage("-> pseudo solution is objective infeasible, return.\n");
14733 
14734  *result = SCIP_DIDNOTRUN;
14735  return SCIP_OKAY;
14736  }
14737 
14738  /* check all linear constraints for feasibility */
14739  violated = FALSE;
14740  for( c = 0; c < nconss && !violated; ++c )
14741  {
14742  SCIP_CALL( checkCons(scip, conss[c], NULL, TRUE, checkrelmaxabs, &violated) );
14743  }
14744 
14745  if( violated )
14746  *result = SCIP_INFEASIBLE;
14747  else
14748  *result = SCIP_FEASIBLE;
14749 
14750  SCIPdebugMessage("-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
14751 
14752  return SCIP_OKAY;
14753 }
14754 
14755 
14756 /** feasibility check method of constraint handler for integral solutions */
14757 static
14758 SCIP_DECL_CONSCHECK(consCheckLinear)
14759 { /*lint --e{715}*/
14760  SCIP_CONSHDLRDATA* conshdlrdata;
14761  SCIP_Bool checkrelmaxabs;
14762  SCIP_Bool violated;
14763  int c;
14764 
14765  assert(scip != NULL);
14766  assert(conshdlr != NULL);
14767  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14768  assert(result != NULL);
14769 
14770  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14771  assert(conshdlrdata != NULL);
14772 
14773  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
14775  /*debugMessage("Check method of linear constraints\n");*/
14776 
14777  /* check all linear constraints for feasibility */
14778  violated = FALSE;
14779  for( c = 0; c < nconss && !violated; ++c )
14780  {
14781  SCIP_CALL( checkCons(scip, conss[c], sol, checklprows, checkrelmaxabs, &violated) );
14782  }
14783 
14784  if( violated )
14785  {
14786  *result = SCIP_INFEASIBLE;
14787 
14788  if( printreason )
14789  {
14790  SCIP_CONSDATA* consdata;
14791  SCIP_Real activity;
14792 
14793  consdata = SCIPconsGetData(conss[c-1]);
14794  assert( consdata != NULL);
14795 
14796  activity = consdataGetActivity(scip, consdata, sol);
14797 
14798  SCIP_CALL( SCIPprintCons(scip, conss[c-1], NULL ) );
14799  SCIPinfoMessage(scip, NULL, ";\n");
14800 
14801  if( activity == SCIP_INVALID ) /*lint !e777*/
14802  SCIPinfoMessage(scip, NULL, "activity invalid due to positive and negative infinity contributions\n");
14803  else if( SCIPisFeasLT(scip, activity, consdata->lhs) )
14804  SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", consdata->lhs - activity);
14805  else if( SCIPisFeasGT(scip, activity, consdata->rhs) )
14806  SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - consdata->rhs);
14807  }
14808  }
14809  else
14810  *result = SCIP_FEASIBLE;
14811 
14812  return SCIP_OKAY;
14813 }
14814 
14815 
14816 /** domain propagation method of constraint handler */
14817 static
14818 SCIP_DECL_CONSPROP(consPropLinear)
14819 { /*lint --e{715}*/
14820  SCIP_CONSHDLRDATA* conshdlrdata;
14821  SCIP_Bool rangedrowpropagation = FALSE;
14822  SCIP_Bool tightenbounds;
14823  SCIP_Bool cutoff;
14824 
14825  int nchgbds;
14826  int i;
14827 
14828  assert(scip != NULL);
14829  assert(conshdlr != NULL);
14830  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14831  assert(result != NULL);
14832 
14833  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14834  assert(conshdlrdata != NULL);
14835 
14836  /*debugMessage("Prop method of linear constraints\n");*/
14837 
14838  /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
14839  if( SCIPinProbing(scip) )
14840  tightenbounds = TRUE;
14841  else
14842  {
14843  int depth;
14844  int propfreq;
14845  int tightenboundsfreq;
14846  int rangedrowfreq;
14847 
14848  depth = SCIPgetDepth(scip);
14849  propfreq = SCIPconshdlrGetPropFreq(conshdlr);
14850  tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
14851  tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
14852  && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
14853 
14854  /* check if we want to do ranged row propagation */
14855  rangedrowpropagation = conshdlrdata->rangedrowpropagation;
14856  rangedrowpropagation = rangedrowpropagation && !SCIPinRepropagation(scip);
14857  rangedrowpropagation = rangedrowpropagation && (depth <= conshdlrdata->rangedrowmaxdepth);
14858  rangedrowfreq = propfreq * conshdlrdata->rangedrowfreq;
14859  rangedrowpropagation = rangedrowpropagation && (depth % rangedrowfreq == 0);
14860  }
14861 
14862  cutoff = FALSE;
14863  nchgbds = 0;
14864 
14865 
14866  /* process constraints marked for propagation */
14867  for( i = 0; i < nmarkedconss && !cutoff; i++ )
14868  {
14869  SCIP_CALL( SCIPunmarkConsPropagate(scip, conss[i]) );
14870  SCIP_CALL( propagateCons(scip, conss[i], tightenbounds, rangedrowpropagation,
14871  conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, &nchgbds) );
14872  }
14873 
14874  /* adjust result code */
14875  if( cutoff )
14876  *result = SCIP_CUTOFF;
14877  else if( nchgbds > 0 )
14878  *result = SCIP_REDUCEDDOM;
14879  else
14880  *result = SCIP_DIDNOTFIND;
14881 
14882  return SCIP_OKAY;
14883 }
14884 
14885 
14886 #define MAXCONSPRESOLROUNDS 10
14887 /** presolving method of constraint handler */
14888 static
14889 SCIP_DECL_CONSPRESOL(consPresolLinear)
14890 { /*lint --e{715}*/
14891  SCIP_CONSHDLRDATA* conshdlrdata;
14892  SCIP_CONS* cons;
14893  SCIP_CONSDATA* consdata;
14894  SCIP_Real minactivity;
14895  SCIP_Real maxactivity;
14896  SCIP_Bool minactisrelax;
14897  SCIP_Bool maxactisrelax;
14898  SCIP_Bool cutoff;
14899  int oldnfixedvars;
14900  int oldnaggrvars;
14901  int oldnchgbds;
14902  int oldndelconss;
14903  int oldnupgdconss;
14904  int oldnchgcoefs;
14905  int oldnchgsides;
14906  int firstchange;
14907  int firstupgradetry;
14908  int c;
14909 
14910  assert(scip != NULL);
14911  assert(conshdlr != NULL);
14912  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14913  assert(result != NULL);
14914 
14915  /*debugMessage("Presol method of linear constraints\n");*/
14916 
14917  /* remember old preprocessing counters */
14918  cutoff = FALSE;
14919  oldnfixedvars = *nfixedvars;
14920  oldnaggrvars = *naggrvars;
14921  oldnchgbds = *nchgbds;
14922  oldndelconss = *ndelconss;
14923  oldnupgdconss = *nupgdconss;
14924  oldnchgcoefs = *nchgcoefs;
14925  oldnchgsides = *nchgsides;
14926 
14927  /* get constraint handler data */
14928  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14929  assert(conshdlrdata != NULL);
14930 
14931  /* process single constraints */
14932  firstchange = INT_MAX;
14933  firstupgradetry = INT_MAX;
14934  for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
14935  {
14936  int npresolrounds;
14937  SCIP_Bool infeasible;
14938 
14939  infeasible = FALSE;
14940 
14941  cons = conss[c];
14942  assert(SCIPconsIsActive(cons));
14943  consdata = SCIPconsGetData(cons);
14944  assert(consdata != NULL);
14945 
14946  /* constraint should not be already presolved in the initial round */
14947  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->propagated);
14948  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->boundstightened);
14949  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->presolved);
14950  assert(consdata->propagated || !consdata->presolved);
14951 
14952  /* incorporate fixings and aggregations in constraint */
14953  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
14954 
14955  if( infeasible )
14956  {
14957  SCIPdebugMessage(" -> infeasible fixing\n");
14958  cutoff = TRUE;
14959  break;
14960  }
14961 
14962  assert(consdata->removedfixings);
14963 
14964  /* we can only presolve linear constraints, that are not modifiable */
14965  if( SCIPconsIsModifiable(cons) )
14966  continue;
14967 
14968  /* remember the first changed constraint to begin the next aggregation round with */
14969  if( firstchange == INT_MAX && consdata->changed )
14970  firstchange = c;
14971 
14972  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
14973  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
14974  firstupgradetry = c;
14975 
14976  /* check, if constraint is already preprocessed */
14977  if( consdata->presolved )
14978  continue;
14979 
14980  assert(SCIPconsIsActive(cons));
14981 
14982  SCIPdebugMessage("presolving linear constraint <%s>\n", SCIPconsGetName(cons));
14983  SCIPdebugPrintCons(scip, cons, NULL);
14984 
14985  /* apply presolving as long as possible on the single constraint (however, abort after a certain number of rounds
14986  * to avoid nearly infinite cycling due to very small bound changes)
14987  */
14988  npresolrounds = 0;
14989  while( !consdata->presolved && npresolrounds < MAXCONSPRESOLROUNDS && !SCIPisStopped(scip) )
14990  {
14991  assert(!cutoff);
14992  npresolrounds++;
14993 
14994  /* mark constraint being presolved and propagated */
14995  consdata->presolved = TRUE;
14996  consdata->propagated = TRUE;
14997 
14998  /* normalize constraint */
14999  SCIP_CALL( normalizeCons(scip, cons) );
15000 
15001  /* tighten left and right hand side due to integrality */
15002  SCIP_CALL( tightenSides(scip, cons, nchgsides) );
15003 
15004  /* check bounds */
15005  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
15006  {
15007  SCIPdebugMessage("linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
15008  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15009  cutoff = TRUE;
15010  break;
15011  }
15012 
15013  /* tighten variable's bounds */
15014  SCIP_CALL( tightenBounds(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, nchgbds) );
15015  if( cutoff )
15016  break;
15017 
15018  /* check for fixed variables */
15019  SCIP_CALL( fixVariables(scip, cons, &cutoff, nfixedvars) );
15020  if( cutoff )
15021  break;
15022 
15023  /* check constraint for infeasibility and redundancy */
15024  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
15025  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) || SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
15026  {
15027  SCIPdebugMessage("linear constraint <%s> is infeasible: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
15028  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
15029  cutoff = TRUE;
15030  break;
15031  }
15032  else if( SCIPisFeasGE(scip, minactivity, consdata->lhs) && SCIPisFeasLE(scip, maxactivity, consdata->rhs) )
15033  {
15034  SCIPdebugMessage("linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
15035  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
15036  SCIP_CALL( SCIPdelCons(scip, cons) );
15037  assert(!SCIPconsIsActive(cons));
15038 
15039  if( !consdata->upgraded )
15040  (*ndelconss)++;
15041  break;
15042  }
15043  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisFeasGE(scip, minactivity, consdata->lhs) )
15044  {
15045  SCIPdebugMessage("linear constraint <%s> left hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
15046  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
15047  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
15048  if( !consdata->upgraded )
15049  (*nchgsides)++;
15050  }
15051  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisFeasLE(scip, maxactivity, consdata->rhs) )
15052  {
15053  SCIPdebugMessage("linear constraint <%s> right hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
15054  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
15055  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
15056  if( !consdata->upgraded )
15057  (*nchgsides)++;
15058  }
15059  assert(consdata->nvars >= 1); /* otherwise, it should be redundant or infeasible */
15060 
15061  /* handle empty constraint */
15062  if( consdata->nvars == 0 )
15063  {
15064  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
15065  {
15066  SCIPdebugMessage("empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
15067  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15068  cutoff = TRUE;
15069  }
15070  else
15071  {
15072  SCIPdebugMessage("empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
15073  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15074  SCIP_CALL( SCIPdelCons(scip, cons) );
15075  assert(!SCIPconsIsActive(cons));
15076 
15077  if( !consdata->upgraded )
15078  (*ndelconss)++;
15079  }
15080  break;
15081  }
15082 
15083  /* reduce big-M coefficients, that make the constraint redundant if the variable is on a bound */
15084  SCIP_CALL( consdataTightenCoefs(scip, cons, nchgcoefs, nchgsides) );
15085 
15086  /* try to simplify inequalities */
15087  if( conshdlrdata->simplifyinequalities )
15088  {
15089  SCIP_CALL( simplifyInequalities(scip, cons, nchgcoefs, nchgsides) );
15090  }
15091 
15092  /* aggregation variable in equations */
15093  if( conshdlrdata->aggregatevariables )
15094  {
15095  SCIP_CALL( aggregateVariables(scip, cons, &cutoff, nfixedvars, naggrvars, ndelconss) );
15096  if( cutoff )
15097  break;
15098  }
15099  }
15100 
15101  if( conshdlrdata->rangedrowpropagation && !cutoff && !SCIPisStopped(scip) )
15102  {
15103  int lastnfixedvars;
15104 
15105  lastnfixedvars = *nfixedvars;
15106 
15107  SCIP_CALL( rangedRowPropagation(scip, cons, &cutoff, nfixedvars, nchgbds, naddconss) );
15108  if( !cutoff )
15109  {
15110  if( lastnfixedvars < *nfixedvars )
15111  {
15112  SCIP_CALL( applyFixings(scip, cons, &cutoff) );
15113  }
15114  }
15115 
15116  /* extract cliques from constraint */
15117  if( !cutoff && SCIPconsIsActive(cons) )
15118  {
15119  SCIP_CALL( extractCliques(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars,
15120  nfixedvars, nchgbds, &cutoff) );
15121 
15122  /* check if the constraint got redundant or infeasible */
15123  if( !cutoff && SCIPconsIsActive(cons) && consdata->nvars == 0 )
15124  {
15125  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
15126  {
15127  SCIPdebugMessage("empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
15128  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15129  cutoff = TRUE;
15130  }
15131  else
15132  {
15133  SCIPdebugMessage("empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
15134  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15135  SCIP_CALL( SCIPdelCons(scip, cons) );
15136  assert(!SCIPconsIsActive(cons));
15137 
15138  if( !consdata->upgraded )
15139  (*ndelconss)++;
15140  }
15141  }
15142  }
15143 
15144  /* convert special equalities */
15145  if( !cutoff && SCIPconsIsActive(cons) )
15146  {
15147  SCIP_CALL( convertEquality(scip, cons, conshdlrdata, &cutoff, nfixedvars, naggrvars, ndelconss) );
15148  }
15149 
15150  /* apply dual presolving for variables that appear in only one constraint */
15151  if( !cutoff && SCIPconsIsActive(cons) && conshdlrdata->dualpresolving && SCIPallowDualReds(scip) )
15152  {
15153  SCIP_CALL( dualPresolve(scip, cons, &cutoff, nfixedvars, naggrvars, ndelconss) );
15154  }
15155 
15156  /* check if an inequality is parallel to the objective function */
15157  if( !cutoff && SCIPconsIsActive(cons) )
15158  {
15159  SCIP_CALL( checkParallelObjective(scip, cons, conshdlrdata) );
15160  }
15161 
15162  /* remember the first changed constraint to begin the next aggregation round with */
15163  if( firstchange == INT_MAX && consdata->changed )
15164  firstchange = c;
15165 
15166  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
15167  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
15168  firstupgradetry = c;
15169  }
15170  }
15171 
15172  /* process pairs of constraints: check them for redundancy and try to aggregate them;
15173  * only apply this expensive procedure in exhaustive presolving timing
15174  */
15175  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && (conshdlrdata->presolusehashing || conshdlrdata->presolpairwise) && !SCIPisStopped(scip) )
15176  {
15177  assert(firstchange >= 0);
15178 
15179  if( firstchange < nconss && conshdlrdata->presolusehashing )
15180  {
15181  /* detect redundant constraints; fast version with hash table instead of pairwise comparison */
15182  SCIP_CALL( detectRedundantConstraints(scip, SCIPblkmem(scip), conss, nconss, &firstchange, &cutoff,
15183  ndelconss, nchgsides) );
15184  }
15185 
15186  if( firstchange < nconss && conshdlrdata->presolpairwise )
15187  {
15188  SCIP_CONS** usefulconss;
15189  int nusefulconss;
15190  int firstchangenew;
15191  SCIP_Longint npaircomparisons;
15192 
15193  npaircomparisons = 0;
15194  oldndelconss = *ndelconss;
15195  oldnchgsides = *nchgsides;
15196  oldnchgcoefs = *nchgcoefs;
15197 
15198  /* allocate temporary memory */
15199  SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, nconss) );
15200 
15201  nusefulconss = 0;
15202  firstchangenew = -1;
15203  for( c = 0; c < nconss; ++c )
15204  {
15205  /* update firstchange */
15206  if( c == firstchange )
15207  firstchangenew = nusefulconss;
15208 
15209  /* ignore inactive and modifiable constraints */
15210  if( !SCIPconsIsActive(conss[c]) || SCIPconsIsModifiable(conss[c]) )
15211  continue;
15212 
15213  usefulconss[nusefulconss] = conss[c];
15214  ++nusefulconss;
15215  }
15216  firstchange = firstchangenew;
15217  assert(firstchangenew >= 0 && firstchangenew <= nusefulconss);
15218 
15219  for( c = firstchange; c < nusefulconss && !cutoff && !SCIPisStopped(scip); ++c )
15220  {
15221  /* constraint has become inactive or modifiable during pairwise presolving */
15222  if( usefulconss[c] == NULL )
15223  continue;
15224 
15225  npaircomparisons += (SCIPconsGetData(conss[c])->changed) ? c : (c - firstchange); /*lint !e776*/
15226 
15227  assert(SCIPconsIsActive(usefulconss[c]) && !SCIPconsIsModifiable(usefulconss[c]));
15228  SCIP_CALL( preprocessConstraintPairs(scip, usefulconss, firstchange, c, conshdlrdata->maxaggrnormscale,
15229  &cutoff, ndelconss, nchgsides, nchgcoefs) );
15230 
15231  if( npaircomparisons > conshdlrdata->nmincomparisons )
15232  {
15233  assert(npaircomparisons > 0);
15234  if( ((*ndelconss - oldndelconss) + (*nchgsides - oldnchgsides)/2.0 + (*nchgcoefs - oldnchgcoefs)/10.0) / ((SCIP_Real) npaircomparisons) < conshdlrdata->mingainpernmincomp )
15235  break;
15236  oldndelconss = *ndelconss;
15237  oldnchgsides = *nchgsides;
15238  oldnchgcoefs = *nchgcoefs;
15239  npaircomparisons = 0;
15240  }
15241  }
15242  /* free temporary memory */
15243  SCIPfreeBufferArray(scip, &usefulconss);
15244  }
15245  }
15246 
15247  /* before upgrading, check whether we can apply some additional dual presolving, because a variable only appears
15248  * in linear constraints and we therefore have full information about it
15249  */
15250  if( !cutoff && firstupgradetry < nconss
15251  && *nfixedvars == oldnfixedvars && *naggrvars == oldnaggrvars && *nchgbds == oldnchgbds && *ndelconss == oldndelconss
15252  && *nupgdconss == oldnupgdconss && *nchgcoefs == oldnchgcoefs && *nchgsides == oldnchgsides
15253  )
15254  {
15255  if( conshdlrdata->dualpresolving && SCIPallowDualReds(scip) && !SCIPisStopped(scip) )
15256  {
15257  SCIP_CALL( fullDualPresolve(scip, conss, nconss, &cutoff, nchgbds) );
15258  }
15259  }
15260 
15261  /* try to upgrade constraints into a more specific constraint type;
15262  * only upgrade constraints, if no reductions were found in this round (otherwise, the linear constraint handler
15263  * may find additional reductions before giving control away to other (less intelligent?) constraint handlers)
15264  */
15265  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && SCIPisPresolveFinished(scip) )
15266  {
15267  for( c = firstupgradetry; c < nconss && !SCIPisStopped(scip); ++c )
15268  {
15269  cons = conss[c];
15270 
15271  /* don't upgrade modifiable constraints */
15272  if( SCIPconsIsModifiable(cons) )
15273  continue;
15274 
15275  consdata = SCIPconsGetData(cons);
15276  assert(consdata != NULL);
15277 
15278  /* only upgrade completely presolved constraints, that changed since the last upgrading call */
15279  if( consdata->upgradetried )
15280  continue;
15281  /* @todo force that upgrade will be performed later? */
15282  if( !consdata->presolved )
15283  continue;
15284 
15285  consdata->upgradetried = TRUE;
15286  if( SCIPconsIsActive(cons) )
15287  {
15288  SCIP_CONS* upgdcons;
15289 
15290  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
15291  if( upgdcons != NULL )
15292  {
15293  /* add the upgraded constraint to the problem */
15294  SCIP_CALL( SCIPaddCons(scip, upgdcons) );
15295  SCIP_CALL( SCIPreleaseCons(scip, &upgdcons) );
15296  (*nupgdconss)++;
15297 
15298  /* mark the linear constraint being upgraded and to be removed after presolving;
15299  * don't delete it directly, because it may help to preprocess other linear constraints
15300  */
15301  assert(!consdata->upgraded);
15302  consdata->upgraded = TRUE;
15303 
15304  /* delete upgraded inequalities immediately;
15305  * delete upgraded equalities, if we don't need it anymore for aggregation and redundancy checking
15306  */
15307  if( SCIPisLT(scip, consdata->lhs, consdata->rhs)
15308  || !conshdlrdata->presolpairwise
15309  || (conshdlrdata->maxaggrnormscale == 0.0) )
15310  {
15311  SCIP_CALL( SCIPdelCons(scip, cons) );
15312  }
15313  }
15314  }
15315  }
15316  }
15317 
15318  /* return the correct result code */
15319  if( cutoff )
15320  *result = SCIP_CUTOFF;
15321  else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds || *ndelconss > oldndelconss
15322  || *nupgdconss > oldnupgdconss || *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides )
15323  *result = SCIP_SUCCESS;
15324  else
15325  *result = SCIP_DIDNOTFIND;
15326 
15327  return SCIP_OKAY;
15328 }
15329 
15330 
15331 /** propagation conflict resolving method of constraint handler */
15332 static
15333 SCIP_DECL_CONSRESPROP(consRespropLinear)
15334 { /*lint --e{715}*/
15335 
15336  assert(scip != NULL);
15337  assert(cons != NULL);
15338  assert(result != NULL);
15339 
15340  SCIP_CALL( resolvePropagation(scip, cons, infervar, intToInferInfo(inferinfo), boundtype, bdchgidx, result) );
15341 
15342  return SCIP_OKAY;
15343 }
15344 
15345 
15346 /** variable rounding lock method of constraint handler */
15347 static
15348 SCIP_DECL_CONSLOCK(consLockLinear)
15349 { /*lint --e{715}*/
15350  SCIP_CONSDATA* consdata;
15351  SCIP_Bool haslhs;
15352  SCIP_Bool hasrhs;
15353  int i;
15354 
15355  assert(scip != NULL);
15356  assert(cons != NULL);
15357  consdata = SCIPconsGetData(cons);
15358  assert(consdata != NULL);
15359 
15360  haslhs = !SCIPisInfinity(scip, -consdata->lhs);
15361  hasrhs = !SCIPisInfinity(scip, consdata->rhs);
15362 
15363  /* update rounding locks of every single variable */
15364  for( i = 0; i < consdata->nvars; ++i )
15365  {
15366  if( SCIPisPositive(scip, consdata->vals[i]) )
15367  {
15368  if( haslhs )
15369  {
15370  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlockspos, nlocksneg) );
15371  }
15372  if( hasrhs )
15373  {
15374  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlocksneg, nlockspos) );
15375  }
15376  }
15377  else
15378  {
15379  if( haslhs )
15380  {
15381  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlocksneg, nlockspos) );
15382  }
15383  if( hasrhs )
15384  {
15385  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlockspos, nlocksneg) );
15386  }
15387  }
15388  }
15389 
15390  return SCIP_OKAY;
15391 }
15392 
15393 
15394 /** variable deletion method of constraint handler */
15395 static
15396 SCIP_DECL_CONSDELVARS(consDelvarsLinear)
15397 {
15398  assert(scip != NULL);
15399  assert(conshdlr != NULL);
15400  assert(conss != NULL || nconss == 0);
15401 
15402  if( nconss > 0 )
15403  {
15404  SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
15405  }
15406 
15407  return SCIP_OKAY;
15408 }
15409 
15410 /** constraint display method of constraint handler */
15411 static
15412 SCIP_DECL_CONSPRINT(consPrintLinear)
15413 { /*lint --e{715}*/
15414  assert(scip != NULL);
15415  assert(conshdlr != NULL);
15416  assert(cons != NULL);
15417 
15418  SCIP_CALL( consdataPrint(scip, SCIPconsGetData(cons), file) );
15419 
15420  return SCIP_OKAY;
15421 }
15422 
15423 /** constraint copying method of constraint handler */
15424 static
15425 SCIP_DECL_CONSCOPY(consCopyLinear)
15426 { /*lint --e{715}*/
15427  SCIP_VAR** sourcevars;
15428  SCIP_Real* sourcecoefs;
15429  const char* consname;
15430  int nvars;
15431 
15432  assert(scip != NULL);
15433  assert(sourcescip != NULL);
15434  assert(sourcecons != NULL);
15435 
15436  /* get variables and coefficients of the source constraint */
15437  sourcevars = SCIPgetVarsLinear(sourcescip, sourcecons);
15438  sourcecoefs = SCIPgetValsLinear(sourcescip, sourcecons);
15439  nvars = SCIPgetNVarsLinear(sourcescip, sourcecons);
15440 
15441  if( name != NULL )
15442  consname = name;
15443  else
15444  consname = SCIPconsGetName(sourcecons);
15445 
15446  SCIP_CALL( SCIPcopyConsLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
15447  SCIPgetLhsLinear(sourcescip, sourcecons), SCIPgetRhsLinear(sourcescip, sourcecons), varmap, consmap,
15448  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
15449  assert(cons != NULL || *valid == FALSE);
15450 
15451  return SCIP_OKAY;
15452 }
15453 
15454 /** constraint parsing method of constraint handler */
15455 static
15456 SCIP_DECL_CONSPARSE(consParseLinear)
15457 { /*lint --e{715}*/
15458  SCIP_VAR** vars;
15459  SCIP_Real* coefs;
15460  int nvars;
15461  int coefssize;
15462  int requsize;
15463  SCIP_Real lhs;
15464  SCIP_Real rhs;
15465  char* endptr;
15466 
15467  assert(scip != NULL);
15468  assert(success != NULL);
15469  assert(str != NULL);
15470  assert(name != NULL);
15471  assert(cons != NULL);
15473  /* set left and right hand side to their default values */
15474  lhs = -SCIPinfinity(scip);
15475  rhs = SCIPinfinity(scip);
15476 
15477  (*success) = FALSE;
15478 
15479  /* return of string empty */
15480  if( !*str )
15481  return SCIP_OKAY;
15482 
15483  /* ignore whitespace */
15484  while( isspace((unsigned char)*str) )
15485  ++str;
15486 
15487  /* check for left hand side */
15488  if( isdigit((unsigned char)str[0]) || ((str[0] == '-' || str[0] == '+') && isdigit((unsigned char)str[1])) )
15489  {
15490  /* there is a number coming, maybe it is a left-hand-side */
15491  if( !SCIPstrToRealValue(str, &lhs, &endptr) )
15492  {
15493  SCIPerrorMessage("error parsing number from <%s>\n", str);
15494  return SCIP_OKAY;
15495  }
15496 
15497  /* ignore whitespace */
15498  while( isspace((unsigned char)*endptr) )
15499  ++endptr;
15500 
15501  if( endptr[0] != '<' || endptr[1] != '=' )
15502  {
15503  /* no '<=' coming, so it was the first coefficient, but not a left-hand-side */
15504  lhs = -SCIPinfinity(scip);
15505  }
15506  else
15507  {
15508  /* it was indeed a left-hand-side, so continue parsing after it */
15509  str = endptr + 2;
15510 
15511  /* ignore whitespace */
15512  while( isspace((unsigned char)*str) )
15513  ++str;
15514  }
15515  }
15516 
15517  /* initialize buffers for storing the variables and coefficients */
15518  coefssize = 100;
15519  SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
15520  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, coefssize) );
15521 
15522  /* parse linear sum to get variables and coefficients */
15523  SCIP_CALL( SCIPparseVarsLinearsum(scip, str, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
15524 
15525  if( *success && requsize > coefssize )
15526  {
15527  /* realloc buffers and try again */
15528  coefssize = requsize;
15529  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, coefssize) );
15530  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, coefssize) );
15531 
15532  SCIP_CALL( SCIPparseVarsLinearsum(scip, str, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
15533  assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
15534  }
15535 
15536  if( !*success )
15537  {
15538  SCIPerrorMessage("no luck in parsing linear sum '%s'\n", str);
15539  }
15540  else
15541  {
15542  (*success) = FALSE;
15543  str = endptr;
15544 
15545  /* check for left or right hand side */
15546  while( isspace((unsigned char)*str) )
15547  ++str;
15548 
15549  /* check for free constraint */
15550  if( strncmp(str, "[free]", 6) == 0 )
15551  {
15552  if( !SCIPisInfinity(scip, -lhs) )
15553  {
15554  SCIPerrorMessage("cannot have left hand side and [free] status \n");
15555  return SCIP_OKAY;
15556  }
15557  (*success) = TRUE;
15558  }
15559  else
15560  {
15561  switch( *str )
15562  {
15563  case '<':
15564  *success = SCIPstrToRealValue(str+2, &rhs, &endptr);
15565  break;
15566  case '=':
15567  if( !SCIPisInfinity(scip, -lhs) )
15568  {
15569  SCIPerrorMessage("cannot have == on rhs if there was a <= on lhs\n");
15570  return SCIP_OKAY;
15571  }
15572  else
15573  {
15574  *success = SCIPstrToRealValue(str+2, &rhs, &endptr);
15575  lhs = rhs;
15576  }
15577  break;
15578  case '>':
15579  if( !SCIPisInfinity(scip, -lhs) )
15580  {
15581  SCIPerrorMessage("cannot have => on rhs if there was a <= on lhs\n");
15582  return SCIP_OKAY;
15583  }
15584  else
15585  {
15586  *success = SCIPstrToRealValue(str+2, &lhs, &endptr);
15587  break;
15588  }
15589  case '\0':
15590  *success = TRUE;
15591  break;
15592  default:
15593  SCIPerrorMessage("unexpected character %c\n", *str);
15594  return SCIP_OKAY;
15595  }
15596  }
15597 
15598  if( *success )
15599  {
15600  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
15601  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
15602  }
15603  }
15604 
15605  SCIPfreeBufferArray(scip, &coefs);
15606  SCIPfreeBufferArray(scip, &vars);
15607 
15608  return SCIP_OKAY;
15609 }
15610 
15611 
15612 /** constraint method of constraint handler which returns the variables (if possible) */
15613 static
15614 SCIP_DECL_CONSGETVARS(consGetVarsLinear)
15615 { /*lint --e{715}*/
15616  SCIP_CONSDATA* consdata;
15617 
15618  consdata = SCIPconsGetData(cons);
15619  assert(consdata != NULL);
15620 
15621  if( varssize < consdata->nvars )
15622  (*success) = FALSE;
15623  else
15624  {
15625  assert(vars != NULL);
15626 
15627  BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
15628  (*success) = TRUE;
15629  }
15631  return SCIP_OKAY;
15632 }
15633 
15634 /** constraint method of constraint handler which returns the number of variables (if possible) */
15635 static
15636 SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
15637 { /*lint --e{715}*/
15638  SCIP_CONSDATA* consdata;
15639 
15640  consdata = SCIPconsGetData(cons);
15641  assert(consdata != NULL);
15642 
15643  (*nvars) = consdata->nvars;
15644  (*success) = TRUE;
15645 
15646  return SCIP_OKAY;
15647 }
15648 
15649 /*
15650  * Callback methods of event handler
15651  */
15653 static
15654 SCIP_DECL_EVENTEXEC(eventExecLinear)
15655 { /*lint --e{715}*/
15656  SCIP_CONS* cons;
15657  SCIP_CONSDATA* consdata;
15658  SCIP_VAR* var;
15659  SCIP_EVENTTYPE eventtype;
15660 
15661  assert(scip != NULL);
15662  assert(eventhdlr != NULL);
15663  assert(eventdata != NULL);
15664  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
15665  assert(event != NULL);
15666 
15667  cons = eventdata->cons;
15668  assert(cons != NULL);
15669  consdata = SCIPconsGetData(cons);
15670  assert(consdata != NULL);
15671 
15672  eventtype = SCIPeventGetType(event);
15673  var = SCIPeventGetVar(event);
15674 
15675  if( (eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) != 0 )
15676  {
15677  SCIP_Real oldbound;
15678  SCIP_Real newbound;
15679  SCIP_Real val;
15680  int varpos;
15681 
15682  varpos = eventdata->varpos;
15683  assert(0 <= varpos && varpos < consdata->nvars);
15684  oldbound = SCIPeventGetOldbound(event);
15685  newbound = SCIPeventGetNewbound(event);
15686  assert(var != NULL);
15687  assert(consdata->vars[varpos] == var);
15688  val = consdata->vals[varpos];
15689 
15690  /* update the activity values */
15691  if( (eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
15692  consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, val, TRUE);
15693  else
15694  {
15695  assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0);
15696  consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, val, TRUE);
15697  }
15698 
15699  consdata->presolved = FALSE;
15700  consdata->rangedrowpropagation = FALSE;
15701 
15702  /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
15703  if( (eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0 )
15704  {
15705  consdata->propagated = FALSE;
15706  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
15707 
15708  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
15709  if( consdata->maxactdeltavar == var )
15710  {
15711  consdata->maxactdelta = SCIP_INVALID;
15712  consdata->maxactdeltavar = NULL;
15713  }
15714  }
15715  /* update maximal activity delta if a bound was relaxed */
15716  else if( (eventtype & SCIP_EVENTTYPE_BOUNDRELAXED) != 0 && !SCIPisInfinity(scip, consdata->maxactdelta) )
15717  {
15718  SCIP_Real lb;
15719  SCIP_Real ub;
15720  SCIP_Real domain;
15721  SCIP_Real delta;
15722 
15723  lb = SCIPvarGetLbLocal(var);
15724  ub = SCIPvarGetUbLocal(var);
15725 
15726  domain = ub - lb;
15727  delta = REALABS(val) * domain;
15728 
15729  if( delta > consdata->maxactdelta )
15730  {
15731  consdata->maxactdelta = delta;
15732  consdata->maxactdeltavar = var;
15733  }
15734  }
15735 
15736  /* check whether bound tightening might now be successful (if the current bound was relaxed, it might be
15737  * that it can be tightened again)
15738  */
15739  if( consdata->boundstightened )
15740  {
15741  switch( eventtype )
15742  {
15745  consdata->boundstightened = (val > 0.0 && SCIPisInfinity(scip, consdata->rhs))
15746  || (val < 0.0 && SCIPisInfinity(scip, -consdata->lhs));
15747  break;
15750  consdata->boundstightened = (val > 0.0 && SCIPisInfinity(scip, -consdata->lhs))
15751  || (val < 0.0 && SCIPisInfinity(scip, consdata->rhs));
15752  break;
15753  default:
15754  SCIPerrorMessage("invalid event type %d\n", eventtype);
15755  return SCIP_INVALIDDATA;
15756  }
15757  }
15758  }
15759  else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != 0 )
15760  {
15761  /* we want to remove the fixed variable */
15762  consdata->presolved = FALSE;
15763  consdata->removedfixings = FALSE;
15764  consdata->rangedrowpropagation = FALSE;
15765 
15766  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
15767  if( consdata->maxactdeltavar == var )
15768  {
15769  consdata->maxactdelta = SCIP_INVALID;
15770  consdata->maxactdeltavar = NULL;
15771  }
15772  }
15773 
15774  else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != 0 )
15775  {
15776  /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
15777  assert(SCIPvarGetNLocksDown(var) <= 1);
15778  assert(SCIPvarGetNLocksUp(var) <= 1);
15779  consdata->presolved = FALSE;
15780  }
15781  else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != 0 )
15782  {
15783  SCIP_Real oldbound;
15784  SCIP_Real newbound;
15785  SCIP_Real val;
15786  int varpos;
15787 
15788  varpos = eventdata->varpos;
15789  assert(0 <= varpos && varpos < consdata->nvars);
15790  oldbound = SCIPeventGetOldbound(event);
15791  newbound = SCIPeventGetNewbound(event);
15792  assert(var != NULL);
15793  assert(consdata->vars[varpos] == var);
15794  val = consdata->vals[varpos];
15795 
15796  consdata->rangedrowpropagation = FALSE;
15797 
15798  /* update the activity values */
15799  if( (eventtype & SCIP_EVENTTYPE_GLBCHANGED) != 0 )
15800  consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, val, TRUE);
15801  else
15802  {
15803  assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != 0);
15804  consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, val, TRUE);
15805  }
15806  }
15807  else
15808  {
15809  assert((eventtype & SCIP_EVENTTYPE_VARDELETED) != 0);
15810  consdata->varsdeleted = TRUE;
15811  }
15812 
15813  return SCIP_OKAY;
15814 }
15815 
15816 
15817 /*
15818  * Callback methods of conflict handler
15819  */
15820 
15821 static
15822 SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
15823 { /*lint --e{715}*/
15824  SCIP_VAR** vars;
15825  SCIP_Real* vals;
15826  SCIP_Real lhs;
15827  int i;
15828 
15829  assert(scip != NULL);
15830  assert(conflicthdlr != NULL);
15831  assert(strcmp(SCIPconflicthdlrGetName(conflicthdlr), CONFLICTHDLR_NAME) == 0);
15832  assert(bdchginfos != NULL || nbdchginfos == 0);
15833  assert(result != NULL);
15834 
15835  /* don't process already resolved conflicts */
15836  if( resolved )
15837  {
15838  *result = SCIP_DIDNOTRUN;
15839  return SCIP_OKAY;
15840  }
15841 
15842  *result = SCIP_DIDNOTFIND;
15843 
15844  /* create array of variables and coefficients: sum_{i \in P} x_i - sum_{i \in N} x_i >= 1 - |N| */
15845  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
15846  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nbdchginfos) );
15847  lhs = 1.0;
15848  for( i = 0; i < nbdchginfos; ++i )
15849  {
15850  assert(bdchginfos != NULL);
15851 
15852  vars[i] = SCIPbdchginfoGetVar(bdchginfos[i]);
15853 
15854  /* we can only treat binary variables */
15855  /**@todo extend linear conflict constraints to some non-binary cases */
15856  if( !SCIPvarIsBinary(vars[i]) )
15857  break;
15858 
15859  /* check whether the variable is fixed to zero (P) or one (N) in the conflict set */
15860  if( SCIPbdchginfoGetNewbound(bdchginfos[i]) < 0.5 )
15861  vals[i] = 1.0;
15862  else
15863  {
15864  vals[i] = -1.0;
15865  lhs -= 1.0;
15866  }
15867  }
15868 
15869  if( i == nbdchginfos )
15870  {
15871  SCIP_CONS* cons;
15872  SCIP_CONS* upgdcons;
15873  char consname[SCIP_MAXSTRLEN];
15874 
15875  /* create a constraint out of the conflict set */
15876  (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "cf%"SCIP_LONGINT_FORMAT, SCIPgetNConflictConssApplied(scip));
15877  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, nbdchginfos, vars, vals, lhs, SCIPinfinity(scip),
15878  FALSE, separate, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
15879 
15880  /* try to automatically convert a linear constraint into a more specific and more specialized constraint */
15881  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
15882  if( upgdcons != NULL )
15883  {
15884  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
15885  cons = upgdcons;
15886  }
15887 
15888  /* add constraint to SCIP */
15889  SCIP_CALL( SCIPaddConsNode(scip, node, cons, validnode) );
15890  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
15891 
15892  *result = SCIP_CONSADDED;
15893  }
15894 
15895  /* free temporary memory */
15896  SCIPfreeBufferArray(scip, &vals);
15897  SCIPfreeBufferArray(scip, &vars);
15898 
15899  return SCIP_OKAY;
15900 }
15901 
15902 
15903 /*
15904  * Quadratic constraint upgrading
15905  */
15906 
15907 
15908 /** upgrades quadratic constraints with only and at least one linear variables into a linear constraint
15909  */
15910 static
15911 SCIP_DECL_QUADCONSUPGD(upgradeConsQuadratic)
15912 { /*lint --e{715}*/
15913  assert(scip != NULL);
15914  assert(cons != NULL);
15915  assert(nupgdconss != NULL);
15916  assert(upgdconss != NULL);
15917 
15918  *nupgdconss = 0;
15919 
15920  SCIPdebugMessage("upgradeConsQuadratic called for constraint <%s>\n", SCIPconsGetName(cons));
15921  SCIPdebugPrintCons(scip, cons, NULL);
15922 
15923  if( SCIPgetNQuadVarTermsQuadratic(scip, cons) > 0 )
15924  return SCIP_OKAY;
15925  if( SCIPgetNLinearVarsQuadratic(scip, cons) == 0 )
15926  return SCIP_OKAY;
15928  if( upgdconsssize < 1 )
15929  {
15930  /* signal that we need more memory */
15931  *nupgdconss = -1;
15932  return SCIP_OKAY;
15933  }
15934 
15935  *nupgdconss = 1;
15936  SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
15937  SCIPgetNLinearVarsQuadratic(scip, cons),
15938  SCIPgetLinearVarsQuadratic(scip, cons),
15939  SCIPgetCoefsLinearVarsQuadratic(scip, cons),
15940  SCIPgetLhsQuadratic(scip, cons), SCIPgetRhsQuadratic(scip, cons),
15944  SCIPconsIsStickingAtNode(cons)) );
15945  SCIPdebugMessage("created linear constraint:\n");
15946  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
15947 
15948  return SCIP_OKAY;
15949 }
15950 
15951 /** tries to upgrade a nonlinear constraint into a linear constraint */
15952 static
15953 SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
15954 {
15955  assert(nupgdconss != NULL);
15956  assert(upgdconss != NULL);
15957 
15958  *nupgdconss = 0;
15959 
15960  /* no interest in nonlinear constraints */
15961  if( SCIPgetExprgraphNodeNonlinear(scip, cons) != NULL )
15962  return SCIP_OKAY;
15963 
15964  /* no interest in constant constraints */
15965  if( SCIPgetNLinearVarsNonlinear(scip, cons) == 0 )
15966  return SCIP_OKAY;
15967 
15968  if( upgdconsssize < 1 )
15969  {
15970  /* request larger upgdconss array */
15971  *nupgdconss = -1;
15972  return SCIP_OKAY;
15973  }
15974 
15975  *nupgdconss = 1;
15976  SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
15978  SCIPgetLhsNonlinear(scip, cons), SCIPgetRhsNonlinear(scip, cons),
15982  SCIPconsIsStickingAtNode(cons)) );
15983 
15984  return SCIP_OKAY;
15985 }
15986 
15987 /*
15988  * constraint specific interface methods
15989  */
15990 
15991 /** creates the handler for linear constraints and includes it in SCIP */
15993  SCIP* scip /**< SCIP data structure */
15994  )
15995 {
15996  SCIP_CONSHDLRDATA* conshdlrdata;
15997  SCIP_CONSHDLR* conshdlr;
15998  SCIP_EVENTHDLR* eventhdlr;
15999  SCIP_CONFLICTHDLR* conflicthdlr;
16000 
16001  assert(scip != NULL);
16002 
16003  /* create event handler for bound change events */
16005  eventExecLinear, NULL) );
16006 
16007  /* create conflict handler for linear constraints */
16009  conflictExecLinear, NULL) );
16010 
16011  /* create constraint handler data */
16012  SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
16013 
16014  /* include constraint handler */
16017  consEnfolpLinear, consEnfopsLinear, consCheckLinear, consLockLinear,
16018  conshdlrdata) );
16019 
16020  assert(conshdlr != NULL);
16021 
16022  /* set non-fundamental callbacks via specific setter functions */
16023  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinear, consCopyLinear) );
16024  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinear) );
16025  SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsLinear) );
16026  SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitLinear) );
16027  SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreLinear) );
16028  SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinear) );
16029  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinear) );
16030  SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinear) );
16031  SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinear) );
16032  SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitLinear) );
16033  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinear) );
16034 #ifdef WITH_PRINTORIGCONSTYPES
16035  SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreLinear) );
16036 #endif
16037  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinear) );
16038  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolLinear, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
16039  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinear) );
16040  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropLinear, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
16042  SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinear) );
16043  SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinear, consSepasolLinear, CONSHDLR_SEPAFREQ,
16045  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinear) );
16046 
16047  if( SCIPfindConshdlr(scip, "quadratic") != NULL )
16048  {
16049  /* include function that upgrades quadratic constraint to linear constraints */
16051  }
16052 
16053  if( SCIPfindConshdlr(scip, "nonlinear") != NULL )
16054  {
16055  /* include the linear constraint upgrade in the nonlinear constraint handler */
16057  }
16058 
16059  /* add linear constraint handler parameters */
16060  SCIP_CALL( SCIPaddIntParam(scip,
16061  "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
16062  "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
16063  &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, INT_MAX, NULL, NULL) );
16064  SCIP_CALL( SCIPaddIntParam(scip,
16065  "constraints/" CONSHDLR_NAME "/maxrounds",
16066  "maximal number of separation rounds per node (-1: unlimited)",
16067  &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
16068  SCIP_CALL( SCIPaddIntParam(scip,
16069  "constraints/" CONSHDLR_NAME "/maxroundsroot",
16070  "maximal number of separation rounds per node in the root node (-1: unlimited)",
16071  &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
16072  SCIP_CALL( SCIPaddIntParam(scip,
16073  "constraints/" CONSHDLR_NAME "/maxsepacuts",
16074  "maximal number of cuts separated per separation round",
16075  &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
16076  SCIP_CALL( SCIPaddIntParam(scip,
16077  "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
16078  "maximal number of cuts separated per separation round in the root node",
16079  &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
16081  "constraints/" CONSHDLR_NAME "/presolpairwise",
16082  "should pairwise constraint comparison be performed in presolving?",
16083  &conshdlrdata->presolpairwise, TRUE, DEFAULT_PRESOLPAIRWISE, NULL, NULL) );
16085  "constraints/" CONSHDLR_NAME "/presolusehashing",
16086  "should hash table be used for detecting redundant constraints in advance",
16087  &conshdlrdata->presolusehashing, TRUE, DEFAULT_PRESOLUSEHASHING, NULL, NULL) );
16088  SCIP_CALL( SCIPaddIntParam(scip,
16089  "constraints/" CONSHDLR_NAME "/nmincomparisons",
16090  "number for minimal pairwise presolve comparisons",
16091  &conshdlrdata->nmincomparisons, TRUE, DEFAULT_NMINCOMPARISONS, 1, INT_MAX, NULL, NULL) );
16093  "constraints/" CONSHDLR_NAME "/mingainpernmincomparisons",
16094  "minimal gain per minimal pairwise presolve comparisons to repeat pairwise comparison round",
16095  &conshdlrdata->mingainpernmincomp, TRUE, DEFAULT_MINGAINPERNMINCOMP, 0.0, 1.0, NULL, NULL) );
16097  "constraints/" CONSHDLR_NAME "/maxaggrnormscale",
16098  "maximal allowed relative gain in maximum norm for constraint aggregation (0.0: disable constraint aggregation)",
16099  &conshdlrdata->maxaggrnormscale, TRUE, DEFAULT_MAXAGGRNORMSCALE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
16101  "constraints/" CONSHDLR_NAME "/maxeasyactivitydelta",
16102  "maximum activity delta to run easy propagation on linear constraint (faster, but numerically less stable)",
16103  &conshdlrdata->maxeasyactivitydelta, TRUE, DEFAULT_MAXEASYACTIVITYDELTA, 0.0, SCIP_REAL_MAX, NULL, NULL) );
16105  "constraints/" CONSHDLR_NAME "/maxcardbounddist",
16106  "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for separating knapsack cardinality cuts",
16107  &conshdlrdata->maxcardbounddist, TRUE, DEFAULT_MAXCARDBOUNDDIST, 0.0, 1.0, NULL, NULL) );
16109  "constraints/" CONSHDLR_NAME "/separateall",
16110  "should all constraints be subject to cardinality cut generation instead of only the ones with non-zero dual value?",
16111  &conshdlrdata->separateall, FALSE, DEFAULT_SEPARATEALL, NULL, NULL) );
16113  "constraints/" CONSHDLR_NAME "/aggregatevariables",
16114  "should presolving search for aggregations in equations",
16115  &conshdlrdata->aggregatevariables, TRUE, DEFAULT_AGGREGATEVARIABLES, NULL, NULL) );
16117  "constraints/" CONSHDLR_NAME "/simplifyinequalities",
16118  "should presolving try to simplify inequalities",
16119  &conshdlrdata->simplifyinequalities, TRUE, DEFAULT_SIMPLIFYINEQUALITIES, NULL, NULL) );
16121  "constraints/" CONSHDLR_NAME "/dualpresolving",
16122  "should dual presolving steps be performed?",
16123  &conshdlrdata->dualpresolving, TRUE, DEFAULT_DUALPRESOLVING, NULL, NULL) );
16125  "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
16126  &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
16128  "constraints/" CONSHDLR_NAME "/checkrelmaxabs",
16129  "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)?",
16130  &conshdlrdata->checkrelmaxabs, TRUE, DEFAULT_CHECKRELMAXABS, NULL, NULL) );
16132  "constraints/" CONSHDLR_NAME "/detectcutoffbound",
16133  "should presolving try to detect constraints parallel to the objective function defining an upper bound and prevent these constraints from entering the LP?",
16134  &conshdlrdata->detectcutoffbound, TRUE, DEFAULT_DETECTCUTOFFBOUND, NULL, NULL) );
16136  "constraints/" CONSHDLR_NAME "/detectlowerbound",
16137  "should presolving try to detect constraints parallel to the objective function defining a lower bound and prevent these constraints from entering the LP?",
16138  &conshdlrdata->detectlowerbound, TRUE, DEFAULT_DETECTLOWERBOUND, NULL, NULL) );
16140  "constraints/" CONSHDLR_NAME "/detectpartialobjective",
16141  "should presolving try to detect subsets of constraints parallel to the objective function?",
16142  &conshdlrdata->detectpartialobjective, TRUE, DEFAULT_DETECTPARTIALOBJECTIVE, NULL, NULL) );
16144  "constraints/" CONSHDLR_NAME "/rangedrowpropagation",
16145  "should presolving and propagation try to improve bounds, detect infeasibility, and extract sub-constraints from ranged rows and equations?",
16146  &conshdlrdata->rangedrowpropagation, TRUE, DEFAULT_RANGEDROWPROPAGATION, NULL, NULL) );
16148  "constraints/" CONSHDLR_NAME "/rangedrowartcons",
16149  "should presolving and propagation extract sub-constraints from ranged rows and equations?",
16150  &conshdlrdata->rangedrowartcons, TRUE, DEFAULT_RANGEDROWARTCONS, NULL, NULL) );
16151  SCIP_CALL( SCIPaddIntParam(scip,
16152  "constraints/" CONSHDLR_NAME "/rangedrowmaxdepth",
16153  "maximum depth to apply ranged row propagation",
16154  &conshdlrdata->rangedrowmaxdepth, TRUE, DEFAULT_RANGEDROWMAXDEPTH, 0, INT_MAX, NULL, NULL) );
16155  SCIP_CALL( SCIPaddIntParam(scip,
16156  "constraints/" CONSHDLR_NAME "/rangedrowfreq",
16157  "frequency for applying ranged row propagation",
16158  &conshdlrdata->rangedrowfreq, TRUE, DEFAULT_RANGEDROWFREQ, 1, INT_MAX, NULL, NULL) );
16160  "constraints/" CONSHDLR_NAME "/multaggrremove",
16161  "should multi-aggregations only be performed if the constraint can be removed afterwards?",
16162  &conshdlrdata->multaggrremove, TRUE, DEFAULT_MULTAGGRREMOVE, NULL, NULL) );
16163 
16164  return SCIP_OKAY;
16165 }
16166 
16167 /** includes a linear constraint update method into the linear constraint handler */
16169  SCIP* scip, /**< SCIP data structure */
16170  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
16171  int priority, /**< priority of upgrading method */
16172  const char* conshdlrname /**< name of the constraint handler */
16173  )
16174 {
16175  SCIP_CONSHDLR* conshdlr;
16176  SCIP_CONSHDLRDATA* conshdlrdata;
16177  SCIP_LINCONSUPGRADE* linconsupgrade;
16178  char paramname[SCIP_MAXSTRLEN];
16179  char paramdesc[SCIP_MAXSTRLEN];
16180 
16181  assert(scip != NULL);
16182  assert(linconsupgd != NULL);
16183  assert(conshdlrname != NULL );
16185  /* find the linear constraint handler */
16186  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
16187  if( conshdlr == NULL )
16188  {
16189  SCIPerrorMessage("linear constraint handler not found\n");
16190  return SCIP_PLUGINNOTFOUND;
16191  }
16192 
16193  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16194  assert(conshdlrdata != NULL);
16195 
16196  /* check if linear constraint update method already exists in constraint handler data */
16197  if( !conshdlrdataHasUpgrade(scip, conshdlrdata, linconsupgd, conshdlrname) )
16198  {
16199  /* create a linear constraint upgrade data object */
16200  SCIP_CALL( linconsupgradeCreate(scip, &linconsupgrade, linconsupgd, priority) );
16201 
16202  /* insert linear constraint update method into constraint handler data */
16203  SCIP_CALL( conshdlrdataIncludeUpgrade(scip, conshdlrdata, linconsupgrade) );
16204 
16205  /* adds parameter to turn on and off the upgrading step */
16206  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/linear/upgrade/%s", conshdlrname);
16207  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "enable linear upgrading for constraint handler <%s>", conshdlrname);
16209  paramname, paramdesc,
16210  &linconsupgrade->active, FALSE, TRUE, NULL, NULL) );
16211  }
16212 
16213  return SCIP_OKAY;
16214 }
16215 
16216 /** creates and captures a linear constraint
16217  *
16218  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
16219  */
16221  SCIP* scip, /**< SCIP data structure */
16222  SCIP_CONS** cons, /**< pointer to hold the created constraint */
16223  const char* name, /**< name of constraint */
16224  int nvars, /**< number of nonzeros in the constraint */
16225  SCIP_VAR** vars, /**< array with variables of constraint entries */
16226  SCIP_Real* vals, /**< array with coefficients of constraint entries */
16227  SCIP_Real lhs, /**< left hand side of constraint */
16228  SCIP_Real rhs, /**< right hand side of constraint */
16229  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
16230  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
16231  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
16232  * Usually set to TRUE. */
16233  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
16234  * TRUE for model constraints, FALSE for additional, redundant constraints. */
16235  SCIP_Bool check, /**< should the constraint be checked for feasibility?
16236  * TRUE for model constraints, FALSE for additional, redundant constraints. */
16237  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
16238  * Usually set to TRUE. */
16239  SCIP_Bool local, /**< is constraint only valid locally?
16240  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
16241  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
16242  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
16243  * adds coefficients to this constraint. */
16244  SCIP_Bool dynamic, /**< Is constraint subject to aging?
16245  * Usually set to FALSE. Set to TRUE for own cuts which
16246  * are separated as constraints. */
16247  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
16248  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
16249  SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
16250  * if it may be moved to a more global node?
16251  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
16252  )
16253 {
16254  SCIP_CONSHDLRDATA* conshdlrdata;
16255  SCIP_CONSHDLR* conshdlr;
16256  SCIP_CONSDATA* consdata;
16257 
16258  assert(scip != NULL);
16259  assert(cons != NULL);
16260 
16261  /* find the linear constraint handler */
16262  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
16263  if( conshdlr == NULL )
16264  {
16265  SCIPerrorMessage("linear constraint handler not found\n");
16266  return SCIP_PLUGINNOTFOUND;
16267  }
16268 
16269  /* check for event handler */
16270  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16271  assert(conshdlrdata != NULL);
16272  assert(conshdlrdata->eventhdlr != NULL);
16273 
16274  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
16275  * constraint after presolving we have to ensure that it holds active variables
16276  */
16277  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE && nvars > 0 )
16278  {
16279  SCIP_VAR** consvars;
16280  SCIP_Real* consvals;
16281  SCIP_Real constant = 0.0;
16282  int nconsvars;
16283  int requiredsize;
16284 
16285  nconsvars = nvars;
16286  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
16287  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
16288 
16289  /* get active variables for new constraint */
16290  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
16291 
16292  /* if space was not enough we need to resize the buffers */
16293  if( requiredsize > nconsvars )
16294  {
16295  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
16296  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
16297 
16298  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
16299  assert(requiredsize <= nconsvars);
16300  }
16301 
16302  /* adjust sides and check that we do not subtract infinity values */
16303  if( SCIPisInfinity(scip, REALABS(constant)) )
16304  {
16305  if( constant < 0.0 )
16306  {
16307  if( SCIPisInfinity(scip, lhs) )
16308  {
16309  SCIPfreeBufferArray(scip, &consvals);
16310  SCIPfreeBufferArray(scip, &consvars);
16311 
16312  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);
16313 
16314  SCIPABORT();
16315  return SCIP_INVALIDDATA; /*lint !e527*/
16316  }
16317  if( SCIPisInfinity(scip, rhs) )
16318  {
16319  SCIPfreeBufferArray(scip, &consvals);
16320  SCIPfreeBufferArray(scip, &consvars);
16321 
16322  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);
16323 
16324  SCIPABORT();
16325  return SCIP_INVALIDDATA; /*lint !e527*/
16326  }
16327 
16328  lhs = -SCIPinfinity(scip);
16329  rhs = -SCIPinfinity(scip);
16330  }
16331  else
16332  {
16333  if( SCIPisInfinity(scip, -lhs) )
16334  {
16335  SCIPfreeBufferArray(scip, &consvals);
16336  SCIPfreeBufferArray(scip, &consvars);
16337 
16338  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);
16339 
16340  SCIPABORT();
16341  return SCIP_INVALIDDATA; /*lint !e527*/
16342  }
16343  if( SCIPisInfinity(scip, -rhs) )
16344  {
16345  SCIPfreeBufferArray(scip, &consvals);
16346  SCIPfreeBufferArray(scip, &consvars);
16347 
16348  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);
16349 
16350  SCIPABORT();
16351  return SCIP_INVALIDDATA; /*lint !e527*/
16352  }
16353 
16354  lhs = SCIPinfinity(scip);
16355  rhs = SCIPinfinity(scip);
16356  }
16357  }
16358  else
16359  {
16360  if( !SCIPisInfinity(scip, REALABS(lhs)) )
16361  lhs -= constant;
16362  if( !SCIPisInfinity(scip, REALABS(rhs)) )
16363  rhs -= constant;
16364 
16365  if( SCIPisInfinity(scip, -lhs) )
16366  lhs = -SCIPinfinity(scip);
16367  else if( SCIPisInfinity(scip, lhs) )
16368  lhs = SCIPinfinity(scip);
16369 
16370  if( SCIPisInfinity(scip, rhs) )
16371  rhs = SCIPinfinity(scip);
16372  else if( SCIPisInfinity(scip, -rhs) )
16373  rhs = -SCIPinfinity(scip);
16374  }
16375 
16376  /* create constraint data */
16377  SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
16378  assert(consdata != NULL);
16379 
16380  SCIPfreeBufferArray(scip, &consvals);
16381  SCIPfreeBufferArray(scip, &consvars);
16382  }
16383  else
16384  {
16385  /* create constraint data */
16386  SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
16387  assert(consdata != NULL);
16388  }
16389 
16390  /* create constraint */
16391  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
16392  local, modifiable, dynamic, removable, stickingatnode) );
16393 
16394  if( SCIPisTransformed(scip) && needEvents(scip) )
16395  {
16396  /* catch bound change events of variables */
16397  SCIP_CALL( consCatchAllEvents(scip, *cons, conshdlrdata->eventhdlr) );
16398  assert(consdata->eventdata != NULL);
16399  }
16400 
16401  return SCIP_OKAY;
16402 }
16403 
16404 /** creates and captures a linear constraint
16405  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
16406  * method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
16407  *
16408  * @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
16409  *
16410  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
16411  */
16413  SCIP* scip, /**< SCIP data structure */
16414  SCIP_CONS** cons, /**< pointer to hold the created constraint */
16415  const char* name, /**< name of constraint */
16416  int nvars, /**< number of nonzeros in the constraint */
16417  SCIP_VAR** vars, /**< array with variables of constraint entries */
16418  SCIP_Real* vals, /**< array with coefficients of constraint entries */
16419  SCIP_Real lhs, /**< left hand side of constraint */
16420  SCIP_Real rhs /**< right hand side of constraint */
16421  )
16422 {
16423  assert(scip != NULL);
16424 
16425  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
16426  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
16427 
16428  return SCIP_OKAY;
16429 }
16430 
16431 /** creates by copying and captures a linear constraint */
16433  SCIP* scip, /**< target SCIP data structure */
16434  SCIP_CONS** cons, /**< pointer to store the created target constraint */
16435  SCIP* sourcescip, /**< source SCIP data structure */
16436  const char* name, /**< name of constraint */
16437  int nvars, /**< number of variables in source variable array */
16438  SCIP_VAR** sourcevars, /**< source variables of the linear constraints */
16439  SCIP_Real* sourcecoefs, /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
16440  SCIP_Real lhs, /**< left hand side of the linear constraint */
16441  SCIP_Real rhs, /**< right hand side of the linear constraint */
16442  SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
16443  * variables of the target SCIP */
16444  SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
16445  * target constraints */
16446  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
16447  SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
16448  SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
16449  SCIP_Bool check, /**< should the constraint be checked for feasibility? */
16450  SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
16451  SCIP_Bool local, /**< is constraint only valid locally? */
16452  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
16453  SCIP_Bool dynamic, /**< is constraint subject to aging? */
16454  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
16455  SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
16456  * if it may be moved to a more global node? */
16457  SCIP_Bool global, /**< create a global or a local copy? */
16458  SCIP_Bool* valid /**< pointer to store if the copying was valid */
16459  )
16460 {
16461  SCIP_VAR** vars;
16462  SCIP_Real* coefs;
16463 
16464  SCIP_Real constant;
16465  int requiredsize;
16466  int v;
16467 
16468  if( SCIPisGT(scip, lhs, rhs) )
16469  {
16470  *valid = FALSE;
16471  return SCIP_OKAY;
16472  }
16473 
16474  (*valid) = TRUE;
16475 
16476  if( nvars == 0 )
16477  {
16478  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
16479  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
16480  return SCIP_OKAY;
16481  }
16482 
16483  /* duplicate variable array */
16484  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, sourcevars, nvars) );
16485 
16486  /* duplicate coefficient array */
16487  if( sourcecoefs != NULL )
16488  {
16489  SCIP_CALL( SCIPduplicateBufferArray(scip, &coefs, sourcecoefs, nvars) );
16490  }
16491  else
16492  {
16493  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
16494  for( v = 0; v < nvars; ++v )
16495  coefs[v] = 1.0;
16496  }
16497 
16498  constant = 0.0;
16499 
16500  /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
16501  * the target SCIP
16502  */
16503  if( !SCIPvarIsOriginal(vars[0]) )
16504  {
16505  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize, TRUE) );
16506 
16507  if( requiredsize > nvars )
16508  {
16509  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
16510  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
16511 
16512  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize, TRUE) );
16513  assert(requiredsize <= nvars);
16514  }
16515  }
16516  else
16517  {
16518  for( v = 0; v < nvars; ++v )
16519  {
16520  assert(SCIPvarIsOriginal(vars[v]));
16521  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
16522  assert(vars[v] != NULL);
16523  }
16524  }
16525 
16526  /* map variables of the source constraint to variables of the target SCIP */
16527  for( v = 0; v < nvars && *valid; ++v )
16528  {
16529  SCIP_VAR* var;
16530  var = vars[v];
16531 
16532  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, valid) );
16533  assert(!(*valid) || vars[v] != NULL);
16534  }
16535 
16536  /* only create the target constraint, if all variables could be copied */
16537  if( *valid )
16538  {
16539  if( !SCIPisInfinity(scip, -lhs) )
16540  lhs -= constant;
16541 
16542  if( !SCIPisInfinity(scip, rhs) )
16543  rhs -= constant;
16544 
16545  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
16546  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
16547  }
16548 
16549  /* free buffer array */
16550  SCIPfreeBufferArray(scip, &coefs);
16551  SCIPfreeBufferArray(scip, &vars);
16552 
16553  return SCIP_OKAY;
16554 }
16555 
16556 /** adds coefficient to linear constraint (if it is not zero) */
16558  SCIP* scip, /**< SCIP data structure */
16559  SCIP_CONS* cons, /**< constraint data */
16560  SCIP_VAR* var, /**< variable of constraint entry */
16561  SCIP_Real val /**< coefficient of constraint entry */
16562  )
16563 {
16564  assert(scip != NULL);
16565  assert(cons != NULL);
16566  assert(var != NULL);
16567 
16568  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16569  {
16570  SCIPerrorMessage("constraint is not linear\n");
16571  return SCIP_INVALIDDATA;
16572  }
16574  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
16575  * constraint after presolving we have to ensure that it holds active variables
16576  */
16577  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE )
16578  {
16579  SCIP_CONSDATA* consdata;
16580  SCIP_VAR** consvars;
16581  SCIP_Real* consvals;
16582  SCIP_Real constant = 0.0;
16583  SCIP_Real rhs;
16584  SCIP_Real lhs;
16585  int nconsvars;
16586  int requiredsize;
16587  int v;
16588 
16589  nconsvars = 1;
16590  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
16591  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
16592  consvars[0] = var;
16593  consvals[0] = val;
16594 
16595  /* get active variables for new constraint */
16596  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
16597 
16598  /* if space was not enough we need to resize the buffers */
16599  if( requiredsize > nconsvars )
16600  {
16601  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
16602  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
16603 
16604  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
16605  assert(requiredsize <= nconsvars);
16606  }
16607 
16608  consdata = SCIPconsGetData(cons);
16609  assert(consdata != NULL);
16610 
16611  lhs = consdata->lhs;
16612  rhs = consdata->rhs;
16613 
16614  /* adjust sides and check that we do not subtract infinity values */
16615  /* constant is infinite */
16616  if( SCIPisInfinity(scip, REALABS(constant)) )
16617  {
16618  if( constant < 0.0 )
16619  {
16620  if( SCIPisInfinity(scip, lhs) )
16621  {
16622  SCIPfreeBufferArray(scip, &consvals);
16623  SCIPfreeBufferArray(scip, &consvars);
16624 
16625  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));
16626 
16627  SCIPABORT();
16628  return SCIP_INVALIDDATA; /*lint !e527*/
16629  }
16630  if( SCIPisInfinity(scip, rhs) )
16631  {
16632  SCIPfreeBufferArray(scip, &consvals);
16633  SCIPfreeBufferArray(scip, &consvars);
16634 
16635  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));
16636 
16637  SCIPABORT();
16638  return SCIP_INVALIDDATA; /*lint !e527*/
16639  }
16640 
16641  lhs = -SCIPinfinity(scip);
16642  rhs = -SCIPinfinity(scip);
16643  }
16644  else
16645  {
16646  if( SCIPisInfinity(scip, -lhs) )
16647  {
16648  SCIPfreeBufferArray(scip, &consvals);
16649  SCIPfreeBufferArray(scip, &consvars);
16650 
16651  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));
16652 
16653  SCIPABORT();
16654  return SCIP_INVALIDDATA; /*lint !e527*/
16655  }
16656  if( SCIPisInfinity(scip, -rhs) )
16657  {
16658  SCIPfreeBufferArray(scip, &consvals);
16659  SCIPfreeBufferArray(scip, &consvars);
16660 
16661  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));
16662 
16663  SCIPABORT();
16664  return SCIP_INVALIDDATA; /*lint !e527*/
16665  }
16666 
16667  lhs = SCIPinfinity(scip);
16668  rhs = SCIPinfinity(scip);
16669  }
16670  }
16671  /* constant is not infinite */
16672  else
16673  {
16674  if( !SCIPisInfinity(scip, REALABS(lhs)) )
16675  lhs -= constant;
16676  if( !SCIPisInfinity(scip, REALABS(rhs)) )
16677  rhs -= constant;
16678 
16679  if( SCIPisInfinity(scip, -lhs) )
16680  lhs = -SCIPinfinity(scip);
16681  else if( SCIPisInfinity(scip, lhs) )
16682  lhs = SCIPinfinity(scip);
16683 
16684  if( SCIPisInfinity(scip, rhs) )
16685  rhs = SCIPinfinity(scip);
16686  else if( SCIPisInfinity(scip, -rhs) )
16687  rhs = -SCIPinfinity(scip);
16688  }
16689 
16690  /* add all active variables to constraint */
16691  for( v = nconsvars - 1; v >= 0; --v )
16692  {
16693  SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
16694  }
16695 
16696  /* update left and right hand sides */
16697  SCIP_CALL( chgLhs(scip, cons, lhs));
16698  SCIP_CALL( chgRhs(scip, cons, rhs));
16699 
16700  SCIPfreeBufferArray(scip, &consvals);
16701  SCIPfreeBufferArray(scip, &consvars);
16702  }
16703  else
16704  {
16705  SCIP_CALL( addCoef(scip, cons, var, val) );
16706  }
16707 
16708  return SCIP_OKAY;
16709 }
16710 
16711 /** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
16712  * not yet contained in the constraint
16713  *
16714  * @note This method may only be called during problem creation stage for an original constraint and variable.
16715  *
16716  * @note This method requires linear time to search for occurences of the variable in the constraint data.
16717  */
16719  SCIP* scip, /**< SCIP data structure */
16720  SCIP_CONS* cons, /**< constraint data */
16721  SCIP_VAR* var, /**< variable of constraint entry */
16722  SCIP_Real val /**< new coefficient of constraint entry */
16723  )
16724 {
16725  SCIP_CONSDATA* consdata;
16726  SCIP_VAR** vars;
16727  SCIP_Bool found;
16728  int i;
16729 
16730  assert(scip != NULL);
16731  assert(cons != NULL);
16732  assert(var != NULL);
16733 
16735  {
16736  SCIPerrorMessage("constraint is not linear\n");
16737  return SCIP_INVALIDDATA;
16738  }
16739 
16740  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM || !SCIPconsIsOriginal(cons) || !SCIPvarIsOriginal(var) )
16741  {
16742  SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
16743  return SCIP_INVALIDDATA;
16744  }
16745 
16746  consdata = SCIPconsGetData(cons);
16747  assert(consdata != NULL);
16748 
16749  vars = consdata->vars;
16750  found = FALSE;
16751  i = 0;
16752  while( i < consdata->nvars )
16753  {
16754  if( vars[i] == var )
16755  {
16756  if( found || SCIPisZero(scip, val) )
16757  {
16758  SCIP_CALL( delCoefPos(scip, cons, i) );
16759 
16760  /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
16761  i--;
16762  }
16763  else
16764  {
16765  SCIP_CALL( chgCoefPos(scip, cons, i, val) );
16766  }
16767  found = TRUE;
16768  }
16769  i++;
16770  }
16771 
16772  if( !found && !SCIPisZero(scip, val) )
16773  {
16774  SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
16775  }
16776 
16777  return SCIP_OKAY;
16778 }
16779 
16780 /** deletes variable from linear constraint
16781  *
16782  * @note This method may only be called during problem creation stage for an original constraint and variable.
16783  *
16784  * @note This method requires linear time to search for occurences of the variable in the constraint data.
16785  */
16787  SCIP* scip, /**< SCIP data structure */
16788  SCIP_CONS* cons, /**< constraint data */
16789  SCIP_VAR* var /**< variable of constraint entry */
16790  )
16791 {
16792  assert(scip != NULL);
16793  assert(cons != NULL);
16794  assert(var != NULL);
16795 
16796  SCIP_CALL( SCIPchgCoefLinear(scip, cons, var, 0.0) );
16797 
16798  return SCIP_OKAY;
16799 }
16800 
16801 /** gets left hand side of linear constraint */
16803  SCIP* scip, /**< SCIP data structure */
16804  SCIP_CONS* cons /**< constraint data */
16805  )
16806 {
16807  SCIP_CONSDATA* consdata;
16808 
16809  assert(scip != NULL);
16810  assert(cons != NULL);
16811 
16812  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16813  {
16814  SCIPerrorMessage("constraint is not linear\n");
16815  SCIPABORT();
16816  return SCIP_INVALID; /*lint !e527*/
16817  }
16819  consdata = SCIPconsGetData(cons);
16820  assert(consdata != NULL);
16821 
16822  return consdata->lhs;
16823 }
16824 
16825 /** gets right hand side of linear constraint */
16827  SCIP* scip, /**< SCIP data structure */
16828  SCIP_CONS* cons /**< constraint data */
16829  )
16830 {
16831  SCIP_CONSDATA* consdata;
16832 
16833  assert(scip != NULL);
16834  assert(cons != NULL);
16835 
16836  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16837  {
16838  SCIPerrorMessage("constraint is not linear\n");
16839  SCIPABORT();
16840  return SCIP_INVALID; /*lint !e527*/
16841  }
16843  consdata = SCIPconsGetData(cons);
16844  assert(consdata != NULL);
16845 
16846  return consdata->rhs;
16847 }
16848 
16849 /** changes left hand side of linear constraint */
16851  SCIP* scip, /**< SCIP data structure */
16852  SCIP_CONS* cons, /**< constraint data */
16853  SCIP_Real lhs /**< new left hand side */
16854  )
16855 {
16856  assert(scip != NULL);
16857  assert(cons != NULL);
16858 
16859  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16860  {
16861  SCIPerrorMessage("constraint is not linear\n");
16862  return SCIP_INVALIDDATA;
16863  }
16864 
16865  SCIP_CALL( chgLhs(scip, cons, lhs) );
16867  return SCIP_OKAY;
16868 }
16869 
16870 /** changes right hand side of linear constraint */
16872  SCIP* scip, /**< SCIP data structure */
16873  SCIP_CONS* cons, /**< constraint data */
16874  SCIP_Real rhs /**< new right hand side */
16875  )
16876 {
16877  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16878  {
16879  SCIPerrorMessage("constraint is not linear\n");
16880  return SCIP_INVALIDDATA;
16881  }
16882 
16883  SCIP_CALL( chgRhs(scip, cons, rhs) );
16884 
16885  return SCIP_OKAY;
16886 }
16888 /** gets the number of variables in the linear constraint */
16889 int SCIPgetNVarsLinear(
16890  SCIP* scip, /**< SCIP data structure */
16891  SCIP_CONS* cons /**< constraint data */
16892  )
16893 {
16894  SCIP_CONSDATA* consdata;
16895 
16896  assert(scip != NULL);
16897  assert(cons != NULL);
16898 
16899  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16900  {
16901  SCIPerrorMessage("constraint is not linear\n");
16902  SCIPABORT();
16903  return -1; /*lint !e527*/
16904  }
16906  consdata = SCIPconsGetData(cons);
16907  assert(consdata != NULL);
16908 
16909  return consdata->nvars;
16910 }
16911 
16912 /** gets the array of variables in the linear constraint; the user must not modify this array! */
16914  SCIP* scip, /**< SCIP data structure */
16915  SCIP_CONS* cons /**< constraint data */
16916  )
16917 {
16918  SCIP_CONSDATA* consdata;
16919 
16920  assert(scip != NULL);
16921  assert(cons != NULL);
16922 
16923  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16924  {
16925  SCIPerrorMessage("constraint is not linear\n");
16926  SCIPABORT();
16927  return NULL; /*lint !e527*/
16928  }
16930  consdata = SCIPconsGetData(cons);
16931  assert(consdata != NULL);
16932 
16933  return consdata->vars;
16934 }
16935 
16936 /** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
16938  SCIP* scip, /**< SCIP data structure */
16939  SCIP_CONS* cons /**< constraint data */
16940  )
16941 {
16942  SCIP_CONSDATA* consdata;
16943 
16944  assert(scip != NULL);
16945  assert(cons != NULL);
16946 
16947  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16948  {
16949  SCIPerrorMessage("constraint is not linear\n");
16950  SCIPABORT();
16951  return NULL; /*lint !e527*/
16952  }
16954  consdata = SCIPconsGetData(cons);
16955  assert(consdata != NULL);
16956 
16957  return consdata->vals;
16958 }
16959 
16960 /** gets the activity of the linear constraint in the given solution
16961  *
16962  * @note if the solution contains values at infinity, this method will return SCIP_INVALID in case the activity
16963  * comprises positive and negative infinity contributions
16964  */
16966  SCIP* scip, /**< SCIP data structure */
16967  SCIP_CONS* cons, /**< constraint data */
16968  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
16969  )
16970 {
16971  SCIP_CONSDATA* consdata;
16972 
16973  assert(scip != NULL);
16974  assert(cons != NULL);
16975 
16976  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
16977  {
16978  SCIPerrorMessage("constraint is not linear\n");
16979  SCIPABORT();
16980  return SCIP_INVALID; /*lint !e527*/
16981  }
16982 
16983  consdata = SCIPconsGetData(cons);
16984  assert(consdata != NULL);
16985 
16986  if( consdata->row != NULL )
16987  return SCIPgetRowSolActivity(scip, consdata->row, sol);
16988  else
16989  return consdataGetActivity(scip, consdata, sol);
16990 }
16991 
16992 /** gets the feasibility of the linear constraint in the given solution */
16994  SCIP* scip, /**< SCIP data structure */
16995  SCIP_CONS* cons, /**< constraint data */
16996  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
16997  )
16998 {
16999  SCIP_CONSDATA* consdata;
17000 
17001  assert(scip != NULL);
17002  assert(cons != NULL);
17003 
17004  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17005  {
17006  SCIPerrorMessage("constraint is not linear\n");
17007  SCIPABORT();
17008  return SCIP_INVALID; /*lint !e527*/
17009  }
17010 
17011  consdata = SCIPconsGetData(cons);
17012  assert(consdata != NULL);
17013 
17014  if( consdata->row != NULL )
17015  return SCIPgetRowSolFeasibility(scip, consdata->row, sol);
17016  else
17017  return consdataGetFeasibility(scip, consdata, sol);
17018 }
17019 
17020 /** gets the dual solution of the linear constraint in the current LP */
17022  SCIP* scip, /**< SCIP data structure */
17023  SCIP_CONS* cons /**< constraint data */
17024  )
17025 {
17026  SCIP_CONSDATA* consdata;
17027 
17028  assert(scip != NULL);
17029  assert(cons != NULL);
17030 
17031  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17032  {
17033  SCIPerrorMessage("constraint is not linear\n");
17034  SCIPABORT();
17035  return SCIP_INVALID; /*lint !e527*/
17036  }
17038  consdata = SCIPconsGetData(cons);
17039  assert(consdata != NULL);
17040 
17041  if( consdata->row != NULL )
17042  return SCIProwGetDualsol(consdata->row);
17043  else
17044  return 0.0;
17045 }
17046 
17047 /** gets the dual Farkas value of the linear constraint in the current infeasible LP */
17049  SCIP* scip, /**< SCIP data structure */
17050  SCIP_CONS* cons /**< constraint data */
17051  )
17052 {
17053  SCIP_CONSDATA* consdata;
17054 
17055  assert(scip != NULL);
17056  assert(cons != NULL);
17057 
17058  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17059  {
17060  SCIPerrorMessage("constraint is not linear\n");
17061  SCIPABORT();
17062  return SCIP_INVALID; /*lint !e527*/
17063  }
17065  consdata = SCIPconsGetData(cons);
17066  assert(consdata != NULL);
17067 
17068  if( consdata->row != NULL )
17069  return SCIProwGetDualfarkas(consdata->row);
17070  else
17071  return 0.0;
17072 }
17073 
17074 /** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
17075  * the user must not modify the row!
17076  */
17078  SCIP* scip, /**< SCIP data structure */
17079  SCIP_CONS* cons /**< constraint data */
17080  )
17081 {
17082  SCIP_CONSDATA* consdata;
17083 
17084  assert(scip != NULL);
17085  assert(cons != NULL);
17086 
17087  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17088  {
17089  SCIPerrorMessage("constraint is not linear\n");
17090  SCIPABORT();
17091  return NULL; /*lint !e527*/
17092  }
17094  consdata = SCIPconsGetData(cons);
17095  assert(consdata != NULL);
17096 
17097  return consdata->row;
17098 }
17099 
17100 /** tries to automatically convert a linear constraint into a more specific and more specialized constraint */
17102  SCIP* scip, /**< SCIP data structure */
17103  SCIP_CONS* cons, /**< source constraint to try to convert */
17104  SCIP_CONS** upgdcons /**< pointer to store upgraded constraint, or NULL if not successful */
17105  )
17106 {
17107  SCIP_CONSHDLR* conshdlr;
17108  SCIP_CONSHDLRDATA* conshdlrdata;
17109  SCIP_CONSDATA* consdata;
17110  SCIP_VAR* var;
17111  SCIP_Real val;
17112  SCIP_Real lb;
17113  SCIP_Real ub;
17114  SCIP_Real poscoeffsum;
17115  SCIP_Real negcoeffsum;
17116  SCIP_Bool integral;
17117  int nposbin;
17118  int nnegbin;
17119  int nposint;
17120  int nnegint;
17121  int nposimpl;
17122  int nnegimpl;
17123  int nposimplbin;
17124  int nnegimplbin;
17125  int nposcont;
17126  int nnegcont;
17127  int ncoeffspone;
17128  int ncoeffsnone;
17129  int ncoeffspint;
17130  int ncoeffsnint;
17131  int ncoeffspfrac;
17132  int ncoeffsnfrac;
17133  int i;
17134 
17135  assert(scip != NULL);
17136  assert(cons != NULL);
17137  assert(upgdcons != NULL);
17138 
17139  *upgdcons = NULL;
17140 
17141  /* we cannot upgrade a modifiable linear constraint, since we don't know what additional coefficients to expect */
17142  if( SCIPconsIsModifiable(cons) )
17143  return SCIP_OKAY;
17144 
17145  /* check for upgradability */
17146  if( SCIPconsGetNUpgradeLocks(cons) > 0 )
17147  return SCIP_OKAY;
17148 
17149  /* get the constraint handler and check, if it's really a linear constraint */
17150  conshdlr = SCIPconsGetHdlr(cons);
17151  if( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) != 0 )
17152  {
17153  SCIPerrorMessage("constraint is not linear\n");
17154  return SCIP_INVALIDDATA;
17155  }
17156 
17157  /* get constraint handler data and constraint data */
17158  conshdlrdata = SCIPconshdlrGetData(conshdlr);
17159  assert(conshdlrdata != NULL);
17160  consdata = SCIPconsGetData(cons);
17161  assert(consdata != NULL);
17162 
17163  /* check, if the constraint was already upgraded and will be deleted anyway after preprocessing */
17164  if( consdata->upgraded )
17165  return SCIP_OKAY;
17166 
17167  /* check, if the constraint is already stored as LP row */
17168  if( consdata->row != NULL )
17169  {
17170  if( SCIProwIsInLP(consdata->row) )
17171  {
17172  SCIPerrorMessage("cannot upgrade linear constraint that is already stored as row in the LP\n");
17173  return SCIP_INVALIDDATA;
17174  }
17175  else
17176  {
17177  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
17178  }
17179  }
17180 
17181  /* normalize constraint */
17182  SCIP_CALL( normalizeCons(scip, cons) );
17183 
17184 
17185  /*
17186  * calculate some statistics on linear constraint
17187  */
17188 
17189  nposbin = 0;
17190  nnegbin = 0;
17191  nposint = 0;
17192  nnegint = 0;
17193  nposimpl = 0;
17194  nnegimpl = 0;
17195  nposimplbin = 0;
17196  nnegimplbin = 0;
17197  nposcont = 0;
17198  nnegcont = 0;
17199  ncoeffspone = 0;
17200  ncoeffsnone = 0;
17201  ncoeffspint = 0;
17202  ncoeffsnint = 0;
17203  ncoeffspfrac = 0;
17204  ncoeffsnfrac = 0;
17205  integral = TRUE;
17206  poscoeffsum = 0.0;
17207  negcoeffsum = 0.0;
17208 
17209  for( i = 0; i < consdata->nvars; ++i )
17210  {
17211  var = consdata->vars[i];
17212  val = consdata->vals[i];
17213  lb = SCIPvarGetLbLocal(var);
17214  ub = SCIPvarGetUbLocal(var);
17215  assert(!SCIPisZero(scip, val));
17216 
17217  switch( SCIPvarGetType(var) )
17218  {
17219  case SCIP_VARTYPE_BINARY:
17220  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
17221  integral = integral && SCIPisIntegral(scip, val);
17222  if( val >= 0.0 )
17223  nposbin++;
17224  else
17225  nnegbin++;
17226  break;
17227  case SCIP_VARTYPE_INTEGER:
17228  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
17229  integral = integral && SCIPisIntegral(scip, val);
17230  if( val >= 0.0 )
17231  nposint++;
17232  else
17233  nnegint++;
17234  break;
17235  case SCIP_VARTYPE_IMPLINT:
17236  if( SCIPvarIsBinary(var) )
17237  {
17238  if( val >= 0.0 )
17239  nposimplbin++;
17240  else
17241  nnegimplbin++;
17242  }
17243  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
17244  integral = integral && SCIPisIntegral(scip, val);
17245  if( val >= 0.0 )
17246  nposimpl++;
17247  else
17248  nnegimpl++;
17249  break;
17251  integral = integral && SCIPisEQ(scip, lb, ub) && SCIPisIntegral(scip, val * lb);
17252  if( val >= 0.0 )
17253  nposcont++;
17254  else
17255  nnegcont++;
17256  break;
17257  default:
17258  SCIPerrorMessage("unknown variable type\n");
17259  return SCIP_INVALIDDATA;
17260  }
17261  if( SCIPisEQ(scip, val, 1.0) )
17262  ncoeffspone++;
17263  else if( SCIPisEQ(scip, val, -1.0) )
17264  ncoeffsnone++;
17265  else if( SCIPisIntegral(scip, val) )
17266  {
17267  if( SCIPisPositive(scip, val) )
17268  ncoeffspint++;
17269  else
17270  ncoeffsnint++;
17271  }
17272  else
17273  {
17274  if( SCIPisPositive(scip, val) )
17275  ncoeffspfrac++;
17276  else
17277  ncoeffsnfrac++;
17278  }
17279  if( SCIPisPositive(scip, val) )
17280  poscoeffsum += val;
17281  else
17282  negcoeffsum += val;
17283  }
17284 
17285 
17286  /*
17287  * call the upgrading methods
17288  */
17289 
17290  SCIPdebugMessage("upgrading linear constraint <%s> (%d upgrade methods):\n",
17291  SCIPconsGetName(cons), conshdlrdata->nlinconsupgrades);
17292  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",
17293  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposcont, nnegcont,
17294  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
17295  poscoeffsum, negcoeffsum, integral);
17296 
17297  /* try all upgrading methods in priority order in case the upgrading step is enable */
17298  for( i = 0; i < conshdlrdata->nlinconsupgrades && *upgdcons == NULL; ++i )
17299  {
17300  if( conshdlrdata->linconsupgrades[i]->active )
17301  {
17302  SCIP_CALL( conshdlrdata->linconsupgrades[i]->linconsupgd(scip, cons, consdata->nvars,
17303  consdata->vars, consdata->vals, consdata->lhs, consdata->rhs,
17304  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposimplbin, nnegimplbin, nposcont, nnegcont,
17305  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
17306  poscoeffsum, negcoeffsum, integral,
17307  upgdcons) );
17308  }
17309  }
17310 
17311 #ifdef SCIP_DEBUG
17312  if( *upgdcons != NULL )
17313  {
17314  SCIPdebugPrintCons(scip, cons, NULL);
17315  SCIPdebugMessage(" -> upgraded to constraint type <%s>\n", SCIPconshdlrGetName(SCIPconsGetHdlr(*upgdcons)));
17316  SCIPdebugPrintCons(scip, *upgdcons, NULL);
17317  }
17318 #endif
17319 
17320  return SCIP_OKAY;
17321 }
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:32768
#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:22764
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41180
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:16759
struct InferInfo INFERINFO
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:16781
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:41293
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip.c:28295
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:10735
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:5847
SCIP_Bool SCIPconsIsLocked(SCIP_CONS *cons)
Definition: cons.c:7943
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip.c:5557
static SCIP_RETCODE tightenVarBounds(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:6542
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:25575
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:16341
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:28272
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:22873
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:17456
#define CONSHDLR_NAME
Definition: cons_linear.c:61
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:41256
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:11991
#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:1562
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip.h:20402
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:9788
#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:7467
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:10415
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:11577
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16521
#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:9079
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1220
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:15823
SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
Definition: cons.c:7903
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:41528
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:10690
#define SCIP_MAXSTRLEN
Definition: def.h:198
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip.c:5603
#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:5215
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:17011
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1125
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:41640
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:7853
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:7685
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip.c:5303
SCIP_Real SCIPcutoffbounddelta(SCIP *scip)
Definition: scip.c:40776
SCIP_RETCODE SCIPupdateCutoffbound(SCIP *scip, SCIP_Real cutoffbound)
Definition: scip.c:38171
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:16965
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:12339
SCIP_Real SCIPgetHugeValue(SCIP *scip)
Definition: scip.c:41282
static void consdataRecomputeMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1172
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
Definition: scip.c:24307
#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:17512
SCIP_Real SCIPgetDualfarkasLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip.c:5787
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:7913
#define FALSE
Definition: def.h:53
static SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
static SCIP_DECL_CONSEXITSOL(consExitsolLinear)
static void consdataInvalidateActivities(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1075
SCIP_DECL_LINCONSUPGD((*linconsupgd))
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:17067
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10780
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:7747
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:8169
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:52
#define SCIPdebug(x)
Definition: pub_message.h:74
#define DEFAULT_MAXCARDBOUNDDIST
Definition: cons_linear.c:109
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7644
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17546
#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:5764
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:7245
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:41580
SCIP_RETCODE SCIPconvertCutsToConss(SCIP *scip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition: scip.c:2792
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:53
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip.c:19656
static SCIP_DECL_CONSENFOPS(consEnfopsLinear)
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip.c:23070
SCIP_VAR ** SCIPgetLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
int SCIPconsGetNUpgradeLocks(SCIP_CONS *cons)
Definition: cons.c:7995
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:16416
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:41616
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:38147
SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:25773
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:27875
SCIP_Bool SCIPisSumGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41453
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip.h:20385
static SCIP_RETCODE tightenSides(SCIP *scip, SCIP_CONS *cons, int *nchgsides)
Definition: cons_linear.c:8568
SCIP_Real SCIPvarGetLbAtIndex(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:15695
#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:34593
SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
Definition: misc.c:7615
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20414
SCIP_Bool SCIPisSumRelLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41982
static SCIP_DECL_CONSEXITPRE(consExitpreLinear)
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16803
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:10915
SCIP_RETCODE SCIPchgRowRhs(SCIP *scip, SCIP_ROW *row, SCIP_Real rhs)
Definition: scip.c:27770
SCIP_RETCODE SCIPsetConsPropagated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool propagate)
Definition: scip.c:25134
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:7843
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:7783
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:5435
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:26224
SCIP_RETCODE SCIPaddCut(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip.c:30577
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:24936
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:83
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
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:20418
static SCIP_DECL_SORTINDCOMP(consdataCompVar)
Definition: cons_linear.c:2971
int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
Definition: var.c:11206
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
Definition: scip.c:41652
#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:41863
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip.c:5328
SCIP_Real SCIPgetLowerbound(SCIP *scip)
Definition: scip.c:37979
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:7773
#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:20638
SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
Definition: var.c:16712
#define MAXMULTIAGGRQUOTIENT
Definition: cons_linear.c:9239
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:1475
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
Definition: scip.c:24707
#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:5352
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:3516
#define MAXCONSPRESOLROUNDS
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16460
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:3542
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:23057
#define SCIP_EVENTTYPE_LBRELAXED
Definition: type_event.h:56
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16532
static SCIP_DECL_EVENTEXEC(eventExecLinear)
SCIP_Bool SCIPisUpdateUnreliable(SCIP *scip, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: scip.c:42063
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:7210
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:3921
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:6955
SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition: var.c:16690
SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17556
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip.c:36232
static SCIP_RETCODE checkParallelObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons_linear.c:9980
#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 .
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip)
Definition: scip.c:24329
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:41193
SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
Definition: var.c:16470
#define DEFAULT_DETECTCUTOFFBOUND
Definition: cons_linear.c:118
static SCIP_RETCODE updateCutoffbound(SCIP *scip, SCIP_CONS *cons, SCIP_Real primalbound)
Definition: cons_linear.c:9934
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:16483
SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:25547
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:1750
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:20383
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:7196
SCIP_Real * SCIPgetLinearCoefsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:41592
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:41317
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:17159
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:7883
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20355
int SCIPgetNLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNSepaRounds(SCIP *scip)
Definition: scip.c:37589
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20426
#define CONSHDLR_PROPFREQ
Definition: cons_linear.c:67
#define SCIPdebugPrintf
Definition: pub_message.h:80
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip.h:20403
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip.c:19592
SCIP_RETCODE SCIPupdateConsFlags(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1)
Definition: scip.c:25287
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:16701
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:41604
static SCIP_DECL_CONSSEPALP(consSepalpLinear)
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:3901
int SCIPcalcHashtableSize(int minsize)
Definition: misc.c:1152
SCIP_Real SCIPvarGetUbAtIndex(SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: var.c:15787
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip.c:23037
SCIP_Real SCIPepsilon(SCIP *scip)
Definition: scip.c:40692
static void consdataCalcMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1278
SCIP_Bool SCIPvarIsInitial(SCIP_VAR *var)
Definition: var.c:16542
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41206
#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:5496
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:19783
static SCIP_RETCODE conshdlrdataEnsureLinconsupgradesSize(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, int num)
Definition: cons_linear.c:433
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:40927
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:7624
SCIP_Bool SCIPvarIsRemovable(SCIP_VAR *var)
Definition: var.c:16552
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:8653
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41515
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:16496
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:19125
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:41366
SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
Definition: var.c:16562
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:5472
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip.h:20391
SCIP_Bool SCIPisScalingIntegral(SCIP *scip, SCIP_Real val, SCIP_Real scalar)
Definition: scip.c:41341
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:5931
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)
#define REALABS(x)
Definition: def.h:148
static SCIP_RETCODE checkPartialObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons_linear.c:9867
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:16735
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:41245
#define SCIP_CALL(x)
Definition: def.h:263
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip.c:5261
#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:26341
#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:5161
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1714
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:31741
SCIP_VAR ** SCIPgetLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41554
int SCIPconshdlrGetPropFreq(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4765
static SCIP_DECL_CONSINIT(consInitLinear)
#define SCIPdebugGetSolVal(scip, var, val)
Definition: debug.h:246
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:7654
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:23007
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip.c:16968
static SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip.c:11966
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
Definition: scip.c:41268
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:21688
#define SCIP_EVENTTYPE_UBCHANGED
Definition: type_event.h:96
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12117
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:7335
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:17200
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41219
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:16771
SCIP_RETCODE SCIPsetConshdlrDelvars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELVARS((*consdelvars)))
Definition: scip.c:5718
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip.c:22668
void SCIPhashtablePrintStatistics(SCIP_HASHTABLE *hashtable, SCIP_MESSAGEHDLR *messagehdlr)
Definition: misc.c:1789
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:20259
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:16934
#define QUADCONSUPGD_PRIORITY
Definition: cons_linear.c:150
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17021
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:5448
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:24759
SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip.c:21797
SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
Definition: scip.c:25084
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:16638
static SCIP_Longint getVarSignature(SCIP_VAR *var)
Definition: cons_linear.c:2912
#define SCIP_Bool
Definition: def.h:50
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:1188
#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:7863
static SCIP_Real consdataGetActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:2822
#define MAXTIGHTENROUNDS
Definition: cons_linear.c:6810
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:8240
SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
Definition: scip.c:24356
static SCIP_RETCODE mergeMultiples(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:4229
SCIP_Real SCIPgetLocalLowerbound(SCIP *scip)
Definition: scip.c:12228
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:17412
static SCIP_DECL_CONSDELVARS(consDelvarsLinear)
methods for debugging
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:7873
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:7743
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:16792
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:16723
int SCIPconsGetPos(SCIP_CONS *cons)
Definition: cons.c:7634
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip.c:5580
int SCIPgetNRuns(SCIP *scip)
Definition: scip.c:36928
#define SCIPreallocMemoryArray(scip, ptr, newnum)
Definition: scip.h:20363
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:89
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:16747
#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:1622
#define DEFAULT_MAXROUNDSROOT
Definition: cons_linear.c:88
#define SCIP_EVENTTYPE_GBDCHANGED
Definition: type_event.h:94
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:20400
Proprule
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:37750
#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:1270
#define DEFAULT_SIMPLIFYINEQUALITIES
Definition: cons_linear.c:116
static SCIP_RETCODE createRow(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:7172
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41232
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:1505
#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:16052
#define SCIP_REAL_MAX
Definition: def.h:125
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:20535
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:20466
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:41956
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip.c:36278
SCIP_RETCODE SCIPaddObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip.c:10077
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip.c:5534
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:11514
#define MAXSCALEDCOEFINTEGER
Definition: cons_linear.c:142
static SCIP_DECL_CONSCHECK(consCheckLinear)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16506
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:41378
static void consdataCalcSignatures(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2951
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20371
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:16955
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:5741
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:18934
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition: misc.c:3824
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:25059
static const SCIP_Real scalars[]
Definition: lp.c:5506
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1253
#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
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:7602
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:41329
static SCIP_DECL_CONSPRINT(consPrintLinear)
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:20422
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
Definition: scip.c:5424
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:278
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41541
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip.c:19519
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16648
static SCIP_RETCODE convertBinaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9135
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:25799
#define SCIP_Real
Definition: def.h:124
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_CONS *cons, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
Definition: cons_linear.c:6814
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:7803
SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
Definition: scip.c:25034
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:20365
#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:9193
SCIP_Bool SCIPisSumRelGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:42008
#define MIN(x, y)
Definition: memory.c:63
#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:27587
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)
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:28321
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41567
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:20397
#define SCIP_INVALID
Definition: def.h:144
SCIP_Real SCIPfeastol(SCIP *scip)
Definition: scip.c:40720
#define DEFAULT_RANGEDROWPROPAGATION
Definition: cons_linear.c:131
SCIP_Longint SCIPgetNConflictConssApplied(SCIP *scip)
Definition: scip.c:37724
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:27725
#define CONSHDLR_DESC
Definition: cons_linear.c:62
#define SCIP_Longint
Definition: def.h:109
SCIP_RETCODE SCIPupgradeConsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **upgdcons)
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip.c:3728
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:19751
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:917
#define SCIPdebugAddSolVal(scip, var, val)
Definition: debug.h:245
static SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXIT((*consexit)))
Definition: scip.c:5376
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition: scip.c:19465
SCIP_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
#define MAX_CLIQUE_NONZEROS_PER_CONS
Definition: cons_linear.c:7535
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:9249
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:49
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:16628
int SCIPgetNObjVars(SCIP *scip)
Definition: scip.c:10963
SCIP_RETCODE SCIPaddConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip.c:12036
static int inferInfoToInt(INFERINFO inferinfo)
Definition: cons_linear.c:372
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
#define MAXVALRECOMP
Definition: cons_linear.c:8617
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:24423
static SCIP_DECL_CONSPRESOL(consPresolLinear)
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip.c:40996
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:85
#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:18947
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:41305
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:3598
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip.c:5810
#define SCIPfreeMemoryArrayNull(scip, ptr)
Definition: scip.h:20374
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:27851
#define SCIPABORT()
Definition: def.h:235
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:7793
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:7078
static INFERINFO intToInferInfo(int i)
Definition: cons_linear.c:359
int SCIPconsGetNLocksPos(SCIP_CONS *cons)
Definition: cons.c:7953
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:7823
int SCIPconsGetNLocksNeg(SCIP_CONS *cons)
Definition: cons.c:7963
#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:3931
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:27746
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:7189
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition: scip.c:36444
#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:41878
#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)